diff options
author | erikdebruijn <erikdebruijn@cb376a5e-1013-0410-a455-b6b1f9ac8223> | 2010-03-11 21:22:49 +0000 |
---|---|---|
committer | erikdebruijn <erikdebruijn@cb376a5e-1013-0410-a455-b6b1f9ac8223> | 2010-03-11 21:22:49 +0000 |
commit | 4eb3ef1a878f26fc6deedf0e503153b08b84b02c (patch) | |
tree | ef77711dd8af12c3c97d9c621093348c8d77040f | |
parent | efa612a74fa25f82b6304bac852887d0e78d2915 (diff) | |
download | reprap-backup-4eb3ef1a878f26fc6deedf0e503153b08b84b02c.tar.gz reprap-backup-4eb3ef1a878f26fc6deedf0e503153b08b84b02c.zip |
Added the open source code for people to modify their BfB electronics firmware. BitsFromBytes have kindly provided {RapMan,G_Code,OLED,Stepper,Extruder,Screens}{.h,.c}. Other files were added by me to get a version that compiles succesfully with MPLAB 8.40
which can be downloaded for free from Microchip.com.
git-svn-id: https://reprap.svn.sourceforge.net/svnroot/reprap@3555 cb376a5e-1013-0410-a455-b6b1f9ac8223
91 files changed, 139415 insertions, 0 deletions
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Bits From Bytes Software Licence Agreement.pdf b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Bits From Bytes Software Licence Agreement.pdf Binary files differnew file mode 100644 index 00000000..33ac7f9c --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Bits From Bytes Software Licence Agreement.pdf diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/CreativeCommons-by-nc-sa-3.0-summary.pdf b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/CreativeCommons-by-nc-sa-3.0-summary.pdf Binary files differnew file mode 100644 index 00000000..bca9532f --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/CreativeCommons-by-nc-sa-3.0-summary.pdf diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/CreativeCommons-by-nc-sa-3.0.pdf b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/CreativeCommons-by-nc-sa-3.0.pdf Binary files differnew file mode 100644 index 00000000..95ea2819 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/CreativeCommons-by-nc-sa-3.0.pdf diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Enviroment.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Enviroment.h new file mode 100644 index 00000000..665c165d --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Enviroment.h @@ -0,0 +1,100 @@ +/**********************************************************************
+ ************************* Environment.h ****************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+//SPI2 pins for SD card see HardwareProfile
+#define OLED_CS PORTBbits.RB5 //Analog pin
+// Description: OLED-SPI Chip Select TRIS bit
+#define OLED_CS_TRIS TRISBbits.TRISB5
+#define DC PORTEbits.RE6 //Digital
+#define RES PORTEbits.RE7 //Digital
+
+
+//General Defines
+#define On 1
+#define OFF 0
+//#define TRUE 1
+//#define FALSE 0
+
+#define CLOCK_SPEED 80000000
+#define INPUT_PIN 1
+#define OUTPUT_PIN 0
+
+//Stepper Setup
+#define EXTRUDER_STEP_PER_REV 3200
+#define PR3_FREQUENCY 5e6 //=80MHz (sysclk) div_8 then div 2 for Pre-Scaler
+#define PR3_CONSTANT PR3_FREQUENCY*600/EXTRUDER_STEP_PER_REV //Use for 600 RPM * 10 to allow int maths
+
+//Interrupt defines
+#define _T3IE IEC0bits.T3IE
+#define _T3IF IFS0bits.T3IF
+
+//Buttons
+#define YPlusTop_Btn PORTBbits.RB15 //Analog pin
+#define YMinusBot_Btn PORTBbits.RB4 //Analog pin
+#define XPlusRight_Btn PORTBbits.RB3 //Analog pin
+#define XMinusLeft_Btn PORTBbits.RB2 //Analog pin
+#define ZPlus_up_Btn PORTFbits.RF5 //Digital pin
+#define ZMinus_down_Btn PORTFbits.RF4 //Digital pin
+#define Manual_Select PORTGbits.RG9 //Digital pin
+
+//Axis Limit switches
+#define X_HomeSwitch PORTDbits.RD4 //Digital pin
+#define Y_HomeSwitch PORTCbits.RC13 //Digital pin
+#define Z_HomeSwitch PORTCbits.RC14 //Digital pin
+
+//FETS
+#define HEATER PORTFbits.RF0 //Digital pin
+#define FAN PORTEbits.RE5 //Digital pin
+#define AUX PORTDbits.RD11 //Digital pin
+
+#define FILLAMENT_ERROR PORTBbits.RB0 //Analog pin
+
+//Analog
+#define THERMISTOR_ADC 11 //B11 Thermistor Analog Channel
+#define TOOL_ID 12 //B12 TOOL identification resistor
+
+//Display mode defines
+#define MANUAL_MOVE 0
+#define TEMPERATURE 1
+#define RPM 2
+#define AUTO_MODE 3
+
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Extruder.c b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Extruder.c new file mode 100644 index 00000000..c9b7d73d --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Extruder.c @@ -0,0 +1,510 @@ +/**********************************************************************
+ *************************** Extruder.c *****************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ * Erik de Bruijn 11/03/2010 Less limiting of the mininum extrusion rate!
+ ***********************************************************************/
+#include "Extruder.h"
+#include "Stepper.h"
+#include "Enviroment.h"
+#include "G_Code.h"
+#include "OLED.h"
+#include <plib.h> //required for interrupt handlers
+#include "stdlib.h"
+
+#define INPUT 1
+#define OUTPUT 0
+#define PRESSED 0
+#define NOT_PRESSED 1
+
+//default values for extruder reverse and prime steps
+#define STEPS_TO_REVERSE 1000
+#define STEPS_TO_PRIME 1000
+#define Z_HOP_STEPS 500
+
+//Variables
+int Thermistor_Failure_Counter = 0;
+int ADC_reading = 0;
+
+volatile int StepReady;
+//long Reverse_ms = 50;
+//long Prime_ms = 25;
+int SampleCountThermistor = 0;
+long AveSamplesThermistor = 0;
+long LowValue,HighValue,Range;
+float Fraction;
+long DataVal,TempVal;
+long raw_temperature;
+float temperature1;
+//char mode;
+int HeaterON = 0; //Heater Flag
+int temperature_OK = FALSE; //Motor flag
+short update_temp = FALSE;
+long SetTemperature = 0; //Value set from control board
+int RPM_Setting = 400;
+
+int PR3_Setting = 65525, Step_Cycle = 0, Direction = CCW;
+int RPM_Setting_Old = 0;
+int New_Data = FALSE;
+int UART_Counter = 0;
+char Message[20];
+
+int Reverse_Steps;
+int Prime_Steps;
+int Reverse_Step_Count;
+int Prime_Step_Count;
+
+int Temperature_Cycle = 0;
+extern int Operation_Mode;
+extern char FastMoveMotorEnable;//Flag to switch motor on/off during fast move
+
+//Thermistor 204GT 200K Ohms at ambient 600 ohm ref resister, 5V
+const long Therm_Table[31] = {
+1024,1023,1022,1020,1018,1015,1010,1004,995,984, //0-90
+969,950,927,899,865,827,784,737,687,635, //100-190
+583,531,480,433,388,346,309,275,244,217, //200-290
+193}; //300
+
+
+
+/***********************************************************/
+// Functions
+/***********************************************************/
+//low priority interrupt for running the temperature control loop
+void __ISR( _TIMER_2_VECTOR,ipl4) T2InterruptHandler(void)
+{
+ switch(Temperature_Cycle)
+ {
+ case 0: //maintains the ave. raw temp reading
+ ADC_reading = Read_Analog(THERMISTOR_ADC);
+
+ if (ADC_reading > 0)
+ {
+ AveSamplesThermistor += ADC_reading;
+ ++SampleCountThermistor;
+ if (SampleCountThermistor > 9)
+ {
+ raw_temperature = AveSamplesThermistor/10;
+ SampleCountThermistor = 0;
+ AveSamplesThermistor = 0;
+ Temperature_Cycle = 1;
+ break;
+ }
+ }
+ Temperature_Cycle = 0;
+ break;
+ case 1: //returns the temperature in DegC from raw_temperature
+ temperature1 = Thermistor_LookUp(raw_temperature);
+ Temperature_Cycle = 2;
+ break;
+ case 2: //changes settings
+ Control_Temperature();
+ Temperature_Cycle = 0;
+ if(HEATER)Thermistor_Failure_Counter++;
+ else Thermistor_Failure_Counter = 0;
+
+ if (!RPM_Change)
+ {
+ if (!XPlusRight_Btn){RPM_Change = 1;RPM_Setting += 1;}//ERIK: was 10
+ if (!XMinusLeft_Btn){RPM_Change = 1;RPM_Setting -=1;}//ERIK: was 10
+ }
+ if (!Temp_Change)
+ {
+ if (!YPlusTop_Btn) {Temp_Change = 1;SetTemperature++;}
+ if (!YMinusBot_Btn) {Temp_Change = 1;SetTemperature--;}
+ }
+ break;
+ }
+ TMR2 = 0; //Reset clock
+ mT2ClearIntFlag();
+
+}//ISR Timer2
+
+/***********************************************************/
+//Stepper Interrupt Control
+void __ISR( _TIMER_3_VECTOR,ipl7) T3InterruptHandler(void)
+{
+ switch(Step_Cycle){
+ case 0:
+ if (!StepReady)
+ {
+ if (Reverse_Step_Count>0)--Reverse_Step_Count; //decrement step count
+ if (Prime_Step_Count>0)--Prime_Step_Count;
+ StepReady = 1; //Step taken from count
+ }
+ EXTRUDER_DIR = Direction;
+ PR3 = 5;
+ Step_Cycle = 1;
+
+ break;
+ case 1:
+ if (StepReady)
+ {
+ EXTRUDER_STEP = On; //Step pin high
+ }
+ PR3 = 10;
+ Step_Cycle = 2;
+ break;
+ case 2:
+ if (StepReady)
+ {
+ EXTRUDER_STEP = OFF; //step pin low
+ }
+ PR3 = PR3_Setting;
+ Step_Cycle = 0;
+ StepReady = 0; //Step complete
+ break;
+ }
+ TMR3 = 0;
+ mT3ClearIntFlag();
+
+}//ISR Timer3
+
+/***********************************************************/
+void Control_Stepper_Motor(void)
+{
+ RPM_Setting_Old = RPM_Setting;
+
+ if (RPM_Setting < 2) RPM_Setting = 2; //Limit minimum to 1.5 RPM // ERIK: limit 0.2
+ if (RPM_Setting > 2000) RPM_Setting = 2000; //Limit maximum to 200 RPM
+ PR3_Setting=(PR3_CONSTANT/RPM_Setting)-25;
+
+ if(temperature_OK){
+ EXTRUDER_DISABLE = FALSE; //run motor
+ if(RPM_Setting <=15)EXTRUDER_DISABLE = TRUE; //If slower than 1.5RPM turn motor off
+ }
+ else EXTRUDER_DISABLE = TRUE;
+
+}//Control_Stepper_Motor
+
+/*************************************************/
+void Control_Temperature(void)
+{
+//Change_M104 flag to alter the heating method
+//Change_M104 == 1 temperature is changed by G_Code the new temp
+//must be achieved before it continues
+//Change_M104 == 0 is used during printing
+extern char Change_M104;
+extern char PauseFlag;
+
+ if(SetTemperature<0)SetTemperature = 0;
+ if(SetTemperature>300)SetTemperature = 300;
+
+ if (PauseFlag == 0)
+ {
+ if (temperature1 < SetTemperature)HEATER = On;
+ else HEATER = OFF;
+ }
+ else HEATER = OFF;
+
+ if (Change_M104 == 0) //Temperature control during print
+ {
+ if ((temperature1 < SetTemperature-10)||
+ (temperature1 > SetTemperature+10)||
+ (SetTemperature<100))
+ {
+ temperature_OK = FALSE; //To control motor
+ EXTRUDER_DISABLE = TRUE;
+ }
+ else temperature_OK = TRUE;
+ }
+
+ if (Change_M104 == 1) //Temperature change called for by G_Code
+ {
+ if ((temperature1 < SetTemperature-1)||
+ (temperature1 > SetTemperature+1)||
+ (SetTemperature<100)||
+ (temperature1 == 0))
+ {
+ temperature_OK = FALSE; //To control motor
+ EXTRUDER_DISABLE = TRUE;
+ }
+ else temperature_OK = TRUE;
+
+ }
+
+ if (EnableFanControl == TRUE)
+ {
+ if (temperature1 < SetTemperature-5) FAN = OFF; //Fan control
+ else FAN = On;
+ }
+
+ if (temperature1 == -1)Extruder_Status(OFF);//Error condition switch all off
+ if (temperature1 == 999)Extruder_Status(OFF);//Error condition switch all off
+
+}//Control_Temperature
+
+/*************************************************/
+float Thermistor_LookUp(long raw_temperature)
+{
+float temperature;
+int k;
+
+ if (raw_temperature < 28){temperature = 999;return temperature;} //Value over temp
+ if (raw_temperature >= 1023 && Thermistor_Failure_Counter > 50)
+ {temperature = -1;return temperature;}//Thermistor failure after 5 bad ave.readings
+
+ for(k=0; k<31; ++k){ // Loop through the Thermistor array
+ TempVal = Therm_Table[k];
+ if (raw_temperature > TempVal){
+ LowValue = TempVal;
+ HighValue = Therm_Table[k-1];
+ Range = HighValue - LowValue; //contains the range
+ DataVal = raw_temperature - LowValue;
+ Fraction = (float)DataVal/Range;
+ Fraction *= 10; //as the range is 10Degrees
+ temperature = (float)(k*10) - Fraction;
+ return temperature;
+ }
+ }
+}//Thermistor_LookUp
+
+/*************************************************/
+int Read_Analog(int Ch)
+{
+int i;
+ AD1CHSbits.CH0SA = Ch; //select analog +ve input
+ AD1CON1bits.SAMP = 1; //start sampling
+ for(i=0;i<200;i++); //delay
+ AD1CON1bits.SAMP = 0;
+ while (!AD1CON1bits.DONE); //wait for conversion to complete
+ return ADC1BUF0; //read the conversion result
+
+}//Read_Analog
+
+/*************************************************/
+void Extruder_Status(int on_off)
+{
+ switch(on_off == On){
+ case On:
+ EXTRUDER_DISABLE = !TRUE;
+ mT2IntEnable(TRUE); //Enable T2 interrputs Heater
+ mT3IntEnable(TRUE); //Enable T3 interrputs Stepper
+ //Delayms(1000); //Time to get first reading from Thermistor
+ Thermistor_Failure_Counter = 0;
+ break;
+ case OFF:
+ HEATER = OFF;
+ EXTRUDER_DISABLE = TRUE;
+ mT2IntEnable(!TRUE); //Disable T2 interrputs Heater
+ mT3IntEnable(!TRUE); //Disable T3 interrputs Stepper
+ break;
+ case NO_MOTOR:
+ EXTRUDER_DISABLE = TRUE;
+ mT3IntEnable(!TRUE);
+ break;
+ }
+}//Extruder_Status
+
+/*************************************************/
+void InitExtruder(void)
+{
+ //Initializations
+ TRISEbits.TRISE1 = OUTPUT; //Step
+ TRISEbits.TRISE2 = OUTPUT; //Dir
+ TRISEbits.TRISE0 = OUTPUT; //Enable
+
+ mOSCSetPBDIV(OSC_PB_DIV_8);
+
+ //Timer 2 is used to run the temperature control
+ //PB clk = 8MHz Post scaler = 2 to 1 tick every 25uS
+ T2CON = 0x0; //256 PS setting register
+ T2CONSET = 0x0070; //Set PS to 2
+ TMR2 = 0; //Reset clock
+ PR2 = 500; //Initialise PR2 value (when T2 matches PR2 it interrupts)
+ mT2SetIntPriority(4); //Set T2 interrupt to LOW priority
+ mT2ClearIntFlag(); //Clear interrupt flag
+ T2CONSET = 0x8000; //Turn on T2
+ mT2IntEnable(!TRUE); //Enable T2 interrputs
+
+ //Timer 3 is used to time the stepper motor steps
+ //PB clk = 8MHz Post scaler = 2 to 1 tick every 25uS
+ T3CON = 0x0; //Clear timer setting register
+ T3CONSET = 0x0010; //Set PS to 2
+ TMR3 = 0; //Reset clock
+ PR3 = 5000;//500; //Initialise PR3 value (when T3 matches PR3 it interrupts)
+ mT3SetIntPriority(7); //Set T3 interrupt to top priority
+ INTEnableSystemMultiVectoredInt();//Set T3 to vectored i.e. Fast
+ mT3ClearIntFlag(); //Clear interrupt flag
+ T3CONSET = 0x8000; //Turn on T3
+
+ mT3IntEnable(!TRUE); //Enable T3 interrputs
+ EXTRUDER_DISABLE = TRUE; //Disable Stepper
+ EnableFanControl = FALSE; //Default - Disable fan
+ FastMoveMotorEnable = FALSE; //Default - set extruder motor off
+
+}//InitExtruder
+
+/***********************************************************/
+void Manual_Extruder( void )
+{
+int i=0;
+ OLED_Fill_RAM(BLANK_SCREEN);
+ while(!XPlusRight_Btn); //Wait for menu selection key to be released
+ RPM_Setting = 0;
+ SetTemperature = 0;
+ OLED_Extruder_Screen();
+ Extruder_Status(On);
+ while (Manual_Select == NOT_PRESSED){
+ Control_Stepper_Motor();
+ i++;
+ if(i>1000)
+ {
+ OLED_Extruder_Screen();
+ if (!XPlusRight_Btn)RPM_Setting +=1;//Erik: was 10
+ if (!XMinusLeft_Btn)RPM_Setting -=1;//Erik: was 10
+ if (!YPlusTop_Btn) SetTemperature++;
+ if (!YMinusBot_Btn) SetTemperature--;
+ i=0;
+ }
+ }
+ Extruder_Status(OFF);
+
+}//Manual_Extruder
+
+/***********************************************************/
+// Delay uS
+//Max delay 21,000,000,000 i.e. 2,100 seconds = 35 Minutes
+//Calling has overhead of 260nS i.e. delay = 0 takes 260nS
+//delay = 1 takes 1.26uS
+void delay_us(long delayus)
+{
+int i_util;
+
+ for(i_util=0;i_util<delayus*4;i_util++)
+ {
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ }
+}//delay_us
+
+/***********************************************************/
+// Delay mS
+//See delay_us for limits
+void delay_ms(long delayms)
+{
+ delay_us(delayms*1000);
+
+}//delay_ms
+
+/***********************************************************/
+void Extruder_Reverse(void)
+{
+//StepData Bits 7 XDir, 6 X, 5 YDir, 4 Y, 3 ZDir, 2 Z, 1 & 0 Not used
+//unsigned char StepData = 0; //used for Z hop
+//unsigned int Z_Hop;
+
+ if((Ex_Reverse)&&(EXTRUDER_DISABLE == !TRUE))
+ {
+ /*
+ if (Do_Z_Hop == TRUE) //Gcode switch TODO
+ {
+ //Z Hop up
+ StepData |= 0x08; //Set Z Direction set bit 3 on
+ StepData |= 0x04; //z set step bit 2 on
+ Feed_Rate = 750;
+ Z_Hop = Z_HOP_STEPS;
+ do
+ {
+ AddToStepBuffer(StepData,0,0); //add step data to circular buffer
+ --Z_Hop;
+ }
+ while (Z_Hop>0);
+ Done_Hop_UP = TRUE; Not defined yet
+ }
+ */
+
+ Direction = CW;
+ if (Reverse_Step_Count == 0) //if not set in gCode then use default
+ {
+ if (Reverse_Steps == 0) Reverse_Step_Count = STEPS_TO_REVERSE; //Set number of steps to reverse
+ else Reverse_Step_Count = Reverse_Steps;
+ }
+
+ PR3_Setting=(PR3_CONSTANT/1000)-25; //set up step interrupt
+ while (Reverse_Step_Count >0);//wait for number of steps to complete
+ Direction = CCW; //reset normal direction
+ }
+}
+
+/***********************************************************/
+void Extruder_Prime(void)
+{
+//StepData Bits 7 XDir, 6 X, 5 YDir, 4 Y, 3 ZDir, 2 Z, 1 & 0 Not used
+//unsigned char StepData = 0; //used for Z hop
+//unsigned int Z_Hop;
+
+ if((Ex_Reverse)&&(EXTRUDER_DISABLE == !TRUE))
+ {
+ /*
+ if ((Do_Z_Hop == TRUE)&&(Done_Hop_UP == TRUE)) //GCode switch and there must have been a hop up
+ { //before we hop down.
+ //Z Hop down
+ StepData = StepData & ~0x08; //Set Z Direction set bit 3 off
+ StepData |= 0x04; //z set step bit 2 on
+ Feed_Rate = 750;
+ Z_Hop = Z_HOP_STEPS;
+ do
+ {
+ AddToStepBuffer(StepData,0,0); //add step data to circular buffer
+ --Z_Hop;
+ }
+ while (Z_Hop>0);
+ Done_Hop_UP = FALSE; Not defined yet
+ }
+ */
+ Direction = CCW;
+ if (Prime_Step_Count == 0)//if not set use default
+ {
+ if (Prime_Steps == 0) Prime_Step_Count = STEPS_TO_PRIME; //Set number of steps to reverse
+ else Prime_Step_Count = Prime_Steps;
+ }
+
+ PR3_Setting=(PR3_CONSTANT/1000)-25;//was1500
+ while (Prime_Step_Count >0);//wait for number of steps to complete
+ PR3_Setting=(PR3_CONSTANT/RPM_Setting)-25;
+ }
+}
+/***********************************************************/
+
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Extruder.d b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Extruder.d new file mode 100644 index 00000000..691be876 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Extruder.d @@ -0,0 +1,36 @@ +Extruder.o: Extruder.c Extruder.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h \
+ Enviroment.h Stepper.h G_Code.h OLED.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Extruder.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Extruder.h new file mode 100644 index 00000000..2e4f0c58 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Extruder.h @@ -0,0 +1,77 @@ +/**********************************************************************
+ *************************** Extruder.h *****************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+#include <p32xxxx.h>
+//#include <plib.h> //required for interrupt handlers
+#include "GenericTypeDefs.h"
+#include "Enviroment.h"
+//#include "stdlib.h"
+
+#define CW 0
+#define CCW 1
+#define NO_MOTOR 2
+
+#define EXTRUDER_DISABLE PORTEbits.RE0 //Digital
+#define EXTRUDER_STEP PORTEbits.RE1 //Digital
+#define EXTRUDER_DIR PORTEbits.RE2 //Digital
+
+extern char ExtruderStatus; //M103,M101 flag extruder off and on
+extern int Feed_Rate;
+
+int Ex_Reverse;
+
+//Functions
+int Read_Analog(int Ch);
+float Thermistor_LookUp(long raw_temperature);
+char RPM_Change; //set if RPM has changed
+char Temp_Change; //set if Temperature has changed
+char EnableFanControl; //Set if Fan is to be active
+
+void Control_Temperature(void);
+void InitExtruder(void);
+void delay_us(long delayus);
+void delay_ms(long delayms);
+void Control_Stepper_Motor(void);
+void Manual_Extruder(void);
+extern void Extruder_Status(int on_off);
+extern void Extruder_Reverse(void);
+extern void Extruder_Prime(void);
+
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSDefs.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSDefs.h new file mode 100644 index 00000000..5eabe7d0 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSDefs.h @@ -0,0 +1,532 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: FSDefs.h
+ * Dependencies: GenericTypeDefs.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#ifndef _FSDEF__H
+#define _FSDEF__H
+
+#include "GenericTypeDefs.h"
+
+// Summary: An enumeration used for various error codes.
+// Description: The CETYPE enumeration is used to indicate different error conditions during device operation.
+typedef enum _CETYPE
+{
+ CE_GOOD = 0, // No error
+ CE_ERASE_FAIL, // An erase failed
+ CE_NOT_PRESENT, // No device was present
+ CE_NOT_FORMATTED, // The disk is of an unsupported format
+ CE_BAD_PARTITION, // The boot record is bad
+ CE_UNSUPPORTED_FS, // The file system type is unsupported
+ CE_INIT_ERROR, // An initialization error has occured
+ CE_NOT_INIT, // An operation was performed on an uninitialized device
+ CE_BAD_SECTOR_READ, // A bad read of a sector occured
+ CE_WRITE_ERROR, // Could not write to a sector
+ CE_INVALID_CLUSTER, // Invalid cluster value > maxcls
+ CE_FILE_NOT_FOUND, // Could not find the file on the device
+ CE_DIR_NOT_FOUND, // Could not find the directory
+ CE_BAD_FILE, // File is corrupted
+ CE_DONE, // No more files in this directory
+ CE_COULD_NOT_GET_CLUSTER, // Could not load/allocate next cluster in file
+ CE_FILENAME_2_LONG, // A specified file name is too long to use
+ CE_FILENAME_EXISTS, // A specified filename already exists on the device
+ CE_INVALID_FILENAME, // Invalid file name
+ CE_DELETE_DIR, // The user tried to delete a directory with FSremove
+ CE_DIR_FULL, // All root dir entry are taken
+ CE_DISK_FULL, // All clusters in partition are taken
+ CE_DIR_NOT_EMPTY, // This directory is not empty yet, remove files before deleting
+ CE_NONSUPPORTED_SIZE, // The disk is too big to format as FAT16
+ CE_WRITE_PROTECTED, // Card is write protected
+ CE_FILENOTOPENED, // File not opened for the write
+ CE_SEEK_ERROR, // File location could not be changed successfully
+ CE_BADCACHEREAD, // Bad cache read
+ CE_CARDFAT32, // FAT 32 - card not supported
+ CE_READONLY, // The file is read-only
+ CE_WRITEONLY, // The file is write-only
+ CE_INVALID_ARGUMENT, // Invalid argument
+ CE_TOO_MANY_FILES_OPEN // Too many files are already open
+} CETYPE;
+
+
+// Summary: A macro indicating a dir entry was found
+// Description: The FOUND macro indicates that a directory entry was found in the specified position
+#define FOUND 0
+
+// Summary: A macro indicating no dir entry was found
+// Description: The NOT_FOUND macro indicates that the specified directory entry to load was deleted
+#define NOT_FOUND 1
+
+// Summary: A macro indicating that no more files were found
+// Description: The NO_MORE macro indicates that there are no more directory entries to search for
+#define NO_MORE 2
+
+
+
+// Summary: A macro indicating the device is formatted with FAT12
+// Description: The FAT12 macro is used to indicate that the file system on the device being accessed is a FAT12 file system.
+#define FAT12 1
+
+// Summary: A macro indicating the device is formatted with FAT16
+// Description: The FAT16 macro is used to indicate that the file system on the device being accessed is a FAT16 file system.
+#define FAT16 2
+
+// Summary: A macro indicating the device is formatted with FAT32
+// Description: The FAT32 macro is used to indicate that the file system on the device being accessed is a FAT32 file system.
+#define FAT32 3
+
+
+
+// Summary: A read-only attribute macro
+// Description: A macro for the read-only attribute. A file with this attribute should not be written to. Note that this
+// attribute will not actually prevent a write to the file; that functionality is operating-system dependant. The
+// user should take care not to write to a read-only file.
+#define ATTR_READ_ONLY 0x01
+
+// Summary: A hidden attribute macro
+// Description: A macro for the hidden attribute. A file with this attribute may be hidden from the user, depending on the
+// implementation of the operating system.
+#define ATTR_HIDDEN 0x02
+
+// Summary: A system attribute macro
+// Description: A macro for the system attribute. A file with this attribute is used by the operating system, and should not be
+// modified. Note that this attribute will not actually prevent a write to the file.
+#define ATTR_SYSTEM 0x04
+
+// Summary: A volume attribute macro
+// Description: A macro for the volume attribute. If the first directory entry in the root directory has the volume attribute set,
+// the device will use the name in that directory entry as the volume name.
+#define ATTR_VOLUME 0x08
+
+// Summary: A macro for the attributes for a long-file name entry
+// Description: A macro for the long-name attributes. If a directory entry is used in a long-file name implementation, it will have
+// all four lower bits set. This indicates that any software that does not support long file names should ignore that
+// entry.
+#define ATTR_LONG_NAME 0x0f
+
+// Summary: A directory attribute macro
+// Description: A macro for the directory attribute. If a directory entry has this attribute set, the file it points to is a directory-
+// type file, and will contain directory entries that point to additional directories or files.
+#define ATTR_DIRECTORY 0x10
+
+// Summary: An archive attribute macro
+// Description: A macro for the archive attribute. This attribute will indicate to some archiving programs that the file with this
+// attribute needs to be backed up. Most operating systems create files with the archive attribute set.
+#define ATTR_ARCHIVE 0x20
+
+// Summary: A macro for all attributes
+// Description: A macro for all attributes. The search functions in this library require an argument that determines which attributes
+// a file is allowed to have in order to be found. If ATTR_MASK is specified as this argument, any file may be found, regardless
+// of its attributes.
+#define ATTR_MASK 0x3f
+
+
+
+// Summary: A macro to indicate an empty FAT entry
+// Description: The CLUSTER_EMPTY value is used to indicate that a FAT entry and it's corresponding cluster are available.
+#define CLUSTER_EMPTY 0x0000
+
+// Summary: A macro to indicate the last cluster value for FAT12
+// Description: The LAST_CLUSTER_FAT12 macro is used when reading the FAT to indicate that the next FAT12 entry for a file contains
+// the end-of-file value.
+#define LAST_CLUSTER_FAT12 0xff8
+
+// Summary: A macro to indicate the last cluster value for FAT16
+// Description: The LAST_CLUSTER_FAT16 macro is used when reading the FAT to indicate that the next FAT16 entry for a file contains
+// the end-of-file value.
+#define LAST_CLUSTER_FAT16 0xfff8
+
+// Summary: A macro to indicate the last allocatable cluster for FAT12
+// Description: The END_CLUSTER_FAT12 value is used as a comparison in FAT12 to determine that the firmware has reached the end of
+// the range of allowed allocatable clusters.
+#define END_CLUSTER_FAT12 0xFF7
+
+// Summary: A macro to indicate the last allocatable cluster for FAT16
+// Description: The END_CLUSTER_FAT16 value is used as a comparison in FAT16 to determine that the firmware has reached the end of
+// the range of allowed allocatable clusters.
+#define END_CLUSTER_FAT16 0xFFF7
+
+// Summary: A macro to indicate the failure of the ReadFAT function
+// Description: The CLUSTER_FAIL_FAT16 macro is used by the ReadFAT function to indicate that an error occured reading a FAT12 or FAT16
+// file allocation table. Note that since '0xFFF8' is used for the last cluster return value in the FAT16 implementation
+// the end-of-file value '0xFFFF' can be used to indicate an error condition.
+#define CLUSTER_FAIL_FAT16 0xFFFF
+
+
+
+#ifdef SUPPORT_FAT32
+ // Summary: A macro to indicate the last cluster value for FAT32
+ // Description: The LAST_CLUSTER_FAT32 macro is used when reading the FAT to indicate that the next FAT32 entry for a file contains
+ // the end-of-file value.
+ #define LAST_CLUSTER_FAT32 0x0FFFFFF8
+
+ // Summary: A macro to indicate the last allocatable cluster for FAT32
+ // Description: The END_CLUSTER_FAT32 value is used as a comparison in FAT32 to determine that the firmware has reached the end of
+ // the range of allowed allocatable clusters.
+ #define END_CLUSTER_FAT32 0x0FFFFFF7
+
+ // Summary: A macro to indicate the failure of the ReadFAT function
+ // Description: The CLUSTER_FAIL_FAT32 macro is used by the ReadFAT function to indicate that an error occured reading a FAT32
+ // file allocation able.
+ #define CLUSTER_FAIL_FAT32 0x0FFFFFFF
+
+#endif
+
+// Summary: A macro indicating the number of bytes in a directory entry.
+// Description: The NUMBER_OF_BYTES_IN_DIR_ENTRY macro represents the number of bytes in one directory entry. It is used to calculate
+// the number of sectors in the root directory based on information in the boot sector.
+#define NUMBER_OF_BYTES_IN_DIR_ENTRY 32
+
+
+
+// Summary: A macro for a deleted dir entry marker.
+// Description: The DIR_DEL macro is used to mark a directory entry as deleted. When a file is deleted, this value will replace the
+// first character in the file name, and will indicate that the file the entry points to was deleted.
+#define DIR_DEL 0xE5
+
+// Summary: A macro for the last dir entry marker.
+// Description: The DIR_EMPTY macro is used to indicate the last entry in a directory. Since entries in use cannot start with a 0 and
+// deleted entries start with the DIR_DEL character, a 0 will mark the end of the in-use or previously used group of
+// entries in a directory
+#define DIR_EMPTY 0
+
+
+
+// Summary: A macro used to indicate the length of an 8.3 file name
+// Description: The DIR_NAMESIZE macro is used when validing the name portion of 8.3 filenames
+#define DIR_NAMESIZE 8
+
+// Summary: A macro used to indicate the length of an 8.3 file extension
+// Description: The DIR_EXTENSION macro is used when validating the extension portion of 8.3 filenames
+#define DIR_EXTENSION 3
+
+// Summary: A macro used to indicate the length of an 8.3 file name and extension
+// Description: The DIR_NAMECOMP macro is used when validating 8.3 filenames
+#define DIR_NAMECOMP (DIR_NAMESIZE+DIR_EXTENSION)
+
+
+
+// Summary: A macro to write a byte to RAM
+// Description: The RAMwrite macro is used to write a byte of data to a RAM array
+#define RAMwrite( a, f, d) *(a+f) = d
+
+// Summary: A macro to read a byte from RAM
+// Description: The RAMread macro is used to read a byte of data from a RAM array
+#define RAMread( a, f) *(a+f)
+
+// Summary: A macro to read a 16-bit word from RAM
+// Description: The RAMreadW macro is used to read two bytes of data from a RAM array
+#define RAMreadW( a, f) *(WORD *)(a+f)
+
+// Summary: A macro to read a 32-bit word from RAM
+// Description: The RAMreadD macro is used to read four bytes of data from a RAM array
+#define RAMreadD( a, f) *(DWORD *)(a+f)
+
+
+
+#ifndef EOF
+ // Summary: Indicates error conditions or end-of-file conditions
+ // Description: The EOF macro is used to indicate error conditions in some function calls. It is also used to indicate
+ // that the end-of-file has been reached.
+ #define EOF ((int)-1)
+#endif
+
+
+
+// Summary: A structure containing information about the device.
+// Description: The DISK structure contains information about the device being accessed.
+typedef struct
+{
+ BYTE * buffer; // Address of the global data buffer used to read and write file information
+ DWORD firsts; // Logical block address of the first sector of the FAT partition on the device
+ DWORD fat; // Logical block address of the FAT
+ DWORD root; // Logical block address of the root directory
+ DWORD data; // Logical block address of the data section of the device.
+ WORD maxroot; // The maximum number of entries in the root directory.
+ DWORD maxcls; // The maximum number of clusters in the partition.
+ WORD fatsize; // The number of sectors in the FAT
+ BYTE fatcopy; // The number of copies of the FAT in the partition
+ BYTE SecPerClus; // The number of sectors per cluster in the data region
+ BYTE type; // The file system type of the partition (FAT12, FAT16 or FAT32)
+ BYTE mount; // Device mount flag (TRUE if disk was mounted successfully, FALSE otherwise)
+#ifdef __PIC32MX__
+} __attribute__ ((packed)) DISK;
+#else
+} DISK;
+#endif
+
+
+#ifdef __18CXX
+ // Summary: A 24-bit data type
+ // Description: The SWORD macro is used to defined a 24-bit data type. For 16+ bit architectures, this must be represented as
+ // an array of three bytes.
+ typedef unsigned short long SWORD;
+#else
+ // Summary: A 24-bit data type
+ // Description: The SWORD macro is used to defined a 24-bit data type. For 16+ bit architectures, this must be represented as
+ // an array of three bytes.
+ typedef struct
+ {
+ unsigned char array[3];
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) SWORD;
+#else
+ } SWORD;
+#endif
+#endif
+
+
+
+// Summary: A structure containing the bios parameter block for a FAT12 file system (in the boot sector)
+// Description: The _BPB_FAT12 structure provides a layout of the "bios parameter block" in the boot sector of a FAT12 partition.
+typedef struct {
+ SWORD BootSec_JumpCmd; // Jump Command
+ BYTE BootSec_OEMName[8]; // OEM name
+ WORD BootSec_BPS; // Number of bytes per sector
+ BYTE BootSec_SPC; // Number of sectors per cluster
+ WORD BootSec_ResrvSec; // Number of reserved sectors at the beginning of the partition
+ BYTE BootSec_FATCount; // Number of FATs on the partition
+ WORD BootSec_RootDirEnts; // Number of root directory entries
+ WORD BootSec_TotSec16; // Total number of sectors
+ BYTE BootSec_MDesc; // Media descriptor
+ WORD BootSec_SPF; // Number of sectors per FAT
+ WORD BootSec_SPT; // Number of sectors per track
+ WORD BootSec_HeadCnt; // Number of heads
+ DWORD BootSec_HiddenSecCnt; // Number of hidden sectors
+ DWORD BootSec_Reserved; // Reserved space
+ BYTE BootSec_DriveNum; // Drive number
+ BYTE BootSec_Reserved2; // Reserved space
+ BYTE BootSec_BootSig; // Boot signature - equal to 0x29
+ BYTE BootSec_VolID[4]; // Volume ID
+ BYTE BootSec_VolLabel[11]; // Volume Label
+ BYTE BootSec_FSType[8]; // File system type in ASCII. Not used for determination
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) _BPB_FAT12;
+#else
+ } _BPB_FAT12;
+#endif
+
+// Summary: A structure containing the bios parameter block for a FAT16 file system (in the boot sector)
+// Description: The _BPB_FAT16 structure provides a layout of the "bios parameter block" in the boot sector of a FAT16 partition.
+typedef struct {
+ SWORD BootSec_JumpCmd; // Jump Command
+ BYTE BootSec_OEMName[8]; // OEM name
+ WORD BootSec_BPS; // Number of bytes per sector
+ BYTE BootSec_SPC; // Number of sectors per cluster
+ WORD BootSec_ResrvSec; // Number of reserved sectors at the beginning of the partition
+ BYTE BootSec_FATCount; // Number of FATs on the partition
+ WORD BootSec_RootDirEnts; // Number of root directory entries
+ WORD BootSec_TotSec16; // Total number of sectors
+ BYTE BootSec_MDesc; // Media descriptor
+ WORD BootSec_SPF; // Number of sectors per FAT
+ WORD BootSec_SPT; // Number of sectors per track
+ WORD BootSec_HeadCnt; // Number of heads
+ DWORD BootSec_HiddenSecCnt; // Number of hidden sectors
+ DWORD BootSec_TotSec32; // Total sector count (32 bits)
+ BYTE BootSec_DriveNum; // Drive number
+ BYTE BootSec_Reserved; // Reserved space
+ BYTE BootSec_BootSig; // Boot signature - equal to 0x29
+ BYTE BootSec_VolID[4]; // Volume ID
+ BYTE BootSec_VolLabel[11]; // Volume Label
+ BYTE BootSec_FSType[8]; // File system type in ASCII. Not used for determination
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) _BPB_FAT16;
+#else
+ } _BPB_FAT16;
+#endif
+
+// Summary: A structure containing the bios parameter block for a FAT32 file system (in the boot sector)
+// Description: The _BPB_FAT32 structure provides a layout of the "bios parameter block" in the boot sector of a FAT32 partition.
+typedef struct {
+ SWORD BootSec_jmpBoot; // Jump Command
+ BYTE BootSec_OEMName[8]; // OEM name
+ WORD BootSec_BytsPerSec; // Number of bytes per sector
+ BYTE BootSec_SecPerClus; // Number of sectors per cluster
+ WORD BootSec_RsvdSecCnt; // Number of reserved sectors at the beginning of the partition
+ BYTE BootSec_NumFATs; // Number of FATs on the partition
+ WORD BootSec_RootEntCnt; // Number of root directory entries
+ WORD BootSec_TotSec16; // Total number of sectors
+ BYTE BootSec_Media; // Media descriptor
+ WORD BootSec_FATSz16; // Number of sectors per FAT
+ WORD BootSec_SecPerTrk; // Number of sectors per track
+ WORD BootSec_NumHeads; // Number of heads
+ DWORD BootSec_HiddSec; // Number of hidden sectors
+ DWORD BootSec_TotSec32; // Total sector count (32 bits)
+ DWORD BootSec_FATSz32; // Sectors per FAT (32 bits)
+ WORD BootSec_ExtFlags; // Presently active FAT. Defined by bits 0-3 if bit 7 is 1.
+ WORD BootSec_FSVers; // FAT32 filesystem version. Should be 0:0
+ DWORD BootSec_RootClus; // Start cluster of the root directory (should be 2)
+ WORD BootSec_FSInfo; // File system information
+ WORD BootSec_BkBootSec; // Backup boot sector address.
+ BYTE BootSec_Reserved[12]; // Reserved space
+ BYTE BootSec_DrvNum; // Drive number
+ BYTE BootSec_Reserved1; // Reserved space
+ BYTE BootSec_BootSig; // Boot signature - 0x29
+ BYTE BootSec_VolID[4]; // Volume ID
+ BYTE BootSec_VolLab[11]; // Volume Label
+ BYTE BootSec_FilSysType[8]; // File system type in ASCII. Not used for determination
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) _BPB_FAT32;
+#else
+ } _BPB_FAT32;
+#endif
+
+
+// Description: A macro for the boot sector bytes per sector value offset
+#define BSI_BPS 11
+
+// Description: A macro for the boot sector sector per cluster value offset
+#define BSI_SPC 13
+
+// Description: A macro for the boot sector reserved sector count value offset
+#define BSI_RESRVSEC 14
+
+// Description: A macro for the boot sector FAT count value offset
+#define BSI_FATCOUNT 16
+
+// Description: A macro for the boot sector root directory entry count value offset
+#define BSI_ROOTDIRENTS 17
+
+// Description: A macro for the boot sector 16-bit total sector count value offset
+#define BSI_TOTSEC16 19
+
+// Description: A macro for the boot sector sectors per FAT value offset
+#define BSI_SPF 22
+
+// Description: A macro for the boot sector 32-bit total sector count value offset
+#define BSI_TOTSEC32 32
+
+// Description: A macro for the boot sector boot signature offset
+#define BSI_BOOTSIG 38
+
+// Description: A macro for the boot sector file system type string offset
+#define BSI_FSTYPE 54
+
+// Description: A macro for the boot sector 32-bit sector per FAT value offset
+#define BSI_FATSZ32 36
+
+// Description: A macro for the boot sector start cluster of root directory value offset
+#define BSI_ROOTCLUS 44
+
+// Description: A macro for the FAT32 boot sector boot signature offset
+#define BSI_FAT32_BOOTSIG 66
+
+// Description: A macro for the FAT32 boot sector file system type string offset
+#define BSI_FAT32_FSTYPE 82
+
+
+
+// Summary: A partition table entry structure.
+// Description: The PTE_MBR structure contains values found in a partition table entry in the MBR of a device.
+typedef struct
+{
+ BYTE PTE_BootDes; // The boot descriptor (should be 0x00 in a non-bootable device)
+ SWORD PTE_FrstPartSect; // The cylinder-head-sector address of the first sector of the partition
+ BYTE PTE_FSDesc; // The file system descriptor
+ SWORD PTE_LstPartSect; // The cylinder-head-sector address of the last sector of the partition
+ DWORD PTE_FrstSect; // The logical block address of the first sector of the partition
+ DWORD PTE_NumSect; // The number of sectors in a partition
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) PTE_MBR;
+#else
+ } PTE_MBR;
+#endif
+
+
+// Summary: A structure of the organization of a master boot record.
+// Description: The _PT_MBR structure has the same form as a master boot record. When the MBR is loaded from the device, it will
+// be cast as a _PT_MBR structure so the MBR elements can be accessed.
+typedef struct
+{
+ BYTE ConsChkRtn[446]; // Boot code
+ PTE_MBR Partition0; // The first partition table entry
+ PTE_MBR Partition1; // The second partition table entry
+ PTE_MBR Partition2; // The third partition table entry
+ PTE_MBR Partition3; // The fourth partition table entry
+ BYTE Signature0; // MBR signature code - equal to 0x55
+ BYTE Signature1; // MBR signature code - equal to 0xAA
+#ifdef __18CXX
+}_PT_MBR;
+#else
+}__attribute__((packed)) _PT_MBR;
+#endif
+
+// Summary: A pointer to a _PT_MBR structure
+// Description: The PT_MBR pointer points to a _PT_MBR structure.
+typedef _PT_MBR * PT_MBR;
+
+
+
+// Summary: A structure of the organization of a boot sector.
+// Description: The _BootSec structure has the same form as a boot sector. When the boot sector is loaded from the device, it will
+// be cast as a _BootSec structure so the boot sector elements can be accessed.
+typedef struct
+{
+ // A union of different bios parameter blocks
+ union
+ {
+ _BPB_FAT32 FAT_32;
+ _BPB_FAT16 FAT_16;
+ _BPB_FAT12 FAT_12;
+ }FAT;
+ BYTE Reserved[MEDIA_SECTOR_SIZE-sizeof(_BPB_FAT32)-2]; // Reserved space
+ BYTE Signature0; // Boot sector signature code - equal to 0x55
+ BYTE Signature1; // Boot sector signature code - equal to 0xAA
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) _BootSec;
+#else
+ } _BootSec;
+#endif
+
+// Summary: A pointer to a _BootSec structure
+// Description: The BootSec pointer points to a _BootSec structure.
+typedef _BootSec * BootSec;
+
+
+
+// Summary: A macro indicating the offset for the master boot record
+// Description: FO_MBR is a macro that indicates the addresss of the master boot record on the device. When the device is initialized
+// this sector will be read
+#define FO_MBR 0L
+
+
+
+// Summary: A macro for the first boot sector/MBR signature byte
+// Description: The FAT_GOOD_SIGN_0 macro is used to determine that the first byte of the MBR or boot sector signature code is correct
+#define FAT_GOOD_SIGN_0 0x55
+
+// Summary: A macro for the second boot sector/MBR signature byte
+// Description: The FAT_GOOD_SIGN_1 macro is used to determine that the second byte of the MBR or boot sector signature code is correct
+#define FAT_GOOD_SIGN_1 0xAA
+
+
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.c b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.c new file mode 100644 index 00000000..6a42c66b --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.c @@ -0,0 +1,8874 @@ +/******************************************************************************
+*
+* Microchip Memory Disk Drive File System
+*
+******************************************************************************
+* FileName: FSIO.c
+* Dependencies: GenericTypeDefs.h
+* FSIO.h
+* Physical interface include file (SD-SPI.h, CF-PMP.h, ...)
+* string.h
+* stdlib.h
+* FSDefs.h
+* ctype.h
+* salloc.h
+* Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+* Compiler: C18/C30/C32
+* Company: Microchip Technology, Inc.
+* Version: 1.2.0
+*
+* Software License Agreement
+*
+* The software supplied herewith by Microchip Technology Incorporated
+* (the �Company�) for its PICmicro� Microcontroller is intended and
+* supplied to you, the Company�s customer, for use solely and
+* exclusively on Microchip PICmicro Microcontroller products. The
+* software is owned by the Company and/or its supplier, and is
+* protected under applicable copyright laws. All rights are reserved.
+* Any use in violation of the foregoing restrictions may subject the
+* user to criminal sanctions under applicable laws, as well as to
+* civil liability for the breach of the terms and conditions of this
+* license.
+*
+* THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+*
+*****************************************************************************/
+
+#include "FSIO.h"
+#include "GenericTypeDefs.h"
+#include "string.h"
+#include "stdlib.h"
+#include "ctype.h"
+#include "MDD File System\FSDefs.h"
+
+#ifdef ALLOW_FSFPRINTF
+#include "stdarg.h"
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ #ifdef __18CXX
+ #include "salloc.h"
+ #endif
+#endif
+
+#ifndef ALLOW_WRITES
+ #ifdef ALLOW_FORMATS
+ #error Write functions must be enabled to use the format function
+ #endif
+ #ifdef ALLOW_FSFPRINTF
+ #error Write functions must be enabled to use the FSfprintf function
+ #endif
+#endif
+
+#ifdef USEREALTIMECLOCK
+ #ifdef USERDEFINEDCLOCK
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#elif defined USERDEFINEDCLOCK
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#endif
+/*****************************************************************************/
+/* Global Variables */
+/*****************************************************************************/
+
+#ifndef FS_DYNAMIC_MEM
+ FSFILE gFileArray[FS_MAX_FILES_OPEN]; // Array that contains file information (static allocation)
+ BYTE gFileSlotOpen[FS_MAX_FILES_OPEN]; // Array that indicates which elements of gFileArray are available for use
+#endif
+
+DWORD gLastFATSectorRead = 0xFFFF; // Global variable indicating which FAT sector was read last
+BYTE gNeedFATWrite = FALSE; // Global variable indicating that there is information that needs to be written to the FAT
+FSFILE * gBufferOwner = NULL; // Global variable indicating which file is using the data buffer
+DWORD gLastDataSectorRead = 0xFFFFFFFF; // Global variable indicating which data sector was read last
+BYTE gNeedDataWrite = FALSE; // Global variable indicating that there is information that needs to be written to the data section
+BYTE nextClusterIsLast = FALSE; // Global variable indicating that the entries in a directory align with a cluster boundary
+
+// Timing variables
+BYTE gTimeCrtMS; // Global time variable (for timestamps) used to indicate create time (milliseconds)
+WORD gTimeCrtTime; // Global time variable (for timestamps) used to indicate create time
+WORD gTimeCrtDate; // Global time variable (for timestamps) used to indicate create date
+WORD gTimeAccDate; // Global time variable (for timestamps) used to indicate last access date
+WORD gTimeWrtTime; // Global time variable (for timestamps) used to indicate last update time
+WORD gTimeWrtDate; // Global time variable (for timestamps) used to indicate last update date
+
+BYTE gBufferZeroed = FALSE; // Global variable indicating that the data buffer contains all zeros
+
+DWORD FatRootDirClusterValue; // Global variable containing the cluster number of the root dir (0 for FAT12/16)
+
+BYTE FSerrno; // Global error variable. Set to one of many error codes after each function call.
+
+DWORD TempClusterCalc; // Global variable used to store the calculated value of the cluster of a specified sector.
+BYTE dirCleared; // Global variable used by the "recursive" FSrmdir function to indicate that all subdirectories and files have been deleted from the target directory.
+BYTE recache = FALSE; // Global variable used by the "recursive" FSrmdir function to indicate that additional cache reads are needed.
+FSFILE tempCWDobj; // Global variable used to preserve the current working directory information.
+FSFILE gFileTemp; // Global variable used for file operations.
+
+#ifdef ALLOW_DIRS
+ FSFILE cwd; // Global current working directory
+ FSFILE * cwdptr = &cwd; // Pointer to the current working directory
+#endif
+
+
+#ifdef __18CXX
+ #pragma udata dataBuffer
+ BYTE gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ #pragma udata FATBuffer
+ BYTE gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE __attribute__ ((aligned(4))) gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ BYTE __attribute__ ((aligned(4))) gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+
+#pragma udata
+
+DISK gDiskData; // Global structure containing device information.
+
+
+
+/************************************************************************/
+/* Structures and defines */
+/************************************************************************/
+
+// Directory entry structure
+typedef struct
+{
+ char DIR_Name[DIR_NAMESIZE]; // File name
+ char DIR_Extension[DIR_EXTENSION]; // File extension
+ BYTE DIR_Attr; // File attributes
+ BYTE DIR_NTRes; // Reserved byte
+ BYTE DIR_CrtTimeTenth; // Create time (millisecond field)
+ WORD DIR_CrtTime; // Create time (second, minute, hour field)
+ WORD DIR_CrtDate; // Create date
+ WORD DIR_LstAccDate; // Last access date
+ WORD DIR_FstClusHI; // High word of the entry's first cluster number
+ WORD DIR_WrtTime; // Last update time
+ WORD DIR_WrtDate; // Last update date
+ WORD DIR_FstClusLO; // Low word of the entry's first cluster number
+ DWORD DIR_FileSize; // The 32-bit file size
+}_DIRENTRY;
+
+typedef _DIRENTRY * DIRENTRY; // A pointer to a directory entry structure
+
+#define DIRECTORY 0x12 // Value indicating that the CreateFileEntry function will be creating a directory
+
+#define DIRENTRIES_PER_SECTOR (MEDIA_SECTOR_SIZE / 32) // The number of directory entries in a sector
+
+// internal errors
+#define CE_FAT_EOF 60 // Error that indicates an attempt to read FAT entries beyond the end of the file
+#define CE_EOF 61 // Error that indicates that the end of the file has been reached
+
+typedef FSFILE * FILEOBJ; // Pointer to an FSFILE object
+
+#ifdef ALLOW_FSFPRINTF
+
+#define _FLAG_MINUS 0x1 // FSfprintf minus flag indicator
+#define _FLAG_PLUS 0x2 // FSfprintf plus flag indicator
+#define _FLAG_SPACE 0x4 // FSfprintf space flag indicator
+#define _FLAG_OCTO 0x8 // FSfprintf octothorpe (hash mark) flag indicator
+#define _FLAG_ZERO 0x10 // FSfprintf zero flag indicator
+#define _FLAG_SIGNED 0x80 // FSfprintf signed flag indicator
+
+#ifdef __18CXX
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONG 1 // FSfprintf 32-bit argument size flag
+ #define _FMT_SHRTLONG 2 // FSfprintf 24-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#else
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONGLONG 1 // FSfprintf 64-bit argument size flag
+ #define _FMT_LONG 2 // FSfprintf 32-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#endif
+
+#ifdef __18CXX
+ static const rom char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#else
+ static const char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#endif
+
+#endif
+
+/************************************************************************************/
+/* Prototypes */
+/************************************************************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls);
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead);
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle);
+DWORD Cluster2Sector(DISK * disk, DWORD cluster);
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle);
+#ifdef INCREMENTTIMESTAMP
+ void IncrementTimeStamp(DIRENTRY dir);
+#elif defined USEREALTIMECLOCK
+ void CacheTime (void);
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE ReadByte( BYTE* pBuffer, WORD index );
+ WORD ReadWord( BYTE* pBuffer, WORD index );
+ DWORD ReadDWord( BYTE* pBuffer, WORD index );
+#endif
+
+// Function pointer that points to a physical layer's MDD_xxxxx_WriteProtectState function
+extern BYTE MDD_WriteProtectState(void);
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource);
+BYTE ValidateChars (char * FileName, BYTE mode);
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode);
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode);
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n);
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type);
+
+// Write functions
+#ifdef ALLOW_WRITES
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry);
+ BYTE flushData (void);
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters);
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode);
+ BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk);
+ DWORD FATfindEmptyCluster(FILEOBJ fo);
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle);
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode);
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster);
+ BYTE EraseCluster(DISK *disk, DWORD cluster);
+ CETYPE CreateFirstCluster(FILEOBJ fo);
+ DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite);
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode);
+#endif
+
+// Directory functions
+#ifdef ALLOW_DIRS
+ BYTE GetPreviousEntry (FSFILE * fo);
+ BYTE FormatDirName (char * string, BYTE mode);
+ int CreateDIR (char * path);
+ BYTE writeDotEntries (DISK * dsk, DWORD dotAddress, DWORD dotdotAddress);
+ int eraseDir (char * path);
+#ifdef ALLOW_PGMFUNCTIONS
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs);
+ #endif
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+#else
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs);
+ #endif
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+#endif
+#endif
+
+#ifdef ALLOW_FSFPRINTF
+ #ifdef __18CXX
+ int FSvfprintf (auto FSFILE *handle, auto const rom char *formatString, auto va_list ap);
+ #else
+ int FSvfprintf (FSFILE *handle, const char *formatString, va_list ap);
+ #endif
+ int FSputc (char c, FSFILE * file);
+ unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c);
+#endif
+
+BYTE DISKmount( DISK *dsk);
+BYTE LoadMBR(DISK *dsk);
+BYTE LoadBootSector(DISK *dsk);
+DWORD GetFullClusterNumber(DIRENTRY entry);
+
+
+/*************************************************************************
+ Function:
+ int FSInit(void)
+ Summary:
+ Function to initialize the device.
+ Conditions:
+ The physical device should be connected to the microcontroller.
+ Input:
+ None
+ Return Values:
+ TRUE - Initialization successful
+ FALSE - Initialization unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Initializes the static or dynamic memory slots for holding file
+ structures. Initializes the device with the DISKmount function. Loads
+ MBR and boot sector information. Initializes the current working
+ directory to the root directory for the device if directory support
+ is enabled.
+ Remarks:
+ None
+ *************************************************************************/
+
+int FSInit(void)
+{
+ int fIndex;
+#ifndef FS_DYNAMIC_MEM
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ gFileSlotOpen[fIndex] = TRUE;
+#else
+ #ifdef __18CXX
+ SRAMInitHeap();
+ #endif
+#endif
+
+ gBufferZeroed = FALSE;
+
+ MDD_InitIO();
+
+ if(DISKmount(&gDiskData) == CE_GOOD)
+ {
+ // Initialize the current working directory to the root
+#ifdef ALLOW_DIRS
+ cwdptr->dsk = &gDiskData;
+ cwdptr->sec = 0;
+ cwdptr->pos = 0;
+ cwdptr->seek = 0;
+ cwdptr->size = 0;
+ cwdptr->name[0] = '\\';
+ for (fIndex = 1; fIndex < 11; fIndex++)
+ {
+ cwdptr->name[fIndex] = 0x20;
+ }
+ cwdptr->entry = 0;
+ cwdptr->attributes = ATTR_DIRECTORY;
+ // "FatRootDirClusterValue" indicates the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+#endif
+
+ FSerrno = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/********************************************************************************
+ Function:
+ CETYPE FILEfind (FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+ Summary
+ Finds a file on the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - FSFILE object containing information of the file found
+ foCompareTo - FSFILE object containing the name/attr of the file to be
+ found
+ cmd -
+ - LOOK_FOR_EMPTY_ENTRY: Search for empty entry.
+ - LOOK_FOR_MATCHING_ENTRY: Search for matching entry.
+ mode -
+ - 0: Match file exactly with default attributes.
+ - 1: Match file to user-specified attributes.
+ Return Values:
+ CE_GOOD - File found.
+ CE_FILE_NOT_FOUND - File not found.
+ Side Effects:
+ None.
+ Description:
+ The FILEfind function will sequentially cache directory entries within
+ the current working directory into the foDest FSFILE object. If the cmd
+ parameter is specified as LOOK_FOR_EMPTY_ENTRY the search will continue
+ until an empty directory entry is found. If the cmd parameter is specified
+ as LOOK_FOR_MATCHING_ENTRY these entries will be compared to the foCompareTo
+ object until a match is found or there are no more entries in the current
+ working directory. If the mode is specified a '0' the attributes of the FSFILE
+ entries are irrelevant. If the mode is specified as '1' the attributes of the
+ foDest entry must match the attributes specified in the foCompareTo file and
+ partial string search characters may bypass portions of the comparison.
+ Remarks:
+ None
+ ********************************************************************************/
+
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+{
+ WORD attrib, compareAttrib;
+ WORD fHandle = foDest->entry; // current entry counter
+ BYTE state,index; // state of the current object
+ CETYPE statusB = CE_FILE_NOT_FOUND;
+ BYTE character,test;
+
+ // reset the cluster
+ foDest->dirccls = foDest->dirclus;
+ compareAttrib = 0xFFFF ^ foCompareTo->attributes; // Attribute to be compared as per application layer request
+
+ if (fHandle == 0)
+ {
+ if (Cache_File_Entry(foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ if ((fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) != 0) // Maximum 16 entries possible
+ {
+ if (Cache_File_Entry (foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ if (statusB != CE_BADCACHEREAD)
+ {
+ // Loop until you reach the end or find the file
+ while(1)
+ {
+ if(statusB!=CE_GOOD) //First time entry always here
+ {
+ state = Fill_File_Object(foDest, &fHandle);
+ if(state == NO_MORE) // Reached the end of available files. Comparision over and file not found so quit.
+ {
+ break;
+ }
+ }
+ else // statusB == CE_GOOD then exit
+ {
+ break; // Code below intializes"statusB = CE_GOOD;" so, if no problem in the filled file, Exit the while loop.
+ }
+
+ if(state == FOUND) // Validate the correct matching of filled file data with the required(to be found) one.
+ {
+ /* We got something */
+ // get the attributes
+ attrib = foDest->attributes;
+
+ attrib &= ATTR_MASK;
+ switch (mode)
+ {
+ case 0:
+ // see if we are a volume id or hidden, ignore
+ if(attrib != ATTR_VOLUME)
+ {
+ statusB = CE_GOOD;
+ character = (BYTE)'m'; // random value
+
+ // search for one. if status = TRUE we found one
+ for(index = 0; index < DIR_NAMECOMP; index++)
+ {
+ // get the source character
+ character = foDest->name[index];
+ // get the destination character
+ test = foCompareTo->name[index];
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // Nope its not a match
+ break;
+ }
+ }// for loop
+ } // not dir nor vol
+ break;
+
+ case 1:
+ // Check for attribute match
+ if (((attrib & compareAttrib) == 0) && (attrib != ATTR_LONG_NAME))
+ {
+ statusB = CE_GOOD; // Indicate the already filled file data is correct and go back
+ character = (BYTE)'m'; // random value
+ if (foCompareTo->name[0] != '*') //If "*" is passed for comparion as 1st char then don't proceed. Go back, file alreay found.
+ {
+ for (index = 0; index < DIR_NAMESIZE; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ // Before calling this "FILEfind" fn, "formatfilename" must be called. Hence, extn always starts from position "8".
+ if ((foCompareTo->name[8] != '*') && (statusB == CE_GOOD))
+ {
+ for (index = 8; index < DIR_NAMECOMP; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ } // Attribute match
+
+ break;
+ }
+ } // not found
+ else
+ {
+ /*** looking for an empty/re-usable entry ***/
+ if ( cmd == LOOK_FOR_EMPTY_ENTRY)
+ statusB = CE_GOOD;
+ } // found or not
+
+ // increment it no matter what happened
+ fHandle++;
+
+ }// while
+ }
+
+ return(statusB);
+} // FILEFind
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+ Summary:
+ Loads file information from the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File to be opened
+ fHandle - Location of file
+ type -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ Return Values:
+ CE_GOOD - FILEopen successful
+ CE_NOT_INIT - Device is not yet initialized
+ CE_FILE_NOT_FOUND - Could not find the file on the device
+ CE_BAD_SECTOR_READ - A bad read of a sector occured
+ Side Effects:
+ None
+ Description:
+ This function will cache a directory entry in the directory specified
+ by the dirclus parameter of hte FSFILE object 'fo.' The offset of the
+ entry in the directory is specified by fHandle. Once the directory entry
+ has been loaded, the first sector of the file can be loaded using the
+ cluster value specified in the directory entry. The type argument will
+ specify the mode the files will be opened in. This will allow this
+ function to set the correct read/write flags for the file.
+ Remarks:
+ If the mode the file is being opened in is a plus mode (e.g. READ+) the
+ flags will be modified further in the FSfopen function.
+ **************************************************************************/
+
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+{
+ DISK *dsk; //Disk structure
+ BYTE r; //Result of search for file
+ DWORD l; //lba of first sector of first cluster
+ CETYPE error = CE_GOOD;
+
+ dsk = (DISK *)(fo->dsk);
+ if (dsk->mount == FALSE)
+ {
+ error = CE_NOT_INIT;
+ }
+ else
+ {
+ // load the sector
+ fo->dirccls = fo->dirclus;
+ // Cache no matter what if it's the first entry
+ if (*fHandle == 0)
+ {
+ if (Cache_File_Entry(fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ // If it's not the first, only cache it if it's
+ // not divisible by the number of entries per sector
+ // If it is, Fill_File_Object will cache it
+ if ((*fHandle & 0xf) != 0)
+ {
+ if (Cache_File_Entry (fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ r = Fill_File_Object(fo, fHandle);
+ if (r != FOUND)
+ error = CE_FILE_NOT_FOUND;
+ else
+ {
+ fo->seek = 0; // first byte in file
+ fo->ccls = fo->cluster; // first cluster
+ fo->sec = 0; // first sector in the cluster
+ fo->pos = 0; // first byte in sector/cluster
+
+ if ( r == NOT_FOUND)
+ {
+ error = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Determine the lba of the selected sector and load
+ l = Cluster2Sector(dsk,fo->ccls);
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+#endif
+ gBufferOwner = fo;
+ if (gLastDataSectorRead != l)
+ {
+ gBufferZeroed = FALSE;
+ if ( !MDD_SectorRead( l, dsk->buffer))
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = l;
+ }
+ } // -- found
+
+ fo->flags.FileWriteEOF = FALSE;
+ // Set flag for operation type
+#ifdef ALLOW_WRITES
+ if (type == 'w' || type == 'a')
+ {
+ fo->flags.write = 1; //write or append
+ fo->flags.read = 0;
+ }
+ else
+ {
+#endif
+ fo->flags.write = 0; //read
+ fo->flags.read = 1;
+#ifdef ALLOW_WRITES
+ } // -- flags
+#endif
+ } // -- r = Found
+ } // -- Mounted
+ return (error);
+} // -- FILEopen
+
+
+/*************************************************************************
+ Function:
+ BYTE FILEget_next_cluster(FILEOBJ fo, WORD n)
+ Summary:
+ Step through a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file to get the next cluster of
+ n - Number of links in the FAT cluster chain to jump through
+ Return Values:
+ CE_GOOD - Operation successful
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_INVALID_CLUSTER - Invalid cluster value \> maxcls
+ CE_FAT_EOF - Fat attempt to read beyond EOF
+ Side Effects:
+ None
+ Description:
+ This function will load 'n' proximate clusters for a file from
+ the FAT on the device. It will stop checking for clusters if the
+ ReadFAT function returns an error, if it reaches the last cluster in
+ a file, or if the device tries to read beyond the last cluster used
+ by the device.
+ Remarks:
+ None
+ *************************************************************************/
+
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n)
+{
+ DWORD c, c2, ClusterFailValue, LastClustervalue;
+ BYTE error = CE_GOOD;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ LastClustervalue = LAST_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT12:
+ LastClustervalue = LAST_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT16:
+ default:
+ LastClustervalue = LAST_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // loop n times
+ do
+ {
+ // get the next cluster link from FAT
+ c2 = fo->ccls;
+ if ( (c = ReadFAT( disk, c2)) == ClusterFailValue)
+ error = CE_BAD_SECTOR_READ;
+ else
+ {
+ // check if cluster value is valid
+ if ( c >= disk->maxcls)
+ {
+ error = CE_INVALID_CLUSTER;
+ }
+
+ // compare against max value of a cluster in FAT
+ // return if eof
+ if ( c >= LastClustervalue) // check against eof
+ {
+ error = CE_FAT_EOF;
+ }
+ }
+
+ // update the FSFILE structure
+ fo->ccls = c;
+
+ } while (--n > 0 && error == CE_GOOD);// loop end
+
+ return(error);
+} // get next cluster
+
+
+/**************************************************************************
+ Function:
+ BYTE DISKmount ( DISK *dsk)
+ Summary:
+ Initialies the device and loads MBR and boot sector information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure to be initialized.
+ Return Values:
+ CE_GOOD - Disk mounted
+ CE_INIT_ERROR - Initialization error has occured
+ Side Effects:
+ None
+ Description:
+ This function will use the function pointed to by the MDD_MediaInitialize
+ function pointer to initialize the device (if any initialization is
+ required). It then attempts to load the master boot record with the
+ LoadMBR function and the boot sector with the LoadBootSector function.
+ These two functions will be used to initialize a global DISK structure
+ that will be used when accessing file information in the future.
+ Remarks:
+ None
+ **************************************************************************/
+
+BYTE DISKmount( DISK *dsk)
+{
+ BYTE error = CE_GOOD;
+
+ dsk->mount = FALSE; // default invalid
+ dsk->buffer = gDataBuffer; // assign buffer
+
+ // Initialize the device
+ if(MDD_MediaInitialize() != TRUE)
+ {
+ error = CE_INIT_ERROR;
+ FSerrno = CE_INIT_ERROR;
+ }
+ else
+ {
+ // Load the Master Boot Record (partition)
+ if((error = LoadMBR(dsk)) == CE_GOOD)
+ {
+ // Now the boot sector
+ if((error = LoadBootSector(dsk)) == CE_GOOD)
+ dsk->mount = TRUE; // Mark that the DISK mounted successfully
+ }
+ } // -- Load file parameters
+
+ return(error);
+} // -- mount
+
+
+
+/********************************************************************
+ Function:
+ CETYPE LoadMBR ( DISK *dsk)
+ Summary:
+ Loads the MBR and extracts necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the master boot record to be loaded
+ Return Values:
+ CE_GOOD - MBR loaded successfully
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_BAD_PARTITION - The boot record is bad
+ Side Effects:
+ None
+ Description:
+ The LoadMBR function will use the function pointed to by the
+ MDD_SectorRead function pointer to read the 0 sector from the
+ device. If a valid boot signature is obtained, this function
+ will compare fields in that cached sector to the values that
+ would be present if that sector was a boot sector. If all of
+ those values match, it will be assumed that the device does not
+ have a master boot record and the 0 sector is actually the boot
+ sector. Otherwise, data about the partition and the actual
+ location of the boot sector will be loaded from the MBR into
+ the DISK structure pointed to by 'dsk.'
+ Remarks:
+ None
+ ********************************************************************/
+
+BYTE LoadMBR(DISK *dsk)
+{
+ PT_MBR Partition;
+ BYTE error = CE_GOOD;
+ BYTE type;
+ BootSec BSec;
+
+ // Get the partition table from the MBR
+ if ( MDD_SectorRead( FO_MBR, dsk->buffer) != TRUE)
+ {
+ error = CE_BAD_SECTOR_READ;
+ FSerrno = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ // Check if the card has no MBR
+ BSec = (BootSec) dsk->buffer;
+
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( dsk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT16;
+ return CE_GOOD;
+ }
+ else
+ {
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FAT32_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 3 ) == '3' && \
+ ReadByte( dsk->buffer, BSI_FAT32_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_32.BootSec_FilSysType[0] == 'F' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[1] == 'A' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[2] == 'T' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[3] == '3' && \
+ BSec->FAT.FAT_32.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT32;
+ return CE_GOOD;
+ }
+ }
+ }
+ // assign it the partition table strucutre
+ Partition = (PT_MBR)dsk->buffer;
+
+ // Ensure its good
+ if((Partition->Signature0 != FAT_GOOD_SIGN_0) || (Partition->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_BAD_PARTITION;
+ error = CE_BAD_PARTITION;
+ }
+ else
+ {
+ /* Valid Master Boot Record Loaded */
+
+ // Get the 32 bit offset to the first partition
+ dsk->firsts = Partition->Partition0.PTE_FrstSect;
+
+ // check if the partition type is acceptable
+ type = Partition->Partition0.PTE_FSDesc;
+
+ switch (type)
+ {
+ case 0x01:
+ dsk->type = FAT12;
+ break;
+
+ case 0x04:
+ case 0x06:
+ case 0x0E:
+ dsk->type = FAT16;
+ break;
+
+ case 0x0B:
+ case 0x0C:
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ dsk->type = FAT32; // FAT32 is supported too
+#else
+ FSerrno = CE_CARDFAT32;
+ error = CE_CARDFAT32;
+#endif
+ break;
+
+ default:
+ FSerrno = CE_UNSUPPORTED_FS;
+ error = CE_UNSUPPORTED_FS;
+ } // switch
+ }
+ }
+
+ return(error);
+}// -- LoadMBR
+
+
+/**************************************************************************
+ Function:
+ BYTE LoadBootSector (DISK *dsk)
+ Summary:
+ Load the boot sector and extract the necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the boot sector
+ Return Values:
+ CE_GOOD - Boot sector loaded
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_NOT_FORMATTED - The disk is of an unsupported format
+ CE_CARDFAT32 - FAT 32 device not supported
+ Side Effects:
+ None
+ Description:
+ LoadBootSector will use the function pointed to by the MDD_SectorWrite
+ function pointer to load the boot sector, whose location was obtained
+ by a previous call of LoadMBR. If the boot sector is loaded successfully,
+ partition information will be calcualted from it and copied into the DISK
+ structure pointed to by 'dsk.'
+ Remarks:
+ None
+ **************************************************************************/
+
+
+BYTE LoadBootSector(DISK *dsk)
+{
+ DWORD RootDirSectors;
+ DWORD TotSec,DataSec;
+ BYTE error = CE_GOOD;
+ BootSec BSec;
+ WORD BytesPerSec;
+ WORD ReservedSectorCount;
+
+ // Get the Boot sector
+ if ( MDD_SectorRead( dsk->firsts, dsk->buffer) != TRUE)
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ BSec = (BootSec)dsk->buffer;
+
+ //Verify the Boot Sector is valid
+ if((BSec->Signature0 != FAT_GOOD_SIGN_0) || (BSec->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ error = CE_NOT_FORMATTED;
+ }
+ else
+ {
+ #ifdef __18CXX
+
+ // Load count of sectors per cluster
+ dsk->SecPerClus = BSec->FAT.FAT_16.BootSec_SPC;
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + BSec->FAT.FAT_16.BootSec_ResrvSec;
+ // Load the count of FAT tables
+ dsk->fatcopy = BSec->FAT.FAT_16.BootSec_FATCount;
+ // Load the size of the FATs
+ dsk->fatsize = BSec->FAT.FAT_16.BootSec_SPF;
+ if(dsk->fatsize == 0)
+ dsk->fatsize = BSec->FAT.FAT_32.BootSec_FATSz32;
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = BSec->FAT.FAT_16.BootSec_RootDirEnts;
+
+ // Determine the total number of sectors in the partition
+ if(BSec->FAT.FAT_16.BootSec_TotSec16 != 0)
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec16;
+ }
+ else
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec32;
+ }
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = BSec->FAT.FAT_16.BootSec_BPS;
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((BSec->FAT.FAT_16.BootSec_RootDirEnts * 32) + (BSec->FAT.FAT_16.BootSec_BPS - 1)) / BSec->FAT.FAT_16.BootSec_BPS;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (dsk->root + RootDirSectors) + dsk->firsts + 2;
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #else // PIC24/30/33
+
+ // Read the count of reserved sectors
+ ReservedSectorCount = ReadWord( dsk->buffer, BSI_RESRVSEC );
+ // Load the count of sectors per cluster
+ dsk->SecPerClus = ReadByte( dsk->buffer, BSI_SPC );
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + ReservedSectorCount;
+ // Load the count of FAT tables
+ dsk->fatcopy = ReadByte( dsk->buffer, BSI_FATCOUNT );
+ // Load the size of the FATs
+ dsk->fatsize = ReadWord( dsk->buffer, BSI_SPF );
+ if(dsk->fatsize == 0)
+ dsk->fatsize = ReadDWord( dsk->buffer, BSI_FATSZ32 );
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = ReadWord( dsk->buffer, BSI_ROOTDIRENTS );
+
+ // Determine the total number of sectors in the partition
+ TotSec = ReadWord( dsk->buffer, BSI_TOTSEC16 );
+ if( TotSec == 0 )
+ TotSec = ReadDWord( dsk->buffer, BSI_TOTSEC32 );
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = ReadWord( dsk->buffer, BSI_BPS );
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((dsk->maxroot * NUMBER_OF_BYTES_IN_DIR_ENTRY) + (BytesPerSec - 1)) / BytesPerSec;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (ReservedSectorCount + (dsk->fatcopy * dsk->fatsize ) + RootDirSectors );
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #endif
+
+ // Determine the file system type based on the number of clusters used
+ if(dsk->maxcls < 4085)
+ {
+ dsk->type = FAT12;
+ }
+ else
+ {
+ if(dsk->maxcls < 65525)
+ {
+ dsk->type = FAT16;
+ }
+ else
+ {
+ #ifdef SUPPORT_FAT32
+ dsk->type = FAT32;
+ #else
+ error = CE_CARDFAT32;
+ FSerrno = CE_CARDFAT32;
+ #endif
+ }
+ }
+
+ #ifdef SUPPORT_FAT32
+ if (dsk->type == FAT32)
+ {
+ #ifdef __18CXX
+ FatRootDirClusterValue = BSec->FAT.FAT_32.BootSec_RootClus;
+ #else
+ FatRootDirClusterValue = ReadDWord( dsk->buffer, BSI_ROOTCLUS );
+ #endif
+ dsk->data = dsk->root + RootDirSectors;
+ }
+ else
+ #endif
+ {
+ FatRootDirClusterValue = 0;
+ dsk->data = dsk->root + ( dsk->maxroot >> 4);
+ }
+
+ #ifdef __18CXX
+ if(BSec->FAT.FAT_16.BootSec_BPS != MEDIA_SECTOR_SIZE)
+ #else
+ if(BytesPerSec != MEDIA_SECTOR_SIZE)
+ #endif
+ {
+ error = CE_NOT_FORMATTED;
+ FSerrno = CE_NOT_FORMATTED;
+ }
+ }
+ }
+ return(error);
+}
+
+
+
+/*************************************************************************
+ Function:
+ DWORD GetFullClusterNumber (DIRENTRY entry)
+ Summary:
+ Gets the cluster number from a directory entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ entry - The cached directory entry to get the cluster number from
+ Returns:
+ The cluster value from the passed directory entry
+ Side Effects:
+ None.
+ Description:
+ This function will load both the high and low 16-bit first cluster
+ values of a file from a directory entry and copy them into a 32-bit
+ cluster number variable, which will be returned.
+ Remarks:
+ None
+ *************************************************************************/
+
+DWORD GetFullClusterNumber(DIRENTRY entry)
+{
+
+ DWORD TempFullClusterCalc = 0;
+
+#ifndef SUPPORT_FAT32 // If FAT32 Not supported.
+ entry->DIR_FstClusHI = 0; // If FAT32 is not supported then Higher Word of the address is "0"
+#endif
+
+ // Get the cluster
+ TempFullClusterCalc = (entry->DIR_FstClusHI);
+ TempFullClusterCalc = TempFullClusterCalc << 16;
+ TempFullClusterCalc |= entry->DIR_FstClusLO;
+
+ return TempFullClusterCalc;
+}
+
+
+#ifdef ALLOW_FORMATS
+#ifdef ALLOW_WRITES
+
+
+/*********************************************************************************
+ Function:
+ int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+ Summary:
+ Creates a master boot record
+ Conditions:
+ The I/O pins for the device have been initialized by the InitIO function.
+ Input:
+ firstSector - The first sector of the partition on the device (cannot
+ be 0; that's the MBR)
+ numSectors - The number of sectors available in memory (including the
+ MBR)
+ Return Values:
+ 0 - MBR was created successfully
+ EOF - MBR could not be created
+ Side Effects:
+ None
+ Description:
+ This function can be used to create a master boot record for a device. Note
+ that this function should not be used on a device that is already formatted
+ with a master boot record (i.e. most SD cards, CF cards, USB keys). This
+ function will fill the global data buffer with appropriate partition information
+ for a FAT partition with a type determined by the number of sectors available
+ to the partition. It will then write the MBR information to the first sector
+ on the device. This function should be followed by a call to FSformat, which
+ will create a boot sector, root dir, and FAT appropriate the the information
+ contained in the new master boot record. Note that FSformat only supports
+ FAT12 and FAT16 formatting at this time, and so cannot be used to format a
+ device with more than 0x3FFD5F sectors.
+ Remarks:
+ This function can damage the device being used, and should not be called
+ unless the user is sure about the size of the device and the first sector value.
+ *********************************************************************************/
+
+int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+{
+ PT_MBR Partition;
+ DWORD CyHdSc = 0x00000000;
+ DWORD tempSector;
+
+ if ((firstSector == 0) || (numSectors <= 1))
+ return EOF;
+
+ if (firstSector > (numSectors - 1))
+ return EOF;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ return EOF;
+
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ Partition = (PT_MBR) gDataBuffer;
+
+ // Set Cylinder-head-sector address of the first sector
+ tempSector = firstSector;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[447] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[448] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[449] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the count of sectors
+ Partition->Partition0.PTE_NumSect = numSectors - firstSector;
+
+ // Set the partition type
+ // We only support creating FAT12 and FAT16 MBRs at this time
+ if (Partition->Partition0.PTE_NumSect < 0x1039)
+ {
+ // FAT12
+ Partition->Partition0.PTE_FSDesc = 0x01;
+ }
+ else if (Partition->Partition0.PTE_NumSect <= 0x3FFD5F)
+ {
+ // FAT16
+ Partition->Partition0.PTE_FSDesc = 0x06;
+ }
+ else
+ return EOF;
+
+ // Set the LBA of the first sector
+ Partition->Partition0.PTE_FrstSect = firstSector;
+
+ // Set the Cylinder-head-sector address of the last sector
+ tempSector = firstSector + numSectors - 1;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[451] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[452] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[453] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the boot descriptor. This will be 0, since we won't
+ // be booting anything from our device probably
+ Partition->Partition0.PTE_BootDes = 0x00;
+
+ // Set the signature codes
+ Partition->Signature0 = 0x55;
+ Partition->Signature1 = 0xAA;
+
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) != TRUE)
+ return EOF;
+ else
+ return 0;
+
+}
+
+
+
+/*******************************************************************
+ Function:
+ int FSformat (char mode, long int serialNumber, char * volumeID)
+ Summary:
+ Formats a device
+ Conditions:
+ The device must possess a valid master boot record.
+ Input:
+ mode - - 0 - Just erase the FAT and root
+ - 1 - Create a new boot sector
+ serialNumber - Serial number to write to the card
+ volumeID - Name of the card
+ Return Values:
+ 0 - Format was successful
+ EOF - Format was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSformat function can be used to create a new boot sector
+ on a device, based on the information in the master boot record.
+ This function will first initialize the I/O pins and the device,
+ and then attempts to read the master boot record. If the MBR
+ cannot be loaded successfully, the function will fail. Next, if
+ the 'mode' argument is specified as '0' the existing boot sector
+ information will be loaded. If the 'mode' argument is '1' an
+ entirely new boot sector will be constructed using the disk
+ values from the master boot record. Once the boot sector has
+ been successfully loaded/created, the locations of the FAT and
+ root will be loaded from it, and they will be completely
+ erased. If the user has specified a volumeID parameter, a
+ VOLUME attribute entry will be created in the root directory
+ to name the device.
+ Remarks:
+ FAT12 and FAT16 formatting is supported.
+ *******************************************************************/
+
+int FSformat (char mode, long int serialNumber, char * volumeID)
+{
+ PT_MBR masterBootRecord;
+ DWORD secCount, FAT16DataClusters, RootDirSectors;
+ BootSec BSec;
+ DISK d;
+ DISK * disk = &d;
+ WORD j;
+ DWORD fatsize, test;
+ BYTE Index;
+#ifdef __18CXX
+ // This is here because of a C18 compiler feature
+ BYTE * dataBufferPointer = gDataBuffer;
+#endif
+
+ FSerrno = CE_GOOD;
+
+ disk->buffer = gDataBuffer;
+
+ MDD_InitIO();
+
+ if (MDD_MediaInitialize() != TRUE)
+ {
+ FSerrno = CE_INIT_ERROR;
+ return EOF;
+ }
+
+ if (MDD_SectorRead (0x00, gDataBuffer) == FALSE)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+
+ // Check if the card has no MBR
+ BSec = (BootSec) disk->buffer;
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( disk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( disk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ switch (mode)
+ {
+ case 1:
+ // not enough info to construct our own boot sector
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ case 0:
+ // We have to determine the operating system, and the
+ // locations and sizes of the root dir and FAT, and the
+ // count of FATs
+ disk->firsts = 0;
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ default:
+ break;
+ }
+ }
+ else
+ {
+ masterBootRecord = (PT_MBR) &gDataBuffer;
+ disk->firsts = masterBootRecord->Partition0.PTE_FrstSect;
+ }
+ }
+
+ switch (mode)
+ {
+ // True: Rewrite the whole boot sector
+ case 1:
+ secCount = masterBootRecord->Partition0.PTE_NumSect;
+
+ if (secCount < 0x1039)
+ {
+ disk->type = FAT12;
+ // Format to FAT12 only if there are too few sectors to format
+ // as FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x01;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ if (secCount >= 0x1028)
+ {
+ // More than 0x18 sectors for FATs, 0x20 for root dir,
+ // 0x8 reserved, and 0xFED for data
+ // So double the number of sectors in a cluster to reduce
+ // the number of data clusters used
+ disk->SecPerClus = 2;
+ }
+ else
+ {
+ // One sector per cluster
+ disk->SecPerClus = 1;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT12 )
+ gDataBuffer[58] = '2';
+ }
+ else if (secCount <= 0x3FFD5F)
+ {
+ disk->type = FAT16;
+ // Format to FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x06;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ FAT16DataClusters = secCount - 0x218;
+ // Figure out how many sectors per cluster we need
+ disk->SecPerClus = 1;
+ while (FAT16DataClusters > 0xFFED)
+ {
+ disk->SecPerClus *= 2;
+ FAT16DataClusters /= 2;
+ }
+ // This shouldnt happen
+ if (disk->SecPerClus > 128)
+ {
+ FSerrno = CE_BAD_PARTITION;
+ return EOF;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT16 )
+ gDataBuffer[58] = '6';
+ }
+ else
+ {
+ // Cannot format; too many sectors
+ FSerrno = CE_NONSUPPORTED_SIZE;
+ return EOF;
+ }
+
+ // Calculate the size of the FAT
+ fatsize = (secCount - 0x21 + (2*disk->SecPerClus));
+ if (disk->type == FAT12)
+ test = (341 * disk->SecPerClus) + 2;
+ else
+ test = (256 * disk->SecPerClus) + 2;
+ fatsize = (fatsize + (test-1)) / test;
+ // Non-file system specific values
+ gDataBuffer[0] = 0xEB; //Jump instruction
+ gDataBuffer[1] = 0x3C;
+ gDataBuffer[2] = 0x90;
+ gDataBuffer[3] = 'M'; //OEM Name "MCHP FAT"
+ gDataBuffer[4] = 'C';
+ gDataBuffer[5] = 'H';
+ gDataBuffer[6] = 'P';
+ gDataBuffer[7] = ' ';
+ gDataBuffer[8] = 'F';
+ gDataBuffer[9] = 'A';
+ gDataBuffer[10] = 'T';
+ gDataBuffer[11] = 0x00; //Bytes per sector - 512
+ gDataBuffer[12] = 0x02;
+ gDataBuffer[13] = disk->SecPerClus; //Sectors per cluster
+ gDataBuffer[14] = 0x08; //Reserved sector count
+ gDataBuffer[15] = 0x00;
+ disk->fat = 0x08 + disk->firsts;
+ gDataBuffer[16] = 0x02; //number of FATs
+ disk->fatcopy = 0x02;
+ gDataBuffer[17] = 0x00; //Max number of root directory entries - 512 files allowed
+ gDataBuffer[18] = 0x02;
+ disk->maxroot = 0x200;
+ gDataBuffer[19] = 0x00; //total sectors
+ gDataBuffer[20] = 0x00;
+ gDataBuffer[21] = 0xF8; //Media Descriptor
+ gDataBuffer[22] = fatsize & 0xFF; //Sectors per FAT
+ gDataBuffer[23] = (fatsize >> 8) & 0xFF;
+ disk->fatsize = fatsize;
+ gDataBuffer[24] = 0x3F; //Sectors per track
+ gDataBuffer[25] = 0x00;
+ gDataBuffer[26] = 0xFF; //Number of heads
+ gDataBuffer[27] = 0x00;
+ // Hidden sectors = sectors between the MBR and the boot sector
+ gDataBuffer[28] = (BYTE)(disk->firsts & 0xFF);
+ gDataBuffer[29] = (BYTE)((disk->firsts / 0x100) & 0xFF);
+ gDataBuffer[30] = (BYTE)((disk->firsts / 0x10000) & 0xFF);
+ gDataBuffer[31] = (BYTE)((disk->firsts / 0x1000000) & 0xFF);
+ // Total Sectors = same as sectors in the partition from MBR
+ gDataBuffer[32] = (BYTE)(secCount & 0xFF);
+ gDataBuffer[33] = (BYTE)((secCount / 0x100) & 0xFF);
+ gDataBuffer[34] = (BYTE)((secCount / 0x10000) & 0xFF);
+ gDataBuffer[35] = (BYTE)((secCount / 0x1000000) & 0xFF);
+ gDataBuffer[36] = 0x00; // Physical drive number
+ gDataBuffer[37] = 0x00; // Reserved (current head)
+ gDataBuffer[38] = 0x29; // Signature code
+ gDataBuffer[39] = (BYTE)(serialNumber & 0xFF);
+ gDataBuffer[40] = (BYTE)((serialNumber / 0x100) & 0xFF);
+ gDataBuffer[41] = (BYTE)((serialNumber / 0x10000) & 0xFF);
+ gDataBuffer[42] = (BYTE)((serialNumber / 0x1000000) & 0xFF);
+ // Volume ID
+ if (volumeID != NULL)
+ {
+ for (Index = 0; (*(volumeID + Index) != 0) && (Index < 11); Index++)
+ {
+ gDataBuffer[Index + 43] = *(volumeID + Index);
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[43 + Index++] = 0x20;
+ }
+ }
+ else
+ {
+ for (Index = 0; Index < 11; Index++)
+ {
+ gDataBuffer[Index+43] = 0;
+ }
+ }
+ gDataBuffer[54] = 'F';
+ gDataBuffer[55] = 'A';
+ gDataBuffer[56] = 'T';
+ gDataBuffer[57] = '1';
+ gDataBuffer[59] = ' ';
+ gDataBuffer[60] = ' ';
+ gDataBuffer[61] = ' ';
+#ifdef __18CXX
+ // C18 can't reference a value greater than 256
+ // using an array name pointer
+ *(dataBufferPointer + 510) = 0x55;
+ *(dataBufferPointer + 511) = 0xAA;
+#else
+ gDataBuffer[510] = 0x55;
+ gDataBuffer[511] = 0xAA;
+#endif
+
+ disk->root = disk->fat + (disk->fatcopy * disk->fatsize);
+
+ if (MDD_SectorWrite (disk->firsts, gDataBuffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ break;
+ case 0:
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ break;
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ }
+
+ // Erase the FAT
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+ gDataBuffer[0] = 0xF8;
+ gDataBuffer[1] = 0xFF;
+ gDataBuffer[2] = 0xFF;
+ if (disk->type == FAT16)
+ gDataBuffer[3] = 0xFF;
+
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (disk->fat + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ memset (gDataBuffer, 0x00, 4);
+
+ for (Index = disk->fat + 1; Index < (disk->fat + disk->fatsize); Index++)
+ {
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (Index + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ }
+
+ // Erase the root directory
+ RootDirSectors = ((disk->maxroot * 32) + (0x200 - 1)) / 0x200;
+
+ for (Index = 1; Index < RootDirSectors; Index++)
+ {
+ if (MDD_SectorWrite (disk->root + Index, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ if (volumeID != NULL)
+ {
+ // Create a drive name entry in the root dir
+ Index = 0;
+ while ((*(volumeID + Index) != 0) && (Index < 11))
+ {
+ gDataBuffer[Index] = *(volumeID + Index);
+ Index++;
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[Index++] = ' ';
+ }
+ gDataBuffer[11] = 0x08;
+ gDataBuffer[17] = 0x11;
+ gDataBuffer[19] = 0x11;
+ gDataBuffer[23] = 0x11;
+
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ else
+ {
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ return 0;
+}
+#endif
+#endif
+
+
+/*******************************************************
+ Function:
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+ Summary:
+ Write dir entry info into a specified entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - \File structure
+ curEntry - Write destination
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will calculate the sector of the
+ directory (whose base sector is pointed to by the
+ dirccls value in the FSFILE object 'fo') that contains
+ a directory entry whose offset is indicated by the
+ curEntry parameter. It will then write the data
+ in the global data buffer (which should already
+ contain the entries for that sector) to the device.
+ Remarks:
+ None
+ *******************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+{
+ DISK *dsk;
+ BYTE status;
+ BYTE offset2;
+ DWORD sector;
+ DWORD ccls;
+
+ dsk = fo->dsk;
+
+ // get the cluster of this entry
+ ccls = fo->dirccls;
+
+ // if its not the root, it's cluster based
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // Root is always cluster-based in FAT32
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ if(ccls != FatRootDirClusterValue)
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+ }
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ // Now write it
+ // "Offset" ensures writing of data belonging to a file entry only. Hence it doesn't change other file entries.
+ if ( !MDD_SectorWrite( sector + offset2, dsk->buffer, FALSE))
+ status = FALSE;
+ else
+ status = TRUE;
+
+ return(status);
+} // Write_File_Entry
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE FAT_erase_cluster_chain (WORD cluster, DISK * dsk)
+ Summary:
+ Erase a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ cluster - The cluster number
+ dsk - The disk structure
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will parse through a cluster chain
+ starting with the cluster pointed to by 'cluster' and
+ mark all of the FAT entries as empty until the end of
+ the chain has been reached or an error occurs.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk)
+{
+ DWORD c,c2,ClusterFailValue;
+ enum _status {Good, Fail, Exit}status;
+
+ status = Good;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ c2 = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT16:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ c2 = LAST_CLUSTER_FAT16;
+ break;
+
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16; // FAT16 value itself
+ c2 = LAST_CLUSTER_FAT12;
+ break;
+ }
+
+ // Make sure there is actually a cluster assigned
+ if(cluster == 0 || cluster == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ while(status == Good)
+ {
+ // Get the FAT entry
+ if((c = ReadFAT( dsk, cluster)) == ClusterFailValue)
+ status = Fail;
+ else
+ {
+ if(c == 0 || c == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ // compare against max value of a cluster in FATxx
+ // look for the last cluster in the chain
+ if ( c >= c2)
+ status = Exit;
+
+ // Now erase this FAT entry
+ if(WriteFAT(dsk, cluster, CLUSTER_EMPTY, FALSE) == ClusterFailValue)
+ status = Fail;
+
+ // now update what the current cluster is
+ cluster = c;
+ }
+ }
+ }// while status
+ }// cluster == 0
+
+ WriteFAT (dsk, 0, 0, TRUE);
+
+ if(status == Exit)
+ return(TRUE);
+ else
+ return(FALSE);
+} // Erase cluster
+#endif
+
+/**************************************************************************
+ Function:
+ DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+ Summary:
+ Load a file entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File information
+ curEntry - Offset of the directory entry to load.
+ ForceRead - Forces loading of a new sector of the directory.
+ Return:
+ DIRENTRY - Pointer to the directory entry that was loaded.
+ Side Effects:
+ Any unwritten data in the data buffer will be written to the device.
+ Description:
+ Load the sector containing the file entry pointed to by 'curEntry'
+ from the directory pointed to by the variables in 'fo.'
+ Remarks:
+ Any modification of this function is extremely likely to
+ break something.
+ **************************************************************************/
+
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+{
+ DIRENTRY dir;
+ DISK *dsk;
+ DWORD sector;
+ DWORD cluster, LastClusterLimit;
+ DWORD ccls;
+ BYTE offset2;
+ BYTE numofclus;
+
+ dsk = fo->dsk;
+
+ // get the base sector of this directory
+ cluster = fo->dirclus;
+ ccls = fo->dirccls;
+
+ // figure out the offset from the base sector
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+ /* There are 16 entries per sector. SECTOR size is 512 bytes. Each entry in ROOT takes 32 bytes.
+ So, 512/32 = 16. So 16 file entries can be made in each sector. */
+
+ offset2 = offset2; // emulator issue
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // the ROOT is always cluster based in FAT32
+ /* In FAT32: There is no ROOT region. Root etries are made in DATA region only.
+ Every cluster of DATA which is accupied by ROOT is tracked by FAT table/entry so the ROOT can grow
+ to an amount which is restricted only by available free DATA region. */
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // if its the root its not cluster based
+ if(cluster != 0)
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ // check if a new sector of the root must be loaded
+ if (ForceRead || (*curEntry & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) // only 16 entries per sector
+ {
+ // see if we have to load a new cluster
+ if((offset2 == 0 && (*curEntry) >= DIRENTRIES_PER_SECTOR) || ForceRead)
+ {
+ if(cluster == 0)
+ {
+ ccls = 0;
+ }
+ else
+ {
+ // If ForceRead, read the number of sectors from 0
+ if(ForceRead)
+ numofclus = ((WORD)(*curEntry) / (WORD)(((WORD)DIRENTRIES_PER_SECTOR) * (WORD)dsk->SecPerClus));
+ // Otherwise just read the next sector
+ else
+ numofclus = 1;
+
+ // move to the correct cluster
+ while(numofclus)
+ {
+ ccls = ReadFAT(dsk, ccls);
+
+ if(ccls >= LastClusterLimit)
+ break;
+ else
+ numofclus--;
+ }
+ }
+ }
+
+ // see if that we have a valid cluster number
+ if(ccls < LastClusterLimit)
+ {
+ fo->dirccls = ccls; // write it back
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ /* see if we are root and about to go pass our boundaries
+ FAT32 stores the root directory in the Data Region along with files and other directories,
+ allowing it to grow without such a restraint */
+ if((ccls == FatRootDirClusterValue) && ((sector + offset2) >= dsk->data) && (FAT32 != dsk->type))
+ {
+ dir = ((DIRENTRY)NULL); // reached the end of the root
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return NULL;
+#endif
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+
+ if ( MDD_SectorRead( sector + offset2, dsk->buffer) != TRUE) // if FALSE: sector could not be read.
+ {
+ dir = ((DIRENTRY)NULL);
+ }
+ else // Sector has been read properly, Copy the root entry info of the file searched.
+ {
+ if(ForceRead) // Buffer holds all 16 root entry info. Point to the one required.
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+ else
+ dir = (DIRENTRY)dsk->buffer;
+ }
+ gLastDataSectorRead = 0xFFFFFFFF;
+ }
+ }
+ else
+ {
+ nextClusterIsLast = TRUE;
+ dir = ((DIRENTRY)NULL);
+ }
+ }
+ else
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+
+ return(dir);
+} // Cache_File_Entry
+
+
+/*************************************************************************
+ Function:
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Create a new file entry
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location to create file
+ Return Values:
+ CE_GOOD - File Creation successful
+ CE_DIR_FULL - All root directory entries are taken
+ CE_WRITE_ERROR - The head cluster of the file could not be created.
+ Side Effects:
+ Modifies the FSerrno variable.
+ Description:
+ With the data passed within fo, create a new file entry in the current
+ directory. This function will first search for empty file entries.
+ Once an empty entry is found, the entry will be populated with data
+ for a file or directory entry. Finally, the first cluster of the
+ new file will be located and allocated, and its value will be
+ written into the file entry.
+ Remarks:
+ None
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode)
+{
+ BYTE index;
+ CETYPE error = CE_GOOD;
+ char name[11];
+
+ FSerrno = CE_GOOD;
+
+ for (index = 0; index < FILE_NAME_SIZE; index ++)
+ {
+ name[index] = fo->name[index];
+ }
+
+ *fHandle = 0;
+
+ // figure out where to put this file in the directory stucture
+ if(FindEmptyEntries(fo, fHandle))
+ {
+ // found the entry, now populate it
+ if((error = PopulateEntries(fo, name ,fHandle, mode)) == CE_GOOD)
+ {
+ // if everything is ok, create a first cluster
+ error = CreateFirstCluster(fo);
+ }
+ }
+ else
+ {
+ error = CE_DIR_FULL;
+ }
+
+ FSerrno = error;
+
+ return(error);
+}
+#endif
+
+/******************************************************
+ Function:
+ CETYPE CreateFirstCluster(FILEOBJ fo)
+ Summary:
+ Create the first cluster for a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file that contains the first cluster
+ Return Values:
+ CE_GOOD - First cluster created successfully
+ CE_WRITE_ERROR - Cluster creation failed
+ Side Effects:
+ None
+ Description:
+ This function will find an unused cluster, link it to
+ a file's directory entry, and write the entry back
+ to the device.
+ Remarks:
+ None.
+ ******************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFirstCluster(FILEOBJ fo)
+{
+ CETYPE error;
+ DWORD cluster,TempMsbCluster;
+ WORD fHandle;
+ DIRENTRY dir;
+ fHandle = fo->entry;
+
+ // Now create the first cluster (head cluster)
+ if((error = FILECreateHeadCluster(fo,&cluster)) == CE_GOOD)
+ {
+ // load the file entry so the new cluster can be linked to it
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ // Now update the new cluster
+ dir->DIR_FstClusLO = (cluster & 0x0000FFFF);
+
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ // Get the higher part of cluster and store it in directory entry.
+ TempMsbCluster = (cluster & 0x0FFF0000); // Since only 28 bits usedin FAT32. Mask the higher MSB nibble.
+ TempMsbCluster = TempMsbCluster >> 16; // Get the date into Lsb place.
+ dir->DIR_FstClusHI = TempMsbCluster;
+#else // If FAT32 support not enabled
+ TempMsbCluster = 0; // Just to avoid compiler warnigng.
+ dir->DIR_FstClusHI = 0;
+#endif
+
+ // now write it
+ if(Write_File_Entry(fo, &fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+ } // Create Cluster
+
+ return(error);
+}// End of CreateFirstCluster
+#endif
+
+/**********************************************************
+ Function:
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Find an empty dir entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Start of entries
+ Return Values:
+ TRUE - One found
+ FALSE - None found
+ Side Effects:
+ None
+ Description:
+ This function will cache directory entries, starting
+ with the one pointed to by the fHandle argument. It will
+ then search through the entries until an unused one
+ is found. If the end of the cluster chain for the
+ directory is reached, a new cluster will be allocated
+ to the directory (unless it's a FAT12 or FAT16 root)
+ and the first entry of the new cluster will be used.
+ Remarks:
+ None.
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+{
+ BYTE status = NOT_FOUND;
+ BYTE amountfound;
+ BYTE a;
+ WORD bHandle;
+ DWORD b;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ if((dir = Cache_File_Entry( fo, fHandle, TRUE)) == NULL)
+ {
+ status = CE_BADCACHEREAD;
+ }
+ else
+ {
+ // while its still not found
+ while(status == NOT_FOUND)
+ {
+ amountfound = 0;
+ bHandle = *fHandle;
+
+ // find (number) continuous entries
+ do
+ {
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // increase number
+ (*fHandle)++;
+ }while((a == DIR_DEL || a == DIR_EMPTY) && (dir != (DIRENTRY)NULL) && (++amountfound < 1));
+
+ // --- now why did we exit?
+ if(dir == NULL) // Last entry of the cluster
+ {
+ //setup the current cluster
+ b = fo->dirccls; // write it back
+
+ // make sure we are not the root directory
+ if(b == FatRootDirClusterValue)
+ {
+ if (fo->dsk->type != FAT32)
+ status = NO_MORE;
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ if(amountfound == 1)
+ {
+ status = FOUND;
+ *fHandle = bHandle;
+ }
+ }
+ }// while
+
+ // copy the base handle over
+ *fHandle = bHandle;
+ }
+
+ if(status == FOUND)
+ return(TRUE);
+ else
+ return(FALSE);
+}
+#endif
+
+/**************************************************************************
+ Function:
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle)
+ Summary:
+ Populate a dir entry with data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ name - Name of the file
+ fHandle - Location of the file
+ Return Values:
+ CE_GOOD - Population successful
+ Side Effects:
+ None
+ Description:
+ This function will write data into a new file entry. It will also
+ load timestamp data (based on the method selected by the user) and
+ update the timestamp variables.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode)
+{
+ BYTE error = CE_GOOD;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+
+ if (dir == NULL)
+ return CE_BADCACHEREAD;
+
+ // copy the contents over
+ strncpy(dir->DIR_Name,name,DIR_NAMECOMP);
+
+ // setup no attributes
+ if (mode == DIRECTORY)
+ dir->DIR_Attr = ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = ATTR_ARCHIVE;
+
+ dir->DIR_NTRes = 0x00; // nt reserved
+ dir->DIR_FstClusHI = 0x0000; // high word of this enty's first cluster number
+ dir->DIR_FstClusLO = 0x0000; // low word of this entry's first cluster number
+ dir->DIR_FileSize = 0x0; // file size in DWORD
+
+ // Timing information for uncontrolled clock mode
+#ifdef INCREMENTTIMESTAMP
+ dir->DIR_CrtTimeTenth = 0xB2; // millisecond stamp
+ dir->DIR_CrtTime = 0x7278; // time created
+ dir->DIR_CrtDate = 0x32B0; // date created
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = 0x32B0; // Last Access date
+ dir->DIR_WrtTime = 0x7279; // last update time
+ dir->DIR_WrtDate = 0x32B0; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ dir->DIR_CrtTime = gTimeCrtTime; // time created //
+ dir->DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate; // Last Access date
+ dir->DIR_WrtTime = gTimeWrtTime; // last update time
+ dir->DIR_WrtDate = gTimeWrtDate; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ // The user will have set the time before this funciton is called
+ dir->DIR_CrtTimeTenth = gTimeCrtMS;
+ dir->DIR_CrtTime = gTimeCrtTime;
+ dir->DIR_CrtDate = gTimeCrtDate;
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate;
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+ fo->size = dir->DIR_FileSize;
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ fo->attributes = dir->DIR_Attr;
+ fo->entry = *fHandle;
+
+ // just write the last entry in
+ if (Write_File_Entry(fo,fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+
+ return(error);
+}
+
+#ifdef USEREALTIMECLOCK
+
+/*************************************************************************
+ Function:
+ void CacheTime (void)
+ Summary:
+ Automatically store timestamp information from the RTCC
+ Conditions:
+ RTCC module enabled. Should not be called by the user.
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ This function will automatically load information from an RTCC
+ module and use it to update the global timing variables. These can
+ then be used to update file timestamps.
+ Remarks:
+ None.
+ *************************************************************************/
+
+void CacheTime (void)
+{
+#ifdef __C30__
+ WORD year, monthday, weekhour, minsec, c, result;
+ BYTE ptr1, ptr0;
+
+ if(RCFGCALbits.RTCPTR0)
+ ptr0 = 1;
+ else
+ ptr0 = 0;
+ if (RCFGCALbits.RTCPTR1)
+ ptr1 = 1;
+ else
+ ptr1 = 0;
+
+ RCFGCALbits.RTCPTR0 = 1;
+ RCFGCALbits.RTCPTR1 = 1;
+ year = RTCVAL;
+ monthday = RTCVAL;
+ weekhour = RTCVAL;
+ minsec = RTCVAL;
+
+ if (ptr0 == 1)
+ RCFGCALbits.RTCPTR0 = 1;
+
+ if (ptr1 == 1)
+ RCFGCALbits.RTCPTR1 = 1;
+
+ c = 0;
+ c += (year & 0x0F);
+ c += ((year & 0xF0) >> 4) * 10;
+ // c equals the last 2 digits of the year from 2000 to 2099
+ // Add 20 to adjust it to FAT time (from 1980 to 2107)
+ c += 20;
+ // shift the result to bits
+ result = c << 9;
+
+ if ((monthday & 0x1000) == 0x1000)
+ {
+ c = 10;
+ }
+ else
+ {
+ c = 0;
+ }
+ c += ((monthday & 0x0F00) >> 8);
+ c <<= 5;
+ result |= c;
+
+ c = (monthday & 0x00F0) >> 4;
+ c *= 10;
+ c += (monthday & 0x000F);
+
+ result |= c;
+
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+ gTimeAccDate = result;
+
+ c = ((weekhour & 0x00F0) >> 4) * 10;
+ c += (weekhour & 0x000F);
+ result = c << 11;
+ c = ((minsec & 0xF000) >> 12) * 10;
+ c += (minsec & 0x0F00) >> 8;
+ result |= (c << 5);
+ c = ((minsec & 0x00F0) >> 4) * 10;
+ c += (minsec & 0x000F);
+
+ // If seconds mod 2 is 1, add 1000 ms
+ if (c % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ c >>= 1;
+ result |= c;
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+#elif defined __C32__
+ rtccTime tm; // time structure
+ rtccDate dt; // date structure
+ RtccGetTimeDate(&tm, &dt);
+ gTimeCrtTime = tm.w[1] | tm.w[0];
+ gTimeWrtDate = dt.w[1] | tm.w[0];
+#endif
+}
+#endif
+
+#ifdef USERDEFINEDCLOCK
+
+/***********************************************************************************************************
+ Function:
+ int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+ Summary:
+ Manually set timestamp variables
+ Conditions:
+ USERDEFINEDCLOCK macro defined in FSconfig.h.
+ Input:
+ year - The year (1980\-2107)
+ month - The month (1\-12)
+ day - The day of the month (1\-31)
+ hour - The hour (0\-23)
+ minute - The minute (0\-59)
+ second - The second (0\-59)
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ Lets the user manually set the timing variables. The values passed in will be converted to the format
+ used by the FAT timestamps.
+ Remarks:
+ Call this before creating a file or directory (set create time) and
+ before closing a file (set last access time, last modified time)
+ ***********************************************************************************************************/
+
+int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+{
+ unsigned int result;
+
+ if ((year < 1980) || (year > 2107) || (month < 1) || (month > 12) ||
+ (day < 1) || (day > 31) || (hour > 23) || (minute > 59) || (second > 59))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ result = (year - 1980) << 9;
+ result |= (unsigned int)((unsigned int)month << 5);
+ result |= (day);
+
+ gTimeAccDate = result;
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+
+ result = ((unsigned int)hour << 11);
+ result |= (unsigned int)((unsigned int)minute << 5);
+ result |= (second/2);
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+
+ if (second % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ FSerrno = CE_GOOD;
+ return 0;
+}
+#endif
+
+#endif
+
+/***********************************************************************
+ Function:
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+ Summary;
+ Allocate a new cluster to a file
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ mode -
+ - 0 - Allocate a cluster to a file
+ - 1 - Allocate a cluster to a directory
+ Return Values:
+ CE_GOOD - Cluster allocated
+ CE_DISK_FULL - No clusters available
+ Side Effects:
+ None
+ Description:
+ This function will find an empty cluster on the device using the
+ FATfindEmptyCluster function. It will then mark it as the last
+ cluster in the file in the FAT chain, and link the current last
+ cluster of the passed file to the new cluster. If the new
+ cluster is a directory cluster, it will be erased (so there are no
+ extraneous directory entries). If it's allocated to a non-directory
+ file, it doesn't need to be erased; extraneous data in the cluster
+ will be unviewable because of the file size parameter.
+ Remarks:
+ None.
+ ***********************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+{
+ DISK * dsk;
+ DWORD c,curcls;
+
+ dsk = fo->dsk;
+ c = fo->ccls;
+
+ // find the next empty cluster
+ c = FATfindEmptyCluster(fo);
+ if (c == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ return CE_DISK_FULL;
+
+
+ // mark the cluster as taken, and last in chain
+ if(dsk->type == FAT12)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT12, FALSE);
+ else if (dsk->type == FAT16)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT16, FALSE);
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT32, FALSE);
+#endif
+
+ // link current cluster to the new one
+ curcls = fo->ccls;
+
+ WriteFAT( dsk, curcls, c, FALSE);
+
+ // update the FILE structure
+ fo->ccls = c;
+
+ // IF this is a dir, we need to erase the cluster
+ // If it's a file, we can leave it- the file size
+ // will limit the data we see to the data that's been
+ // written
+ if (mode == 1)
+ return (EraseCluster(dsk, c));
+ else
+ return CE_GOOD;
+
+} // allocate new cluster
+#endif
+
+/***********************************************
+ Function:
+ DWORD FATfindEmptyCluster(FILEOBJ fo)
+ Summary:
+ Find the next available cluster on the device
+ Conditions:
+ This function should not be called by the
+ user.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ DWORD - Address of empty cluster
+ 0 - Could not find empty cluster
+ Side Effects:
+ None
+ Description:
+ This function will search through the FAT to
+ find the next available cluster on the device.
+ Remarks:
+ Should not be called by user
+ ***********************************************/
+
+#ifdef ALLOW_WRITES
+DWORD FATfindEmptyCluster(FILEOBJ fo)
+{
+ DISK * disk;
+ DWORD value = 0x0;
+ DWORD c,curcls, EndClusterLimit, ClusterFailValue;
+
+ disk = fo->dsk;
+ c = fo->ccls;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ EndClusterLimit = END_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ EndClusterLimit = END_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT12:
+ EndClusterLimit = END_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // just in case
+ if(c < 2)
+ c = 2;
+
+ curcls = c;
+ ReadFAT(disk, c);
+
+ // sequentially scan through the FAT looking for an empty cluster
+ while(c)
+ {
+ // look at its value
+ if ( (value = ReadFAT(disk, c)) == ClusterFailValue)
+ {
+ c = 0;
+ break;
+ }
+
+ // check if empty cluster found
+ if (value == CLUSTER_EMPTY)
+ break;
+
+ c++; // check next cluster in FAT
+ // check if reached last cluster in FAT, re-start from top
+ if (value == EndClusterLimit || c >= disk->maxcls)
+ c = 2;
+
+ // check if full circle done, disk full
+ if ( c == curcls)
+ {
+ c = 0;
+ break;
+ }
+ } // scanning for an empty cluster
+
+ return(c);
+}
+#endif
+
+/************************************************************
+ Function:
+ int FSfclose(FSFILE *fo)
+ Summary:
+ Update file information and free FSFILE objects
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to the file to close
+ Return Values:
+ 0 - File closed successfully
+ EOF - Error closing the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will update the directory entry for the
+ file pointed to by 'fo' with the information contained
+ in 'fo,' including the new file size and attributes.
+ Timestamp information will also be loaded based on the
+ method selected by the user and written to the entry
+ as the last modified time and date. The file entry will
+ then be written to the device. Finally, the memory
+ used for the specified file object will be freed from
+ the dynamic heap or the array of FSFILE objects.
+ Remarks:
+ A function to flush data to the device without closing the
+ file can be created by removing the portion of this
+ function that frees the memory and the line that clears
+ the write flag.
+ ************************************************************/
+
+int FSfclose(FSFILE *fo)
+{
+ WORD fHandle;
+#ifndef FS_DYNAMIC_MEM
+ WORD fIndex;
+#endif
+ int error = 72;
+#ifdef ALLOW_WRITES
+ DIRENTRY dir;
+#endif
+
+ FSerrno = CE_GOOD;
+ fHandle = fo->entry;
+
+#ifdef ALLOW_WRITES
+ if(fo->flags.write)
+ {
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ // Write the current FAT sector to the disk
+ WriteFAT (fo->dsk, 0, 0, TRUE);
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = EOF;
+ return error;
+ }
+
+ // update the time
+#ifdef INCREMENTTIMESTAMP
+ IncrementTimeStamp(dir);
+#elif defined USERDEFINEDCLOCK
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#elif defined USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#endif
+
+ Nop();
+
+ dir->DIR_FileSize = fo->size;
+
+ dir->DIR_Attr = fo->attributes;
+
+ // just write the last entry in
+ if(Write_File_Entry(fo,&fHandle))
+ error = 0;
+ else
+ {
+ FSerrno = CE_WRITE_ERROR;
+ error = EOF;
+ }
+
+ // it's now closed
+ fo->flags.write = FALSE;
+ }
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ FS_free((unsigned char *)fo);
+#else
+
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( fo == &gFileArray[fIndex] )
+ {
+ gFileSlotOpen[fIndex] = TRUE;
+ break;
+ }
+ }
+#endif
+
+ // File opened in read mode
+ if (error == 72)
+ error = 0;
+
+ return(error);
+} // FSfclose
+
+
+
+
+/*******************************************************
+ Function:
+ void IncrementTimeStamp(DIRENTRY dir)
+ Summary:
+ Automatically set the timestamp to "don't care" data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ dir - Pointer to directory structure
+ Return Values:
+ None
+ Side Effects:
+ None
+ Description:
+ This function will increment the timestamp variable in
+ the 'dir' directory entry. This is used for the
+ don't-care timing method.
+ Remarks:
+ None
+ *******************************************************/
+#ifdef INCREMENTTIMESTAMP
+void IncrementTimeStamp(DIRENTRY dir)
+{
+ BYTE seconds;
+ BYTE minutes;
+ BYTE hours;
+
+ BYTE day;
+ BYTE month;
+ BYTE year;
+
+ seconds = (dir->DIR_WrtTime & 0x1f);
+ minutes = ((dir->DIR_WrtTime & 0x07E0) >> 5);
+ hours = ((dir->DIR_WrtTime & 0xF800) >> 11);
+
+ day = (dir->DIR_WrtDate & 0x1f);
+ month = ((dir->DIR_WrtDate & 0x01E0) >> 5);
+ year = ((dir->DIR_WrtDate & 0xFE00) >> 9);
+
+ if(seconds < 29)
+ {
+ // Increment number of seconds by 2
+ // This clock method isn't intended to be accurate anyway
+ seconds++;
+ }
+ else
+ {
+ seconds = 0x00;
+
+ if(minutes < 59)
+ {
+ minutes++;
+ }
+ else
+ {
+ minutes = 0;
+
+ if(hours < 23)
+ {
+ hours++;
+ }
+ else
+ {
+ hours = 0;
+ if(day < 30)
+ {
+ day++;
+ }
+ else
+ {
+ day = 1;
+
+ if(month < 12)
+ {
+ month++;
+ }
+ else
+ {
+ month = 1;
+ // new year
+ year++;
+ // This is only valid until 2107
+ }
+ }
+ }
+ }
+ }
+
+ dir->DIR_WrtTime = (WORD)(seconds);
+ dir->DIR_WrtTime |= ((WORD)(minutes) << 5);
+ dir->DIR_WrtTime |= ((WORD)(hours) << 11);
+
+ dir->DIR_WrtDate = (WORD)(day);
+ dir->DIR_WrtDate |= ((WORD)(month) << 5);
+ dir->DIR_WrtDate |= ((WORD)(year) << 9);
+}
+#endif
+
+/*****************************************************************
+ Function:
+ BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Fill a file object with specified dir entry data
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Passed member's location
+ Return Values:
+ FOUND - Operation successful
+ NOT_FOUND - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then copy
+ the file information for that entry into the 'fo' FSFILE
+ object.
+ Remarks:
+ None.
+ *****************************************************************/
+
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE index, a;
+ BYTE character;
+ BYTE status;
+ BYTE test = 0;
+
+ // Get the entry
+ if (((*fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) && (*fHandle != 0)) // 4-bit mask because 16-root entries max per sector
+ {
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ }
+ else
+ {
+ dir = Cache_File_Entry (fo, fHandle, FALSE);
+ }
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Make sure there is a directory left
+ if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
+ {
+ status = NO_MORE;
+ }
+ else
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ status = NOT_FOUND;
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // print the file name and extension
+ for (index=0; index < DIR_NAMESIZE; index++)
+ {
+ character = dir->DIR_Name[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // its possible to have an extension in a directory
+ character = dir->DIR_Extension[0];
+
+ // Get the file extension if its there
+ for (index=0; index < DIR_EXTENSION; index++)
+ {
+ character = dir->DIR_Extension[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // done and done with the name
+ // fo->name[++test] = (BYTE)'\0';
+
+ // Now store the identifier
+ fo->entry = *fHandle;
+
+ // see if we are still a good file
+ a = dir->DIR_Name[0];
+
+ if(a == DIR_DEL)
+ status = NOT_FOUND;
+ else
+ status = FOUND;
+
+ // Now store the size
+ fo->size = (dir->DIR_FileSize);
+
+ fo->cluster = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ /// -Get and store the attributes
+ a = dir->DIR_Attr;
+ fo->attributes = a;
+
+ // get the date and time
+ if ((a & ATTR_DIRECTORY) != 0)
+ {
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ }
+ else
+ {
+ fo->time = dir->DIR_WrtTime;
+ fo->date = dir->DIR_WrtDate;
+ }
+
+ }// deleted directory
+ }// Ensure we are still good
+ return(status);
+} // Fill_File_Object
+
+
+/************************************************************************
+ Function:
+ DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Load file information from a directory entry and cache the entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Information location
+ Return Values:
+ DIRENTRY - Pointer to the directory entry
+ NULL - Directory entry could not be loaded
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then return a pointer
+ to the directory entry in the global data buffer.
+ Remarks:
+ None.
+ ************************************************************************/
+
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE a;
+
+ fo->dirccls = fo->dirclus;
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+ if (dir == NULL)
+ return NULL;
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Make sure there is a directory left
+ if(a == DIR_EMPTY)
+ dir = (DIRENTRY)NULL;
+
+ if(dir != (DIRENTRY)NULL)
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ dir = (DIRENTRY)NULL;
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // scan through all the long dir entries
+ while(a == ATTR_LONG_NAME)
+ {
+ (*fHandle)++;
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+ if (dir == NULL)
+ return NULL;
+ a = dir->DIR_Attr;
+ } // long file name while loop
+ } // deleted dir
+ }// Ensure we are still good
+
+ return(dir);
+} // LoadDirAttrib
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+ Summary:
+ Erase a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location of file information
+ EraseClusters - Remove cluster allocation from FAT?
+ Return Values:
+ CE_GOOD - File erased successfully
+ CE_FILE_NOT_FOUND - Could not find the file on the card
+ CE_ERASE_FAIL - Internal Card erase failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries in the directory
+ pointed to by the dirclus value in the FSFILE object 'fo' that contains
+ the entry that corresponds to the fHandle offset. It will then mark that
+ entry as deleted. If the EraseClusters argument is TRUE, the chain of
+ clusters for that file will be marked as unused in the FAT by the
+ FAT_erase_cluster_chain function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+{
+ DIRENTRY dir;
+ BYTE a;
+ CETYPE status = CE_GOOD;
+ DWORD clus;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ // reset the cluster
+ clus = fo->dirclus;
+ fo->dirccls = clus;
+
+ // load the sector
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return CE_BADCACHEREAD;
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ a = dir->DIR_Name[0];
+
+ // see if there is something in the dir
+ if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ /* 8.3 File Name - entry*/
+ dir->DIR_Name[0] = DIR_DEL; // mark as deleted
+
+ // Get the starting cluster
+ clus = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ // Now write it
+ if(status != CE_GOOD || !(Write_File_Entry( fo, fHandle)))
+ {
+ status = CE_ERASE_FAIL;
+ }
+ else
+ {
+ if (clus != FatRootDirClusterValue) //
+ {
+ if(EraseClusters)
+ {
+ /* Now remove the cluster allocation from the FAT */
+ status = ((FAT_erase_cluster_chain(clus, disk)) ? CE_GOOD : CE_ERASE_FAIL);
+ }
+ }
+ }
+ } // Not already deleted
+ }// Not existant
+
+ if (status == CE_GOOD)
+ FSerrno = CE_GOOD;
+ else
+ FSerrno = CE_ERASE_FAIL;
+
+ return (status);
+}
+#endif
+
+/***************************************************************
+ Function:
+ int FSrename (const rom char * fileName, FSFILE * fo)
+ Summary:
+ Change the name of a file or directory
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file
+ fo - The file to rename
+ Return Values:
+ 0 - File was renamed successfully
+ EOF - File was not renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrename function will rename a file. First, it will
+ search through the current working directory to ensure the
+ specified new filename is not already in use. If it isn't,
+ the new filename will be written to the file entry of the
+ file pointed to by 'fo.'
+ Remarks:
+ None
+ ***************************************************************/
+
+#ifdef ALLOW_WRITES
+
+int FSrename (const char * fileName, FSFILE * fo)
+{
+ unsigned char j, k = 0;
+ char string[12];
+ WORD fHandle = 1, goodHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ if (fo == NULL)
+ {
+ FSerrno = CE_FILENOTOPENED;
+ return -1;
+ }
+ // If fo != NULL, rename the file
+ if (FormatFileName (fileName, fo->name, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+ else
+ {
+ for (j = 0; j < 11; j++)
+ {
+ string[j] = fo->name[j];
+ }
+ goodHandle = fo->entry;
+
+ fHandle = 0;
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Check if the file name is already used
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+
+ nextClusterIsLast = FALSE;
+ while (1)
+ {
+ // Look through the entries until we get to the end
+ // to make sure the name isn't taken
+ dir = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dir == NULL)
+ {
+ if (nextClusterIsLast == TRUE)
+ {
+ break;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ if (dir->DIR_Name[0] == 0)
+ break;
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+ fHandle++;
+ }
+
+ fHandle = goodHandle;
+ fo->dirccls = fo->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ for (j = 0; j < 11; j++)
+ {
+ dir->DIR_Name[j] = fo->name[j];
+ }
+
+ // just write the last entry in
+ if(!Write_File_Entry(fo,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#endif // Allow writes
+
+
+
+/*********************************************************************
+ Function:
+ FSFILE * FSfopen (const char * fileName, const char *mode)
+ Summary:
+ Open a file
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to open
+ mode -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ - WRITEPLUS - Create a new file or replace an existing file (reads also enabled)
+ - READPLUS - Read data from an existing file (writes also enabled)
+ - APPENDPLUS - Append data to an existing file (reads also enabled)
+ Return Values:
+ FSFILE * - The pointer to the file object
+ NULL - The file could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will open a file or directory. First, RAM in the
+ dynamic heap or static array will be allocated to a new FSFILE object.
+ Then, the specified file name will be formatted to ensure that it's
+ in 8.3 format. Next, the FILEfind function will be used to search
+ for the specified file name. If the name is found, one of three
+ things will happen: if the file was opened in read mode, its file
+ info will be loaded using the FILEopen function; if it was opened in
+ write mode, it will be erased, and a new file will be constructed in
+ its place; if it was opened in append mode, its file info will be
+ loaded with FILEopen and the current location will be moved to the
+ end of the file using the FSfseek function. If the file was not
+ found by FILEfind, it will be created if the mode was specified as
+ a write or append mode. In these cases, a pointer to the heap or
+ static FSFILE object array will be returned. If the file was not
+ found and the mode was specified as a read mode, the memory
+ allocated to the file will be freed and the NULL pointer value
+ will be returned.
+ Remarks:
+ None.
+ *********************************************************************/
+
+FSFILE * FSfopen( const char * fileName, const char *mode )
+{
+ FILEOBJ filePtr;
+#ifndef FS_DYNAMIC_MEM
+ int fIndex;
+#endif
+ BYTE ModeC;
+ WORD fHandle;
+ CETYPE final;
+
+#ifdef FS_DYNAMIC_MEM
+ filePtr = (FILEOBJ) FS_malloc(sizeof(FSFILE));
+#else
+
+ filePtr = NULL;
+
+ //Pick available file structure
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( gFileSlotOpen[fIndex] ) //this slot is available
+ {
+ gFileSlotOpen[fIndex] = FALSE;
+ filePtr = &gFileArray[fIndex];
+ break;
+ }
+ }
+
+ if( filePtr == NULL )
+ {
+ FSerrno = CE_TOO_MANY_FILES_OPEN;
+ return NULL; //no file structure slot available
+ }
+#endif
+
+ //Format the source string.
+ if( !FormatFileName(fileName, filePtr->name, 0) )
+ {
+#ifdef FS_DYNAMIC_MEM
+ FS_free( (unsigned char *)filePtr );
+#else
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+#endif
+ FSerrno = CE_INVALID_FILENAME;
+ return NULL; //bad filename
+ }
+
+ //Read the mode character
+ ModeC = mode[0];
+
+ filePtr->dsk = &gDiskData;
+ filePtr->cluster = 0;
+ filePtr->ccls = 0;
+ filePtr->entry = 0;
+ filePtr->attributes = ATTR_ARCHIVE;
+
+ // start at the current directory
+#ifdef ALLOW_DIRS
+ filePtr->dirclus = cwdptr->dirclus;
+ filePtr->dirccls = cwdptr->dirccls;
+#else
+ filePtr->dirclus = FatRootDirClusterValue;
+ filePtr->dirccls = FatRootDirClusterValue;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, filePtr);
+
+ // See if the file is found
+ if(FILEfind (filePtr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0) == CE_GOOD)
+ {
+ // File is Found
+ switch(ModeC)
+ {
+#ifdef ALLOW_WRITES
+ case 'w':
+ case 'W':
+ {
+ // File exists, we want to create a new one, remove it first
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ break;
+ }
+
+ case 'A':
+ case 'a':
+ {
+ if(filePtr->size != 0)
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ else
+ {
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ }
+ break;
+ }
+#endif
+ case 'R':
+ case 'r':
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'r');
+#ifdef ALLOW_WRITES
+ if ((mode[1] == '+') && !(filePtr->attributes & ATTR_DIRECTORY))
+ filePtr->flags.write = 1;
+#endif
+ break;
+ }
+
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;; //indicate error condition
+ break;
+ }
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ // the file was not found, reset to the default asked
+ FileObjectCopy(filePtr, &gFileTemp);
+
+ // File is not Found
+ if(ModeC == 'w' || ModeC == 'W' || ModeC == 'a' || ModeC == 'A')
+ {
+ // use the user requested name
+ fHandle = 0;
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ else
+#endif
+ final = CE_FILE_NOT_FOUND;
+ }
+
+ if (MDD_WriteProtectState())
+ {
+ filePtr->flags.write = 0;;
+ }
+
+#ifdef FS_DYNAMIC_MEM
+ if( final != CE_GOOD )
+ {
+ FS_free( (unsigned char *)filePtr );
+ filePtr = NULL;
+ }
+#else
+ if( final != CE_GOOD )
+ {
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+ filePtr = NULL;
+ }
+#endif
+ else
+ {
+ FSerrno = CE_GOOD;
+ }
+
+ return filePtr;
+}
+
+/*******************************************************************
+ Function:
+ long FSftell (FSFILE * fo)
+ Summary:
+ Determine the current location in a file
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to file structure
+ Return: Current location in the file
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSftell function will return the current position in the
+ file pointed to by 'fo' by returning the 'seek' variable in the
+ FSFILE object, which is used to keep track of the absolute
+ location of the current position in the file.
+ Remarks:
+ None
+ *******************************************************************/
+
+long FSftell (FSFILE * fo)
+{
+ FSerrno = CE_GOOD;
+ return (fo->seek);
+}
+
+
+#ifdef ALLOW_WRITES
+
+/*********************************************************************
+ Function:
+ int FSremove (const char * fileName)
+ Summary:
+ Delete a file
+ Conditions:
+ File not opened, file exists
+ Input:
+ fileName - Name of the file to erase
+ Return Values:
+ 0 - File removed
+ EOF - File was not removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremove function will attempt to find the specified file with
+ the FILEfind function. If the file is found, it will be erased
+ using the FILEerase function.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSremove (const char * fileName)
+{
+ FILEOBJ fo = &tempCWDobj;
+ CETYPE result;
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+ //Format the source string
+ if( !FormatFileName(fileName, fo->name, 0) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = ATTR_ARCHIVE;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+
+ if (fo->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_DELETE_DIR;
+ return -1;
+ }
+
+ result = FILEerase(fo, &fo->entry, TRUE);
+ if( result == CE_GOOD )
+ return 0;
+ else
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+}
+#endif
+
+/*********************************************************
+ Function:
+ void FSrewind (FSFILE * fo)
+ Summary:
+ Set the current position in a file to the beginning
+ Conditions:
+ File opened.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ None
+ Side Effects:
+ None.
+ Description:
+ The FSrewind funciton will reset the position of the
+ specified file to the beginning of the file. This
+ functionality is faster than using FSfseek to reset
+ the position in the file.
+ Remarks:
+ None.
+ *********************************************************/
+
+void FSrewind (FSFILE * fo)
+{
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ flushData();
+#endif
+ fo->seek = 0;
+ fo->pos = 0;
+ fo->sec = 0;
+ fo->ccls = fo->cluster;
+ gBufferOwner = NULL;
+ return;
+}
+
+/**************************************************************************
+ Function:
+ int FSerror (void)
+ Summary:
+ Return an error code for the last function call
+ Conditions:
+ The return value depends on the last function called.
+ Input:
+ None
+ Side Effects:
+ None.
+ Return Values:
+ FSInit -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The physical media could not be initialized
+ - CE_BAD_SECTOR_READ � The MBR or the boot sector could not be
+ read correctly
+ - CE_BAD_PARITION � The MBR signature code was incorrect.
+ - CE_NOT_FORMATTED � The boot sector signature code was incorrect or
+ indicates an invalid number of bytes per sector.
+ - CE_CARDFAT32 � The physical media is FAT32 type (only an error
+ when FAT32 support is disabled).
+ - CE_UNSUPPORTED_FS � The device is formatted with an unsupported file
+ system (not FAT12 or 16).
+ FSfopen -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The device has not been initialized.
+ - CE_TOO_MANY_FILES_OPEN � The function could not allocate any
+ additional file information to the array
+ of FSFILE structures or the heap.
+ - CE_INVALID_FILENAME � The file name argument was invalid.
+ - CE_INVALID_ARGUMENT � The user attempted to open a directory in a
+ write mode or specified an invalid mode argument.
+ - CE_FILE_NOT_FOUND � The specified file (which was to be opened in read
+ mode) does not exist on the device.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_ERASE_FAIL � The existing file could not be erased (when opening
+ a file in WRITE mode).
+ - CE_DIR_FULL � The directory is full.
+ - CE_DISK_FULL� The data memory section is full.
+ - CE_WRITE_ERROR � A write to the device failed.
+ - CE_SEEK_ERROR � The current position in the file could not be set to
+ the end (when the file was opened in APPEND mode).
+ FSfclose -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer or the new file
+ entry information could not be written to the device.
+ - CE_BADCACHEREAD � The file entry information could not be cached
+ FSfread -
+ - CE_GOOD � No Error
+ - CE_WRITEONLY � The file was opened in a write-only mode.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_BAD_SECTOR_READ � The data sector could not be read.
+ - CE_EOF � The end of the file was reached.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be loaded.
+ FSfwrite -
+ - CE_GOOD � No Error
+ - CE_READONLY � The file was opened in a read-only mode.
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_WRITE_ERROR � There was an error writing data to the device.
+ - CE_BADCACHEREAD � The data sector to be modified could not be read from
+ the device.
+ - CE_DISK_FULL � All data clusters on the device are in use.
+ FSfseek -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_INVALID_ARGUMENT � The specified offset exceeds the size of the file.
+ - CE_BADCACHEREAD � The sector that contains the new current position
+ could not be loaded.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be
+ loaded/allocated.
+ FSftell -
+ - CE_GOOD � No Error
+ FSattrib -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The attribute argument was invalid.
+ - CE_BADCACHEREAD � The existing file entry information could not be
+ loaded.
+ - CE_WRITE_ERROR � The file entry information could not be written to
+ the device.
+ FSrename -
+ - CE_GOOD � No Error
+ - CE_FILENOTOPENED � A null file pointer was passed into the function.
+ - CE_INVALID_FILENAME � The file name passed into the function was invalid.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_FILENAME_EXISTS � A file with the specified name already exists.
+ - CE_WRITE_ERROR � The new file entry data could not be written to the
+ device.
+ FSfeof -
+ - CE_GOOD � No Error
+ FSformat -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The device could not be initialized.
+ - CE_BADCACHEREAD � The master boot record or boot sector could not be
+ loaded successfully.
+ - CE_INVALID_ARGUMENT � The user selected to create their own boot sector on
+ a device that has no master boot record, or the mode
+ argument was invalid.
+ - CE_WRITE_ERROR � The updated MBR/Boot sector could not be written to
+ the device.
+ - CE_BAD_PARTITION � The calculated number of sectors per clusters was
+ invalid.
+ - CE_NONSUPPORTED_SIZE � The card has too many sectors to be formatted as
+ FAT12 or FAT16.
+ FSremove -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � The specified file could not be found.
+ - CE_ERASE_FAIL � The file could not be erased.
+ FSchdir -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The path string was mis-formed or the user tried to
+ change to a non-directory file.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_FOUND � Could not find a directory in the path.
+ FSgetcwd -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The user passed a 0-length buffer into the function.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the current working directory.
+ FSmkdir -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_ARGUMENT � The path string was mis-formed.
+ - CE_BADCACHEREAD � Could not successfully change to a recently created
+ directory to store its dir entry information, or
+ could not cache directory entry information.
+ - CE_INVALID_FILENAME � One or more of the directory names has an invalid
+ format.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device or the dot/dotdot entries could
+ not be written to a newly created directory.
+ - CE_DIR_FULL � There are no available dir entries in the CWD.
+ - CE_DISK_FULL � There are no available clusters in the data region of
+ the device.
+ FSrmdir -
+ - CE_GOOD � No Error
+ - CE_DIR_NOT_FOUND � The directory specified could not be found or the
+ function could not change to a subdirectory within
+ the directory to be deleted (when recursive delete is
+ enabled).
+ - CE_INVALID_ARGUMENT � The user tried to remove the CWD or root directory.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_EMPTY � The directory to be deleted was not empty and
+ recursive subdirectory removal was disabled.
+ - CE_ERASE_FAIL � The directory or one of the directories or files
+ within it could not be deleted.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the CWD.
+ SetClockVars -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The time values passed into the function were
+ invalid.
+ FindFirst -
+ - CE_GOOD � No Error
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ - CE_BADCACHEREAD � The file information for the file that was found
+ could not be cached.
+ FindNext -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The SearchRec object was not initialized by a call to
+ FindFirst.
+ - CE_INVALID_ARGUMENT � The SearchRec object was initialized in a different
+ directory from the CWD.
+ - CE_INVALID_FILENAME � The filename is invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ FSfprintf -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � Characters could not be written to the file.
+ Description:
+ The FSerror function will return the FSerrno variable. This global
+ variable will have been set to an error value during the last call of a
+ library function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSerror (void)
+{
+ return FSerrno;
+}
+
+
+/**************************************************************
+ Function:
+ void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+ Summary:
+ Copy a file object
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - The destination
+ foSource - the source
+ Return:
+ None
+ Side Effects:
+ None
+ Description:
+ The FileObjectCopy function will make an exacy copy of
+ a specified FSFILE object.
+ Remarks:
+ None
+ **************************************************************/
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+{
+ BYTE size;
+ BYTE *dest;
+ BYTE *source;
+ BYTE Index;
+
+ dest = (BYTE *)foDest;
+ source = (BYTE *)foSource;
+
+ size = sizeof(FSFILE);
+
+ for(Index=0;Index< size; Index++)
+ {
+ dest[Index] = source[Index];
+ }
+}
+
+/*************************************************************************
+ Function:
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+ Summary:
+ Create the first cluster of a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ cluster - Cluster location
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ CE_DISK_FULL - All clusters in partition are taken
+ Side Effects:
+ None
+ Description:
+ The FILECreateHeadCluster function will create the first cluster
+ of a file. First, it will find an empty cluster with the
+ FATfindEmptyCluster function and mark it as the last cluster in the
+ file. It will then erase the cluster using the EraseCluster function.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+{
+ DISK * disk;
+ CETYPE error = CE_GOOD;
+
+ disk = fo->dsk;
+
+ // find the next empty cluster
+ *cluster = FATfindEmptyCluster(fo);
+
+ if(*cluster == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ {
+ error = CE_DISK_FULL;
+ }
+ else
+ {
+ // mark the cluster as taken, and last in chain
+ if(disk->type == FAT12)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT12, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+ else if(disk->type == FAT16)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT16, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+
+ #ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT32, FALSE) == CLUSTER_FAIL_FAT32)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+#endif
+
+ // lets erase this cluster
+ if(error == CE_GOOD)
+ {
+ error = EraseCluster(disk,*cluster);
+ }
+ }
+
+ return(error);
+} // allocate head cluster
+#endif
+
+/*************************************************************************
+ Function:
+ BYTE EraseCluster(DISK *disk, DWORD cluster)
+ Summary:
+ Erase a cluster
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - Disk structure
+ cluster - Cluster to be erased
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ Side Effects:
+ None
+ Description:
+ The EraseCluster function will write a 0 value into every byte of
+ the specified cluster.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE EraseCluster(DISK *disk, DWORD cluster)
+{
+ BYTE index;
+ DWORD SectorAddress;
+ BYTE error = CE_GOOD;
+
+ SectorAddress = Cluster2Sector(disk,cluster);
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+
+ gBufferOwner = NULL;
+
+ if (gBufferZeroed == FALSE)
+ {
+ // clear out the memory first
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+ gBufferZeroed = TRUE;
+ }
+
+ // Now clear them out
+ for(index = 0; index < disk->SecPerClus && error == CE_GOOD; index++)
+ {
+ if (MDD_SectorWrite( SectorAddress++, disk->buffer, FALSE) != TRUE)
+ error = CE_WRITE_ERROR;
+ }
+
+ return(error);
+}
+#endif
+
+
+#if defined (__C30__) || defined (__C32__)
+
+/***************************************************
+ Function:
+ BYTE ReadByte(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a byte from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ BYTE - the byte read
+ Side Effects:
+ None
+ Description:
+ Reads a byte from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+BYTE ReadByte( BYTE* pBuffer, WORD index )
+{
+ return( pBuffer[index] );
+}
+
+
+/***************************************************
+ Function:
+ BYTE ReadWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 16-bit word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ WORD - the word read
+ Side Effects:
+ None
+ Description:
+ Reads a 16-bit word from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+WORD ReadWord( BYTE* pBuffer, WORD index )
+{
+ BYTE loByte, hiByte;
+ WORD res;
+
+ loByte = pBuffer[index];
+ hiByte = pBuffer[index+1];
+ res = hiByte;
+ res *= 0x100;
+ res |= loByte;
+ return( res );
+}
+
+
+/****************************************************
+ Function:
+ BYTE ReadDWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 32-bit double word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ DWORD - the double word read
+ Side Effects:
+ None
+ Description:
+ Reads a 32-bit double word from a buffer
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD ReadDWord( BYTE* pBuffer, WORD index )
+{
+ WORD loWord, hiWord;
+ DWORD result;
+
+ loWord = ReadWord( pBuffer, index );
+ hiWord = ReadWord( pBuffer, index+2 );
+
+ result = hiWord;
+ result *= 0x10000;
+ result |= loWord;
+ return result;
+}
+
+#endif
+
+
+
+/****************************************************
+ Function:
+ DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+ Summary:
+ Convert a cluster number to the corresponding sector
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - Disk structure
+ cluster - Cluster to be converted
+ Return:
+ sector - Sector that corresponds to given cluster
+ Side Effects:
+ None
+ Description:
+ The Cluster2Sector function will calculate the
+ sector number that corresponds to the first sector
+ of the cluster whose value was passed into the
+ function.
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+{
+ DWORD sector;
+
+ /* Rt: Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ /* In FAT32, there is no separate ROOT region. It is as well stored in DATA region */
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // The root dir takes up cluster 0 and 1
+ if(cluster == 0 ||cluster == 1)
+ sector = dsk->root + cluster;
+ else
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+ }
+
+ return(sector);
+
+}
+
+
+/***************************************************************************
+ Function:
+ int FSattrib (FSFILE * file, unsigned char attributes)
+ Summary:
+ Change the attributes of a file
+ Conditions:
+ File opened
+ Input:
+ file - Pointer to file structure
+ attributes - The attributes to set for the file
+ - Attribute - Value - Indications
+ - ATTR_READ_ONLY - 0x01 - The read-only attribute
+ - ATTR_HIDDEN - 0x02 - The hidden attribute
+ - ATTR_SYSTEM - 0x04 - The system attribute
+ - ATTR_ARCHIVE - 0x20 - The archive attribute
+ Return Values:
+ 0 - Attribute change was successful
+ -1 - Attribute change was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSattrib funciton will set the attributes of the specified file
+ to the attributes passed in by the user. This function will load the
+ file entry, replace the attributes with the ones specified, and write
+ the attributes back. If the specified file is a directory, the
+ directory attribute will be preserved.
+ Remarks:
+ None
+ ***************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSattrib (FSFILE * file, unsigned char attributes)
+{
+ WORD fHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ // Check for valid attributes
+ if ((attributes & ~0x27) != 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ fHandle = file->entry;
+
+ file->dirccls = file->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(file, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Ensure that we aren't trying to change the
+ // attributes of a volume entry
+ if (dir->DIR_Attr & ATTR_VOLUME)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Don't remove the directory attribute from DIR files
+ if (file->attributes & ATTR_DIRECTORY)
+ dir->DIR_Attr = attributes | ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = attributes;
+
+ // just write the last entry in
+ if(!Write_File_Entry(file,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+
+/*********************************************************************************
+ Function:
+ size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Write data to a file
+ Conditions:
+ File opened in WRITE, APPEND, WRITE+, APPEND+, READ+ mode
+ Input:
+ ptr - Pointer to source buffer
+ size - Size of units in bytes
+ n - Number of units to transfer
+ stream - Pointer to file structure
+ Return:
+ size_t - number of units written
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfwrite function will write data to a file. First, the sector that
+ corresponds to the current position in the file will be loaded (if it hasn't
+ already been cached in the global data buffer). Data will then be written to
+ the device from the specified buffer until the specified amount has been written.
+ If the end of a cluster is reached, the next cluster will be loaded, unless
+ the end-of-file flag for the specified file has been set. If it has, a new
+ cluster will be allocated to the file. Finally, the new position and filezize
+ will be stored in the FSFILE object. The parameters 'size' and 'n' indicate how
+ much data to write. 'Size' refers to the size of one object to write (in bytes),
+ and 'n' will refer to the number of these objects to write. The value returned
+ will be equal to 'n' unless an error occured.
+ Remarks:
+ None.
+ *********************************************************************************/
+
+#ifdef ALLOW_WRITES
+size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD count = size * n;
+ BYTE * src = (BYTE *) ptr;
+ DISK * dsk; // pointer to disk structure
+ CETYPE error = CE_GOOD;
+ WORD pos;
+ DWORD l; // absolute lba of sector to load
+ DWORD seek, filesize;
+ WORD writeCount = 0;
+
+ // see if the file was opened in a write mode
+ if(!(stream->flags.write))
+ {
+ FSerrno = CE_READONLY;
+ error = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ if (count == 0)
+ return 0;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ error = CE_WRITE_PROTECTED;
+ return 0;
+ }
+
+ gBufferZeroed = FALSE;
+ dsk = stream->dsk;
+ // get the stated position
+ pos = stream->pos;
+ seek = stream->seek;
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ // Check if the current stream was the last one to use the
+ // buffer. If not, check if we need to write data from the
+ // old stream
+ if (gBufferOwner != stream)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+ gBufferOwner = stream;
+ }
+ if (gLastDataSectorRead != l)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+
+ gBufferZeroed = FALSE;
+ if(!MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ }
+ gLastDataSectorRead = l;
+ }
+ // exit loop if EOF reached
+ filesize = stream->size;
+
+ // Loop while writing bytes
+ while (error == CE_GOOD && count > 0)
+ {
+ if( seek == filesize )
+ stream->flags.FileWriteEOF = TRUE;
+
+ // load a new sector if necessary, multiples of sector
+ if (pos == MEDIA_SECTOR_SIZE)
+ {
+ BYTE needRead = TRUE;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ // reset position
+ pos = 0;
+
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if (stream->sec == dsk->SecPerClus)
+ {
+ stream->sec = 0;
+
+ if(stream->flags.FileWriteEOF)
+ {
+ error = FILEallocate_new_cluster(stream, 0); // add new cluster to the file
+ needRead = FALSE;
+ }
+ else
+ error = FILEget_next_cluster( stream, 1);
+ }
+
+ if (error == CE_DISK_FULL)
+ {
+ FSerrno = CE_DISK_FULL;
+ return 0;
+ }
+
+ if(error == CE_GOOD)
+ {
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+ gBufferOwner = stream;
+ // If we just allocated a new cluster, then the cluster will
+ // contain garbage data, so it doesn't matter what we write to it
+ // Whatever is in the buffer will work fine
+ if (needRead)
+ {
+ if( !MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = 0xFFFFFFFF;
+ return 0;
+ }
+ else
+ {
+ gLastDataSectorRead = l;
+ }
+ }
+ else
+ gLastDataSectorRead = l;
+ }
+ } // load new sector
+
+ if(error == CE_GOOD)
+ {
+ // Write one byte at a time
+ RAMwrite(dsk->buffer, pos++, *(char *)src);
+ src = src + 1; // compiler bug
+ seek++;
+ count--;
+ writeCount++;
+ // now increment the size of the part
+ if(stream->flags.FileWriteEOF)
+ filesize++;
+ gNeedDataWrite = TRUE;
+ }
+ } // while count
+
+ // save off the positon
+ stream->pos = pos;
+
+ // save off the seek
+ stream->seek = seek;
+
+ // now the new size
+ stream->size = filesize;
+
+ return(writeCount / size);
+} // fwrite
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE flushData (void)
+ Summary:
+ Flush unwritten data to a file
+ Conditions:
+ File opened in a write mode, data needs to be written
+ Return Values:
+ CE_GOOD - Data was updated successfully
+ CE_WRITE_ERROR - Data could not be updated
+ Side Effects:
+ None
+ Description:
+ The flushData function is called when it is necessary to
+ read new data into the global data buffer and the
+ gNeedDataWrite variable indicates that there is data
+ in the buffer that hasn't been written to the device.
+ The flushData function will write the data from the
+ buffer into the current cluster of the FSFILE object
+ that is stored in the gBufferOwner global variable.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE flushData (void)
+{
+ DWORD l;
+ DISK * dsk;
+
+ // This will either be the pointer to the last file, or the handle
+ FILEOBJ stream = gBufferOwner;
+
+ dsk = stream->dsk;
+
+ // figure out the lba
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ if(!MDD_SectorWrite( l, dsk->buffer, FALSE))
+ {
+ return CE_WRITE_ERROR;
+ }
+
+ gNeedDataWrite = FALSE;
+
+ return CE_GOOD;
+}
+#endif
+
+/****************************************************
+ Function:
+ int FSfeof( FSFILE * stream )
+ Summary:
+ Indicate whether the current file position is at the end
+ Conditions:
+ File is open in a read mode
+ Input:
+ stream - Pointer to the target file
+ Return Values:
+ Non-Zero - EOF reached
+ 0 - Not at end of File
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfeof function will indicate that the end-of-
+ file has been reached for the specified file by
+ comparing the absolute location in the file to the
+ size of the file.
+ Remarks:
+ None.
+ ****************************************************/
+
+int FSfeof( FSFILE * stream )
+{
+ FSerrno = CE_GOOD;
+ return( stream->seek == stream->size );
+}
+
+
+/**************************************************************************
+ Function:
+ size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Read data from a file
+ Conditions:
+ File is opened in a read mode
+ Input:
+ ptr - Destination buffer for read bytes
+ size - Size of units in bytes
+ n - Number of units to be read
+ stream - File to be read from
+ Return:
+ size_t - number of units read
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfread function will read data from the specified file. First,
+ the appropriate sector of the file is loaded. Then, data is read into
+ the specified buffer until the specified number of bytes have been read.
+ When a cluster boundary is reached, a new cluster will be loaded. The
+ parameters 'size' and 'n' indicate how much data to read. 'Size'
+ refers to the size of one object to read (in bytes), and 'n' will refer
+ to the number of these objects to read. The value returned will be equal
+ to 'n' unless an error occured or the user tried to read beyond the end
+ of the file.
+ Remarks:
+ None.
+ **************************************************************************/
+
+size_t FSfread (void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD len = size * n;
+ BYTE *pointer = (BYTE *) ptr;
+ DISK *dsk; // Disk structure
+ DWORD seek, sec_sel;
+ WORD pos; //position within sector
+ CETYPE error = CE_GOOD;
+ WORD readCount = 0;
+
+ FSerrno = CE_GOOD;
+
+ dsk = (DISK *)stream->dsk;
+ pos = stream->pos;
+ seek = stream->seek;
+
+ if( !stream->flags.read )
+ {
+ FSerrno = CE_WRITEONLY;
+ return 0; // CE_WRITEONLY
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+#endif
+
+ // if it not my buffer, then get it from the disk.
+ if( (gBufferOwner != stream) && (pos != MEDIA_SECTOR_SIZE ))
+ {
+ gBufferOwner = stream;
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ return 0;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ //loop reading (count) bytes
+ while( len )
+ {
+ if( seek == stream->size )
+ {
+ FSerrno = CE_EOF;
+ error = CE_EOF;
+ break;
+ }
+
+ // In fopen, pos is init to 0 and the sect is loaded
+ if( pos == MEDIA_SECTOR_SIZE )
+ {
+ // reset position
+ pos = 0;
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if( stream->sec == dsk->SecPerClus )
+ {
+ stream->sec = 0;
+ if( (error = FILEget_next_cluster( stream, 1)) != CE_GOOD )
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ break;
+ }
+ }
+
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+
+ gBufferOwner = stream;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ break;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ // copy one byte at a time
+ *pointer = RAMread( dsk->buffer, pos++ );
+ pointer++;
+ seek++;
+ readCount++;
+ len--;
+ }
+
+ // save off the positon
+ stream->pos = pos;
+ // save off the seek
+ stream->seek = seek;
+
+ return(readCount / size);
+} // fread
+
+
+/***************************************************************************
+ Function:
+ BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode )
+ Summary:
+ Format a file name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be formatted
+ fN2 - The location the formatted name will be stored
+ mode - Non-zero if parital string search chars are allowed
+ Return Values:
+ TRUE - Name formatted successfully
+ FALSE - File name could not be formatted
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into FSFILE structure format. If filename is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ filename are valid in this filesystem.
+ Remarks:
+ None.
+ ***************************************************************************/
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode)
+{
+ char * pExt;
+ WORD temp;
+ char szName[15];
+ BYTE count;
+
+ for (count = 0; count < 11; count++)
+ {
+ *(fN2 + count) = ' '; // Load destination filename to be space intially.
+ }
+
+ // Make sure we dont have an empty string or a name with only
+ // an extension
+ if (fileName[0] == '.' || fileName[0] == 0)
+ return FALSE;
+
+ temp = strlen( fileName );
+
+ if( temp <= TOTAL_FILE_SIZE ) // 8+3+1
+ strcpy( szName, fileName ); // copy to RAM in case fileName is located in flash
+ else
+ return FALSE; //long file name
+
+ // Make sure the characters are valid
+ if ( !ValidateChars(szName, mode) )
+ return FALSE;
+
+ //Look for '.' in the szName
+ if( (pExt = strchr( szName, '.' )) != 0 )
+ {
+ *pExt = 0; // Assigning NULL here makes the "szName" to be terminated and "pExt" pointer to hold only extn characters.
+ pExt++; // now pointing to extension
+
+ if( strlen( pExt ) > 3 ) // make sure the extension is 3 bytes or fewer
+ return FALSE;
+ }
+
+ if( strlen(szName) > 8 )
+ return FALSE;
+
+ //copy file name
+ for (count = 0; count < strlen(szName); count++)
+ {
+ *(fN2 + count) = * (szName + count); // Destination filename initially filled with SPACE. Now copy only available chars.
+ }
+
+ //copy extension
+ if(pExt && *pExt )
+ {
+ for (count = 0; count < strlen (pExt); count++)
+ {
+ *(fN2 + count + 8) = *(pExt + count); // Copy the extn to 8th position onwards. Ex: "FILE .Tx "
+ }
+ }
+
+ return TRUE;
+}
+
+#ifdef ALLOW_DIRS
+
+/*************************************************************************
+ Function:
+ BYTE FormatDirName (char * string, BYTE mode)
+ Summary:
+ Format a dir name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ string - The name to be formatted
+ mode -
+ - TRUE - Partial string search characters are allowed
+ - FALSE - Partial string search characters are forbidden
+ Return Values:
+ TRUE - The name was formatted correctly
+ FALSE - The name contained invalid characters
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into directory structure format. If the name is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ directory name are valid in this filesystem.
+ Remarks:
+ None.
+ *************************************************************************/
+
+BYTE FormatDirName (char * string, BYTE mode)
+{
+ unsigned char i, j;
+ char tempString [12];
+
+ if (ValidateChars (string, mode) == FALSE)
+ return FALSE;
+
+ for (i = 0; (i < 8) && (*(string + i) != '.') && (*(string + i) != 0); i++)
+ {
+ tempString[i] = *(string + i);
+ }
+
+ j = i;
+
+ while (i < 8)
+ {
+ tempString [i++] = 0x20;
+ }
+
+ if (*(string + j) == '.')
+ {
+ j++;
+ while (*(string + j) != 0)
+ {
+ tempString[i++] = *(string + j++);
+ }
+ }
+
+ while (i < 11)
+ {
+ tempString[i++] = 0x20;
+ }
+
+ tempString[11] = 0;
+
+ // Forbidden
+ if (tempString[0] == 0x20)
+ {
+ tempString[0] = '_';
+ }
+
+ for (i = 0; i < 12; i++)
+ {
+ *(string + i) = tempString[i];
+ }
+
+ return TRUE;
+}
+#endif
+
+
+/*************************************************************
+ Function:
+ BYTE ValidateChars( char * FileName, BYTE mode)
+ Summary:
+ Validate the characters in a given file name
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be validated
+ mode - Determines if partial string search is allowed
+ Return Values:
+ TRUE - Name was validated
+ FALSE - File name was not valid
+ Side Effects:
+ None
+ Description:
+ The ValidateChars function will compare characters in a
+ specified filename to determine if they're permissable
+ in the FAT file system. Lower-case characters will be
+ converted to upper-case. If the mode argument is specifed
+ to be 'TRUE,' partial string search characters are allowed.
+ Remarks:
+ None.
+ *************************************************************/
+BYTE ValidateChars( char * FileName , BYTE mode)
+{
+ int StrSz, index;
+ unsigned char radix = FALSE;
+
+ StrSz = strlen(FileName);
+
+ for( index = 0; index < StrSz; index++ )
+ {
+ if (((FileName[index] <= 0x20) && (FileName[index] != 0x05)) ||
+ (FileName[index] == 0x22) || (FileName[index] == 0x2B) ||
+ (FileName[index] == 0x2C) || (FileName[index] == 0x2F) ||
+ (FileName[index] == 0x3A) || (FileName[index] == 0x3B) ||
+ (FileName[index] == 0x3C) || (FileName[index] == 0x3D) ||
+ (FileName[index] == 0x3E) || (FileName[index] == 0x5B) ||
+ (FileName[index] == 0x5C) || (FileName[index] == 0x5D) ||
+ (FileName[index] == 0x7C) || ((FileName[index] == 0x2E) && radix == TRUE))
+ {
+ return FALSE;
+ }
+ else
+ {
+ // Check for partial string search chars
+ if (mode == FALSE)
+ {
+ if ((FileName[index] == '*') || (FileName[index] == '?'))
+ return FALSE;
+ }
+ // only one radix ('.') character is allowed
+ if (FileName[index] == 0x2E)
+ {
+ radix = TRUE;
+ }
+ // Convert lower-case to upper-case
+ if ((FileName[index] >= 0x61) && (FileName[index] <= 0x7A))
+ FileName[index] -= 0x20;
+ }
+ }
+ return TRUE;
+}
+
+
+/**********************************************************************
+ Function:
+ int FSfseek(FSFILE *stream, long offset, int whence)
+ Summary:
+ Change the current position in a file
+ Conditions:
+ File opened
+ Input:
+ stream - Pointer to file structure
+ offset - Offset from base location
+ whence -
+ - SEEK_SET - Seek from start of file
+ - SEEK_CUR - Seek from current location
+ - SEEK_END - Seek from end of file (subtract offset)
+ Return Values:
+ 0 - Operation successful
+ -1 - Operation unsuccesful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfseek function will change the current position in the file to
+ one specified by the user. First, an absolute offset is calculated
+ using the offset and base location passed in by the user. Then, the
+ position variables are updated, and the sector number that corresponds
+ to the new location. That sector is then loaded. If the offset
+ falls exactly on a cluster boundary, a new cluster will be allocated
+ to the file and the position will be set to the first byte of that
+ cluster.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSfseek(FSFILE *stream, long offset, int whence)
+{
+ DWORD numsector, temp; // lba of first sector of first cluster
+ DISK* dsk; // pointer to disk structure
+ BYTE test;
+ long offset2 = offset;
+
+ dsk = stream->dsk;
+
+ switch(whence)
+ {
+ case SEEK_CUR:
+ // Apply the offset to the current position
+ offset2 += stream->seek;
+ break;
+ case SEEK_END:
+ // Apply the offset to the end of the file
+ offset2 = stream->size - offset2;
+ break;
+ case SEEK_SET:
+ // automatically there
+ default:
+ break;
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+#endif
+
+ // start from the beginning
+ temp = stream->cluster;
+ stream->ccls = temp;
+
+ temp = stream->size;
+
+ if (offset2 > temp)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return (-1); // past the limits
+ }
+ else
+ {
+ // if we are writing we are no longer at the end
+ stream->flags.FileWriteEOF = FALSE;
+
+ // set the new postion
+ stream->seek = offset2;
+
+ // figure out how many sectors
+ numsector = offset2 / MEDIA_SECTOR_SIZE;
+
+ // figure out how many bytes off of the offset
+ offset2 = offset2 - (numsector * MEDIA_SECTOR_SIZE);
+ stream->pos = offset2;
+
+ // figure out how many clusters
+ temp = numsector / dsk->SecPerClus;
+
+ // figure out the stranded sectors
+ numsector = numsector - (dsk->SecPerClus * temp);
+ stream->sec = numsector;
+
+ // if we are in the current cluster stay there
+ if (temp > 0)
+ {
+ test = FILEget_next_cluster(stream, temp);
+ if (test != CE_GOOD)
+ {
+ if (test == CE_FAT_EOF)
+ {
+#ifdef ALLOW_WRITES
+ if (stream->flags.write)
+ {
+ // load the previous cluster
+ stream->ccls = stream->cluster;
+ // Don't perform this operation if there's only one cluster
+ if (temp != 1)
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (FILEallocate_new_cluster(stream, 0) != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return -1;
+ }
+ // sec and pos should already be zero
+ }
+ else
+ {
+#endif
+ stream->ccls = stream->cluster;
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (test != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1);
+ }
+ stream->pos = MEDIA_SECTOR_SIZE;
+ stream->sec = dsk->SecPerClus - 1;
+#ifdef ALLOW_WRITES
+ }
+#endif
+ }
+ else
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1); // past the limits
+ }
+ }
+ }
+
+ // Determine the lba of the selected sector and load
+ temp = Cluster2Sector(dsk,stream->ccls);
+
+ // now the extra sectors
+ numsector = stream->sec;
+ temp += numsector;
+
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead(temp, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return (-1); // Bad read
+ }
+ gLastDataSectorRead = temp;
+ }
+
+ FSerrno = CE_GOOD;
+
+ return (0);
+}
+
+
+// FSfopenpgm, FSremovepgm, and FSrenamepgm will only work on PIC18s
+#ifdef __18CXX
+#ifdef ALLOW_PGMFUNCTIONS
+
+#ifdef ALLOW_WRITES
+
+/*****************************************************************
+ Function:
+ int FSrenamepgm(const rom char * fileName, FSFILE * fo)
+ Summary:
+ Rename a file named with a ROM string on PIC18
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file (in ROM)
+ fo - The file to rename
+ Return Values:
+ 0 - File renamed successfully
+ -1 - File could not be renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The Fsrenamepgm function will copy the rom fileName specified
+ by the user into a RAM array and pass that array into the
+ FSrename function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *****************************************************************/
+
+int FSrenamepgm (const rom char * fileName, FSFILE * fo)
+{
+ char F[13];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+
+ return FSrename (F, fo);
+}
+#endif
+
+/******************************************************************************
+ Function:
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+ Summary:
+ Open a file named with a ROM string on PIC18
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to be opened (ROM)
+ mode - The mode the file will be opened in (ROM)
+ Return Values:
+ FSFILE * - A pointer to the file object
+ NULL - File could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfopenpgm function will copy a PIC18 ROM fileName and mode argument
+ into RAM arrays, and then pass those arrays to the FSfopen function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ ******************************************************************************/
+
+
+FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+{
+ char F[13];
+ char M[2];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+ for (count = 0; count < 2; count++)
+ {
+ M[count] = *(mode + count);
+ }
+
+ return FSfopen(F, M);
+}
+
+/*************************************************************
+ Function:
+ int FSremovepgm (const rom char * fileName)
+ Summary:
+ Delete a file named with a ROM string on PIC18
+ Conditions:
+ File not opened; file exists
+ Input:
+ fileName - The name of the file to be deleted (ROM)
+ Return Values:
+ 0 - File was removed successfully
+ -1 - File could not be removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremovepgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FSremove function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *************************************************************/
+#ifdef ALLOW_WRITES
+int FSremovepgm (const rom char * fileName)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for(...)
+
+ return FSremove (F);
+}
+#endif
+
+/**************************************************************************************
+ Function:
+ int FindFirstpgm (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Find a file named with a ROM string on PIC18
+ Conditions:
+ None
+ Input:
+ fileName - The name of the file to be found (ROM)
+ attr - The attributes of the file to be found
+ rec - Pointer to a search record to store the file info in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the given parameters was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object will be lost.
+ The FSerrno variable will be changed.
+ Description:
+ The FindFirstpgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FindFirst function.
+ Remarks:
+ Call FindFirstpgm or FindFirst before calling FindNext.
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************************/
+#ifdef ALLOW_FILESEARCH
+int FindFirstpgm (const rom char * fileName, unsigned int attr, SearchRec * rec)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for
+
+ return FindFirst (F,attr,rec);
+}
+#endif
+#endif
+#endif
+
+
+/***********************************************
+ Function:
+ DWORD ReadFAT (DISK *dsk, DWORD ccls)
+ Summary:
+ Read the next entry from the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ Return:
+ DWORD - The next cluster in a file chain
+ Side Effects:
+ None
+ Description:
+ The ReadFAT function will read the FAT and
+ determine the next cluster value after the
+ cluster specified by 'ccls.' Note that the
+ FAT sector that is read is stored in the
+ global FAT cache buffer.
+ Remarks:
+ None.
+ ***********************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls)
+{
+ BYTE q;
+ DWORD p, l; // "l" is the sector Address
+ DWORD c, d, ClusterFailValue,LastClusterLimit; // ClusterEntries
+
+ gBufferZeroed = FALSE;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls * 4;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls *3; // Mulby1.5 to find cluster pos in FAT
+ q = p&1;
+ p >>= 1;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT12;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD)ccls *2; // Mulby 2 to find cluster pos in FAT
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ l = dsk->fat + (p >> 9); // FAT buffer has 512 bytes of size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ // Check if the appropriate FAT sector is already loaded
+ if (gLastFATSectorRead == l)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if(dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ // Check if the MSB is across the sector boundry
+ p = (p +1) & 0x1FF;
+ if (p == 0)
+ {
+ // Start by writing the sector we just worked on to the card
+ // if we need to
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+#endif
+ if (!MDD_SectorRead (l+1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l +1;
+ }
+ }
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ else
+ {
+ // If there's a currently open FAT sector,
+ // write it back before reading into the buffer
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ {
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+ }
+#endif
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF; // Note: It is Sector not Cluster.
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if (dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ p = (p +1) & 0x1FF;
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ }
+
+ // Normalize it so 0xFFFF is an error
+ if (c >= LastClusterLimit)
+ c = LastClusterLimit;
+
+ return c;
+} // ReadFAT
+
+
+
+/****************************************************************************
+ Function:
+ WORD WriteFAT (DISK *dsk, DWORD ccls, WORD value, BYTE forceWrite)
+ Summary:
+ Write an entry to the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ value - The value to write in
+ forceWrite - Force the function to write the current FAT sector
+ Return:
+ 0 - The FAT write was successful
+ FAIL - The FAT could not be written
+ Side Effects:
+ None
+ Description:
+ The WriteFAT function writes an entry to the FAT. If the function
+ is called and the 'forceWrite' argument is TRUE, the function will
+ write the existing FAT data to the device. Otherwise, the function
+ will replace a single entry in the FAT buffer (indicated by 'ccls')
+ with a new value (indicated by 'value.')
+ Remarks:
+ None.
+ ****************************************************************************/
+
+#ifdef ALLOW_WRITES
+DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite)
+{
+ BYTE i, q, c;
+ DWORD p, li, l, ClusterFailValue;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type != FAT32 && dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT32;
+#else // If FAT32 support not enabled
+ if (dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT16;
+#endif
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ gBufferZeroed = FALSE;
+
+ // The only purpose for calling this function with forceWrite
+ // is to write the current FAT sector to the card
+ if (forceWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+
+ return 0;
+ }
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls *4; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls * 3; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ q = p & 1; // Odd or even?
+ p >>= 1;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD) ccls *2; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+ }
+
+ l = dsk->fat + (p >>9); // FAt Buffer is 512 bytes size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ if (gLastFATSectorRead != l)
+ {
+ // If we are loading a new sector then write
+ // the current one to the card if we need to
+ if (gNeedFATWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+ }
+
+ // Load the new sector
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l;
+ }
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32) // Refer page 16 of FAT requirement.
+ {
+ RAMwrite (gFATBuffer, p, ((value&0x000000ff))); // lsb,1st byte of cluster value
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8));
+ RAMwrite (gFATBuffer, p+2, ((value&0x00ff0000) >> 16));
+ RAMwrite (gFATBuffer, p+3, ((value&0x0f000000) >> 24)); // the MSB nibble is supposed to be "0" in FAT32. So mask it.
+ }
+ else
+#endif
+
+ if (dsk->type == FAT16)
+ {
+ RAMwrite (gFATBuffer, p, value); //lsB
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8)); // msB
+ }
+ else if (dsk->type == FAT12)
+ {
+ // Get the current byte from the FAT
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = ((value & 0x0F) << 4) | ( c & 0x0F);
+ }
+ else
+ {
+ c = (value & 0xFF);
+ }
+ // Write in those bits
+ RAMwrite (gFATBuffer, p, c);
+
+ // FAT12 entries can cross sector boundaries
+ // Check if we need to load a new sector
+ p = (p+1) & 0x1FF;
+ if (p == 0)
+ {
+ // call this function to update the FAT on the card
+ if (WriteFAT (dsk, 0,0,TRUE))
+ return ClusterFailValue;
+ // Load the next sector
+ if (!MDD_SectorRead (l +1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l + 1;
+ }
+
+ // Get the second byte of the table entry
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = (value >> 4);
+ }
+ else
+ {
+ c = ((value >> 8) & 0x0F) | (c & 0xF0);
+ }
+ RAMwrite (gFATBuffer, p, c);
+ }
+
+ gNeedFATWrite = TRUE;
+
+ return 0;
+}
+#endif
+
+
+#ifdef ALLOW_DIRS
+
+// This string is used by dir functions to hold dir names temporarily
+char defaultString [13];
+
+
+
+/**************************************************************************
+ Function:
+ int FSchdir (char * path)
+ Summary:
+ Change the current working directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to.
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdir function passes a RAM pointer to the path to the
+ chdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSchdir (char * path)
+{
+ return chdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSchdirpgm (const rom char * path)
+ Summary:
+ Changed the CWD with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to (ROM)
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdirpgm function passes a PIC18 ROM path pointer to the
+ chdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSchdirpgm (const rom char * path)
+{
+ return chdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+ // PIC18
+ int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ Summary:
+ Helper function for FSchdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was changed successfully.
+ EOF - Directory could not be changed.
+ Side Effects:
+ The current working directory will be changed. The FSerrno variable
+ will be changed. Any unwritten data in the data buffer will be written
+ to the device.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able to
+ parse it correctly. The function will loop through a switch statement
+ to process the tokens in the path string. Dot or dotdot entries are
+ handled in the first case statement. A backslash character is handled
+ in the second case statement (note that this case statement will only
+ be used if backslash is the first character in the path; backslash
+ token delimiters will automatically be skipped after each token in the
+ path is processed). The third case statement will handle actual
+ directory name strings.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int chdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ WORD curent = 1;
+ DIRENTRY entry;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ FSFILE tempCWDobj2;
+ char tempArray[12];
+ FILEOBJ tempCWD = &tempCWDobj2;
+ FileObjectCopy (tempCWD, cwdptr);
+
+ FSerrno = CE_GOOD;
+
+ // Check the first char of the path
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+ if (i == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ while(1)
+ {
+ switch (i)
+ {
+ // First case: dot or dotdot entry
+ case '.':
+ // Move past the dot
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if it's a dotdot entry
+ if (i == '.')
+ {
+ // Increment the path variable
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if we're in the root
+ if (tempCWD->dirclus == FatRootDirClusterValue)
+ {
+ // Fails if there's a dotdot chdir from the root
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ else
+ {
+ // Cache the dotdot entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ curent = 1;
+ entry = Cache_File_Entry (tempCWD, &curent, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ tempCWD->dirclus = GetFullClusterNumber(entry); // Get Complete Cluster number.
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // If we changed to root, record the name
+ if (tempCWD->dirclus == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT) // "0" is the value of Dotdot entry for Root in both FAT types.
+ {
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+
+ /* While moving to Root, get the Root cluster value */
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Otherwise set the name to ..
+ tempCWD->name[0] = '.';
+ tempCWD->name[1] = '.';
+ for (j = 2; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ // Cache the dot entry
+ curent = 0;
+ if (Cache_File_Entry(tempCWD, &curent, TRUE) == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Move past the next backslash, if necessary
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // Copy and return, if we're at the end
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ // If we ended with a . entry,
+ // just return what we have
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ else
+ {
+ // Anything else after a dot doesn't make sense
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ }
+
+ break;
+
+ // Second case: the first char is the root backslash
+ // We will ONLY switch to this case if the first char
+ // of the path is a backslash
+ case '\\':
+ // Increment pointer to second char
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Can't start the path with multiple backslashes
+ if (i == '\\')
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == 0)
+ {
+ // The user is changing directory to
+ // the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ cwdptr->name[j] = 0x20;
+ }
+ return 0;
+ }
+ else
+ {
+ // Our first char is the root dir switch
+ tempCWD->dirclus = FatRootDirClusterValue;
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ break;
+
+ default:
+ // We should be at the beginning of a string of letters/numbers
+ j = 0;
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath2);
+ }
+ }
+ else
+ {
+#endif
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath);
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // We got a whole 12 chars
+ // There could be more- truncate it
+ if (j == 12)
+ {
+ while ((i != 0) && (i != '\\'))
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ i = *(++temppath2);
+ }
+ else
+ {
+#endif
+ i = *(++temppath);
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ }
+
+ defaultString[j] = 0;
+
+ if (FormatDirName (defaultString, 0) == FALSE)
+ return -1;
+
+ for (j = 0; j < 11; j++)
+ {
+ tempArray[j] = tempCWD->name[j];
+ tempCWD->name[j] = defaultString[j];
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, tempCWD);
+
+ // See if the directory is there
+ if(FILEfind (&gFileTemp, tempCWD, LOOK_FOR_MATCHING_ENTRY, 0) != CE_GOOD)
+ {
+ // Couldn't find the DIR
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Found the file
+ // Check to make sure it's actually a directory
+ if (gFileTemp.attributes != ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Get the new name
+ for (j = 0; j < 11; j++)
+ {
+ tempCWD->name[j] = gFileTemp.name[j];
+ }
+ tempCWD->dirclus = gFileTemp.cluster;
+ tempCWD->dirccls = tempCWD->dirclus;
+ }
+
+ if (i == 0)
+ {
+ // If we're at the end of the string, we're done
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ while (i == '\\')
+ {
+ // If we get to another backslash, increment past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ break;
+ }
+ } // loop
+}
+
+
+
+// This string is used by FSgetcwd to return the cwd name if the path
+// passed into the function is NULL
+char defaultArray [10];
+
+
+/**************************************************************
+ Function:
+ char * FSgetcwd (char * path, int numchars)
+ Summary:
+ Get the current working directory name
+ Conditions:
+ None
+ Input:
+ path - Pointer to the array to return the cwd name in
+ numchars - Number of chars in the path
+ Return Values:
+ char * - The cwd name string pointer (path or defaultArray)
+ NULL - The current working directory name could not be loaded.
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSgetcwd function will get the name of the current
+ working directory and return it to the user. The name
+ will be copied into the buffer pointed to by 'path,'
+ starting at the root directory and copying as many chars
+ as possible before the end of the buffer. The buffer
+ size is indicated by the 'numchars' argument. The first
+ thing this function will do is load the name of the current
+ working directory, if it isn't already present. This could
+ occur if the user switched to the dotdot entry of a
+ subdirectory immediately before calling this function. The
+ function will then copy the current working directory name
+ into the buffer backwards, and insert a backslash character.
+ Next, the function will continuously switch to the previous
+ directories and copy their names backwards into the buffer
+ until it reaches the root. If the buffer overflows, it
+ will be treated as a circular buffer, and data will be
+ copied over existing characters, starting at the beginning.
+ Once the root directory is reached, the text in the buffer
+ will be swapped, so that the buffer contains as much of the
+ current working directory name as possible, starting at the
+ root.
+ Remarks:
+ None
+ **************************************************************/
+char * FSgetcwd (char * path, int numchars)
+{
+ // If path is passed in as null, set up a default
+ // array with 10 characters
+ char totalchars = (path == NULL) ? 10 : numchars;
+ char * returnPointer;
+ char * bufferEnd;
+ FILEOBJ tempCWD = &gFileTemp;
+ BYTE bufferOverflow = FALSE;
+ signed char j;
+ DWORD curclus;
+ WORD fHandle, tempindex;
+ signed int i, index = 0;
+ char aChar;
+ DIRENTRY entry;
+
+ FSerrno = CE_GOOD;
+
+ // Set up the return value
+ if (path == NULL)
+ returnPointer = defaultArray;
+ else
+ {
+ returnPointer = path;
+ if (numchars == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return NULL;
+ }
+ }
+
+ bufferEnd = returnPointer + totalchars - 1;
+
+ FileObjectCopy (tempCWD, cwdptr);
+
+ if ((tempCWD->name[0] == '.') &&
+ (tempCWD->name[1] == '.'))
+ {
+ // We last changed directory into a dotdot entry
+ // Save the value of the current directory
+ curclus = tempCWD->dirclus;
+ // Put this dir's dotdot entry into the dirclus
+ // Our cwd absolutely is not the root
+ fHandle = 1;
+ tempCWD->dirccls = tempCWD->dirclus;
+ entry = Cache_File_Entry (tempCWD,&fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ // For FAT32, if the .. entry is 0, the cluster won't be 0
+#ifdef SUPPORT_FAT32
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ tempCWD->dirclus = TempClusterCalc;
+
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // Find the direntry for the entry we were just in
+ fHandle = 0;
+ entry = Cache_File_Entry (tempCWD, &fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != curclus) ||
+ ((TempClusterCalc == curclus) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME) || (entry->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ fHandle++;
+ entry = Cache_File_Entry (tempCWD, &fHandle, FALSE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // We've found the entry for the dir we were in
+ for (i = 0; i < 11; i++)
+ {
+ tempCWD->name[i] = entry->DIR_Name[i];
+ cwdptr->name[i] = entry->DIR_Name[i];
+ }
+ // Reset our temp dir back to that cluster
+ tempCWD->dirclus = curclus;
+ tempCWD->dirccls = curclus;
+ // This will set us at the cwd, but it will actually
+ // have the name in the name field this time
+ }
+ // There's actually some kind of name value in the cwd
+ if (tempCWD->name[0] == '\\')
+ {
+ // Easy, our CWD is the root
+ *returnPointer = '\\';
+ *(returnPointer + 1) = 0;
+ return returnPointer;
+ }
+ else
+ {
+ // Loop until we get back to the root
+ while (tempCWD->dirclus != FatRootDirClusterValue)
+ {
+ j = 10;
+ while (tempCWD->name[j] == 0x20)
+ j--;
+ if (j >= 8)
+ {
+ while (j >= 8)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+ *(returnPointer + index++) = '.';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ while (tempCWD->name[j] == 0x20)
+ j--;
+
+ while (j >= 0)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ // Put a backslash delimiter in front of the dir name
+ *(returnPointer + index++) = '\\';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+
+ // Load the previous entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ if (GetPreviousEntry (tempCWD))
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ return NULL;
+ }
+ }
+ }
+
+ // Point the index back at the last char in the string
+ index--;
+
+ i = 0;
+ // Swap the chars in the buffer so they are in the right places
+ if (bufferOverflow)
+ {
+ tempindex = index;
+ // Swap the overflowed values in the buffer
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+
+ // Point at the non-overflowed values
+ i = tempindex + 1;
+ index = bufferEnd - returnPointer;
+
+ // Swap the non-overflowed values into the right places
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ // All the values should be in the right place now
+ // Null-terminate the string
+ *(bufferEnd) = 0;
+ }
+ else
+ {
+ // There was no overflow, just do one set of swaps
+ tempindex = index;
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ *(returnPointer + tempindex + 1) = 0;
+ }
+
+ return returnPointer;
+}
+
+
+/**************************************************************************
+ Function:
+ void GetPreviousEntry (FSFILE * fo)
+ Summary:
+ Get the file entry info for the parent dir of the specified dir
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - The file to get the previous entry of
+ Return Values:
+ 0 - The previous entry was successfully retrieved
+ -1 - The previous entry could not be retrieved
+ Side Effects:
+ None
+ Description:
+ The GetPreviousEntry function is used by the FSgetcwd function to
+ load the previous (parent) directory. This function will load the
+ parent directory and then search through the file entries in that
+ directory for one that matches the cluster number of the original
+ directory. When the matching entry is found, the name of the
+ original directory is copied into the 'fo' FSFILE object.
+ Remarks:
+ None.
+ **************************************************************************/
+
+BYTE GetPreviousEntry (FSFILE * fo)
+{
+ BYTE i;
+ WORD fHandle = 1;
+ DWORD dirclus;
+ DIRENTRY dirptr;
+
+ // Load the previous entry
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ // The previous directory is the root
+ fo->name[0] = '\\';
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = 0x20;
+ }
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Get the directory name
+ // Save the previous cluster value
+ // Get the cluster
+
+ dirclus = TempClusterCalc;
+ fo->dirclus = TempClusterCalc;
+ fo->dirccls = TempClusterCalc;
+
+
+ // Load the previous previous cluster
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+#ifdef SUPPORT_FAT32
+ // If we're using FAT32 and the previous previous cluster is the root, the
+ // value in the dotdot entry will be 0, but the actual cluster won't
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ fo->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ fo->dirclus = TempClusterCalc;
+
+ fo->dirccls = fo->dirclus;
+
+ fHandle = 0;
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+ // Look through it until we get the name
+ // of the previous cluster
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+ while ((TempClusterCalc != dirclus) ||
+ ((TempClusterCalc == dirclus) &&
+ (((unsigned char)dirptr->DIR_Name[0] == 0xE5) || (dirptr->DIR_Attr == ATTR_VOLUME) || (dirptr->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ // Look through the entries until we get the
+ // right one
+ dirptr = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dirptr == NULL)
+ return -1;
+ fHandle++;
+
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number in a loop.
+ }
+
+ // The name should be in the entry now
+ // Copy the actual directory location back
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = dirptr->DIR_Name[i];
+ }
+ fo->dirclus = dirclus;
+ fo->dirccls = dirclus;
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+ Function:
+ int FSmkdir (char * path)
+ Summary:
+ Create a directory
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create.
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdir function passes a RAM pointer to the path to the
+ mkdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSmkdir (char * path)
+{
+ return mkdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSmkdirpgm (const rom char * path)
+ Summary:
+ Create a directory with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create (ROM)
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdirpgm function passes a PIC18 ROM path pointer to the
+ mkdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arugments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSmkdirpgm (const rom char * path)
+{
+ return mkdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+ // PIC18
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+ Summary:
+ Helper function for FSmkdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was created
+ -1 - Directory could not be created
+ Side Effects:
+ Will create all non-existant directories in the path.
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first scan through the path
+ to ensure that any DIR names don't exceed 11 characters. It will then
+ backup the current working directory and begin changing directories
+ through the path until it reaches a directory than can't be changed to.
+ It will then create the specified directory and change directories to
+ the new directory. The function will continue creating and changing to
+ directories until the end of the path is reached. The function will
+ then restore the original current working directory.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ char tempArray[13];
+ FILEOBJ tempCWD = &tempCWDobj;
+
+#ifdef __18CXX
+ char dotdotPath[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath2 != 0) && (*temppath2 != '.')&& (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath2 == '.')
+ {
+ temppath2++;
+ i = 0;
+ while ((*temppath2 != 0) && (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath2 == '\\')
+ temppath2++;
+ if (*temppath2 == 0)
+ break;
+ }
+ }
+ else
+#endif
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath != 0) && (*temppath != '.')&& (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath == '.')
+ {
+ temppath++;
+ i = 0;
+ while ((*temppath != 0) && (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath == '\\')
+ temppath++;
+ if (*temppath == 0)
+ break;
+ }
+
+ temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ temppath2 = romptr;
+#endif
+
+ // We're going to be moving the CWD
+ // Back up the CWD
+ FileObjectCopy (tempCWD, cwdptr);
+
+ // get to the target directory
+ while (1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+
+ if (i == '.')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ if ((i != '.') && (i != 0) && (i != '\\'))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == '.')
+ {
+ if (cwdptr->dirclus == FatRootDirClusterValue)
+ {
+ // If we try to change to the .. from the
+ // root, operation fails
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if ((i != '\\') && (i != 0))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+// dotdot entry
+#ifndef __18CXX
+ FSchdir ("..");
+#else
+ FSchdir (dotdotPath);
+#endif
+ }
+ // Skip past any backslashes
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ // No point in creating a dot or dotdot entry directly
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ // Start at the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (i = 1; i < 11; i++)
+ {
+ cwdptr->name[i] = 0x20;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // If we just got two backslashes in a row at the
+ // beginning of the path, the function fails
+ if (i == '\\')
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (i == 0)
+ {
+ // We can't make the root dir
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ tempArray[12] = 0;
+ while (1)
+ {
+ while(1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Change directories as specified
+ i = *temppath2;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ // Change directories as specified
+ i = *temppath;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ tempArray[j] = 0;
+
+ if (tempArray[0] == '.')
+ {
+ if ((tempArray[1] != 0) && (tempArray[1] != '.'))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if ((tempArray[1] == '.') && (tempArray[2] != 0))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+
+ // Try to change to it
+ // If you can't we need to create it
+ if (FSchdir (tempArray))
+ {
+ break;
+ }
+ else
+ {
+ // We changed into the directory
+ while (i == '\\')
+ {
+ // Next char is a backslash
+ // Move past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // If it's the last one, return success
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+
+ // Create a dir here
+ if (!CreateDIR (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ // Try to change to that directory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Check for another backslash
+ while (*temppath2 == '\\')
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ while (*temppath == '\\')
+ {
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Check to see if we're at the end of the path string
+ if (i == 0)
+ {
+ // We already have one
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+}
+
+
+/**************************************************************************
+ Function:
+ int CreateDIR (char * path)
+ Summary:
+ FSmkdir helper function to create a directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the dir to create
+ Return Values:
+ TRUE - Directory was created successfully
+ FALSE - Directory could not be created.
+ Side Effects:
+ Any unwritten data in the data buffer or the FAT buffer will be written
+ to the device.
+ Description:
+ The CreateDIR function is a helper function for the mkdirhelper
+ function. The CreateDIR function will create a new file entry for
+ a directory and assign a cluster to it. It will erase the cluster
+ and write a dot and dotdot entry to it.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int CreateDIR (char * path)
+{
+ FSFILE * dirEntryPtr = &gFileTemp;
+ DIRENTRY dir;
+ WORD handle = 0;
+ DWORD dot, dotdot;
+ BYTE i;
+
+ for (i = 0; i < 12; i++)
+ {
+ defaultString[i] = *(path + i);
+ }
+
+ if (FormatDirName(defaultString, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return FALSE;
+ }
+
+ // Copy name into file object
+ for (i = 0; i < 11; i++)
+ {
+ dirEntryPtr->name[i] = defaultString[i];
+ }
+
+ dirEntryPtr->dirclus = cwdptr->dirclus;
+ dirEntryPtr->dirccls = cwdptr->dirccls;
+ dirEntryPtr->cluster = 0;
+ dirEntryPtr->ccls = 0;
+ dirEntryPtr->dsk = cwdptr->dsk;
+
+ // Create a directory entry
+ if(CreateFileEntry(dirEntryPtr, &handle, DIRECTORY) != CE_GOOD)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (gNeedFATWrite)
+ if(WriteFAT (dirEntryPtr->dsk, 0, 0, TRUE))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+ // Zero that cluster
+ if (dirEntryPtr->dirclus == FatRootDirClusterValue)
+ dotdot = 0;
+ else
+ dotdot = dirEntryPtr->dirclus;
+ dirEntryPtr->dirccls = dirEntryPtr->dirclus;
+ dir = Cache_File_Entry(dirEntryPtr, &handle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return FALSE;
+ }
+
+ // Get the cluster
+ dot = GetFullClusterNumber(dir); // Get complete cluster number.
+
+ if (writeDotEntries (dirEntryPtr->dsk, dot, dotdot))
+ return TRUE;
+ else
+ return FALSE;
+
+ }
+}
+
+
+/***********************************************************************************
+ Function:
+ BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+ Summary:
+ Create dot and dotdot entries in a non-root directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - The global disk structure
+ dotAddress - The cluster the current dir is in
+ dotdotAddress - The cluster the previous directory was in
+ Return Values:
+ TRUE - The dot and dotdot entries were created
+ FALSE - The dot and dotdot entries could not be created in the new directory
+ Side Effects:
+ None
+ Description:
+ The writeDotEntries function will create and write dot and dotdot entries
+ to a newly created directory.
+ Remarks:
+ None.
+ ***********************************************************************************/
+
+BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+{
+ WORD i;
+ WORD size;
+ _DIRENTRY entry;
+ DIRENTRY entryptr = &entry;
+ DWORD sector;
+
+ gBufferOwner = NULL;
+
+ size = sizeof (_DIRENTRY);
+
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ entry.DIR_Name[0] = '.';
+
+ for (i = 1; i < 11; i++)
+ {
+ entry.DIR_Name[i] = 0x20;
+ }
+ entry.DIR_Attr = ATTR_DIRECTORY;
+ entry.DIR_NTRes = 0x00;
+
+ entry.DIR_FstClusLO = (WORD)(dotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+ entry.DIR_FileSize = 0x00;
+
+// Times need to be the same as the times in the directory entry
+
+// Set dir date for uncontrolled clock source
+#ifdef INCREMENTTIMESTAMP
+ entry.DIR_CrtTimeTenth = 0xB2;
+ entry.DIR_CrtTime = 0x7278;
+ entry.DIR_CrtDate = 0x32B0;
+ entry.DIR_LstAccDate = 0x0000;
+ entry.DIR_WrtTime = 0x0000;
+ entry.DIR_WrtDate = 0x0000;
+#endif
+
+#ifdef USEREALTIMECLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i) = *((char *)entryptr + i);
+ }
+ entry.DIR_Name[1] = '.';
+
+ entry.DIR_FstClusLO = (WORD)(dotdotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotdotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i + size) = *((char *)entryptr + i);
+ }
+
+ sector = Cluster2Sector (disk, dotAddress);
+
+ if (MDD_SectorWrite(sector, disk->buffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// This array is used to prevent a stack frame error
+#ifdef __18CXX
+ char tempArray[13] = " ";
+#endif
+
+
+/**************************************************************************
+ Function:
+ int FSrmdir (char * path)
+ Summary:
+ Delete a directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to remove
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdir function passes a RAM pointer to the path to the
+ rmdirhelper function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int FSrmdir (char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (0, path, NULL, rmsubdirs);
+}
+
+/**************************************************************************
+ Function:
+ int FSrmdirpgm (const rom char * path)
+ Summary:
+ Delete a directory with a path in ROM on PIC18
+ Conditions:
+ None.
+ Input:
+ path - The path of the directory to remove (ROM)
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdirpgm function passes a PIC18 ROM path pointer to the
+ rmdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSrmdirpgm (const rom char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (1, NULL, path, rmsubdirs);
+}
+#endif
+
+/************************************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+ // PIC18
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+ Summary:
+ Helper function for FSrmdir
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The path of the dir to delete
+ rmsubdirs -
+ - TRUE - Remove all sub-directories and files in the directory
+ - FALSE - Non-empty directories can not be removed
+ Return Values:
+ 0 - The specified directory was successfully removed.
+ EOF - The specified directory could not be removed.
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSmkdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first change to the
+ specified directory. If the rmsubdirs argument is FALSE the function
+ will search through the directory to ensure that it is empty and then
+ remove it. If the rmsubdirs argument is TRUE the function will also
+ search through the directory for subdirectories or files. When the
+ function finds a file, the file will be erased. When the function
+ finds a subdirectory, it will switch to the subdirectory and begin
+ removing all of the files in that subdirectory. Once the subdirectory
+ is empty, the function will switch back to the original directory.
+ return to the original position in that directory, and continue removing
+ files. Once the specified directory is empty, the function will
+ change to the parent directory, search through it for the directory
+ to remove, and then erase that directory.
+ Remarks:
+ None.
+ ************************************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+#else
+int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+#endif
+{
+ FILEOBJ tempCWD = &tempCWDobj;
+ FILEOBJ fo = &gFileTemp;
+ DIRENTRY entry;
+ WORD handle = 0;
+ WORD handle2;
+ WORD subDirDepth;
+ BYTE Index, Index2;
+
+#ifndef __18CXX
+ char tempArray[13] = " ";
+#else
+ char dotdotname[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ // Back up the current working directory
+ FileObjectCopy (tempCWD, cwdptr);
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ if (chdirhelper (1, NULL, romptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ }
+ else
+ {
+#endif
+ if (FSchdir (ramptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Make sure we aren't trying to remove the root dir or the CWD
+ if ((cwdptr->dirclus == FatRootDirClusterValue) || (cwdptr->dirclus == tempCWD->dirclus))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Don't remove subdirectories and sub-files
+ if (!rmsubdirs)
+ {
+ while (entry->DIR_Name[0] != 0)
+ {
+ if ((unsigned char)entry->DIR_Name[0] != 0xE5)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_EMPTY;
+ return -1;
+ }
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if ((entry == NULL))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ // Do remove subdirectories and sub-files
+ dirCleared = FALSE;
+ subDirDepth = 0;
+
+ while (!dirCleared)
+ {
+ if (entry->DIR_Name[0] != 0)
+ {
+ if (((unsigned char)entry->DIR_Name[0] != 0xE5) && (entry->DIR_Attr != ATTR_VOLUME) && (entry->DIR_Attr != ATTR_LONG_NAME))
+ {
+ if ((entry->DIR_Attr & ATTR_DIRECTORY) == ATTR_DIRECTORY)
+ {
+ // We have a directory
+ subDirDepth++;
+ for (Index = 0; (Index < DIR_NAMESIZE) && (entry->DIR_Name[Index] != 0x20); Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (entry->DIR_Name[8] != 0x20)
+ {
+ tempArray[Index++] = '.';
+ for (Index2 = 0; (Index2 < DIR_EXTENSION) && (entry->DIR_Name[Index2 + DIR_NAMESIZE] != 0x20); Index2++)
+ {
+ tempArray[Index++] = entry->DIR_Name[Index2 + DIR_NAMESIZE];
+ }
+ }
+ tempArray[Index] = 0;
+ // Change to the subdirectory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Make sure we're not trying to delete the CWD
+ if (cwdptr->dirclus == tempCWD->dirclus)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ handle = 2;
+ recache = TRUE;
+ }
+ else
+ {
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ fo->name[Index] = entry->DIR_Name[Index];
+ }
+
+ fo->dsk = &gDiskData;
+
+ fo->entry = handle;
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+ fo->cluster = 0;
+ fo->ccls = 0;
+
+ if (FILEerase(fo, &handle, TRUE))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ }
+ } // Check to see if it's a DIR entry
+ }// Check non-dir entry to see if its a valid file
+ else
+ {
+ handle++;
+ }
+ if (recache)
+ {
+ recache = FALSE;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ }
+ else
+ {
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ }
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ else
+ {
+ // We have reached the end of the directory
+ if (subDirDepth != 0)
+ {
+ handle2 = 0;
+
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle2, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ handle2 = GetFullClusterNumber(entry); // Get complete cluster number.
+
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ // Return to our previous position in this directory
+ handle = 2;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != handle2) ||
+ ((TempClusterCalc == handle2) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME))))
+ {
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // Erase the directory that we just cleared the subdirectories out of
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+
+ // Decrease the subdirectory depth
+ subDirDepth--;
+ }
+ else
+ {
+ dirCleared = TRUE;
+ } // Check subdirectory depth
+ } // Check until we get an empty entry
+ } // Loop until the whole dir is cleared
+ }
+
+ // Cache the current directory name
+ // tempArray is used so we don't disturb the
+ // global getcwd buffer
+ if (FSgetcwd (tempArray, 12) == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ memset(tempArray, 0x00, 12);
+
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = cwdptr->name[Index];
+ }
+
+ // If we're here, this directory is empty
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+}
+
+
+/****************************************************************
+ Function:
+ int eraseDir (char * path)
+ Summary:
+ FSrmdir helper function to erase dirs
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the directory to delete
+ Return Values:
+ 0 - Dir was deleted successfully
+ -1 - Dir could not be deleted.
+ Side Effects:
+ None
+ Description:
+ The eraseDir function is a helper function for the rmdirhelper
+ function. The eraseDir function will search for the
+ directory that matches the specified path name and then erase
+ it with the FILEerase function.
+ Remarks:
+ None.
+ *****************************************************************/
+
+int eraseDir (char * path)
+{
+ CETYPE result;
+ BYTE Index;
+ FSFILE tempCWDobj2;
+
+ if (MDD_WriteProtectState())
+ {
+ return (-1);
+ }
+
+ // preserve CWD
+ FileObjectCopy(&tempCWDobj2, cwdptr);
+
+ for (Index = 0; Index <11; Index++)
+ {
+ cwdptr->name[Index] = *(path + Index);
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, cwdptr);
+
+ // See if the file is found
+ result = FILEfind (cwdptr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+ result = FILEerase(cwdptr, &cwdptr->entry, TRUE);
+ if( result == CE_GOOD )
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return 0;
+ }
+ else
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+}
+#endif
+
+
+
+#endif
+
+
+#ifdef ALLOW_FILESEARCH
+
+
+/***********************************************************************************
+ Function:
+ int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Initial search function
+ Conditions:
+ None
+ Input:
+ fileName - The name to search for
+ - Parital string search characters
+ - * - Indicates the rest of the filename or extension can vary (e.g. FILE.*)
+ - ? - Indicates that one character in a filename can vary (e.g. F?LE.T?T)
+ attr - The attributes that a found file may have
+ - ATTR_READ_ONLY - File may be read only
+ - ATTR_HIDDEN - File may be a hidden file
+ - ATTR_SYSTEM - File may be a system file
+ - ATTR_VOLUME - Entry may be a volume label
+ - ATTR_DIRECTORY - File may be a directory
+ - ATTR_ARCHIVE - File may have archive attribute
+ - ATTR_MASK - All attributes
+ rec - pointer to a structure to put the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the specified criteria was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object
+ will be lost. The FSerrno variable will be changed.
+ Description:
+ The FindFirst function will search for a file based on parameters passed in
+ by the user. This function will use the FILEfind function to parse through
+ the current working directory searching for entries that match the specified
+ parameters. If a file is found, its parameters are copied into the SearchRec
+ structure, as are the initial parameters passed in by the user and the position
+ of the file entry in the current working directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling FindNext
+ ***********************************************************************************/
+
+int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ WORD fHandle;
+ BYTE j;
+ BYTE Index;
+
+ FSerrno = CE_GOOD;
+
+ if( !FormatFileName(fileName, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ rec->initialized = FALSE;
+
+ for (Index = 0; (Index < 12) && (fileName[Index] != 0); Index++)
+ {
+ rec->searchname[Index] = fileName[Index];
+ }
+ rec->searchname[Index] = 0;
+ rec->searchattr = attr;
+#ifdef ALLOW_DIRS
+ rec->cwdclus = cwdptr->dirclus;
+#else
+ rec->cwdclus = FatRootDirClusterValue;
+#endif
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = attr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ fHandle = fo->entry;
+ result = FILEopen (fo, &fHandle, 'r');
+ }
+ if (result == CE_GOOD)
+ {
+ // Copy as much name as there is
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (Index = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[Index++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[Index] = 0;
+ }
+ else
+ {
+ for (Index = 0; Index < DIR_NAMECOMP; Index++)
+ {
+ rec->filename[Index] = fo->name[Index];
+ }
+ rec->filename[Index] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ rec->initialized = TRUE;
+ return 0;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+}
+
+
+/**********************************************************************
+ Function:
+ int FindNext (SearchRec * rec)
+ Summary:
+ Sequential search function
+ Conditions:
+ None
+ Input:
+ rec - The structure to store the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No additional files matching the specified criteria were found
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FindNext function performs the same function as the FindFirst
+ funciton, except it does not copy any search parameters into the
+ SearchRec structure (only info about found files) and it begins
+ searching at the last directory entry offset at which a file was
+ found, rather than at the beginning of the current working
+ directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling this function
+ **********************************************************************/
+
+int FindNext (SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ BYTE i, j;
+
+ FSerrno = CE_GOOD;
+
+ // Make sure we called FindFirst on this object
+ if (rec->initialized == FALSE)
+ {
+ FSerrno = CE_NOT_INIT;
+ return -1;
+ }
+
+ // Make sure we called FindFirst in the cwd
+#ifdef ALLOW_DIRS
+ if (rec->cwdclus != cwdptr->dirclus)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#endif
+
+ if( !FormatFileName(rec->searchname, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ /* Brn: Copy the formatted name to "fo" which is necesary before calling "FILEfind" function */
+ //strcpy(fo->name,rec->searchname);
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = rec->entry + 1;
+ fo->attributes = rec->searchattr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (i = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[i++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[i] = 0;
+ }
+ else
+ {
+ for (i = 0; i < DIR_NAMECOMP; i++)
+ {
+ rec->filename[i] = fo->name[i];
+ }
+ rec->filename[i] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ return 0;
+ }
+}
+
+
+#endif
+
+
+
+#ifdef ALLOW_FSFPRINTF
+
+
+
+/**********************************************************************
+ Function:
+ int FSputc (char c, FSFILE * file)
+ Summary:
+ FSfprintf helper function to write a char
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ c - The character to write to the file.
+ file - The file to write to.
+ Return Values:
+ 0 - The character was written successfully
+ EOF - The character was not written to the file.
+ Side Effects:
+ None
+ Description:
+ This is a helper function for FSfprintf. It will write one
+ character to a file.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSputc (char c, FSFILE * file)
+{
+ if (FSfwrite ((void *)&c, 1, 1, file) != 1)
+ return EOF;
+ else
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ int str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+ Summary:
+ FSfprintf helper function to write a char multiple times
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - The file to write to.
+ n - The number of times to write that character to a file.
+ c - The character to write to the file.
+ Return Values:
+ 0 - The characters were written successfully
+ EOF - The characters were not written to the file.
+ Side Effects:
+ None
+ Description:
+ This funciton is used by the FSfprintf function to write multiple
+ instances of a single character to a file (for example, when
+ padding a format specifier with leading spacez or zeros).
+ Remarks:
+ None.
+ **********************************************************************/
+
+
+unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+{
+ while (n--)
+ if (FSputc (c, handle) == EOF)
+ return 1;
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSfprintf (FSFILE * fptr, const char * fmt, ...)
+ // PIC18
+ int FSfpritnf (FSFILE * fptr, const rom char * fmt, ...)
+ Summary:
+ Function to write formatted strings to a file
+ Conditions:
+ For PIC18, integer promotion must be enabled in the project build
+ options menu. File opened in a write mode.
+ Input:
+ fptr - A pointer to the file to write to.
+ fmt - A string of characters and format specifiers to write to
+ the file
+ ... - Additional arguments inserted in the string by format
+ specifiers
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Writes a specially formatted string to a file.
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSfprintf (FSFILE *fptr, const rom char *fmt, ...)
+#else
+int FSfprintf (FSFILE *fptr, const char * fmt, ...)
+#endif
+{
+ va_list ap;
+ int n;
+
+ va_start (ap, fmt);
+ n = FSvfprintf (fptr, fmt, ap);
+ va_end (ap);
+ return n;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSvfprintf (FSFILE * handle, const char * formatString, va_list ap)
+ // PIC18
+ int FSvfpritnf (auto FSFILE * handle, auto const rom char * formatString, auto va_list ap)
+ Summary:
+ Helper function for FSfprintf
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - A pointer to the file to write to.
+ formatString - A string of characters and format specifiers to write to
+ the file
+ ap - A structure pointing to the arguments on the stack
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function will access the elements passed to FSfprintf
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSvfprintf (auto FSFILE *handle, auto const rom char * formatString, auto va_list ap)
+#else
+int FSvfprintf (FSFILE *handle, const char * formatString, va_list ap)
+#endif
+{
+ unsigned char c;
+ int count = 0;
+
+ for (c = *formatString; c; c = *++formatString)
+ {
+ if (c == '%')
+ {
+ unsigned char flags = 0;
+ unsigned char width = 0;
+ unsigned char precision = 0;
+ unsigned char have_precision = 0;
+ unsigned char size = 0;
+#ifndef __18CXX
+ unsigned char size2 = 0;
+#endif
+ unsigned char space_cnt;
+ unsigned char cval;
+#ifdef __18CXX
+ unsigned long larg;
+ far rom char * romstring;
+#else
+ unsigned long long larg;
+#endif
+ char * ramstring;
+ int n;
+
+ FSerrno = CE_GOOD;
+
+ c = *++formatString;
+
+ while (c == '-' || c == '+' || c == ' ' || c == '#'
+ || c == '0')
+ {
+ switch (c)
+ {
+ case '-':
+ flags |= _FLAG_MINUS;
+ break;
+ case '+':
+ flags |= _FLAG_PLUS;
+ break;
+ case ' ':
+ flags |= _FLAG_SPACE;
+ break;
+ case '#':
+ flags |= _FLAG_OCTO;
+ break;
+ case '0':
+ flags |= _FLAG_ZERO;
+ break;
+ }
+ c = *++formatString;
+ }
+ /* the optional width field is next */
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n < 0)
+ {
+ flags |= _FLAG_MINUS;
+ width = -n;
+ }
+ else
+ width = n;
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ width = cval;
+ }
+
+ /* if '-' is specified, '0' is ignored */
+ if (flags & _FLAG_MINUS)
+ flags &= ~_FLAG_ZERO;
+
+ /* the optional precision field is next */
+ if (c == '.')
+ {
+ c = *++formatString;
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n >= 0)
+ {
+ precision = n;
+ have_precision = 1;
+ }
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ precision = cval;
+ have_precision = 1;
+ }
+ }
+
+ /* the optional 'h' specifier. since int and short int are
+ the same size for MPLAB C18, this is a NOP for us. */
+ if (c == 'h')
+ {
+ c = *++formatString;
+ /* if 'c' is another 'h' character, this is an 'hh'
+ specifier and the size is 8 bits */
+ if (c == 'h')
+ {
+ size = _FMT_BYTE;
+ c = *++formatString;
+ }
+ }
+ else if (c == 't' || c == 'z')
+ c = *++formatString;
+#ifdef __18CXX
+ else if (c == 'H' || c == 'T' || c == 'Z')
+ {
+ size = _FMT_SHRTLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l' || c == 'j')
+#else
+ else if (c == 'q' || c == 'j')
+ {
+ size = _FMT_LONGLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l')
+#endif
+ {
+ size = _FMT_LONG;
+ c = *++formatString;
+ }
+
+ switch (c)
+ {
+ case '\0':
+ /* this is undefined behaviour. we have a trailing '%' character
+ in the string, perhaps with some flags, width, precision
+ stuff as well, but no format specifier. We'll, arbitrarily,
+ back up a character so that the loop will terminate
+ properly when it loops back and we'll output a '%'
+ character. */
+ --formatString;
+ /* fallthrough */
+ case '%':
+ if (FSputc ('%', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ break;
+ case 'c':
+ space_cnt = 0;
+ if (width > 1)
+ {
+ space_cnt = width - 1;
+ count += space_cnt;
+ }
+ if (space_cnt && !(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ c = va_arg (ap, int);
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'S':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ romstring = va_arg (ap, rom far char *);
+ else
+ romstring = (far rom char*)va_arg (ap, rom near char *);
+ n = strlenpgm (romstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the
+ string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *romstring; c && cval < width; c = *++romstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+#endif
+ case 's':
+ ramstring = va_arg (ap, char *);
+ n = strlen (ramstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *ramstring; c && cval < width; c = *++ramstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'd':
+ case 'i':
+ flags |= _FLAG_SIGNED;
+ /* fall through */
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'b':
+ case 'B':
+ /* This is a bit of a trick. The 'l' and 'hh' size
+ specifiers are valid only for the integer conversions,
+ not the 'p' or 'P' conversions, and are ignored for the
+ latter. By jumping over the additional size specifier
+ checks here we get the best code size since we can
+ limit the size checks in the remaining code. */
+ if (size == _FMT_LONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, long int);
+ else
+ larg = va_arg (ap, unsigned long int);
+ goto _do_integer_conversion;
+ }
+ else if (size == _FMT_BYTE)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed char) va_arg (ap, int);
+ else
+ larg = (unsigned char) va_arg (ap, unsigned int);
+ goto _do_integer_conversion;
+ }
+#ifndef __18CXX
+ else if (size == _FMT_LONGLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed long long)va_arg (ap, long long);
+ else
+ larg = (unsigned long long) va_arg (ap, unsigned long long);
+ goto _do_integer_conversion;
+ }
+#endif
+ /* fall trough */
+ case 'p':
+ case 'P':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, short long int);
+ else
+ larg = va_arg (ap, unsigned short long int);
+ }
+ else
+#endif
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, int);
+ else
+ larg = va_arg (ap, unsigned int);
+ _do_integer_conversion:
+ /* default precision is 1 */
+ if (!have_precision)
+ precision = 1;
+ {
+ unsigned char digit_cnt = 0;
+ unsigned char prefix_cnt = 0;
+ unsigned char sign_char;
+ /* A 32 bit number will require at most 32 digits in the
+ string representation (binary format). */
+#ifdef __18CXX
+ char buf[33];
+ /* Start storing digits least-significant first */
+ char *q = &buf[31];
+ /* null terminate the string */
+ buf[32] = '\0';
+#else
+ char buf[65];
+ char *q = &buf[63];
+ buf[64] = '\0';
+#endif
+ space_cnt = 0;
+ size = 10;
+
+ switch (c)
+ {
+ case 'b':
+ case 'B':
+ size = 2;
+#ifndef __18CXX
+ size2 = 1;
+#endif
+ break;
+ case 'o':
+ size = 8;
+#ifndef __18CXX
+ size2 = 3;
+#endif
+ break;
+ case 'p':
+ case 'P':
+ /* from here on out, treat 'p' conversions just
+ like 'x' conversions. */
+ c += 'x' - 'p';
+ /* fall through */
+ case 'x':
+ case 'X':
+ size = 16;
+#ifndef __18CXX
+ size2 = 4;
+#endif
+ break;
+ }// switch (c)
+
+ /* if it's an unsigned conversion, we should ignore the
+ ' ' and '+' flags */
+ if (!(flags & _FLAG_SIGNED))
+ flags &= ~(_FLAG_PLUS | _FLAG_SPACE);
+
+ /* if it's a negative value, we need to negate the
+ unsigned version before we convert to text. Using
+ unsigned for this allows us to (ab)use the 2's
+ complement system to avoid overflow and be able to
+ adequately handle LONG_MIN.
+
+ We'll figure out what sign character to print, if
+ any, here as well. */
+#ifdef __18CXX
+ if (flags & _FLAG_SIGNED && ((long) larg < 0))
+ {
+ larg = -(long) larg;
+#else
+ if (flags & _FLAG_SIGNED && ((long long) larg < 0))
+ {
+ larg = -(long long) larg;
+#endif
+ sign_char = '-';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_PLUS)
+ {
+ sign_char = '+';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_SPACE)
+ {
+ sign_char = ' ';
+ ++digit_cnt;
+ }
+ else
+ sign_char = '\0';
+ /* get the digits for the actual number. If the
+ precision is zero and the value is zero, the result
+ is no characters. */
+ if (precision || larg)
+ {
+ do
+ {
+#ifdef __18CXX
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ larg /= size;
+#else
+ // larg is congruent mod size2 to its lower 16 bits
+ // for size2 = 2^n, 0 <= n <= 4
+ if (size2 != 0)
+ cval = s_digits[(unsigned int) larg % size];
+ else
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ if (size2 != 0)
+ larg = larg >> size2;
+ else
+ larg /= size;
+#endif
+ *q-- = cval;
+ ++digit_cnt;
+ } while (larg);
+ /* if the '#' flag was specified and we're dealing
+ with an 'o', 'b', 'B', 'x', or 'X' conversion,
+ we need a bit more. */
+ if (flags & _FLAG_OCTO)
+ {
+ if (c == 'o')
+ {
+ /* per the standard, for octal, the '#' flag
+ makes the precision be at least one more
+ than the number of digits in the number */
+ if (precision <= digit_cnt)
+ precision = digit_cnt + 1;
+ }
+ else if (c == 'x' || c == 'X' || c == 'b' || c == 'B')
+ prefix_cnt = 2;
+ }
+ }
+ else
+ digit_cnt = 0;
+
+ /* The leading zero count depends on whether the '0'
+ flag was specified or not. If it was not, then the
+ count is the difference between the specified
+ precision and the number of digits (including the
+ sign character, if any) to be printed; otherwise,
+ it's as if the precision were equal to the max of
+ the specified precision and the field width. If a
+ precision was specified, the '0' flag is ignored,
+ however. */
+ if ((flags & _FLAG_ZERO) && (width > precision)
+ && !have_precision)
+ precision = width;
+ /* for the rest of the processing, precision contains
+ the leading zero count for the conversion. */
+ if (precision > digit_cnt)
+ precision -= digit_cnt;
+ else
+ precision = 0;
+ /* the space count is the difference between the field
+ width and the digit count plus the leading zero
+ count. If the width is less than the digit count
+ plus the leading zero count, the space count is
+ zero. */
+ if (width > precision + digit_cnt + prefix_cnt)
+ space_cnt = width - precision - digit_cnt - prefix_cnt;
+
+ /* for output, we check the justification, if it's
+ right justified and the space count is positive, we
+ emit the space characters first. */
+ if (!(flags & _FLAG_MINUS) && space_cnt)
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ count += space_cnt;
+ space_cnt = 0;
+ }
+ /* if we have a sign character to print, that comes
+ next */
+ if (sign_char)
+ if (FSputc (sign_char, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if we have a prefix (0b, 0B, 0x or 0X), that's next */
+ if (prefix_cnt)
+ {
+ if (FSputc ('0', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ }
+ /* if we have leading zeros, they follow. the prefix, if any
+ is included in the number of digits when determining how
+ many leading zeroes are needed. */
+// if (precision > prefix_cnt)
+ // precision -= prefix_cnt;
+ if (str_put_n_chars (handle, precision, '0'))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* print the actual number */
+ for (cval = *++q; cval; cval = *++q)
+ if (FSputc (cval, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if there are any spaces left, they go to right-pad
+ the field */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ count += precision + digit_cnt + space_cnt + prefix_cnt;
+ }
+ break;
+ case 'n':
+ switch (size)
+ {
+ case _FMT_LONG:
+ *(long *) va_arg (ap, long *) = count;
+ break;
+#ifdef __18CXX
+ case _FMT_SHRTLONG:
+ *(short long *) va_arg (ap, short long *) = count;
+ break;
+#else
+ case _FMT_LONGLONG:
+ *(long long *) va_arg (ap, long long *) = count;
+ break;
+#endif
+ case _FMT_BYTE:
+ *(signed char *) va_arg (ap, signed char *) = count;
+ break;
+ default:
+ *(int *) va_arg (ap, int *) = count;
+ break;
+ }
+ break;
+ default:
+ /* undefined behaviour. we do nothing */
+ break;
+ }
+ }
+ else
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ }
+ }
+ return count;
+}
+
+
+
+#endif
+
+
+
+
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.c.works b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.c.works new file mode 100644 index 00000000..bc8a1ad4 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.c.works @@ -0,0 +1,8878 @@ +/******************************************************************************
+*
+* Microchip Memory Disk Drive File System
+*
+******************************************************************************
+* FileName: FSIO.c
+* Dependencies: GenericTypeDefs.h
+* FSIO.h
+* Physical interface include file (SD-SPI.h, CF-PMP.h, ...)
+* string.h
+* stdlib.h
+* FSDefs.h
+* ctype.h
+* salloc.h
+* Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+* Compiler: C18/C30/C32
+* Company: Microchip Technology, Inc.
+* Version: 1.2.0
+*
+* Software License Agreement
+*
+* The software supplied herewith by Microchip Technology Incorporated
+* (the �Company�) for its PICmicro� Microcontroller is intended and
+* supplied to you, the Company�s customer, for use solely and
+* exclusively on Microchip PICmicro Microcontroller products. The
+* software is owned by the Company and/or its supplier, and is
+* protected under applicable copyright laws. All rights are reserved.
+* Any use in violation of the foregoing restrictions may subject the
+* user to criminal sanctions under applicable laws, as well as to
+* civil liability for the breach of the terms and conditions of this
+* license.
+*
+* THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+*
+*****************************************************************************/
+
+#include "FSIO.h"
+#include "GenericTypeDefs.h"
+#include "string.h"
+#include "stdlib.h"
+#include "ctype.h"
+#include "FSDefs.h"
+
+#ifdef ALLOW_FSFPRINTF
+#include "stdarg.h"
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ #ifdef __18CXX
+ #include "salloc.h"
+ #endif
+#endif
+
+#ifndef ALLOW_WRITES
+ #ifdef ALLOW_FORMATS
+ #error Write functions must be enabled to use the format function
+ #endif
+ #ifdef ALLOW_FSFPRINTF
+ #error Write functions must be enabled to use the FSfprintf function
+ #endif
+#endif
+
+#ifdef USEREALTIMECLOCK
+ #ifdef USERDEFINEDCLOCK
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#elif defined USERDEFINEDCLOCK
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#endif
+/*****************************************************************************/
+/* Global Variables */
+/*****************************************************************************/
+
+#ifndef FS_DYNAMIC_MEM
+ FSFILE gFileArray[FS_MAX_FILES_OPEN]; // Array that contains file information (static allocation)
+ BYTE gFileSlotOpen[FS_MAX_FILES_OPEN]; // Array that indicates which elements of gFileArray are available for use
+#endif
+
+#if defined(USEREALTIMECLOCK) || defined(USERDEFINEDCLOCK)
+// Timing variables
+BYTE gTimeCrtMS; // Global time variable (for timestamps) used to indicate create time (milliseconds)
+WORD gTimeCrtTime; // Global time variable (for timestamps) used to indicate create time
+WORD gTimeCrtDate; // Global time variable (for timestamps) used to indicate create date
+WORD gTimeAccDate; // Global time variable (for timestamps) used to indicate last access date
+WORD gTimeWrtTime; // Global time variable (for timestamps) used to indicate last update time
+WORD gTimeWrtDate; // Global time variable (for timestamps) used to indicate last update date
+#endif
+
+DWORD gLastFATSectorRead = 0xFFFF; // Global variable indicating which FAT sector was read last
+BYTE gNeedFATWrite = FALSE; // Global variable indicating that there is information that needs to be written to the FAT
+FSFILE * gBufferOwner = NULL; // Global variable indicating which file is using the data buffer
+DWORD gLastDataSectorRead = 0xFFFFFFFF; // Global variable indicating which data sector was read last
+BYTE gNeedDataWrite = FALSE; // Global variable indicating that there is information that needs to be written to the data section
+BYTE nextClusterIsLast = FALSE; // Global variable indicating that the entries in a directory align with a cluster boundary
+
+BYTE gBufferZeroed = FALSE; // Global variable indicating that the data buffer contains all zeros
+
+DWORD FatRootDirClusterValue; // Global variable containing the cluster number of the root dir (0 for FAT12/16)
+
+BYTE FSerrno; // Global error variable. Set to one of many error codes after each function call.
+
+DWORD TempClusterCalc; // Global variable used to store the calculated value of the cluster of a specified sector.
+BYTE dirCleared; // Global variable used by the "recursive" FSrmdir function to indicate that all subdirectories and files have been deleted from the target directory.
+BYTE recache = FALSE; // Global variable used by the "recursive" FSrmdir function to indicate that additional cache reads are needed.
+FSFILE tempCWDobj; // Global variable used to preserve the current working directory information.
+FSFILE gFileTemp; // Global variable used for file operations.
+
+#ifdef ALLOW_DIRS
+ FSFILE cwd; // Global current working directory
+ FSFILE * cwdptr = &cwd; // Pointer to the current working directory
+#endif
+
+
+#ifdef __18CXX
+ #pragma udata dataBuffer
+ BYTE gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ #pragma udata FATBuffer
+ BYTE gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE __attribute__ ((aligned(4))) gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ BYTE __attribute__ ((aligned(4))) gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+
+#pragma udata
+
+DISK gDiskData; // Global structure containing device information.
+
+
+
+/************************************************************************/
+/* Structures and defines */
+/************************************************************************/
+
+// Directory entry structure
+typedef struct
+{
+ char DIR_Name[DIR_NAMESIZE]; // File name
+ char DIR_Extension[DIR_EXTENSION]; // File extension
+ BYTE DIR_Attr; // File attributes
+ BYTE DIR_NTRes; // Reserved byte
+ BYTE DIR_CrtTimeTenth; // Create time (millisecond field)
+ WORD DIR_CrtTime; // Create time (second, minute, hour field)
+ WORD DIR_CrtDate; // Create date
+ WORD DIR_LstAccDate; // Last access date
+ WORD DIR_FstClusHI; // High word of the entry's first cluster number
+ WORD DIR_WrtTime; // Last update time
+ WORD DIR_WrtDate; // Last update date
+ WORD DIR_FstClusLO; // Low word of the entry's first cluster number
+ DWORD DIR_FileSize; // The 32-bit file size
+}_DIRENTRY;
+
+typedef _DIRENTRY * DIRENTRY; // A pointer to a directory entry structure
+
+#define DIRECTORY 0x12 // Value indicating that the CreateFileEntry function will be creating a directory
+
+#define DIRENTRIES_PER_SECTOR (MEDIA_SECTOR_SIZE / 32) // The number of directory entries in a sector
+
+// internal errors
+#define CE_FAT_EOF 60 // Error that indicates an attempt to read FAT entries beyond the end of the file
+#define CE_EOF 61 // Error that indicates that the end of the file has been reached
+
+typedef FSFILE * FILEOBJ; // Pointer to an FSFILE object
+
+#ifdef ALLOW_FSFPRINTF
+
+#define _FLAG_MINUS 0x1 // FSfprintf minus flag indicator
+#define _FLAG_PLUS 0x2 // FSfprintf plus flag indicator
+#define _FLAG_SPACE 0x4 // FSfprintf space flag indicator
+#define _FLAG_OCTO 0x8 // FSfprintf octothorpe (hash mark) flag indicator
+#define _FLAG_ZERO 0x10 // FSfprintf zero flag indicator
+#define _FLAG_SIGNED 0x80 // FSfprintf signed flag indicator
+
+#ifdef __18CXX
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONG 1 // FSfprintf 32-bit argument size flag
+ #define _FMT_SHRTLONG 2 // FSfprintf 24-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#else
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONGLONG 1 // FSfprintf 64-bit argument size flag
+ #define _FMT_LONG 2 // FSfprintf 32-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#endif
+
+#ifdef __18CXX
+ static const rom char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#else
+ static const char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#endif
+
+#endif
+
+/************************************************************************************/
+/* Prototypes */
+/************************************************************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls);
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead);
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle);
+DWORD Cluster2Sector(DISK * disk, DWORD cluster);
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle);
+#ifdef INCREMENTTIMESTAMP
+ void IncrementTimeStamp(DIRENTRY dir);
+#elif defined USEREALTIMECLOCK
+ void CacheTime (void);
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE ReadByte( BYTE* pBuffer, WORD index );
+ WORD ReadWord( BYTE* pBuffer, WORD index );
+ DWORD ReadDWord( BYTE* pBuffer, WORD index );
+#endif
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource);
+BYTE ValidateChars (char * FileName, BYTE mode);
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode);
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode);
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n);
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type);
+
+// Write functions
+#ifdef ALLOW_WRITES
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry);
+ BYTE flushData (void);
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters);
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode);
+ BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk);
+ DWORD FATfindEmptyCluster(FILEOBJ fo);
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle);
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode);
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster);
+ BYTE EraseCluster(DISK *disk, DWORD cluster);
+ CETYPE CreateFirstCluster(FILEOBJ fo);
+ DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite);
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode);
+#endif
+
+// Directory functions
+#ifdef ALLOW_DIRS
+ BYTE GetPreviousEntry (FSFILE * fo);
+ BYTE FormatDirName (char * string, BYTE mode);
+ int CreateDIR (char * path);
+ BYTE writeDotEntries (DISK * dsk, DWORD dotAddress, DWORD dotdotAddress);
+ int eraseDir (char * path);
+#ifdef ALLOW_PGMFUNCTIONS
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs);
+ #endif
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+#else
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs);
+ #endif
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+#endif
+#endif
+
+#ifdef ALLOW_FSFPRINTF
+ #ifdef __18CXX
+ int FSvfprintf (auto FSFILE *handle, auto const rom char *formatString, auto va_list ap);
+ #else
+ int FSvfprintf (FSFILE *handle, const char *formatString, va_list ap);
+ #endif
+ int FSputc (char c, FSFILE * file);
+ unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c);
+#endif
+
+BYTE DISKmount( DISK *dsk);
+BYTE LoadMBR(DISK *dsk);
+BYTE LoadBootSector(DISK *dsk);
+DWORD GetFullClusterNumber(DIRENTRY entry);
+
+
+/*************************************************************************
+ Function:
+ int FSInit(void)
+ Summary:
+ Function to initialize the device.
+ Conditions:
+ The physical device should be connected to the microcontroller.
+ Input:
+ None
+ Return Values:
+ TRUE - Initialization successful
+ FALSE - Initialization unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Initializes the static or dynamic memory slots for holding file
+ structures. Initializes the device with the DISKmount function. Loads
+ MBR and boot sector information. Initializes the current working
+ directory to the root directory for the device if directory support
+ is enabled.
+ Remarks:
+ None
+ *************************************************************************/
+
+int FSInit(void)
+{
+ int fIndex;
+#ifndef FS_DYNAMIC_MEM
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ gFileSlotOpen[fIndex] = TRUE;
+#else
+ #ifdef __18CXX
+ SRAMInitHeap();
+ #endif
+#endif
+
+ gBufferZeroed = FALSE;
+
+ MDD_InitIO();
+
+ if(DISKmount(&gDiskData) == CE_GOOD)
+ {
+ // Initialize the current working directory to the root
+#ifdef ALLOW_DIRS
+ cwdptr->dsk = &gDiskData;
+ cwdptr->sec = 0;
+ cwdptr->pos = 0;
+ cwdptr->seek = 0;
+ cwdptr->size = 0;
+ cwdptr->name[0] = '\\';
+ for (fIndex = 1; fIndex < 11; fIndex++)
+ {
+ cwdptr->name[fIndex] = 0x20;
+ }
+ cwdptr->entry = 0;
+ cwdptr->attributes = ATTR_DIRECTORY;
+ // "FatRootDirClusterValue" indicates the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+#endif
+
+ FSerrno = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/********************************************************************************
+ Function:
+ CETYPE FILEfind (FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+ Summary
+ Finds a file on the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - FSFILE object containing information of the file found
+ foCompareTo - FSFILE object containing the name/attr of the file to be
+ found
+ cmd -
+ - LOOK_FOR_EMPTY_ENTRY: Search for empty entry.
+ - LOOK_FOR_MATCHING_ENTRY: Search for matching entry.
+ mode -
+ - 0: Match file exactly with default attributes.
+ - 1: Match file to user-specified attributes.
+ Return Values:
+ CE_GOOD - File found.
+ CE_FILE_NOT_FOUND - File not found.
+ Side Effects:
+ None.
+ Description:
+ The FILEfind function will sequentially cache directory entries within
+ the current working directory into the foDest FSFILE object. If the cmd
+ parameter is specified as LOOK_FOR_EMPTY_ENTRY the search will continue
+ until an empty directory entry is found. If the cmd parameter is specified
+ as LOOK_FOR_MATCHING_ENTRY these entries will be compared to the foCompareTo
+ object until a match is found or there are no more entries in the current
+ working directory. If the mode is specified a '0' the attributes of the FSFILE
+ entries are irrelevant. If the mode is specified as '1' the attributes of the
+ foDest entry must match the attributes specified in the foCompareTo file and
+ partial string search characters may bypass portions of the comparison.
+ Remarks:
+ None
+ ********************************************************************************/
+
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+{
+ WORD attrib, compareAttrib;
+ WORD fHandle = foDest->entry; // current entry counter
+ BYTE state,index; // state of the current object
+ CETYPE statusB = CE_FILE_NOT_FOUND;
+ BYTE character,test;
+
+ // reset the cluster
+ foDest->dirccls = foDest->dirclus;
+ compareAttrib = 0xFFFF ^ foCompareTo->attributes; // Attribute to be compared as per application layer request
+
+ if (fHandle == 0)
+ {
+ if (Cache_File_Entry(foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ if ((fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) != 0) // Maximum 16 entries possible
+ {
+ if (Cache_File_Entry (foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ if (statusB != CE_BADCACHEREAD)
+ {
+ // Loop until you reach the end or find the file
+ while(1)
+ {
+ if(statusB!=CE_GOOD) //First time entry always here
+ {
+ state = Fill_File_Object(foDest, &fHandle);
+ if(state == NO_MORE) // Reached the end of available files. Comparision over and file not found so quit.
+ {
+ break;
+ }
+ }
+ else // statusB == CE_GOOD then exit
+ {
+ break; // Code below intializes"statusB = CE_GOOD;" so, if no problem in the filled file, Exit the while loop.
+ }
+
+ if(state == FOUND) // Validate the correct matching of filled file data with the required(to be found) one.
+ {
+ /* We got something */
+ // get the attributes
+ attrib = foDest->attributes;
+
+ attrib &= ATTR_MASK;
+ switch (mode)
+ {
+ case 0:
+ // see if we are a volume id or hidden, ignore
+ if(attrib != ATTR_VOLUME)
+ {
+ statusB = CE_GOOD;
+ character = (BYTE)'m'; // random value
+
+ // search for one. if status = TRUE we found one
+ for(index = 0; index < DIR_NAMECOMP; index++)
+ {
+ // get the source character
+ character = foDest->name[index];
+ // get the destination character
+ test = foCompareTo->name[index];
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // Nope its not a match
+ break;
+ }
+ }// for loop
+ } // not dir nor vol
+ break;
+
+ case 1:
+ // Check for attribute match
+ if (((attrib & compareAttrib) == 0) && (attrib != ATTR_LONG_NAME))
+ {
+ statusB = CE_GOOD; // Indicate the already filled file data is correct and go back
+ character = (BYTE)'m'; // random value
+ if (foCompareTo->name[0] != '*') //If "*" is passed for comparion as 1st char then don't proceed. Go back, file alreay found.
+ {
+ for (index = 0; index < DIR_NAMESIZE; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ // Before calling this "FILEfind" fn, "formatfilename" must be called. Hence, extn always starts from position "8".
+ if ((foCompareTo->name[8] != '*') && (statusB == CE_GOOD))
+ {
+ for (index = 8; index < DIR_NAMECOMP; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ } // Attribute match
+
+ break;
+ }
+ } // not found
+ else
+ {
+ /*** looking for an empty/re-usable entry ***/
+ if ( cmd == LOOK_FOR_EMPTY_ENTRY)
+ statusB = CE_GOOD;
+ } // found or not
+
+ // increment it no matter what happened
+ fHandle++;
+
+ }// while
+ }
+
+ return(statusB);
+} // FILEFind
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+ Summary:
+ Loads file information from the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File to be opened
+ fHandle - Location of file
+ type -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ Return Values:
+ CE_GOOD - FILEopen successful
+ CE_NOT_INIT - Device is not yet initialized
+ CE_FILE_NOT_FOUND - Could not find the file on the device
+ CE_BAD_SECTOR_READ - A bad read of a sector occured
+ Side Effects:
+ None
+ Description:
+ This function will cache a directory entry in the directory specified
+ by the dirclus parameter of hte FSFILE object 'fo.' The offset of the
+ entry in the directory is specified by fHandle. Once the directory entry
+ has been loaded, the first sector of the file can be loaded using the
+ cluster value specified in the directory entry. The type argument will
+ specify the mode the files will be opened in. This will allow this
+ function to set the correct read/write flags for the file.
+ Remarks:
+ If the mode the file is being opened in is a plus mode (e.g. READ+) the
+ flags will be modified further in the FSfopen function.
+ **************************************************************************/
+
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+{
+ DISK *dsk; //Disk structure
+ BYTE r; //Result of search for file
+ DWORD l; //lba of first sector of first cluster
+ CETYPE error = CE_GOOD;
+
+ dsk = (DISK *)(fo->dsk);
+ if (dsk->mount == FALSE)
+ {
+ error = CE_NOT_INIT;
+ }
+ else
+ {
+ // load the sector
+ fo->dirccls = fo->dirclus;
+ // Cache no matter what if it's the first entry
+ if (*fHandle == 0)
+ {
+ if (Cache_File_Entry(fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ // If it's not the first, only cache it if it's
+ // not divisible by the number of entries per sector
+ // If it is, Fill_File_Object will cache it
+ if ((*fHandle & 0xf) != 0)
+ {
+ if (Cache_File_Entry (fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ r = Fill_File_Object(fo, fHandle);
+ if (r != FOUND)
+ error = CE_FILE_NOT_FOUND;
+ else
+ {
+ fo->seek = 0; // first byte in file
+ fo->ccls = fo->cluster; // first cluster
+ fo->sec = 0; // first sector in the cluster
+ fo->pos = 0; // first byte in sector/cluster
+
+ if ( r == NOT_FOUND)
+ {
+ error = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Determine the lba of the selected sector and load
+ l = Cluster2Sector(dsk,fo->ccls);
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+#endif
+ gBufferOwner = fo;
+ if (gLastDataSectorRead != l)
+ {
+ gBufferZeroed = FALSE;
+ if ( !MDD_SectorRead( l, dsk->buffer))
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = l;
+ }
+ } // -- found
+
+ fo->flags.FileWriteEOF = FALSE;
+ // Set flag for operation type
+#ifdef ALLOW_WRITES
+ if (type == 'w' || type == 'a')
+ {
+ fo->flags.write = 1; //write or append
+ fo->flags.read = 0;
+ }
+ else
+ {
+#endif
+ fo->flags.write = 0; //read
+ fo->flags.read = 1;
+#ifdef ALLOW_WRITES
+ } // -- flags
+#endif
+ } // -- r = Found
+ } // -- Mounted
+ return (error);
+} // -- FILEopen
+
+
+/*************************************************************************
+ Function:
+ BYTE FILEget_next_cluster(FILEOBJ fo, WORD n)
+ Summary:
+ Step through a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file to get the next cluster of
+ n - Number of links in the FAT cluster chain to jump through
+ Return Values:
+ CE_GOOD - Operation successful
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_INVALID_CLUSTER - Invalid cluster value \> maxcls
+ CE_FAT_EOF - Fat attempt to read beyond EOF
+ Side Effects:
+ None
+ Description:
+ This function will load 'n' proximate clusters for a file from
+ the FAT on the device. It will stop checking for clusters if the
+ ReadFAT function returns an error, if it reaches the last cluster in
+ a file, or if the device tries to read beyond the last cluster used
+ by the device.
+ Remarks:
+ None
+ *************************************************************************/
+
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n)
+{
+ DWORD c, c2, ClusterFailValue, LastClustervalue;
+ BYTE error = CE_GOOD;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ LastClustervalue = LAST_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT12:
+ LastClustervalue = LAST_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT16:
+ default:
+ LastClustervalue = LAST_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // loop n times
+ do
+ {
+ // get the next cluster link from FAT
+ c2 = fo->ccls;
+ if ( (c = ReadFAT( disk, c2)) == ClusterFailValue)
+ error = CE_BAD_SECTOR_READ;
+ else
+ {
+ // check if cluster value is valid
+ if ( c >= disk->maxcls)
+ {
+ error = CE_INVALID_CLUSTER;
+ }
+
+ // compare against max value of a cluster in FAT
+ // return if eof
+ if ( c >= LastClustervalue) // check against eof
+ {
+ error = CE_FAT_EOF;
+ }
+ }
+
+ // update the FSFILE structure
+ fo->ccls = c;
+
+ } while (--n > 0 && error == CE_GOOD);// loop end
+
+ return(error);
+} // get next cluster
+
+
+/**************************************************************************
+ Function:
+ BYTE DISKmount ( DISK *dsk)
+ Summary:
+ Initialies the device and loads MBR and boot sector information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure to be initialized.
+ Return Values:
+ CE_GOOD - Disk mounted
+ CE_INIT_ERROR - Initialization error has occured
+ Side Effects:
+ None
+ Description:
+ This function will use the function pointed to by the MDD_MediaInitialize
+ function pointer to initialize the device (if any initialization is
+ required). It then attempts to load the master boot record with the
+ LoadMBR function and the boot sector with the LoadBootSector function.
+ These two functions will be used to initialize a global DISK structure
+ that will be used when accessing file information in the future.
+ Remarks:
+ None
+ **************************************************************************/
+
+BYTE DISKmount( DISK *dsk)
+{
+ BYTE error = CE_GOOD;
+
+ dsk->mount = FALSE; // default invalid
+ dsk->buffer = gDataBuffer; // assign buffer
+
+ // Initialize the device
+ if(MDD_MediaInitialize() != TRUE)
+ {
+ error = CE_INIT_ERROR;
+ FSerrno = CE_INIT_ERROR;
+ }
+ else
+ {
+ // Load the Master Boot Record (partition)
+ if((error = LoadMBR(dsk)) == CE_GOOD)
+ {
+ // Now the boot sector
+ if((error = LoadBootSector(dsk)) == CE_GOOD)
+ dsk->mount = TRUE; // Mark that the DISK mounted successfully
+ }
+ } // -- Load file parameters
+
+ return(error);
+} // -- mount
+
+
+
+/********************************************************************
+ Function:
+ CETYPE LoadMBR ( DISK *dsk)
+ Summary:
+ Loads the MBR and extracts necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the master boot record to be loaded
+ Return Values:
+ CE_GOOD - MBR loaded successfully
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_BAD_PARTITION - The boot record is bad
+ Side Effects:
+ None
+ Description:
+ The LoadMBR function will use the function pointed to by the
+ MDD_SectorRead function pointer to read the 0 sector from the
+ device. If a valid boot signature is obtained, this function
+ will compare fields in that cached sector to the values that
+ would be present if that sector was a boot sector. If all of
+ those values match, it will be assumed that the device does not
+ have a master boot record and the 0 sector is actually the boot
+ sector. Otherwise, data about the partition and the actual
+ location of the boot sector will be loaded from the MBR into
+ the DISK structure pointed to by 'dsk.'
+ Remarks:
+ None
+ ********************************************************************/
+
+BYTE LoadMBR(DISK *dsk)
+{
+ PT_MBR Partition;
+ BYTE error = CE_GOOD;
+ BYTE type;
+ BootSec BSec;
+
+ // Get the partition table from the MBR
+ if ( MDD_SectorRead( FO_MBR, dsk->buffer) != TRUE)
+ {
+ error = CE_BAD_SECTOR_READ;
+ FSerrno = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ // Check if the card has no MBR
+ BSec = (BootSec) dsk->buffer;
+
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( dsk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT16;
+ return CE_GOOD;
+ }
+ else
+ {
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FAT32_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 3 ) == '3' && \
+ ReadByte( dsk->buffer, BSI_FAT32_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_32.BootSec_FilSysType[0] == 'F' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[1] == 'A' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[2] == 'T' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[3] == '3' && \
+ BSec->FAT.FAT_32.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT32;
+ return CE_GOOD;
+ }
+ }
+ }
+ // assign it the partition table strucutre
+ Partition = (PT_MBR)dsk->buffer;
+
+ // Ensure its good
+ if((Partition->Signature0 != FAT_GOOD_SIGN_0) || (Partition->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_BAD_PARTITION;
+ error = CE_BAD_PARTITION;
+ }
+ else
+ {
+ /* Valid Master Boot Record Loaded */
+
+ // Get the 32 bit offset to the first partition
+ dsk->firsts = Partition->Partition0.PTE_FrstSect;
+
+ // check if the partition type is acceptable
+ type = Partition->Partition0.PTE_FSDesc;
+
+ switch (type)
+ {
+ case 0x01:
+ dsk->type = FAT12;
+ break;
+
+ case 0x04:
+ case 0x06:
+ case 0x0E:
+ dsk->type = FAT16;
+ break;
+
+ case 0x0B:
+ case 0x0C:
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ dsk->type = FAT32; // FAT32 is supported too
+#else
+ FSerrno = CE_CARDFAT32;
+ error = CE_CARDFAT32;
+#endif
+ break;
+
+ default:
+ FSerrno = CE_UNSUPPORTED_FS;
+ error = CE_UNSUPPORTED_FS;
+ } // switch
+ }
+ }
+
+ return(error);
+}// -- LoadMBR
+
+
+/**************************************************************************
+ Function:
+ BYTE LoadBootSector (DISK *dsk)
+ Summary:
+ Load the boot sector and extract the necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the boot sector
+ Return Values:
+ CE_GOOD - Boot sector loaded
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_NOT_FORMATTED - The disk is of an unsupported format
+ CE_CARDFAT32 - FAT 32 device not supported
+ Side Effects:
+ None
+ Description:
+ LoadBootSector will use the function pointed to by the MDD_SectorWrite
+ function pointer to load the boot sector, whose location was obtained
+ by a previous call of LoadMBR. If the boot sector is loaded successfully,
+ partition information will be calcualted from it and copied into the DISK
+ structure pointed to by 'dsk.'
+ Remarks:
+ None
+ **************************************************************************/
+
+
+BYTE LoadBootSector(DISK *dsk)
+{
+ DWORD RootDirSectors;
+ DWORD TotSec,DataSec;
+ BYTE error = CE_GOOD;
+ BootSec BSec;
+ WORD BytesPerSec;
+ WORD ReservedSectorCount;
+
+ // Get the Boot sector
+ if ( MDD_SectorRead( dsk->firsts, dsk->buffer) != TRUE)
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ BSec = (BootSec)dsk->buffer;
+
+ //Verify the Boot Sector is valid
+ if((BSec->Signature0 != FAT_GOOD_SIGN_0) || (BSec->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ error = CE_NOT_FORMATTED;
+ }
+ else
+ {
+ #ifdef __18CXX
+
+ // Load count of sectors per cluster
+ dsk->SecPerClus = BSec->FAT.FAT_16.BootSec_SPC;
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + BSec->FAT.FAT_16.BootSec_ResrvSec;
+ // Load the count of FAT tables
+ dsk->fatcopy = BSec->FAT.FAT_16.BootSec_FATCount;
+ // Load the size of the FATs
+ dsk->fatsize = BSec->FAT.FAT_16.BootSec_SPF;
+ if(dsk->fatsize == 0)
+ dsk->fatsize = BSec->FAT.FAT_32.BootSec_FATSz32;
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = BSec->FAT.FAT_16.BootSec_RootDirEnts;
+
+ // Determine the total number of sectors in the partition
+ if(BSec->FAT.FAT_16.BootSec_TotSec16 != 0)
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec16;
+ }
+ else
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec32;
+ }
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = BSec->FAT.FAT_16.BootSec_BPS;
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((BSec->FAT.FAT_16.BootSec_RootDirEnts * 32) + (BSec->FAT.FAT_16.BootSec_BPS - 1)) / BSec->FAT.FAT_16.BootSec_BPS;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (dsk->root + RootDirSectors) + dsk->firsts + 2;
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #else // PIC24/30/33
+
+ // Read the count of reserved sectors
+ ReservedSectorCount = ReadWord( dsk->buffer, BSI_RESRVSEC );
+ // Load the count of sectors per cluster
+ dsk->SecPerClus = ReadByte( dsk->buffer, BSI_SPC );
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + ReservedSectorCount;
+ // Load the count of FAT tables
+ dsk->fatcopy = ReadByte( dsk->buffer, BSI_FATCOUNT );
+ // Load the size of the FATs
+ dsk->fatsize = ReadWord( dsk->buffer, BSI_SPF );
+ if(dsk->fatsize == 0)
+ dsk->fatsize = ReadDWord( dsk->buffer, BSI_FATSZ32 );
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = ReadWord( dsk->buffer, BSI_ROOTDIRENTS );
+
+ // Determine the total number of sectors in the partition
+ TotSec = ReadWord( dsk->buffer, BSI_TOTSEC16 );
+ if( TotSec == 0 )
+ TotSec = ReadDWord( dsk->buffer, BSI_TOTSEC32 );
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = ReadWord( dsk->buffer, BSI_BPS );
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((dsk->maxroot * NUMBER_OF_BYTES_IN_DIR_ENTRY) + (BytesPerSec - 1)) / BytesPerSec;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (ReservedSectorCount + (dsk->fatcopy * dsk->fatsize ) + RootDirSectors );
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #endif
+
+ // Determine the file system type based on the number of clusters used
+ if(dsk->maxcls < 4085)
+ {
+ dsk->type = FAT12;
+ }
+ else
+ {
+ if(dsk->maxcls < 65525)
+ {
+ dsk->type = FAT16;
+ }
+ else
+ {
+ #ifdef SUPPORT_FAT32
+ dsk->type = FAT32;
+ #else
+ error = CE_CARDFAT32;
+ FSerrno = CE_CARDFAT32;
+ #endif
+ }
+ }
+
+ #ifdef SUPPORT_FAT32
+ if (dsk->type == FAT32)
+ {
+ #ifdef __18CXX
+ FatRootDirClusterValue = BSec->FAT.FAT_32.BootSec_RootClus;
+ #else
+ FatRootDirClusterValue = ReadDWord( dsk->buffer, BSI_ROOTCLUS );
+ #endif
+ dsk->data = dsk->root + RootDirSectors;
+ }
+ else
+ #endif
+ {
+ FatRootDirClusterValue = 0;
+ dsk->data = dsk->root + ( dsk->maxroot >> 4);
+ }
+
+ #ifdef __18CXX
+ if(BSec->FAT.FAT_16.BootSec_BPS != MEDIA_SECTOR_SIZE)
+ #else
+ if(BytesPerSec != MEDIA_SECTOR_SIZE)
+ #endif
+ {
+ error = CE_NOT_FORMATTED;
+ FSerrno = CE_NOT_FORMATTED;
+ }
+ }
+ }
+ return(error);
+}
+
+
+
+/*************************************************************************
+ Function:
+ DWORD GetFullClusterNumber (DIRENTRY entry)
+ Summary:
+ Gets the cluster number from a directory entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ entry - The cached directory entry to get the cluster number from
+ Returns:
+ The cluster value from the passed directory entry
+ Side Effects:
+ None.
+ Description:
+ This function will load both the high and low 16-bit first cluster
+ values of a file from a directory entry and copy them into a 32-bit
+ cluster number variable, which will be returned.
+ Remarks:
+ None
+ *************************************************************************/
+
+DWORD GetFullClusterNumber(DIRENTRY entry)
+{
+
+ DWORD TempFullClusterCalc = 0;
+
+#ifndef SUPPORT_FAT32 // If FAT32 Not supported.
+ entry->DIR_FstClusHI = 0; // If FAT32 is not supported then Higher Word of the address is "0"
+#endif
+
+ // Get the cluster
+ TempFullClusterCalc = (entry->DIR_FstClusHI);
+ TempFullClusterCalc = TempFullClusterCalc << 16;
+ TempFullClusterCalc |= entry->DIR_FstClusLO;
+
+ return TempFullClusterCalc;
+}
+
+
+#ifdef ALLOW_FORMATS
+#ifdef ALLOW_WRITES
+
+
+/*********************************************************************************
+ Function:
+ int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+ Summary:
+ Creates a master boot record
+ Conditions:
+ The I/O pins for the device have been initialized by the InitIO function.
+ Input:
+ firstSector - The first sector of the partition on the device (cannot
+ be 0; that's the MBR)
+ numSectors - The number of sectors available in memory (including the
+ MBR)
+ Return Values:
+ 0 - MBR was created successfully
+ EOF - MBR could not be created
+ Side Effects:
+ None
+ Description:
+ This function can be used to create a master boot record for a device. Note
+ that this function should not be used on a device that is already formatted
+ with a master boot record (i.e. most SD cards, CF cards, USB keys). This
+ function will fill the global data buffer with appropriate partition information
+ for a FAT partition with a type determined by the number of sectors available
+ to the partition. It will then write the MBR information to the first sector
+ on the device. This function should be followed by a call to FSformat, which
+ will create a boot sector, root dir, and FAT appropriate the the information
+ contained in the new master boot record. Note that FSformat only supports
+ FAT12 and FAT16 formatting at this time, and so cannot be used to format a
+ device with more than 0x3FFD5F sectors.
+ Remarks:
+ This function can damage the device being used, and should not be called
+ unless the user is sure about the size of the device and the first sector value.
+ *********************************************************************************/
+
+int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+{
+ PT_MBR Partition;
+ DWORD CyHdSc = 0x00000000;
+ DWORD tempSector;
+
+ if ((firstSector == 0) || (numSectors <= 1))
+ return EOF;
+
+ if (firstSector > (numSectors - 1))
+ return EOF;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ return EOF;
+
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ Partition = (PT_MBR) gDataBuffer;
+
+ // Set Cylinder-head-sector address of the first sector
+ tempSector = firstSector;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[447] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[448] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[449] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the count of sectors
+ Partition->Partition0.PTE_NumSect = numSectors - firstSector;
+
+ // Set the partition type
+ // We only support creating FAT12 and FAT16 MBRs at this time
+ if (Partition->Partition0.PTE_NumSect < 0x1039)
+ {
+ // FAT12
+ Partition->Partition0.PTE_FSDesc = 0x01;
+ }
+ else if (Partition->Partition0.PTE_NumSect <= 0x3FFD5F)
+ {
+ // FAT16
+ Partition->Partition0.PTE_FSDesc = 0x06;
+ }
+ else
+ return EOF;
+
+ // Set the LBA of the first sector
+ Partition->Partition0.PTE_FrstSect = firstSector;
+
+ // Set the Cylinder-head-sector address of the last sector
+ tempSector = firstSector + numSectors - 1;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[451] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[452] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[453] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the boot descriptor. This will be 0, since we won't
+ // be booting anything from our device probably
+ Partition->Partition0.PTE_BootDes = 0x00;
+
+ // Set the signature codes
+ Partition->Signature0 = 0x55;
+ Partition->Signature1 = 0xAA;
+
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) != TRUE)
+ return EOF;
+ else
+ return 0;
+
+}
+
+
+
+/*******************************************************************
+ Function:
+ int FSformat (char mode, long int serialNumber, char * volumeID)
+ Summary:
+ Formats a device
+ Conditions:
+ The device must possess a valid master boot record.
+ Input:
+ mode - - 0 - Just erase the FAT and root
+ - 1 - Create a new boot sector
+ serialNumber - Serial number to write to the card
+ volumeID - Name of the card
+ Return Values:
+ 0 - Format was successful
+ EOF - Format was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSformat function can be used to create a new boot sector
+ on a device, based on the information in the master boot record.
+ This function will first initialize the I/O pins and the device,
+ and then attempts to read the master boot record. If the MBR
+ cannot be loaded successfully, the function will fail. Next, if
+ the 'mode' argument is specified as '0' the existing boot sector
+ information will be loaded. If the 'mode' argument is '1' an
+ entirely new boot sector will be constructed using the disk
+ values from the master boot record. Once the boot sector has
+ been successfully loaded/created, the locations of the FAT and
+ root will be loaded from it, and they will be completely
+ erased. If the user has specified a volumeID parameter, a
+ VOLUME attribute entry will be created in the root directory
+ to name the device.
+ Remarks:
+ FAT12 and FAT16 formatting is supported.
+ *******************************************************************/
+
+int FSformat (char mode, long int serialNumber, char * volumeID)
+{
+ PT_MBR masterBootRecord;
+ DWORD secCount, FAT16DataClusters, RootDirSectors;
+ BootSec BSec;
+ DISK d;
+ DISK * disk = &d;
+ WORD j;
+ DWORD fatsize, test;
+ BYTE Index;
+#ifdef __18CXX
+ // This is here because of a C18 compiler feature
+ BYTE * dataBufferPointer = gDataBuffer;
+#endif
+
+ FSerrno = CE_GOOD;
+
+ disk->buffer = gDataBuffer;
+
+ MDD_InitIO();
+
+ if (MDD_MediaInitialize() != TRUE)
+ {
+ FSerrno = CE_INIT_ERROR;
+ return EOF;
+ }
+
+ if (MDD_SectorRead (0x00, gDataBuffer) == FALSE)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+
+ // Check if the card has no MBR
+ BSec = (BootSec) disk->buffer;
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( disk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( disk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ switch (mode)
+ {
+ case 1:
+ // not enough info to construct our own boot sector
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ case 0:
+ // We have to determine the operating system, and the
+ // locations and sizes of the root dir and FAT, and the
+ // count of FATs
+ disk->firsts = 0;
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ default:
+ break;
+ }
+ }
+ else
+ {
+ masterBootRecord = (PT_MBR) &gDataBuffer;
+ disk->firsts = masterBootRecord->Partition0.PTE_FrstSect;
+ }
+ }
+
+ switch (mode)
+ {
+ // True: Rewrite the whole boot sector
+ case 1:
+ secCount = masterBootRecord->Partition0.PTE_NumSect;
+
+ if (secCount < 0x1039)
+ {
+ disk->type = FAT12;
+ // Format to FAT12 only if there are too few sectors to format
+ // as FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x01;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ if (secCount >= 0x1028)
+ {
+ // More than 0x18 sectors for FATs, 0x20 for root dir,
+ // 0x8 reserved, and 0xFED for data
+ // So double the number of sectors in a cluster to reduce
+ // the number of data clusters used
+ disk->SecPerClus = 2;
+ }
+ else
+ {
+ // One sector per cluster
+ disk->SecPerClus = 1;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT12 )
+ gDataBuffer[58] = '2';
+ }
+ else if (secCount <= 0x3FFD5F)
+ {
+ disk->type = FAT16;
+ // Format to FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x06;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ FAT16DataClusters = secCount - 0x218;
+ // Figure out how many sectors per cluster we need
+ disk->SecPerClus = 1;
+ while (FAT16DataClusters > 0xFFED)
+ {
+ disk->SecPerClus *= 2;
+ FAT16DataClusters /= 2;
+ }
+ // This shouldnt happen
+ if (disk->SecPerClus > 128)
+ {
+ FSerrno = CE_BAD_PARTITION;
+ return EOF;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT16 )
+ gDataBuffer[58] = '6';
+ }
+ else
+ {
+ // Cannot format; too many sectors
+ FSerrno = CE_NONSUPPORTED_SIZE;
+ return EOF;
+ }
+
+ // Calculate the size of the FAT
+ fatsize = (secCount - 0x21 + (2*disk->SecPerClus));
+ if (disk->type == FAT12)
+ test = (341 * disk->SecPerClus) + 2;
+ else
+ test = (256 * disk->SecPerClus) + 2;
+ fatsize = (fatsize + (test-1)) / test;
+ // Non-file system specific values
+ gDataBuffer[0] = 0xEB; //Jump instruction
+ gDataBuffer[1] = 0x3C;
+ gDataBuffer[2] = 0x90;
+ gDataBuffer[3] = 'M'; //OEM Name "MCHP FAT"
+ gDataBuffer[4] = 'C';
+ gDataBuffer[5] = 'H';
+ gDataBuffer[6] = 'P';
+ gDataBuffer[7] = ' ';
+ gDataBuffer[8] = 'F';
+ gDataBuffer[9] = 'A';
+ gDataBuffer[10] = 'T';
+ gDataBuffer[11] = 0x00; //Bytes per sector - 512
+ gDataBuffer[12] = 0x02;
+ gDataBuffer[13] = disk->SecPerClus; //Sectors per cluster
+ gDataBuffer[14] = 0x08; //Reserved sector count
+ gDataBuffer[15] = 0x00;
+ disk->fat = 0x08 + disk->firsts;
+ gDataBuffer[16] = 0x02; //number of FATs
+ disk->fatcopy = 0x02;
+ gDataBuffer[17] = 0x00; //Max number of root directory entries - 512 files allowed
+ gDataBuffer[18] = 0x02;
+ disk->maxroot = 0x200;
+ gDataBuffer[19] = 0x00; //total sectors
+ gDataBuffer[20] = 0x00;
+ gDataBuffer[21] = 0xF8; //Media Descriptor
+ gDataBuffer[22] = fatsize & 0xFF; //Sectors per FAT
+ gDataBuffer[23] = (fatsize >> 8) & 0xFF;
+ disk->fatsize = fatsize;
+ gDataBuffer[24] = 0x3F; //Sectors per track
+ gDataBuffer[25] = 0x00;
+ gDataBuffer[26] = 0xFF; //Number of heads
+ gDataBuffer[27] = 0x00;
+ // Hidden sectors = sectors between the MBR and the boot sector
+ gDataBuffer[28] = (BYTE)(disk->firsts & 0xFF);
+ gDataBuffer[29] = (BYTE)((disk->firsts / 0x100) & 0xFF);
+ gDataBuffer[30] = (BYTE)((disk->firsts / 0x10000) & 0xFF);
+ gDataBuffer[31] = (BYTE)((disk->firsts / 0x1000000) & 0xFF);
+ // Total Sectors = same as sectors in the partition from MBR
+ gDataBuffer[32] = (BYTE)(secCount & 0xFF);
+ gDataBuffer[33] = (BYTE)((secCount / 0x100) & 0xFF);
+ gDataBuffer[34] = (BYTE)((secCount / 0x10000) & 0xFF);
+ gDataBuffer[35] = (BYTE)((secCount / 0x1000000) & 0xFF);
+ gDataBuffer[36] = 0x00; // Physical drive number
+ gDataBuffer[37] = 0x00; // Reserved (current head)
+ gDataBuffer[38] = 0x29; // Signature code
+ gDataBuffer[39] = (BYTE)(serialNumber & 0xFF);
+ gDataBuffer[40] = (BYTE)((serialNumber / 0x100) & 0xFF);
+ gDataBuffer[41] = (BYTE)((serialNumber / 0x10000) & 0xFF);
+ gDataBuffer[42] = (BYTE)((serialNumber / 0x1000000) & 0xFF);
+ // Volume ID
+ if (volumeID != NULL)
+ {
+ for (Index = 0; (*(volumeID + Index) != 0) && (Index < 11); Index++)
+ {
+ gDataBuffer[Index + 43] = *(volumeID + Index);
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[43 + Index++] = 0x20;
+ }
+ }
+ else
+ {
+ for (Index = 0; Index < 11; Index++)
+ {
+ gDataBuffer[Index+43] = 0;
+ }
+ }
+ gDataBuffer[54] = 'F';
+ gDataBuffer[55] = 'A';
+ gDataBuffer[56] = 'T';
+ gDataBuffer[57] = '1';
+ gDataBuffer[59] = ' ';
+ gDataBuffer[60] = ' ';
+ gDataBuffer[61] = ' ';
+#ifdef __18CXX
+ // C18 can't reference a value greater than 256
+ // using an array name pointer
+ *(dataBufferPointer + 510) = 0x55;
+ *(dataBufferPointer + 511) = 0xAA;
+#else
+ gDataBuffer[510] = 0x55;
+ gDataBuffer[511] = 0xAA;
+#endif
+
+ disk->root = disk->fat + (disk->fatcopy * disk->fatsize);
+
+ if (MDD_SectorWrite (disk->firsts, gDataBuffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ break;
+ case 0:
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ break;
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ }
+
+ // Erase the FAT
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+ gDataBuffer[0] = 0xF8;
+ gDataBuffer[1] = 0xFF;
+ gDataBuffer[2] = 0xFF;
+ if (disk->type == FAT16)
+ gDataBuffer[3] = 0xFF;
+
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (disk->fat + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ memset (gDataBuffer, 0x00, 4);
+
+ for (Index = disk->fat + 1; Index < (disk->fat + disk->fatsize); Index++)
+ {
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (Index + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ }
+
+ // Erase the root directory
+ RootDirSectors = ((disk->maxroot * 32) + (0x200 - 1)) / 0x200;
+
+ for (Index = 1; Index < RootDirSectors; Index++)
+ {
+ if (MDD_SectorWrite (disk->root + Index, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ if (volumeID != NULL)
+ {
+ // Create a drive name entry in the root dir
+ Index = 0;
+ while ((*(volumeID + Index) != 0) && (Index < 11))
+ {
+ gDataBuffer[Index] = *(volumeID + Index);
+ Index++;
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[Index++] = ' ';
+ }
+ gDataBuffer[11] = 0x08;
+ gDataBuffer[17] = 0x11;
+ gDataBuffer[19] = 0x11;
+ gDataBuffer[23] = 0x11;
+
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ else
+ {
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ return 0;
+}
+#endif
+#endif
+
+
+/*******************************************************
+ Function:
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+ Summary:
+ Write dir entry info into a specified entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - \File structure
+ curEntry - Write destination
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will calculate the sector of the
+ directory (whose base sector is pointed to by the
+ dirccls value in the FSFILE object 'fo') that contains
+ a directory entry whose offset is indicated by the
+ curEntry parameter. It will then write the data
+ in the global data buffer (which should already
+ contain the entries for that sector) to the device.
+ Remarks:
+ None
+ *******************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+{
+ DISK *dsk;
+ BYTE status;
+ BYTE offset2;
+ DWORD sector;
+ DWORD ccls;
+
+ dsk = fo->dsk;
+
+ // get the cluster of this entry
+ ccls = fo->dirccls;
+
+ // if its not the root, it's cluster based
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // Root is always cluster-based in FAT32
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ if(ccls != FatRootDirClusterValue)
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+ }
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ // Now write it
+ // "Offset" ensures writing of data belonging to a file entry only. Hence it doesn't change other file entries.
+ if ( !MDD_SectorWrite( sector + offset2, dsk->buffer, FALSE))
+ status = FALSE;
+ else
+ status = TRUE;
+
+ return(status);
+} // Write_File_Entry
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE FAT_erase_cluster_chain (WORD cluster, DISK * dsk)
+ Summary:
+ Erase a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ cluster - The cluster number
+ dsk - The disk structure
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will parse through a cluster chain
+ starting with the cluster pointed to by 'cluster' and
+ mark all of the FAT entries as empty until the end of
+ the chain has been reached or an error occurs.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk)
+{
+ DWORD c,c2,ClusterFailValue;
+ enum _status {Good, Fail, Exit}status;
+
+ status = Good;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ c2 = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT16:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ c2 = LAST_CLUSTER_FAT16;
+ break;
+
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16; // FAT16 value itself
+ c2 = LAST_CLUSTER_FAT12;
+ break;
+ }
+
+ // Make sure there is actually a cluster assigned
+ if(cluster == 0 || cluster == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ while(status == Good)
+ {
+ // Get the FAT entry
+ if((c = ReadFAT( dsk, cluster)) == ClusterFailValue)
+ status = Fail;
+ else
+ {
+ if(c == 0 || c == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ // compare against max value of a cluster in FATxx
+ // look for the last cluster in the chain
+ if ( c >= c2)
+ status = Exit;
+
+ // Now erase this FAT entry
+ if(WriteFAT(dsk, cluster, CLUSTER_EMPTY, FALSE) == ClusterFailValue)
+ status = Fail;
+
+ // now update what the current cluster is
+ cluster = c;
+ }
+ }
+ }// while status
+ }// cluster == 0
+
+ WriteFAT (dsk, 0, 0, TRUE);
+
+ if(status == Exit)
+ return(TRUE);
+ else
+ return(FALSE);
+} // Erase cluster
+#endif
+
+/**************************************************************************
+ Function:
+ DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+ Summary:
+ Load a file entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File information
+ curEntry - Offset of the directory entry to load.
+ ForceRead - Forces loading of a new sector of the directory.
+ Return:
+ DIRENTRY - Pointer to the directory entry that was loaded.
+ Side Effects:
+ Any unwritten data in the data buffer will be written to the device.
+ Description:
+ Load the sector containing the file entry pointed to by 'curEntry'
+ from the directory pointed to by the variables in 'fo.'
+ Remarks:
+ Any modification of this function is extremely likely to
+ break something.
+ **************************************************************************/
+
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+{
+ DIRENTRY dir;
+ DISK *dsk;
+ DWORD sector;
+ DWORD cluster, LastClusterLimit;
+ DWORD ccls;
+ BYTE offset2;
+ BYTE numofclus;
+
+ dsk = fo->dsk;
+
+ // get the base sector of this directory
+ cluster = fo->dirclus;
+ ccls = fo->dirccls;
+
+ // figure out the offset from the base sector
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+ /* There are 16 entries per sector. SECTOR size is 512 bytes. Each entry in ROOT takes 32 bytes.
+ So, 512/32 = 16. So 16 file entries can be made in each sector. */
+
+ offset2 = offset2; // emulator issue
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // the ROOT is always cluster based in FAT32
+ /* In FAT32: There is no ROOT region. Root etries are made in DATA region only.
+ Every cluster of DATA which is accupied by ROOT is tracked by FAT table/entry so the ROOT can grow
+ to an amount which is restricted only by available free DATA region. */
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // if its the root its not cluster based
+ if(cluster != 0)
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ // check if a new sector of the root must be loaded
+ if (ForceRead || (*curEntry & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) // only 16 entries per sector
+ {
+ // see if we have to load a new cluster
+ if((offset2 == 0 && (*curEntry) >= DIRENTRIES_PER_SECTOR) || ForceRead)
+ {
+ if(cluster == 0)
+ {
+ ccls = 0;
+ }
+ else
+ {
+ // If ForceRead, read the number of sectors from 0
+ if(ForceRead)
+ numofclus = ((WORD)(*curEntry) / (WORD)(((WORD)DIRENTRIES_PER_SECTOR) * (WORD)dsk->SecPerClus));
+ // Otherwise just read the next sector
+ else
+ numofclus = 1;
+
+ // move to the correct cluster
+ while(numofclus)
+ {
+ ccls = ReadFAT(dsk, ccls);
+
+ if(ccls >= LastClusterLimit)
+ break;
+ else
+ numofclus--;
+ }
+ }
+ }
+
+ // see if that we have a valid cluster number
+ if(ccls < LastClusterLimit)
+ {
+ fo->dirccls = ccls; // write it back
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ /* see if we are root and about to go pass our boundaries
+ FAT32 stores the root directory in the Data Region along with files and other directories,
+ allowing it to grow without such a restraint */
+ if((ccls == FatRootDirClusterValue) && ((sector + offset2) >= dsk->data) && (FAT32 != dsk->type))
+ {
+ dir = ((DIRENTRY)NULL); // reached the end of the root
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return NULL;
+#endif
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+
+ if ( MDD_SectorRead( sector + offset2, dsk->buffer) != TRUE) // if FALSE: sector could not be read.
+ {
+ dir = ((DIRENTRY)NULL);
+ }
+ else // Sector has been read properly, Copy the root entry info of the file searched.
+ {
+ if(ForceRead) // Buffer holds all 16 root entry info. Point to the one required.
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+ else
+ dir = (DIRENTRY)dsk->buffer;
+ }
+ gLastDataSectorRead = 0xFFFFFFFF;
+ }
+ }
+ else
+ {
+ nextClusterIsLast = TRUE;
+ dir = ((DIRENTRY)NULL);
+ }
+ }
+ else
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+
+ return(dir);
+} // Cache_File_Entry
+
+
+/*************************************************************************
+ Function:
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Create a new file entry
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location to create file
+ Return Values:
+ CE_GOOD - File Creation successful
+ CE_DIR_FULL - All root directory entries are taken
+ CE_WRITE_ERROR - The head cluster of the file could not be created.
+ Side Effects:
+ Modifies the FSerrno variable.
+ Description:
+ With the data passed within fo, create a new file entry in the current
+ directory. This function will first search for empty file entries.
+ Once an empty entry is found, the entry will be populated with data
+ for a file or directory entry. Finally, the first cluster of the
+ new file will be located and allocated, and its value will be
+ written into the file entry.
+ Remarks:
+ None
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode)
+{
+ BYTE index;
+ CETYPE error = CE_GOOD;
+ char name[11];
+
+ FSerrno = CE_GOOD;
+
+ for (index = 0; index < FILE_NAME_SIZE; index ++)
+ {
+ name[index] = fo->name[index];
+ }
+
+ *fHandle = 0;
+
+ // figure out where to put this file in the directory stucture
+ if(FindEmptyEntries(fo, fHandle))
+ {
+ // found the entry, now populate it
+ if((error = PopulateEntries(fo, name ,fHandle, mode)) == CE_GOOD)
+ {
+ // if everything is ok, create a first cluster
+ error = CreateFirstCluster(fo);
+ }
+ }
+ else
+ {
+ error = CE_DIR_FULL;
+ }
+
+ FSerrno = error;
+
+ return(error);
+}
+#endif
+
+/******************************************************
+ Function:
+ CETYPE CreateFirstCluster(FILEOBJ fo)
+ Summary:
+ Create the first cluster for a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file that contains the first cluster
+ Return Values:
+ CE_GOOD - First cluster created successfully
+ CE_WRITE_ERROR - Cluster creation failed
+ Side Effects:
+ None
+ Description:
+ This function will find an unused cluster, link it to
+ a file's directory entry, and write the entry back
+ to the device.
+ Remarks:
+ None.
+ ******************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFirstCluster(FILEOBJ fo)
+{
+ CETYPE error;
+ DWORD cluster,TempMsbCluster;
+ WORD fHandle;
+ DIRENTRY dir;
+ fHandle = fo->entry;
+
+ // Now create the first cluster (head cluster)
+ if((error = FILECreateHeadCluster(fo,&cluster)) == CE_GOOD)
+ {
+ // load the file entry so the new cluster can be linked to it
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ // Now update the new cluster
+ dir->DIR_FstClusLO = (cluster & 0x0000FFFF);
+
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ // Get the higher part of cluster and store it in directory entry.
+ TempMsbCluster = (cluster & 0x0FFF0000); // Since only 28 bits usedin FAT32. Mask the higher MSB nibble.
+ TempMsbCluster = TempMsbCluster >> 16; // Get the date into Lsb place.
+ dir->DIR_FstClusHI = TempMsbCluster;
+#else // If FAT32 support not enabled
+ TempMsbCluster = 0; // Just to avoid compiler warnigng.
+ dir->DIR_FstClusHI = 0;
+#endif
+
+ // now write it
+ if(Write_File_Entry(fo, &fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+ } // Create Cluster
+
+ return(error);
+}// End of CreateFirstCluster
+#endif
+
+/**********************************************************
+ Function:
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Find an empty dir entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Start of entries
+ Return Values:
+ TRUE - One found
+ FALSE - None found
+ Side Effects:
+ None
+ Description:
+ This function will cache directory entries, starting
+ with the one pointed to by the fHandle argument. It will
+ then search through the entries until an unused one
+ is found. If the end of the cluster chain for the
+ directory is reached, a new cluster will be allocated
+ to the directory (unless it's a FAT12 or FAT16 root)
+ and the first entry of the new cluster will be used.
+ Remarks:
+ None.
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+{
+ BYTE status = NOT_FOUND;
+ BYTE amountfound;
+ BYTE a;
+ WORD bHandle;
+ DWORD b;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ if((dir = Cache_File_Entry( fo, fHandle, TRUE)) == NULL)
+ {
+ status = CE_BADCACHEREAD;
+ }
+ else
+ {
+ // while its still not found
+ while(status == NOT_FOUND)
+ {
+ amountfound = 0;
+ bHandle = *fHandle;
+
+ // find (number) continuous entries
+ do
+ {
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // increase number
+ (*fHandle)++;
+ }while((a == DIR_DEL || a == DIR_EMPTY) && (dir != (DIRENTRY)NULL) && (++amountfound < 1));
+
+ // --- now why did we exit?
+ if(dir == NULL) // Last entry of the cluster
+ {
+ //setup the current cluster
+ b = fo->dirccls; // write it back
+
+ // make sure we are not the root directory
+ if(b == FatRootDirClusterValue)
+ {
+ if (fo->dsk->type != FAT32)
+ status = NO_MORE;
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ if(amountfound == 1)
+ {
+ status = FOUND;
+ *fHandle = bHandle;
+ }
+ }
+ }// while
+
+ // copy the base handle over
+ *fHandle = bHandle;
+ }
+
+ if(status == FOUND)
+ return(TRUE);
+ else
+ return(FALSE);
+}
+#endif
+
+/**************************************************************************
+ Function:
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle)
+ Summary:
+ Populate a dir entry with data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ name - Name of the file
+ fHandle - Location of the file
+ Return Values:
+ CE_GOOD - Population successful
+ Side Effects:
+ None
+ Description:
+ This function will write data into a new file entry. It will also
+ load timestamp data (based on the method selected by the user) and
+ update the timestamp variables.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode)
+{
+ BYTE error = CE_GOOD;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+
+ if (dir == NULL)
+ return CE_BADCACHEREAD;
+
+ // copy the contents over
+ strncpy(dir->DIR_Name,name,DIR_NAMECOMP);
+
+ // setup no attributes
+ if (mode == DIRECTORY)
+ dir->DIR_Attr = ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = ATTR_ARCHIVE;
+
+ dir->DIR_NTRes = 0x00; // nt reserved
+ dir->DIR_FstClusHI = 0x0000; // high word of this enty's first cluster number
+ dir->DIR_FstClusLO = 0x0000; // low word of this entry's first cluster number
+ dir->DIR_FileSize = 0x0; // file size in DWORD
+
+ // Timing information for uncontrolled clock mode
+#ifdef INCREMENTTIMESTAMP
+ dir->DIR_CrtTimeTenth = 0xB2; // millisecond stamp
+ dir->DIR_CrtTime = 0x7278; // time created
+ dir->DIR_CrtDate = 0x32B0; // date created
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = 0x32B0; // Last Access date
+ dir->DIR_WrtTime = 0x7279; // last update time
+ dir->DIR_WrtDate = 0x32B0; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ dir->DIR_CrtTime = gTimeCrtTime; // time created //
+ dir->DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate; // Last Access date
+ dir->DIR_WrtTime = gTimeWrtTime; // last update time
+ dir->DIR_WrtDate = gTimeWrtDate; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ // The user will have set the time before this funciton is called
+ dir->DIR_CrtTimeTenth = gTimeCrtMS;
+ dir->DIR_CrtTime = gTimeCrtTime;
+ dir->DIR_CrtDate = gTimeCrtDate;
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate;
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+ fo->size = dir->DIR_FileSize;
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ fo->attributes = dir->DIR_Attr;
+ fo->entry = *fHandle;
+
+ // just write the last entry in
+ if (Write_File_Entry(fo,fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+
+ return(error);
+}
+
+#ifdef USEREALTIMECLOCK
+
+/*************************************************************************
+ Function:
+ void CacheTime (void)
+ Summary:
+ Automatically store timestamp information from the RTCC
+ Conditions:
+ RTCC module enabled. Should not be called by the user.
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ This function will automatically load information from an RTCC
+ module and use it to update the global timing variables. These can
+ then be used to update file timestamps.
+ Remarks:
+ None.
+ *************************************************************************/
+
+void CacheTime (void)
+{
+#ifdef __C30__
+ WORD year, monthday, weekhour, minsec, c, result;
+ BYTE ptr1, ptr0;
+
+ if(RCFGCALbits.RTCPTR0)
+ ptr0 = 1;
+ else
+ ptr0 = 0;
+ if (RCFGCALbits.RTCPTR1)
+ ptr1 = 1;
+ else
+ ptr1 = 0;
+
+ RCFGCALbits.RTCPTR0 = 1;
+ RCFGCALbits.RTCPTR1 = 1;
+ year = RTCVAL;
+ monthday = RTCVAL;
+ weekhour = RTCVAL;
+ minsec = RTCVAL;
+
+ if (ptr0 == 1)
+ RCFGCALbits.RTCPTR0 = 1;
+
+ if (ptr1 == 1)
+ RCFGCALbits.RTCPTR1 = 1;
+
+ c = 0;
+ c += (year & 0x0F);
+ c += ((year & 0xF0) >> 4) * 10;
+ // c equals the last 2 digits of the year from 2000 to 2099
+ // Add 20 to adjust it to FAT time (from 1980 to 2107)
+ c += 20;
+ // shift the result to bits
+ result = c << 9;
+
+ if ((monthday & 0x1000) == 0x1000)
+ {
+ c = 10;
+ }
+ else
+ {
+ c = 0;
+ }
+ c += ((monthday & 0x0F00) >> 8);
+ c <<= 5;
+ result |= c;
+
+ c = (monthday & 0x00F0) >> 4;
+ c *= 10;
+ c += (monthday & 0x000F);
+
+ result |= c;
+
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+ gTimeAccDate = result;
+
+ c = ((weekhour & 0x00F0) >> 4) * 10;
+ c += (weekhour & 0x000F);
+ result = c << 11;
+ c = ((minsec & 0xF000) >> 12) * 10;
+ c += (minsec & 0x0F00) >> 8;
+ result |= (c << 5);
+ c = ((minsec & 0x00F0) >> 4) * 10;
+ c += (minsec & 0x000F);
+
+ // If seconds mod 2 is 1, add 1000 ms
+ if (c % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ c >>= 1;
+ result |= c;
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+#elif defined __C32__
+ rtccTime tm; // time structure
+ rtccDate dt; // date structure
+ RtccGetTimeDate(&tm, &dt);
+ gTimeCrtTime = tm.w[1] | tm.w[0];
+ gTimeWrtDate = dt.w[1] | tm.w[0];
+#endif
+}
+#endif
+
+#ifdef USERDEFINEDCLOCK
+
+/***********************************************************************************************************
+ Function:
+ int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+ Summary:
+ Manually set timestamp variables
+ Conditions:
+ USERDEFINEDCLOCK macro defined in FSconfig.h.
+ Input:
+ year - The year (1980\-2107)
+ month - The month (1\-12)
+ day - The day of the month (1\-31)
+ hour - The hour (0\-23)
+ minute - The minute (0\-59)
+ second - The second (0\-59)
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ Lets the user manually set the timing variables. The values passed in will be converted to the format
+ used by the FAT timestamps.
+ Remarks:
+ Call this before creating a file or directory (set create time) and
+ before closing a file (set last access time, last modified time)
+ ***********************************************************************************************************/
+
+int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+{
+ unsigned int result;
+
+ if ((year < 1980) || (year > 2107) || (month < 1) || (month > 12) ||
+ (day < 1) || (day > 31) || (hour > 23) || (minute > 59) || (second > 59))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ result = (year - 1980) << 9;
+ result |= (unsigned int)((unsigned int)month << 5);
+ result |= (day);
+
+ gTimeAccDate = result;
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+
+ result = ((unsigned int)hour << 11);
+ result |= (unsigned int)((unsigned int)minute << 5);
+ result |= (second/2);
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+
+ if (second % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ FSerrno = CE_GOOD;
+ return 0;
+}
+#endif
+
+#endif
+
+/***********************************************************************
+ Function:
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+ Summary;
+ Allocate a new cluster to a file
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ mode -
+ - 0 - Allocate a cluster to a file
+ - 1 - Allocate a cluster to a directory
+ Return Values:
+ CE_GOOD - Cluster allocated
+ CE_DISK_FULL - No clusters available
+ Side Effects:
+ None
+ Description:
+ This function will find an empty cluster on the device using the
+ FATfindEmptyCluster function. It will then mark it as the last
+ cluster in the file in the FAT chain, and link the current last
+ cluster of the passed file to the new cluster. If the new
+ cluster is a directory cluster, it will be erased (so there are no
+ extraneous directory entries). If it's allocated to a non-directory
+ file, it doesn't need to be erased; extraneous data in the cluster
+ will be unviewable because of the file size parameter.
+ Remarks:
+ None.
+ ***********************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+{
+ DISK * dsk;
+ DWORD c,curcls;
+
+ dsk = fo->dsk;
+ c = fo->ccls;
+
+ // find the next empty cluster
+ c = FATfindEmptyCluster(fo);
+ if (c == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ return CE_DISK_FULL;
+
+
+ // mark the cluster as taken, and last in chain
+ if(dsk->type == FAT12)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT12, FALSE);
+ else if (dsk->type == FAT16)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT16, FALSE);
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT32, FALSE);
+#endif
+
+ // link current cluster to the new one
+ curcls = fo->ccls;
+
+ WriteFAT( dsk, curcls, c, FALSE);
+
+ // update the FILE structure
+ fo->ccls = c;
+
+ // IF this is a dir, we need to erase the cluster
+ // If it's a file, we can leave it- the file size
+ // will limit the data we see to the data that's been
+ // written
+ if (mode == 1)
+ return (EraseCluster(dsk, c));
+ else
+ return CE_GOOD;
+
+} // allocate new cluster
+#endif
+
+/***********************************************
+ Function:
+ DWORD FATfindEmptyCluster(FILEOBJ fo)
+ Summary:
+ Find the next available cluster on the device
+ Conditions:
+ This function should not be called by the
+ user.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ DWORD - Address of empty cluster
+ 0 - Could not find empty cluster
+ Side Effects:
+ None
+ Description:
+ This function will search through the FAT to
+ find the next available cluster on the device.
+ Remarks:
+ Should not be called by user
+ ***********************************************/
+
+#ifdef ALLOW_WRITES
+DWORD FATfindEmptyCluster(FILEOBJ fo)
+{
+ DISK * disk;
+ DWORD value = 0x0;
+ DWORD c,curcls, EndClusterLimit, ClusterFailValue;
+
+ disk = fo->dsk;
+ c = fo->ccls;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ EndClusterLimit = END_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ EndClusterLimit = END_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT12:
+ EndClusterLimit = END_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // just in case
+ if(c < 2)
+ c = 2;
+
+ curcls = c;
+ ReadFAT(disk, c);
+
+ // sequentially scan through the FAT looking for an empty cluster
+ while(c)
+ {
+ // look at its value
+ if ( (value = ReadFAT(disk, c)) == ClusterFailValue)
+ {
+ c = 0;
+ break;
+ }
+
+ // check if empty cluster found
+ if (value == CLUSTER_EMPTY)
+ break;
+
+ c++; // check next cluster in FAT
+ // check if reached last cluster in FAT, re-start from top
+ if (value == EndClusterLimit || c >= disk->maxcls)
+ c = 2;
+
+ // check if full circle done, disk full
+ if ( c == curcls)
+ {
+ c = 0;
+ break;
+ }
+ } // scanning for an empty cluster
+
+ return(c);
+}
+#endif
+
+/************************************************************
+ Function:
+ int FSfclose(FSFILE *fo)
+ Summary:
+ Update file information and free FSFILE objects
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to the file to close
+ Return Values:
+ 0 - File closed successfully
+ EOF - Error closing the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will update the directory entry for the
+ file pointed to by 'fo' with the information contained
+ in 'fo,' including the new file size and attributes.
+ Timestamp information will also be loaded based on the
+ method selected by the user and written to the entry
+ as the last modified time and date. The file entry will
+ then be written to the device. Finally, the memory
+ used for the specified file object will be freed from
+ the dynamic heap or the array of FSFILE objects.
+ Remarks:
+ A function to flush data to the device without closing the
+ file can be created by removing the portion of this
+ function that frees the memory and the line that clears
+ the write flag.
+ ************************************************************/
+
+int FSfclose(FSFILE *fo)
+{
+ WORD fHandle;
+#ifndef FS_DYNAMIC_MEM
+ WORD fIndex;
+#endif
+ int error = 72;
+#ifdef ALLOW_WRITES
+ DIRENTRY dir;
+#endif
+
+ FSerrno = CE_GOOD;
+ fHandle = fo->entry;
+
+#ifdef ALLOW_WRITES
+ if(fo->flags.write)
+ {
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ // Write the current FAT sector to the disk
+ WriteFAT (fo->dsk, 0, 0, TRUE);
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = EOF;
+ return error;
+ }
+
+ // update the time
+#ifdef INCREMENTTIMESTAMP
+ IncrementTimeStamp(dir);
+#elif defined USERDEFINEDCLOCK
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#elif defined USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#endif
+
+ dir->DIR_FileSize = fo->size;
+
+ dir->DIR_Attr = fo->attributes;
+
+ // just write the last entry in
+ if(Write_File_Entry(fo,&fHandle))
+ error = 0;
+ else
+ {
+ FSerrno = CE_WRITE_ERROR;
+ error = EOF;
+ }
+
+ // it's now closed
+ fo->flags.write = FALSE;
+ }
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ FS_free((unsigned char *)fo);
+#else
+
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( fo == &gFileArray[fIndex] )
+ {
+ gFileSlotOpen[fIndex] = TRUE;
+ break;
+ }
+ }
+#endif
+
+ // File opened in read mode
+ if (error == 72)
+ error = 0;
+
+ return(error);
+} // FSfclose
+
+
+
+
+/*******************************************************
+ Function:
+ void IncrementTimeStamp(DIRENTRY dir)
+ Summary:
+ Automatically set the timestamp to "don't care" data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ dir - Pointer to directory structure
+ Return Values:
+ None
+ Side Effects:
+ None
+ Description:
+ This function will increment the timestamp variable in
+ the 'dir' directory entry. This is used for the
+ don't-care timing method.
+ Remarks:
+ None
+ *******************************************************/
+#ifdef INCREMENTTIMESTAMP
+void IncrementTimeStamp(DIRENTRY dir)
+{
+ BYTE seconds;
+ BYTE minutes;
+ BYTE hours;
+
+ BYTE day;
+ BYTE month;
+ BYTE year;
+
+ seconds = (dir->DIR_WrtTime & 0x1f);
+ minutes = ((dir->DIR_WrtTime & 0x07E0) >> 5);
+ hours = ((dir->DIR_WrtTime & 0xF800) >> 11);
+
+ day = (dir->DIR_WrtDate & 0x1f);
+ month = ((dir->DIR_WrtDate & 0x01E0) >> 5);
+ year = ((dir->DIR_WrtDate & 0xFE00) >> 9);
+
+ if(seconds < 29)
+ {
+ // Increment number of seconds by 2
+ // This clock method isn't intended to be accurate anyway
+ seconds++;
+ }
+ else
+ {
+ seconds = 0x00;
+
+ if(minutes < 59)
+ {
+ minutes++;
+ }
+ else
+ {
+ minutes = 0;
+
+ if(hours < 23)
+ {
+ hours++;
+ }
+ else
+ {
+ hours = 0;
+ if(day < 30)
+ {
+ day++;
+ }
+ else
+ {
+ day = 1;
+
+ if(month < 12)
+ {
+ month++;
+ }
+ else
+ {
+ month = 1;
+ // new year
+ year++;
+ // This is only valid until 2107
+ }
+ }
+ }
+ }
+ }
+
+ dir->DIR_WrtTime = (WORD)(seconds);
+ dir->DIR_WrtTime |= ((WORD)(minutes) << 5);
+ dir->DIR_WrtTime |= ((WORD)(hours) << 11);
+
+ dir->DIR_WrtDate = (WORD)(day);
+ dir->DIR_WrtDate |= ((WORD)(month) << 5);
+ dir->DIR_WrtDate |= ((WORD)(year) << 9);
+}
+#endif
+
+/*****************************************************************
+ Function:
+ BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Fill a file object with specified dir entry data
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Passed member's location
+ Return Values:
+ FOUND - Operation successful
+ NOT_FOUND - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then copy
+ the file information for that entry into the 'fo' FSFILE
+ object.
+ Remarks:
+ None.
+ *****************************************************************/
+
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE index, a;
+ BYTE character;
+ BYTE status;
+ BYTE test = 0;
+
+ // Get the entry
+ if (((*fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) && (*fHandle != 0)) // 4-bit mask because 16-root entries max per sector
+ {
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ }
+ else
+ {
+ dir = Cache_File_Entry (fo, fHandle, FALSE);
+ }
+
+
+ // Make sure there is a directory left
+ if(dir == (DIRENTRY)NULL)
+ {
+ status = NO_MORE;
+ }
+ else
+ {
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ {
+ status = NOT_FOUND;
+ }
+ else if ( a == DIR_EMPTY)
+ {
+ status = NO_MORE;
+ }
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // print the file name and extension
+ for (index=0; index < DIR_NAMESIZE; index++)
+ {
+ character = dir->DIR_Name[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // its possible to have an extension in a directory
+ character = dir->DIR_Extension[0];
+
+ // Get the file extension if its there
+ for (index=0; index < DIR_EXTENSION; index++)
+ {
+ character = dir->DIR_Extension[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // done and done with the name
+ // fo->name[++test] = (BYTE)'\0';
+
+ // Now store the identifier
+ fo->entry = *fHandle;
+
+ // see if we are still a good file
+ a = dir->DIR_Name[0];
+
+ if(a == DIR_DEL)
+ status = NOT_FOUND;
+ else
+ status = FOUND;
+
+ // Now store the size
+ fo->size = (dir->DIR_FileSize);
+
+ fo->cluster = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ /// -Get and store the attributes
+ a = dir->DIR_Attr;
+ fo->attributes = a;
+
+ // get the date and time
+ if ((a & ATTR_DIRECTORY) != 0)
+ {
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ }
+ else
+ {
+ fo->time = dir->DIR_WrtTime;
+ fo->date = dir->DIR_WrtDate;
+ }
+
+ }// deleted directory
+ }// Ensure we are still good
+ return(status);
+} // Fill_File_Object
+
+
+/************************************************************************
+ Function:
+ DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Load file information from a directory entry and cache the entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Information location
+ Return Values:
+ DIRENTRY - Pointer to the directory entry
+ NULL - Directory entry could not be loaded
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then return a pointer
+ to the directory entry in the global data buffer.
+ Remarks:
+ None.
+ ************************************************************************/
+
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE a;
+
+ fo->dirccls = fo->dirclus;
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+ if (dir == NULL)
+ return NULL;
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Make sure there is a directory left
+ if(a == DIR_EMPTY)
+ dir = (DIRENTRY)NULL;
+
+ if(dir != (DIRENTRY)NULL)
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ dir = (DIRENTRY)NULL;
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // scan through all the long dir entries
+ while(a == ATTR_LONG_NAME)
+ {
+ (*fHandle)++;
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+ if (dir == NULL)
+ return NULL;
+ a = dir->DIR_Attr;
+ } // long file name while loop
+ } // deleted dir
+ }// Ensure we are still good
+
+ return(dir);
+} // LoadDirAttrib
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+ Summary:
+ Erase a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location of file information
+ EraseClusters - Remove cluster allocation from FAT?
+ Return Values:
+ CE_GOOD - File erased successfully
+ CE_FILE_NOT_FOUND - Could not find the file on the card
+ CE_ERASE_FAIL - Internal Card erase failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries in the directory
+ pointed to by the dirclus value in the FSFILE object 'fo' that contains
+ the entry that corresponds to the fHandle offset. It will then mark that
+ entry as deleted. If the EraseClusters argument is TRUE, the chain of
+ clusters for that file will be marked as unused in the FAT by the
+ FAT_erase_cluster_chain function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+{
+ DIRENTRY dir;
+ BYTE a;
+ CETYPE status = CE_GOOD;
+ DWORD clus;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ // reset the cluster
+ clus = fo->dirclus;
+ fo->dirccls = clus;
+
+ // load the sector
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return CE_BADCACHEREAD;
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ a = dir->DIR_Name[0];
+
+ // see if there is something in the dir
+ if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ /* 8.3 File Name - entry*/
+ dir->DIR_Name[0] = DIR_DEL; // mark as deleted
+
+ // Get the starting cluster
+ clus = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ // Now write it
+ if(status != CE_GOOD || !(Write_File_Entry( fo, fHandle)))
+ {
+ status = CE_ERASE_FAIL;
+ }
+ else
+ {
+ if (clus != FatRootDirClusterValue) //
+ {
+ if(EraseClusters)
+ {
+ /* Now remove the cluster allocation from the FAT */
+ status = ((FAT_erase_cluster_chain(clus, disk)) ? CE_GOOD : CE_ERASE_FAIL);
+ }
+ }
+ }
+ } // Not already deleted
+ }// Not existant
+
+ if (status == CE_GOOD)
+ FSerrno = CE_GOOD;
+ else
+ FSerrno = CE_ERASE_FAIL;
+
+ return (status);
+}
+#endif
+
+/***************************************************************
+ Function:
+ int FSrename (const rom char * fileName, FSFILE * fo)
+ Summary:
+ Change the name of a file or directory
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file
+ fo - The file to rename
+ Return Values:
+ 0 - File was renamed successfully
+ EOF - File was not renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrename function will rename a file. First, it will
+ search through the current working directory to ensure the
+ specified new filename is not already in use. If it isn't,
+ the new filename will be written to the file entry of the
+ file pointed to by 'fo.'
+ Remarks:
+ None
+ ***************************************************************/
+
+#ifdef ALLOW_WRITES
+
+int FSrename (const char * fileName, FSFILE * fo)
+{
+ unsigned char j, k = 0;
+ char string[12];
+ WORD fHandle = 1, goodHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ if (fo == NULL)
+ {
+ FSerrno = CE_FILENOTOPENED;
+ return -1;
+ }
+ // If fo != NULL, rename the file
+ if (FormatFileName (fileName, fo->name, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+ else
+ {
+ for (j = 0; j < 11; j++)
+ {
+ string[j] = fo->name[j];
+ }
+ goodHandle = fo->entry;
+
+ fHandle = 0;
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Check if the file name is already used
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+
+ nextClusterIsLast = FALSE;
+ while (1)
+ {
+ // Look through the entries until we get to the end
+ // to make sure the name isn't taken
+ dir = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dir == NULL)
+ {
+ if (nextClusterIsLast == TRUE)
+ {
+ break;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ if (dir->DIR_Name[0] == 0)
+ break;
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+ fHandle++;
+ }
+
+ fHandle = goodHandle;
+ fo->dirccls = fo->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ for (j = 0; j < 11; j++)
+ {
+ dir->DIR_Name[j] = fo->name[j];
+ }
+
+ // just write the last entry in
+ if(!Write_File_Entry(fo,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#endif // Allow writes
+
+
+
+/*********************************************************************
+ Function:
+ FSFILE * FSfopen (const char * fileName, const char *mode)
+ Summary:
+ Open a file
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to open
+ mode -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ - WRITEPLUS - Create a new file or replace an existing file (reads also enabled)
+ - READPLUS - Read data from an existing file (writes also enabled)
+ - APPENDPLUS - Append data to an existing file (reads also enabled)
+ Return Values:
+ FSFILE * - The pointer to the file object
+ NULL - The file could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will open a file or directory. First, RAM in the
+ dynamic heap or static array will be allocated to a new FSFILE object.
+ Then, the specified file name will be formatted to ensure that it's
+ in 8.3 format. Next, the FILEfind function will be used to search
+ for the specified file name. If the name is found, one of three
+ things will happen: if the file was opened in read mode, its file
+ info will be loaded using the FILEopen function; if it was opened in
+ write mode, it will be erased, and a new file will be constructed in
+ its place; if it was opened in append mode, its file info will be
+ loaded with FILEopen and the current location will be moved to the
+ end of the file using the FSfseek function. If the file was not
+ found by FILEfind, it will be created if the mode was specified as
+ a write or append mode. In these cases, a pointer to the heap or
+ static FSFILE object array will be returned. If the file was not
+ found and the mode was specified as a read mode, the memory
+ allocated to the file will be freed and the NULL pointer value
+ will be returned.
+ Remarks:
+ None.
+ *********************************************************************/
+
+FSFILE * FSfopen( const char * fileName, const char *mode )
+{
+ FILEOBJ filePtr;
+#ifndef FS_DYNAMIC_MEM
+ int fIndex;
+#endif
+ BYTE ModeC;
+ WORD fHandle;
+ CETYPE final;
+
+#ifdef FS_DYNAMIC_MEM
+ filePtr = (FILEOBJ) FS_malloc(sizeof(FSFILE));
+#else
+
+ filePtr = NULL;
+
+ //Pick available file structure
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( gFileSlotOpen[fIndex] ) //this slot is available
+ {
+ gFileSlotOpen[fIndex] = FALSE;
+ filePtr = &gFileArray[fIndex];
+ break;
+ }
+ }
+
+ if( filePtr == NULL )
+ {
+ FSerrno = CE_TOO_MANY_FILES_OPEN;
+ return NULL; //no file structure slot available
+ }
+#endif
+
+ //Format the source string.
+ if( !FormatFileName(fileName, filePtr->name, 0) )
+ {
+#ifdef FS_DYNAMIC_MEM
+ FS_free( (unsigned char *)filePtr );
+#else
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+#endif
+ FSerrno = CE_INVALID_FILENAME;
+ return NULL; //bad filename
+ }
+
+ //Read the mode character
+ ModeC = mode[0];
+
+ filePtr->dsk = &gDiskData;
+ filePtr->cluster = 0;
+ filePtr->ccls = 0;
+ filePtr->entry = 0;
+ filePtr->attributes = ATTR_ARCHIVE;
+
+ // start at the current directory
+#ifdef ALLOW_DIRS
+ filePtr->dirclus = cwdptr->dirclus;
+ filePtr->dirccls = cwdptr->dirccls;
+#else
+ filePtr->dirclus = FatRootDirClusterValue;
+ filePtr->dirccls = FatRootDirClusterValue;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, filePtr);
+
+ // See if the file is found
+ if(FILEfind (filePtr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0) == CE_GOOD)
+ {
+ // File is Found
+ switch(ModeC)
+ {
+#ifdef ALLOW_WRITES
+ case 'w':
+ case 'W':
+ {
+ // File exists, we want to create a new one, remove it first
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ break;
+ }
+
+ case 'A':
+ case 'a':
+ {
+ if(filePtr->size != 0)
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ else
+ {
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ }
+ break;
+ }
+#endif
+ case 'R':
+ case 'r':
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'r');
+#ifdef ALLOW_WRITES
+ if ((mode[1] == '+') && !(filePtr->attributes & ATTR_DIRECTORY))
+ filePtr->flags.write = 1;
+#endif
+ break;
+ }
+
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;; //indicate error condition
+ break;
+ }
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ // the file was not found, reset to the default asked
+ FileObjectCopy(filePtr, &gFileTemp);
+
+ // File is not Found
+ if(ModeC == 'w' || ModeC == 'W' || ModeC == 'a' || ModeC == 'A')
+ {
+ // use the user requested name
+ fHandle = 0;
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ else
+#endif
+ final = CE_FILE_NOT_FOUND;
+ }
+
+ if (MDD_WriteProtectState())
+ {
+ filePtr->flags.write = 0;;
+ }
+
+#ifdef FS_DYNAMIC_MEM
+ if( final != CE_GOOD )
+ {
+ FS_free( (unsigned char *)filePtr );
+ filePtr = NULL;
+ }
+#else
+ if( final != CE_GOOD )
+ {
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+ filePtr = NULL;
+ }
+#endif
+ else
+ {
+ FSerrno = CE_GOOD;
+ }
+
+ return filePtr;
+}
+
+/*******************************************************************
+ Function:
+ long FSftell (FSFILE * fo)
+ Summary:
+ Determine the current location in a file
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to file structure
+ Return: Current location in the file
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSftell function will return the current position in the
+ file pointed to by 'fo' by returning the 'seek' variable in the
+ FSFILE object, which is used to keep track of the absolute
+ location of the current position in the file.
+ Remarks:
+ None
+ *******************************************************************/
+
+long FSftell (FSFILE * fo)
+{
+ FSerrno = CE_GOOD;
+ return (fo->seek);
+}
+
+
+#ifdef ALLOW_WRITES
+
+/*********************************************************************
+ Function:
+ int FSremove (const char * fileName)
+ Summary:
+ Delete a file
+ Conditions:
+ File not opened, file exists
+ Input:
+ fileName - Name of the file to erase
+ Return Values:
+ 0 - File removed
+ EOF - File was not removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremove function will attempt to find the specified file with
+ the FILEfind function. If the file is found, it will be erased
+ using the FILEerase function.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSremove (const char * fileName)
+{
+ FILEOBJ fo = &tempCWDobj;
+ CETYPE result;
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+ //Format the source string
+ if( !FormatFileName(fileName, fo->name, 0) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = ATTR_ARCHIVE;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+
+ if (fo->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_DELETE_DIR;
+ return -1;
+ }
+
+ result = FILEerase(fo, &fo->entry, TRUE);
+ if( result == CE_GOOD )
+ return 0;
+ else
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+}
+#endif
+
+/*********************************************************
+ Function:
+ void FSrewind (FSFILE * fo)
+ Summary:
+ Set the current position in a file to the beginning
+ Conditions:
+ File opened.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ None
+ Side Effects:
+ None.
+ Description:
+ The FSrewind funciton will reset the position of the
+ specified file to the beginning of the file. This
+ functionality is faster than using FSfseek to reset
+ the position in the file.
+ Remarks:
+ None.
+ *********************************************************/
+
+void FSrewind (FSFILE * fo)
+{
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ flushData();
+#endif
+ fo->seek = 0;
+ fo->pos = 0;
+ fo->sec = 0;
+ fo->ccls = fo->cluster;
+ gBufferOwner = NULL;
+ return;
+}
+
+/**************************************************************************
+ Function:
+ int FSerror (void)
+ Summary:
+ Return an error code for the last function call
+ Conditions:
+ The return value depends on the last function called.
+ Input:
+ None
+ Side Effects:
+ None.
+ Return Values:
+ FSInit -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The physical media could not be initialized
+ - CE_BAD_SECTOR_READ � The MBR or the boot sector could not be
+ read correctly
+ - CE_BAD_PARITION � The MBR signature code was incorrect.
+ - CE_NOT_FORMATTED � The boot sector signature code was incorrect or
+ indicates an invalid number of bytes per sector.
+ - CE_CARDFAT32 � The physical media is FAT32 type (only an error
+ when FAT32 support is disabled).
+ - CE_UNSUPPORTED_FS � The device is formatted with an unsupported file
+ system (not FAT12 or 16).
+ FSfopen -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The device has not been initialized.
+ - CE_TOO_MANY_FILES_OPEN � The function could not allocate any
+ additional file information to the array
+ of FSFILE structures or the heap.
+ - CE_INVALID_FILENAME � The file name argument was invalid.
+ - CE_INVALID_ARGUMENT � The user attempted to open a directory in a
+ write mode or specified an invalid mode argument.
+ - CE_FILE_NOT_FOUND � The specified file (which was to be opened in read
+ mode) does not exist on the device.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_ERASE_FAIL � The existing file could not be erased (when opening
+ a file in WRITE mode).
+ - CE_DIR_FULL � The directory is full.
+ - CE_DISK_FULL� The data memory section is full.
+ - CE_WRITE_ERROR � A write to the device failed.
+ - CE_SEEK_ERROR � The current position in the file could not be set to
+ the end (when the file was opened in APPEND mode).
+ FSfclose -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer or the new file
+ entry information could not be written to the device.
+ - CE_BADCACHEREAD � The file entry information could not be cached
+ FSfread -
+ - CE_GOOD � No Error
+ - CE_WRITEONLY � The file was opened in a write-only mode.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_BAD_SECTOR_READ � The data sector could not be read.
+ - CE_EOF � The end of the file was reached.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be loaded.
+ FSfwrite -
+ - CE_GOOD � No Error
+ - CE_READONLY � The file was opened in a read-only mode.
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_WRITE_ERROR � There was an error writing data to the device.
+ - CE_BADCACHEREAD � The data sector to be modified could not be read from
+ the device.
+ - CE_DISK_FULL � All data clusters on the device are in use.
+ FSfseek -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_INVALID_ARGUMENT � The specified offset exceeds the size of the file.
+ - CE_BADCACHEREAD � The sector that contains the new current position
+ could not be loaded.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be
+ loaded/allocated.
+ FSftell -
+ - CE_GOOD � No Error
+ FSattrib -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The attribute argument was invalid.
+ - CE_BADCACHEREAD � The existing file entry information could not be
+ loaded.
+ - CE_WRITE_ERROR � The file entry information could not be written to
+ the device.
+ FSrename -
+ - CE_GOOD � No Error
+ - CE_FILENOTOPENED � A null file pointer was passed into the function.
+ - CE_INVALID_FILENAME � The file name passed into the function was invalid.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_FILENAME_EXISTS � A file with the specified name already exists.
+ - CE_WRITE_ERROR � The new file entry data could not be written to the
+ device.
+ FSfeof -
+ - CE_GOOD � No Error
+ FSformat -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The device could not be initialized.
+ - CE_BADCACHEREAD � The master boot record or boot sector could not be
+ loaded successfully.
+ - CE_INVALID_ARGUMENT � The user selected to create their own boot sector on
+ a device that has no master boot record, or the mode
+ argument was invalid.
+ - CE_WRITE_ERROR � The updated MBR/Boot sector could not be written to
+ the device.
+ - CE_BAD_PARTITION � The calculated number of sectors per clusters was
+ invalid.
+ - CE_NONSUPPORTED_SIZE � The card has too many sectors to be formatted as
+ FAT12 or FAT16.
+ FSremove -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � The specified file could not be found.
+ - CE_ERASE_FAIL � The file could not be erased.
+ FSchdir -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The path string was mis-formed or the user tried to
+ change to a non-directory file.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_FOUND � Could not find a directory in the path.
+ FSgetcwd -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The user passed a 0-length buffer into the function.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the current working directory.
+ FSmkdir -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_ARGUMENT � The path string was mis-formed.
+ - CE_BADCACHEREAD � Could not successfully change to a recently created
+ directory to store its dir entry information, or
+ could not cache directory entry information.
+ - CE_INVALID_FILENAME � One or more of the directory names has an invalid
+ format.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device or the dot/dotdot entries could
+ not be written to a newly created directory.
+ - CE_DIR_FULL � There are no available dir entries in the CWD.
+ - CE_DISK_FULL � There are no available clusters in the data region of
+ the device.
+ FSrmdir -
+ - CE_GOOD � No Error
+ - CE_DIR_NOT_FOUND � The directory specified could not be found or the
+ function could not change to a subdirectory within
+ the directory to be deleted (when recursive delete is
+ enabled).
+ - CE_INVALID_ARGUMENT � The user tried to remove the CWD or root directory.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_EMPTY � The directory to be deleted was not empty and
+ recursive subdirectory removal was disabled.
+ - CE_ERASE_FAIL � The directory or one of the directories or files
+ within it could not be deleted.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the CWD.
+ SetClockVars -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The time values passed into the function were
+ invalid.
+ FindFirst -
+ - CE_GOOD � No Error
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ - CE_BADCACHEREAD � The file information for the file that was found
+ could not be cached.
+ FindNext -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The SearchRec object was not initialized by a call to
+ FindFirst.
+ - CE_INVALID_ARGUMENT � The SearchRec object was initialized in a different
+ directory from the CWD.
+ - CE_INVALID_FILENAME � The filename is invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ FSfprintf -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � Characters could not be written to the file.
+ Description:
+ The FSerror function will return the FSerrno variable. This global
+ variable will have been set to an error value during the last call of a
+ library function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSerror (void)
+{
+ return FSerrno;
+}
+
+
+/**************************************************************
+ Function:
+ void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+ Summary:
+ Copy a file object
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - The destination
+ foSource - the source
+ Return:
+ None
+ Side Effects:
+ None
+ Description:
+ The FileObjectCopy function will make an exacy copy of
+ a specified FSFILE object.
+ Remarks:
+ None
+ **************************************************************/
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+{
+ BYTE size;
+ BYTE *dest;
+ BYTE *source;
+ BYTE Index;
+
+ dest = (BYTE *)foDest;
+ source = (BYTE *)foSource;
+
+ size = sizeof(FSFILE);
+
+ for(Index=0;Index< size; Index++)
+ {
+ dest[Index] = source[Index];
+ }
+}
+
+/*************************************************************************
+ Function:
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+ Summary:
+ Create the first cluster of a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ cluster - Cluster location
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ CE_DISK_FULL - All clusters in partition are taken
+ Side Effects:
+ None
+ Description:
+ The FILECreateHeadCluster function will create the first cluster
+ of a file. First, it will find an empty cluster with the
+ FATfindEmptyCluster function and mark it as the last cluster in the
+ file. It will then erase the cluster using the EraseCluster function.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+{
+ DISK * disk;
+ CETYPE error = CE_GOOD;
+
+ disk = fo->dsk;
+
+ // find the next empty cluster
+ *cluster = FATfindEmptyCluster(fo);
+
+ if(*cluster == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ {
+ error = CE_DISK_FULL;
+ }
+ else
+ {
+ // mark the cluster as taken, and last in chain
+ if(disk->type == FAT12)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT12, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+ else if(disk->type == FAT16)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT16, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+
+ #ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT32, FALSE) == CLUSTER_FAIL_FAT32)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+#endif
+
+ // lets erase this cluster
+ if(error == CE_GOOD)
+ {
+ error = EraseCluster(disk,*cluster);
+ }
+ }
+
+ return(error);
+} // allocate head cluster
+#endif
+
+/*************************************************************************
+ Function:
+ BYTE EraseCluster(DISK *disk, DWORD cluster)
+ Summary:
+ Erase a cluster
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - Disk structure
+ cluster - Cluster to be erased
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ Side Effects:
+ None
+ Description:
+ The EraseCluster function will write a 0 value into every byte of
+ the specified cluster.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE EraseCluster(DISK *disk, DWORD cluster)
+{
+ BYTE index;
+ DWORD SectorAddress;
+ BYTE error = CE_GOOD;
+
+ SectorAddress = Cluster2Sector(disk,cluster);
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+
+ gBufferOwner = NULL;
+
+ if (gBufferZeroed == FALSE)
+ {
+ // clear out the memory first
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+ gBufferZeroed = TRUE;
+ }
+
+ // Now clear them out
+ for(index = 0; index < disk->SecPerClus && error == CE_GOOD; index++)
+ {
+ if (MDD_SectorWrite( SectorAddress++, disk->buffer, FALSE) != TRUE)
+ error = CE_WRITE_ERROR;
+ }
+
+ return(error);
+}
+#endif
+
+
+#if defined (__C30__) || defined (__C32__)
+
+/***************************************************
+ Function:
+ BYTE ReadByte(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a byte from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ BYTE - the byte read
+ Side Effects:
+ None
+ Description:
+ Reads a byte from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+BYTE ReadByte( BYTE* pBuffer, WORD index )
+{
+ return( pBuffer[index] );
+}
+
+
+/***************************************************
+ Function:
+ BYTE ReadWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 16-bit word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ WORD - the word read
+ Side Effects:
+ None
+ Description:
+ Reads a 16-bit word from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+WORD ReadWord( BYTE* pBuffer, WORD index )
+{
+ BYTE loByte, hiByte;
+ WORD res;
+
+ loByte = pBuffer[index];
+ hiByte = pBuffer[index+1];
+ res = hiByte;
+ res *= 0x100;
+ res |= loByte;
+ return( res );
+}
+
+
+/****************************************************
+ Function:
+ BYTE ReadDWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 32-bit double word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ DWORD - the double word read
+ Side Effects:
+ None
+ Description:
+ Reads a 32-bit double word from a buffer
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD ReadDWord( BYTE* pBuffer, WORD index )
+{
+ WORD loWord, hiWord;
+ DWORD result;
+
+ loWord = ReadWord( pBuffer, index );
+ hiWord = ReadWord( pBuffer, index+2 );
+
+ result = hiWord;
+ result *= 0x10000;
+ result |= loWord;
+ return result;
+}
+
+#endif
+
+
+
+/****************************************************
+ Function:
+ DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+ Summary:
+ Convert a cluster number to the corresponding sector
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - Disk structure
+ cluster - Cluster to be converted
+ Return:
+ sector - Sector that corresponds to given cluster
+ Side Effects:
+ None
+ Description:
+ The Cluster2Sector function will calculate the
+ sector number that corresponds to the first sector
+ of the cluster whose value was passed into the
+ function.
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+{
+ DWORD sector;
+
+ /* Rt: Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ /* In FAT32, there is no separate ROOT region. It is as well stored in DATA region */
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // The root dir takes up cluster 0 and 1
+ if(cluster == 0 ||cluster == 1)
+ sector = dsk->root + cluster;
+ else
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+ }
+
+ return(sector);
+
+}
+
+
+/***************************************************************************
+ Function:
+ int FSattrib (FSFILE * file, unsigned char attributes)
+ Summary:
+ Change the attributes of a file
+ Conditions:
+ File opened
+ Input:
+ file - Pointer to file structure
+ attributes - The attributes to set for the file
+ - Attribute - Value - Indications
+ - ATTR_READ_ONLY - 0x01 - The read-only attribute
+ - ATTR_HIDDEN - 0x02 - The hidden attribute
+ - ATTR_SYSTEM - 0x04 - The system attribute
+ - ATTR_ARCHIVE - 0x20 - The archive attribute
+ Return Values:
+ 0 - Attribute change was successful
+ -1 - Attribute change was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSattrib funciton will set the attributes of the specified file
+ to the attributes passed in by the user. This function will load the
+ file entry, replace the attributes with the ones specified, and write
+ the attributes back. If the specified file is a directory, the
+ directory attribute will be preserved.
+ Remarks:
+ None
+ ***************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSattrib (FSFILE * file, unsigned char attributes)
+{
+ WORD fHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ // Check for valid attributes
+ if ((attributes & ~0x27) != 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ fHandle = file->entry;
+
+ file->dirccls = file->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(file, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Ensure that we aren't trying to change the
+ // attributes of a volume entry
+ if (dir->DIR_Attr & ATTR_VOLUME)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Don't remove the directory attribute from DIR files
+ if (file->attributes & ATTR_DIRECTORY)
+ dir->DIR_Attr = attributes | ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = attributes;
+
+ // just write the last entry in
+ if(!Write_File_Entry(file,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+
+/*********************************************************************************
+ Function:
+ size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Write data to a file
+ Conditions:
+ File opened in WRITE, APPEND, WRITE+, APPEND+, READ+ mode
+ Input:
+ ptr - Pointer to source buffer
+ size - Size of units in bytes
+ n - Number of units to transfer
+ stream - Pointer to file structure
+ Return:
+ size_t - number of units written
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfwrite function will write data to a file. First, the sector that
+ corresponds to the current position in the file will be loaded (if it hasn't
+ already been cached in the global data buffer). Data will then be written to
+ the device from the specified buffer until the specified amount has been written.
+ If the end of a cluster is reached, the next cluster will be loaded, unless
+ the end-of-file flag for the specified file has been set. If it has, a new
+ cluster will be allocated to the file. Finally, the new position and filezize
+ will be stored in the FSFILE object. The parameters 'size' and 'n' indicate how
+ much data to write. 'Size' refers to the size of one object to write (in bytes),
+ and 'n' will refer to the number of these objects to write. The value returned
+ will be equal to 'n' unless an error occured.
+ Remarks:
+ None.
+ *********************************************************************************/
+
+#ifdef ALLOW_WRITES
+size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD count = size * n;
+ BYTE * src = (BYTE *) ptr;
+ DISK * dsk; // pointer to disk structure
+ CETYPE error = CE_GOOD;
+ WORD pos;
+ DWORD l; // absolute lba of sector to load
+ DWORD seek, filesize;
+ WORD writeCount = 0;
+
+ // see if the file was opened in a write mode
+ if(!(stream->flags.write))
+ {
+ FSerrno = CE_READONLY;
+ error = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ if (count == 0)
+ return 0;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ error = CE_WRITE_PROTECTED;
+ return 0;
+ }
+
+ gBufferZeroed = FALSE;
+ dsk = stream->dsk;
+ // get the stated position
+ pos = stream->pos;
+ seek = stream->seek;
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ // Check if the current stream was the last one to use the
+ // buffer. If not, check if we need to write data from the
+ // old stream
+ if (gBufferOwner != stream)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+ gBufferOwner = stream;
+ }
+ if (gLastDataSectorRead != l)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+
+ gBufferZeroed = FALSE;
+ if(!MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ }
+ gLastDataSectorRead = l;
+ }
+ // exit loop if EOF reached
+ filesize = stream->size;
+
+ // Loop while writing bytes
+ while (error == CE_GOOD && count > 0)
+ {
+ if( seek == filesize )
+ stream->flags.FileWriteEOF = TRUE;
+
+ // load a new sector if necessary, multiples of sector
+ if (pos == MEDIA_SECTOR_SIZE)
+ {
+ BYTE needRead = TRUE;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ // reset position
+ pos = 0;
+
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if (stream->sec == dsk->SecPerClus)
+ {
+ stream->sec = 0;
+
+ if(stream->flags.FileWriteEOF)
+ {
+ error = FILEallocate_new_cluster(stream, 0); // add new cluster to the file
+ needRead = FALSE;
+ }
+ else
+ error = FILEget_next_cluster( stream, 1);
+ }
+
+ if (error == CE_DISK_FULL)
+ {
+ FSerrno = CE_DISK_FULL;
+ return 0;
+ }
+
+ if(error == CE_GOOD)
+ {
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+ gBufferOwner = stream;
+ // If we just allocated a new cluster, then the cluster will
+ // contain garbage data, so it doesn't matter what we write to it
+ // Whatever is in the buffer will work fine
+ if (needRead)
+ {
+ if( !MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = 0xFFFFFFFF;
+ return 0;
+ }
+ else
+ {
+ gLastDataSectorRead = l;
+ }
+ }
+ else
+ gLastDataSectorRead = l;
+ }
+ } // load new sector
+
+ if(error == CE_GOOD)
+ {
+ // Write one byte at a time
+ RAMwrite(dsk->buffer, pos++, *(char *)src);
+ src = src + 1; // compiler bug
+ seek++;
+ count--;
+ writeCount++;
+ // now increment the size of the part
+ if(stream->flags.FileWriteEOF)
+ filesize++;
+ gNeedDataWrite = TRUE;
+ }
+ } // while count
+
+ // save off the positon
+ stream->pos = pos;
+
+ // save off the seek
+ stream->seek = seek;
+
+ // now the new size
+ stream->size = filesize;
+
+ return(writeCount / size);
+} // fwrite
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE flushData (void)
+ Summary:
+ Flush unwritten data to a file
+ Conditions:
+ File opened in a write mode, data needs to be written
+ Return Values:
+ CE_GOOD - Data was updated successfully
+ CE_WRITE_ERROR - Data could not be updated
+ Side Effects:
+ None
+ Description:
+ The flushData function is called when it is necessary to
+ read new data into the global data buffer and the
+ gNeedDataWrite variable indicates that there is data
+ in the buffer that hasn't been written to the device.
+ The flushData function will write the data from the
+ buffer into the current cluster of the FSFILE object
+ that is stored in the gBufferOwner global variable.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE flushData (void)
+{
+ DWORD l;
+ DISK * dsk;
+
+ // This will either be the pointer to the last file, or the handle
+ FILEOBJ stream = gBufferOwner;
+
+ dsk = stream->dsk;
+
+ // figure out the lba
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ if(!MDD_SectorWrite( l, dsk->buffer, FALSE))
+ {
+ return CE_WRITE_ERROR;
+ }
+
+ gNeedDataWrite = FALSE;
+
+ return CE_GOOD;
+}
+#endif
+
+/****************************************************
+ Function:
+ int FSfeof( FSFILE * stream )
+ Summary:
+ Indicate whether the current file position is at the end
+ Conditions:
+ File is open in a read mode
+ Input:
+ stream - Pointer to the target file
+ Return Values:
+ Non-Zero - EOF reached
+ 0 - Not at end of File
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfeof function will indicate that the end-of-
+ file has been reached for the specified file by
+ comparing the absolute location in the file to the
+ size of the file.
+ Remarks:
+ None.
+ ****************************************************/
+
+int FSfeof( FSFILE * stream )
+{
+ FSerrno = CE_GOOD;
+ return( stream->seek == stream->size );
+}
+
+
+/**************************************************************************
+ Function:
+ size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Read data from a file
+ Conditions:
+ File is opened in a read mode
+ Input:
+ ptr - Destination buffer for read bytes
+ size - Size of units in bytes
+ n - Number of units to be read
+ stream - File to be read from
+ Return:
+ size_t - number of units read
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfread function will read data from the specified file. First,
+ the appropriate sector of the file is loaded. Then, data is read into
+ the specified buffer until the specified number of bytes have been read.
+ When a cluster boundary is reached, a new cluster will be loaded. The
+ parameters 'size' and 'n' indicate how much data to read. 'Size'
+ refers to the size of one object to read (in bytes), and 'n' will refer
+ to the number of these objects to read. The value returned will be equal
+ to 'n' unless an error occured or the user tried to read beyond the end
+ of the file.
+ Remarks:
+ None.
+ **************************************************************************/
+
+size_t FSfread (void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD len = size * n;
+ BYTE *pointer = (BYTE *) ptr;
+ DISK *dsk; // Disk structure
+ DWORD seek, sec_sel;
+ WORD pos; //position within sector
+ CETYPE error = CE_GOOD;
+ WORD readCount = 0;
+
+ FSerrno = CE_GOOD;
+
+ dsk = (DISK *)stream->dsk;
+ pos = stream->pos;
+ seek = stream->seek;
+
+ if( !stream->flags.read )
+ {
+ FSerrno = CE_WRITEONLY;
+ return 0; // CE_WRITEONLY
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+#endif
+
+ // if it not my buffer, then get it from the disk.
+ if( (gBufferOwner != stream) && (pos != MEDIA_SECTOR_SIZE ))
+ {
+ gBufferOwner = stream;
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ return 0;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ //loop reading (count) bytes
+ while( len )
+ {
+ if( seek == stream->size )
+ {
+ FSerrno = CE_EOF;
+ error = CE_EOF;
+ break;
+ }
+
+ // In fopen, pos is init to 0 and the sect is loaded
+ if( pos == MEDIA_SECTOR_SIZE )
+ {
+ // reset position
+ pos = 0;
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if( stream->sec == dsk->SecPerClus )
+ {
+ stream->sec = 0;
+ if( (error = FILEget_next_cluster( stream, 1)) != CE_GOOD )
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ break;
+ }
+ }
+
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+
+ gBufferOwner = stream;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ break;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ // copy one byte at a time
+ *pointer = RAMread( dsk->buffer, pos++ );
+ pointer++;
+ seek++;
+ readCount++;
+ len--;
+ }
+
+ // save off the positon
+ stream->pos = pos;
+ // save off the seek
+ stream->seek = seek;
+
+ return(readCount / size);
+} // fread
+
+
+/***************************************************************************
+ Function:
+ BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode )
+ Summary:
+ Format a file name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be formatted
+ fN2 - The location the formatted name will be stored
+ mode - Non-zero if parital string search chars are allowed
+ Return Values:
+ TRUE - Name formatted successfully
+ FALSE - File name could not be formatted
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into FSFILE structure format. If filename is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ filename are valid in this filesystem.
+ Remarks:
+ None.
+ ***************************************************************************/
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode)
+{
+ char * pExt;
+ WORD temp;
+ char szName[15];
+ BYTE count;
+
+ for (count = 0; count < 11; count++)
+ {
+ *(fN2 + count) = ' '; // Load destination filename to be space intially.
+ }
+
+ // Make sure we dont have an empty string or a name with only
+ // an extension
+ if (fileName[0] == '.' || fileName[0] == 0)
+ return FALSE;
+
+ temp = strlen( fileName );
+
+ if( temp <= TOTAL_FILE_SIZE ) // 8+3+1
+ strcpy( szName, fileName ); // copy to RAM in case fileName is located in flash
+ else
+ return FALSE; //long file name
+
+ // Make sure the characters are valid
+ if ( !ValidateChars(szName, mode) )
+ return FALSE;
+
+ //Look for '.' in the szName
+ if( (pExt = strchr( szName, '.' )) != 0 )
+ {
+ *pExt = 0; // Assigning NULL here makes the "szName" to be terminated and "pExt" pointer to hold only extn characters.
+ pExt++; // now pointing to extension
+
+ if( strlen( pExt ) > 3 ) // make sure the extension is 3 bytes or fewer
+ return FALSE;
+ }
+
+ if( strlen(szName) > 8 )
+ return FALSE;
+
+ //copy file name
+ for (count = 0; count < strlen(szName); count++)
+ {
+ *(fN2 + count) = * (szName + count); // Destination filename initially filled with SPACE. Now copy only available chars.
+ }
+
+ //copy extension
+ if(pExt && *pExt )
+ {
+ for (count = 0; count < strlen (pExt); count++)
+ {
+ *(fN2 + count + 8) = *(pExt + count); // Copy the extn to 8th position onwards. Ex: "FILE .Tx "
+ }
+ }
+
+ return TRUE;
+}
+
+#ifdef ALLOW_DIRS
+
+/*************************************************************************
+ Function:
+ BYTE FormatDirName (char * string, BYTE mode)
+ Summary:
+ Format a dir name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ string - The name to be formatted
+ mode -
+ - TRUE - Partial string search characters are allowed
+ - FALSE - Partial string search characters are forbidden
+ Return Values:
+ TRUE - The name was formatted correctly
+ FALSE - The name contained invalid characters
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into directory structure format. If the name is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ directory name are valid in this filesystem.
+ Remarks:
+ None.
+ *************************************************************************/
+
+BYTE FormatDirName (char * string, BYTE mode)
+{
+ unsigned char i, j;
+ char tempString [12];
+
+ if (ValidateChars (string, mode) == FALSE)
+ return FALSE;
+
+ for (i = 0; (i < 8) && (*(string + i) != '.') && (*(string + i) != 0); i++)
+ {
+ tempString[i] = *(string + i);
+ }
+
+ j = i;
+
+ while (i < 8)
+ {
+ tempString [i++] = 0x20;
+ }
+
+ if (*(string + j) == '.')
+ {
+ j++;
+ while (*(string + j) != 0)
+ {
+ tempString[i++] = *(string + j++);
+ }
+ }
+
+ while (i < 11)
+ {
+ tempString[i++] = 0x20;
+ }
+
+ tempString[11] = 0;
+
+ // Forbidden
+ if (tempString[0] == 0x20)
+ {
+ tempString[0] = '_';
+ }
+
+ for (i = 0; i < 12; i++)
+ {
+ *(string + i) = tempString[i];
+ }
+
+ return TRUE;
+}
+#endif
+
+
+/*************************************************************
+ Function:
+ BYTE ValidateChars( char * FileName, BYTE mode)
+ Summary:
+ Validate the characters in a given file name
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be validated
+ mode - Determines if partial string search is allowed
+ Return Values:
+ TRUE - Name was validated
+ FALSE - File name was not valid
+ Side Effects:
+ None
+ Description:
+ The ValidateChars function will compare characters in a
+ specified filename to determine if they're permissable
+ in the FAT file system. Lower-case characters will be
+ converted to upper-case. If the mode argument is specifed
+ to be 'TRUE,' partial string search characters are allowed.
+ Remarks:
+ None.
+ *************************************************************/
+BYTE ValidateChars( char * FileName , BYTE mode)
+{
+ int StrSz, index;
+ unsigned char radix = FALSE;
+
+ StrSz = strlen(FileName);
+
+ for( index = 0; index < StrSz; index++ )
+ {
+ if (((FileName[index] <= 0x20) && (FileName[index] != 0x05)) ||
+ (FileName[index] == 0x22) || (FileName[index] == 0x2B) ||
+ (FileName[index] == 0x2C) || (FileName[index] == 0x2F) ||
+ (FileName[index] == 0x3A) || (FileName[index] == 0x3B) ||
+ (FileName[index] == 0x3C) || (FileName[index] == 0x3D) ||
+ (FileName[index] == 0x3E) || (FileName[index] == 0x5B) ||
+ (FileName[index] == 0x5C) || (FileName[index] == 0x5D) ||
+ (FileName[index] == 0x7C) || ((FileName[index] == 0x2E) && radix == TRUE))
+ {
+ return FALSE;
+ }
+ else
+ {
+ // Check for partial string search chars
+ if (mode == FALSE)
+ {
+ if ((FileName[index] == '*') || (FileName[index] == '?'))
+ return FALSE;
+ }
+ // only one radix ('.') character is allowed
+ if (FileName[index] == 0x2E)
+ {
+ radix = TRUE;
+ }
+ // Convert lower-case to upper-case
+ if ((FileName[index] >= 0x61) && (FileName[index] <= 0x7A))
+ FileName[index] -= 0x20;
+ }
+ }
+ return TRUE;
+}
+
+
+/**********************************************************************
+ Function:
+ int FSfseek(FSFILE *stream, long offset, int whence)
+ Summary:
+ Change the current position in a file
+ Conditions:
+ File opened
+ Input:
+ stream - Pointer to file structure
+ offset - Offset from base location
+ whence -
+ - SEEK_SET - Seek from start of file
+ - SEEK_CUR - Seek from current location
+ - SEEK_END - Seek from end of file (subtract offset)
+ Return Values:
+ 0 - Operation successful
+ -1 - Operation unsuccesful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfseek function will change the current position in the file to
+ one specified by the user. First, an absolute offset is calculated
+ using the offset and base location passed in by the user. Then, the
+ position variables are updated, and the sector number that corresponds
+ to the new location. That sector is then loaded. If the offset
+ falls exactly on a cluster boundary, a new cluster will be allocated
+ to the file and the position will be set to the first byte of that
+ cluster.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSfseek(FSFILE *stream, long offset, int whence)
+{
+ DWORD numsector, temp; // lba of first sector of first cluster
+ DISK* dsk; // pointer to disk structure
+ BYTE test;
+ long offset2 = offset;
+
+ dsk = stream->dsk;
+
+ switch(whence)
+ {
+ case SEEK_CUR:
+ // Apply the offset to the current position
+ offset2 += stream->seek;
+ break;
+ case SEEK_END:
+ // Apply the offset to the end of the file
+ offset2 = stream->size - offset2;
+ break;
+ case SEEK_SET:
+ // automatically there
+ default:
+ break;
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+#endif
+
+ // start from the beginning
+ temp = stream->cluster;
+ stream->ccls = temp;
+
+ temp = stream->size;
+
+ if (offset2 > temp)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return (-1); // past the limits
+ }
+ else
+ {
+ // if we are writing we are no longer at the end
+ stream->flags.FileWriteEOF = FALSE;
+
+ // set the new postion
+ stream->seek = offset2;
+
+ // figure out how many sectors
+ numsector = offset2 / MEDIA_SECTOR_SIZE;
+
+ // figure out how many bytes off of the offset
+ offset2 = offset2 - (numsector * MEDIA_SECTOR_SIZE);
+ stream->pos = offset2;
+
+ // figure out how many clusters
+ temp = numsector / dsk->SecPerClus;
+
+ // figure out the stranded sectors
+ numsector = numsector - (dsk->SecPerClus * temp);
+ stream->sec = numsector;
+
+ // if we are in the current cluster stay there
+ if (temp > 0)
+ {
+ test = FILEget_next_cluster(stream, temp);
+ if (test != CE_GOOD)
+ {
+ if (test == CE_FAT_EOF)
+ {
+#ifdef ALLOW_WRITES
+ if (stream->flags.write)
+ {
+ // load the previous cluster
+ stream->ccls = stream->cluster;
+ // Don't perform this operation if there's only one cluster
+ if (temp != 1)
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (FILEallocate_new_cluster(stream, 0) != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return -1;
+ }
+ // sec and pos should already be zero
+ }
+ else
+ {
+#endif
+ stream->ccls = stream->cluster;
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (test != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1);
+ }
+ stream->pos = MEDIA_SECTOR_SIZE;
+ stream->sec = dsk->SecPerClus - 1;
+#ifdef ALLOW_WRITES
+ }
+#endif
+ }
+ else
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1); // past the limits
+ }
+ }
+ }
+
+ // Determine the lba of the selected sector and load
+ temp = Cluster2Sector(dsk,stream->ccls);
+
+ // now the extra sectors
+ numsector = stream->sec;
+ temp += numsector;
+
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead(temp, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return (-1); // Bad read
+ }
+ gLastDataSectorRead = temp;
+ }
+
+ FSerrno = CE_GOOD;
+
+ return (0);
+}
+
+
+// FSfopenpgm, FSremovepgm, and FSrenamepgm will only work on PIC18s
+#ifdef __18CXX
+#ifdef ALLOW_PGMFUNCTIONS
+
+#ifdef ALLOW_WRITES
+
+/*****************************************************************
+ Function:
+ int FSrenamepgm(const rom char * fileName, FSFILE * fo)
+ Summary:
+ Rename a file named with a ROM string on PIC18
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file (in ROM)
+ fo - The file to rename
+ Return Values:
+ 0 - File renamed successfully
+ -1 - File could not be renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The Fsrenamepgm function will copy the rom fileName specified
+ by the user into a RAM array and pass that array into the
+ FSrename function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *****************************************************************/
+
+int FSrenamepgm (const rom char * fileName, FSFILE * fo)
+{
+ char F[13];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+
+ return FSrename (F, fo);
+}
+#endif
+
+/******************************************************************************
+ Function:
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+ Summary:
+ Open a file named with a ROM string on PIC18
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to be opened (ROM)
+ mode - The mode the file will be opened in (ROM)
+ Return Values:
+ FSFILE * - A pointer to the file object
+ NULL - File could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfopenpgm function will copy a PIC18 ROM fileName and mode argument
+ into RAM arrays, and then pass those arrays to the FSfopen function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ ******************************************************************************/
+
+
+FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+{
+ char F[13];
+ char M[2];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+ for (count = 0; count < 2; count++)
+ {
+ M[count] = *(mode + count);
+ }
+
+ return FSfopen(F, M);
+}
+
+/*************************************************************
+ Function:
+ int FSremovepgm (const rom char * fileName)
+ Summary:
+ Delete a file named with a ROM string on PIC18
+ Conditions:
+ File not opened; file exists
+ Input:
+ fileName - The name of the file to be deleted (ROM)
+ Return Values:
+ 0 - File was removed successfully
+ -1 - File could not be removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremovepgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FSremove function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *************************************************************/
+#ifdef ALLOW_WRITES
+int FSremovepgm (const rom char * fileName)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for(...)
+
+ return FSremove (F);
+}
+#endif
+
+/**************************************************************************************
+ Function:
+ int FindFirstpgm (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Find a file named with a ROM string on PIC18
+ Conditions:
+ None
+ Input:
+ fileName - The name of the file to be found (ROM)
+ attr - The attributes of the file to be found
+ rec - Pointer to a search record to store the file info in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the given parameters was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object will be lost.
+ The FSerrno variable will be changed.
+ Description:
+ The FindFirstpgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FindFirst function.
+ Remarks:
+ Call FindFirstpgm or FindFirst before calling FindNext.
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************************/
+#ifdef ALLOW_FILESEARCH
+int FindFirstpgm (const rom char * fileName, unsigned int attr, SearchRec * rec)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for
+
+ return FindFirst (F,attr,rec);
+}
+#endif
+#endif
+#endif
+
+
+/***********************************************
+ Function:
+ DWORD ReadFAT (DISK *dsk, DWORD ccls)
+ Summary:
+ Read the next entry from the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ Return:
+ DWORD - The next cluster in a file chain
+ Side Effects:
+ None
+ Description:
+ The ReadFAT function will read the FAT and
+ determine the next cluster value after the
+ cluster specified by 'ccls.' Note that the
+ FAT sector that is read is stored in the
+ global FAT cache buffer.
+ Remarks:
+ None.
+ ***********************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls)
+{
+ BYTE q;
+ DWORD p, l; // "l" is the sector Address
+ DWORD c, d, ClusterFailValue,LastClusterLimit; // ClusterEntries
+
+ gBufferZeroed = FALSE;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls * 4;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls *3; // Mulby1.5 to find cluster pos in FAT
+ q = p&1;
+ p >>= 1;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT12;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD)ccls *2; // Mulby 2 to find cluster pos in FAT
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ l = dsk->fat + (p >> 9); // FAT buffer has 512 bytes of size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ // Check if the appropriate FAT sector is already loaded
+ if (gLastFATSectorRead == l)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if(dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ // Check if the MSB is across the sector boundry
+ p = (p +1) & 0x1FF;
+ if (p == 0)
+ {
+ // Start by writing the sector we just worked on to the card
+ // if we need to
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+#endif
+ if (!MDD_SectorRead (l+1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l +1;
+ }
+ }
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ else
+ {
+ // If there's a currently open FAT sector,
+ // write it back before reading into the buffer
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ {
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+ }
+#endif
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF; // Note: It is Sector not Cluster.
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if (dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ p = (p +1) & 0x1FF;
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ }
+
+ // Normalize it so 0xFFFF is an error
+ if (c >= LastClusterLimit)
+ c = LastClusterLimit;
+
+ return c;
+} // ReadFAT
+
+
+
+/****************************************************************************
+ Function:
+ WORD WriteFAT (DISK *dsk, DWORD ccls, WORD value, BYTE forceWrite)
+ Summary:
+ Write an entry to the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ value - The value to write in
+ forceWrite - Force the function to write the current FAT sector
+ Return:
+ 0 - The FAT write was successful
+ FAIL - The FAT could not be written
+ Side Effects:
+ None
+ Description:
+ The WriteFAT function writes an entry to the FAT. If the function
+ is called and the 'forceWrite' argument is TRUE, the function will
+ write the existing FAT data to the device. Otherwise, the function
+ will replace a single entry in the FAT buffer (indicated by 'ccls')
+ with a new value (indicated by 'value.')
+ Remarks:
+ None.
+ ****************************************************************************/
+
+#ifdef ALLOW_WRITES
+DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite)
+{
+ BYTE i, q, c;
+ DWORD p, li, l, ClusterFailValue;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type != FAT32 && dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT32;
+#else // If FAT32 support not enabled
+ if (dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT16;
+#endif
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ gBufferZeroed = FALSE;
+
+ // The only purpose for calling this function with forceWrite
+ // is to write the current FAT sector to the card
+ if (forceWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+
+ return 0;
+ }
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls *4; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls * 3; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ q = p & 1; // Odd or even?
+ p >>= 1;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD) ccls *2; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+ }
+
+ l = dsk->fat + (p >>9); // FAt Buffer is 512 bytes size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ if (gLastFATSectorRead != l)
+ {
+ // If we are loading a new sector then write
+ // the current one to the card if we need to
+ if (gNeedFATWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+ }
+
+ // Load the new sector
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l;
+ }
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32) // Refer page 16 of FAT requirement.
+ {
+ RAMwrite (gFATBuffer, p, ((value&0x000000ff))); // lsb,1st byte of cluster value
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8));
+ RAMwrite (gFATBuffer, p+2, ((value&0x00ff0000) >> 16));
+ RAMwrite (gFATBuffer, p+3, ((value&0x0f000000) >> 24)); // the MSB nibble is supposed to be "0" in FAT32. So mask it.
+ }
+ else
+#endif
+
+ if (dsk->type == FAT16)
+ {
+ RAMwrite (gFATBuffer, p, value); //lsB
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8)); // msB
+ }
+ else if (dsk->type == FAT12)
+ {
+ // Get the current byte from the FAT
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = ((value & 0x0F) << 4) | ( c & 0x0F);
+ }
+ else
+ {
+ c = (value & 0xFF);
+ }
+ // Write in those bits
+ RAMwrite (gFATBuffer, p, c);
+
+ // FAT12 entries can cross sector boundaries
+ // Check if we need to load a new sector
+ p = (p+1) & 0x1FF;
+ if (p == 0)
+ {
+ // call this function to update the FAT on the card
+ if (WriteFAT (dsk, 0,0,TRUE))
+ return ClusterFailValue;
+ // Load the next sector
+ if (!MDD_SectorRead (l +1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l + 1;
+ }
+
+ // Get the second byte of the table entry
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = (value >> 4);
+ }
+ else
+ {
+ c = ((value >> 8) & 0x0F) | (c & 0xF0);
+ }
+ RAMwrite (gFATBuffer, p, c);
+ }
+
+ gNeedFATWrite = TRUE;
+
+ return 0;
+}
+#endif
+
+
+#ifdef ALLOW_DIRS
+
+// This string is used by dir functions to hold dir names temporarily
+char defaultString [13];
+
+
+
+/**************************************************************************
+ Function:
+ int FSchdir (char * path)
+ Summary:
+ Change the current working directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to.
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdir function passes a RAM pointer to the path to the
+ chdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSchdir (char * path)
+{
+ return chdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSchdirpgm (const rom char * path)
+ Summary:
+ Changed the CWD with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to (ROM)
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdirpgm function passes a PIC18 ROM path pointer to the
+ chdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSchdirpgm (const rom char * path)
+{
+ return chdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+ // PIC18
+ int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ Summary:
+ Helper function for FSchdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was changed successfully.
+ EOF - Directory could not be changed.
+ Side Effects:
+ The current working directory will be changed. The FSerrno variable
+ will be changed. Any unwritten data in the data buffer will be written
+ to the device.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able to
+ parse it correctly. The function will loop through a switch statement
+ to process the tokens in the path string. Dot or dotdot entries are
+ handled in the first case statement. A backslash character is handled
+ in the second case statement (note that this case statement will only
+ be used if backslash is the first character in the path; backslash
+ token delimiters will automatically be skipped after each token in the
+ path is processed). The third case statement will handle actual
+ directory name strings.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int chdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ WORD curent = 1;
+ DIRENTRY entry;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ FSFILE tempCWDobj2;
+ char tempArray[12];
+ FILEOBJ tempCWD = &tempCWDobj2;
+ FileObjectCopy (tempCWD, cwdptr);
+
+ FSerrno = CE_GOOD;
+
+ // Check the first char of the path
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+ if (i == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ while(1)
+ {
+ switch (i)
+ {
+ // First case: dot or dotdot entry
+ case '.':
+ // Move past the dot
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if it's a dotdot entry
+ if (i == '.')
+ {
+ // Increment the path variable
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if we're in the root
+ if (tempCWD->dirclus == FatRootDirClusterValue)
+ {
+ // Fails if there's a dotdot chdir from the root
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ else
+ {
+ // Cache the dotdot entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ curent = 1;
+ entry = Cache_File_Entry (tempCWD, &curent, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ tempCWD->dirclus = GetFullClusterNumber(entry); // Get Complete Cluster number.
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // If we changed to root, record the name
+ if (tempCWD->dirclus == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT) // "0" is the value of Dotdot entry for Root in both FAT types.
+ {
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+
+ /* While moving to Root, get the Root cluster value */
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Otherwise set the name to ..
+ tempCWD->name[0] = '.';
+ tempCWD->name[1] = '.';
+ for (j = 2; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ // Cache the dot entry
+ curent = 0;
+ if (Cache_File_Entry(tempCWD, &curent, TRUE) == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Move past the next backslash, if necessary
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // Copy and return, if we're at the end
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ // If we ended with a . entry,
+ // just return what we have
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ else
+ {
+ // Anything else after a dot doesn't make sense
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ }
+
+ break;
+
+ // Second case: the first char is the root backslash
+ // We will ONLY switch to this case if the first char
+ // of the path is a backslash
+ case '\\':
+ // Increment pointer to second char
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Can't start the path with multiple backslashes
+ if (i == '\\')
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == 0)
+ {
+ // The user is changing directory to
+ // the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ cwdptr->name[j] = 0x20;
+ }
+ return 0;
+ }
+ else
+ {
+ // Our first char is the root dir switch
+ tempCWD->dirclus = FatRootDirClusterValue;
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ break;
+
+ default:
+ // We should be at the beginning of a string of letters/numbers
+ j = 0;
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath2);
+ }
+ }
+ else
+ {
+#endif
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath);
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // We got a whole 12 chars
+ // There could be more- truncate it
+ if (j == 12)
+ {
+ while ((i != 0) && (i != '\\'))
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ i = *(++temppath2);
+ }
+ else
+ {
+#endif
+ i = *(++temppath);
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ }
+
+ defaultString[j] = 0;
+
+ if (FormatDirName (defaultString, 0) == FALSE)
+ return -1;
+
+ for (j = 0; j < 11; j++)
+ {
+ tempArray[j] = tempCWD->name[j];
+ tempCWD->name[j] = defaultString[j];
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, tempCWD);
+
+ // See if the directory is there
+ if(FILEfind (&gFileTemp, tempCWD, LOOK_FOR_MATCHING_ENTRY, 0) != CE_GOOD)
+ {
+ // Couldn't find the DIR
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Found the file
+ // Check to make sure it's actually a directory
+ if (gFileTemp.attributes != ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Get the new name
+ for (j = 0; j < 11; j++)
+ {
+ tempCWD->name[j] = gFileTemp.name[j];
+ }
+ tempCWD->dirclus = gFileTemp.cluster;
+ tempCWD->dirccls = tempCWD->dirclus;
+ }
+
+ if (i == 0)
+ {
+ // If we're at the end of the string, we're done
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ while (i == '\\')
+ {
+ // If we get to another backslash, increment past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ break;
+ }
+ } // loop
+}
+
+
+
+// This string is used by FSgetcwd to return the cwd name if the path
+// passed into the function is NULL
+char defaultArray [10];
+
+
+/**************************************************************
+ Function:
+ char * FSgetcwd (char * path, int numchars)
+ Summary:
+ Get the current working directory name
+ Conditions:
+ None
+ Input:
+ path - Pointer to the array to return the cwd name in
+ numchars - Number of chars in the path
+ Return Values:
+ char * - The cwd name string pointer (path or defaultArray)
+ NULL - The current working directory name could not be loaded.
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSgetcwd function will get the name of the current
+ working directory and return it to the user. The name
+ will be copied into the buffer pointed to by 'path,'
+ starting at the root directory and copying as many chars
+ as possible before the end of the buffer. The buffer
+ size is indicated by the 'numchars' argument. The first
+ thing this function will do is load the name of the current
+ working directory, if it isn't already present. This could
+ occur if the user switched to the dotdot entry of a
+ subdirectory immediately before calling this function. The
+ function will then copy the current working directory name
+ into the buffer backwards, and insert a backslash character.
+ Next, the function will continuously switch to the previous
+ directories and copy their names backwards into the buffer
+ until it reaches the root. If the buffer overflows, it
+ will be treated as a circular buffer, and data will be
+ copied over existing characters, starting at the beginning.
+ Once the root directory is reached, the text in the buffer
+ will be swapped, so that the buffer contains as much of the
+ current working directory name as possible, starting at the
+ root.
+ Remarks:
+ None
+ **************************************************************/
+char * FSgetcwd (char * path, int numchars)
+{
+ // If path is passed in as null, set up a default
+ // array with 10 characters
+ char totalchars = (path == NULL) ? 10 : numchars;
+ char * returnPointer;
+ char * bufferEnd;
+ FILEOBJ tempCWD = &gFileTemp;
+ BYTE bufferOverflow = FALSE;
+ signed char j;
+ DWORD curclus;
+ WORD fHandle, tempindex;
+ signed int i, index = 0;
+ char aChar;
+ DIRENTRY entry;
+
+ FSerrno = CE_GOOD;
+
+ // Set up the return value
+ if (path == NULL)
+ returnPointer = defaultArray;
+ else
+ {
+ returnPointer = path;
+ if (numchars == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return NULL;
+ }
+ }
+
+ bufferEnd = returnPointer + totalchars - 1;
+
+ FileObjectCopy (tempCWD, cwdptr);
+
+ if ((tempCWD->name[0] == '.') &&
+ (tempCWD->name[1] == '.'))
+ {
+ // We last changed directory into a dotdot entry
+ // Save the value of the current directory
+ curclus = tempCWD->dirclus;
+ // Put this dir's dotdot entry into the dirclus
+ // Our cwd absolutely is not the root
+ fHandle = 1;
+ tempCWD->dirccls = tempCWD->dirclus;
+ entry = Cache_File_Entry (tempCWD,&fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ // For FAT32, if the .. entry is 0, the cluster won't be 0
+#ifdef SUPPORT_FAT32
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ tempCWD->dirclus = TempClusterCalc;
+
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // Find the direntry for the entry we were just in
+ fHandle = 0;
+ entry = Cache_File_Entry (tempCWD, &fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != curclus) ||
+ ((TempClusterCalc == curclus) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME) || (entry->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ fHandle++;
+ entry = Cache_File_Entry (tempCWD, &fHandle, FALSE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // We've found the entry for the dir we were in
+ for (i = 0; i < 11; i++)
+ {
+ tempCWD->name[i] = entry->DIR_Name[i];
+ cwdptr->name[i] = entry->DIR_Name[i];
+ }
+ // Reset our temp dir back to that cluster
+ tempCWD->dirclus = curclus;
+ tempCWD->dirccls = curclus;
+ // This will set us at the cwd, but it will actually
+ // have the name in the name field this time
+ }
+ // There's actually some kind of name value in the cwd
+ if (tempCWD->name[0] == '\\')
+ {
+ // Easy, our CWD is the root
+ *returnPointer = '\\';
+ *(returnPointer + 1) = 0;
+ return returnPointer;
+ }
+ else
+ {
+ // Loop until we get back to the root
+ while (tempCWD->dirclus != FatRootDirClusterValue)
+ {
+ j = 10;
+ while (tempCWD->name[j] == 0x20)
+ j--;
+ if (j >= 8)
+ {
+ while (j >= 8)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+ *(returnPointer + index++) = '.';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ while (tempCWD->name[j] == 0x20)
+ j--;
+
+ while (j >= 0)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ // Put a backslash delimiter in front of the dir name
+ *(returnPointer + index++) = '\\';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+
+ // Load the previous entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ if (GetPreviousEntry (tempCWD))
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ return NULL;
+ }
+ }
+ }
+
+ // Point the index back at the last char in the string
+ index--;
+
+ i = 0;
+ // Swap the chars in the buffer so they are in the right places
+ if (bufferOverflow)
+ {
+ tempindex = index;
+ // Swap the overflowed values in the buffer
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+
+ // Point at the non-overflowed values
+ i = tempindex + 1;
+ index = bufferEnd - returnPointer;
+
+ // Swap the non-overflowed values into the right places
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ // All the values should be in the right place now
+ // Null-terminate the string
+ *(bufferEnd) = 0;
+ }
+ else
+ {
+ // There was no overflow, just do one set of swaps
+ tempindex = index;
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ *(returnPointer + tempindex + 1) = 0;
+ }
+
+ return returnPointer;
+}
+
+
+/**************************************************************************
+ Function:
+ void GetPreviousEntry (FSFILE * fo)
+ Summary:
+ Get the file entry info for the parent dir of the specified dir
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - The file to get the previous entry of
+ Return Values:
+ 0 - The previous entry was successfully retrieved
+ -1 - The previous entry could not be retrieved
+ Side Effects:
+ None
+ Description:
+ The GetPreviousEntry function is used by the FSgetcwd function to
+ load the previous (parent) directory. This function will load the
+ parent directory and then search through the file entries in that
+ directory for one that matches the cluster number of the original
+ directory. When the matching entry is found, the name of the
+ original directory is copied into the 'fo' FSFILE object.
+ Remarks:
+ None.
+ **************************************************************************/
+
+BYTE GetPreviousEntry (FSFILE * fo)
+{
+ BYTE i;
+ WORD fHandle = 1;
+ DWORD dirclus;
+ DIRENTRY dirptr;
+
+ // Load the previous entry
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ // The previous directory is the root
+ fo->name[0] = '\\';
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = 0x20;
+ }
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Get the directory name
+ // Save the previous cluster value
+ // Get the cluster
+
+ dirclus = TempClusterCalc;
+ fo->dirclus = TempClusterCalc;
+ fo->dirccls = TempClusterCalc;
+
+
+ // Load the previous previous cluster
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+#ifdef SUPPORT_FAT32
+ // If we're using FAT32 and the previous previous cluster is the root, the
+ // value in the dotdot entry will be 0, but the actual cluster won't
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ fo->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ fo->dirclus = TempClusterCalc;
+
+ fo->dirccls = fo->dirclus;
+
+ fHandle = 0;
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+ // Look through it until we get the name
+ // of the previous cluster
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+ while ((TempClusterCalc != dirclus) ||
+ ((TempClusterCalc == dirclus) &&
+ (((unsigned char)dirptr->DIR_Name[0] == 0xE5) || (dirptr->DIR_Attr == ATTR_VOLUME) || (dirptr->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ // Look through the entries until we get the
+ // right one
+ dirptr = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dirptr == NULL)
+ return -1;
+ fHandle++;
+
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number in a loop.
+ }
+
+ // The name should be in the entry now
+ // Copy the actual directory location back
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = dirptr->DIR_Name[i];
+ }
+ fo->dirclus = dirclus;
+ fo->dirccls = dirclus;
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+ Function:
+ int FSmkdir (char * path)
+ Summary:
+ Create a directory
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create.
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdir function passes a RAM pointer to the path to the
+ mkdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSmkdir (char * path)
+{
+ return mkdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSmkdirpgm (const rom char * path)
+ Summary:
+ Create a directory with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create (ROM)
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdirpgm function passes a PIC18 ROM path pointer to the
+ mkdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arugments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSmkdirpgm (const rom char * path)
+{
+ return mkdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+ // PIC18
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+ Summary:
+ Helper function for FSmkdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was created
+ -1 - Directory could not be created
+ Side Effects:
+ Will create all non-existant directories in the path.
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first scan through the path
+ to ensure that any DIR names don't exceed 11 characters. It will then
+ backup the current working directory and begin changing directories
+ through the path until it reaches a directory than can't be changed to.
+ It will then create the specified directory and change directories to
+ the new directory. The function will continue creating and changing to
+ directories until the end of the path is reached. The function will
+ then restore the original current working directory.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ char tempArray[13];
+ FILEOBJ tempCWD = &tempCWDobj;
+
+#ifdef __18CXX
+ char dotdotPath[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath2 != 0) && (*temppath2 != '.')&& (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath2 == '.')
+ {
+ temppath2++;
+ i = 0;
+ while ((*temppath2 != 0) && (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath2 == '\\')
+ temppath2++;
+ if (*temppath2 == 0)
+ break;
+ }
+ }
+ else
+#endif
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath != 0) && (*temppath != '.')&& (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath == '.')
+ {
+ temppath++;
+ i = 0;
+ while ((*temppath != 0) && (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath == '\\')
+ temppath++;
+ if (*temppath == 0)
+ break;
+ }
+
+ temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ temppath2 = romptr;
+#endif
+
+ // We're going to be moving the CWD
+ // Back up the CWD
+ FileObjectCopy (tempCWD, cwdptr);
+
+ // get to the target directory
+ while (1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+
+ if (i == '.')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ if ((i != '.') && (i != 0) && (i != '\\'))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == '.')
+ {
+ if (cwdptr->dirclus == FatRootDirClusterValue)
+ {
+ // If we try to change to the .. from the
+ // root, operation fails
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if ((i != '\\') && (i != 0))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+// dotdot entry
+#ifndef __18CXX
+ FSchdir ("..");
+#else
+ FSchdir (dotdotPath);
+#endif
+ }
+ // Skip past any backslashes
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ // No point in creating a dot or dotdot entry directly
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ // Start at the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (i = 1; i < 11; i++)
+ {
+ cwdptr->name[i] = 0x20;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // If we just got two backslashes in a row at the
+ // beginning of the path, the function fails
+ if (i == '\\')
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (i == 0)
+ {
+ // We can't make the root dir
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ tempArray[12] = 0;
+ while (1)
+ {
+ while(1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Change directories as specified
+ i = *temppath2;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ // Change directories as specified
+ i = *temppath;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ tempArray[j] = 0;
+
+ if (tempArray[0] == '.')
+ {
+ if ((tempArray[1] != 0) && (tempArray[1] != '.'))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if ((tempArray[1] == '.') && (tempArray[2] != 0))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+
+ // Try to change to it
+ // If you can't we need to create it
+ if (FSchdir (tempArray))
+ {
+ break;
+ }
+ else
+ {
+ // We changed into the directory
+ while (i == '\\')
+ {
+ // Next char is a backslash
+ // Move past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // If it's the last one, return success
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+
+ // Create a dir here
+ if (!CreateDIR (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ // Try to change to that directory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Check for another backslash
+ while (*temppath2 == '\\')
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ while (*temppath == '\\')
+ {
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Check to see if we're at the end of the path string
+ if (i == 0)
+ {
+ // We already have one
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+}
+
+
+/**************************************************************************
+ Function:
+ int CreateDIR (char * path)
+ Summary:
+ FSmkdir helper function to create a directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the dir to create
+ Return Values:
+ TRUE - Directory was created successfully
+ FALSE - Directory could not be created.
+ Side Effects:
+ Any unwritten data in the data buffer or the FAT buffer will be written
+ to the device.
+ Description:
+ The CreateDIR function is a helper function for the mkdirhelper
+ function. The CreateDIR function will create a new file entry for
+ a directory and assign a cluster to it. It will erase the cluster
+ and write a dot and dotdot entry to it.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int CreateDIR (char * path)
+{
+ FSFILE * dirEntryPtr = &gFileTemp;
+ DIRENTRY dir;
+ WORD handle = 0;
+ DWORD dot, dotdot;
+ BYTE i;
+
+ for (i = 0; i < 12; i++)
+ {
+ defaultString[i] = *(path + i);
+ }
+
+ if (FormatDirName(defaultString, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return FALSE;
+ }
+
+ // Copy name into file object
+ for (i = 0; i < 11; i++)
+ {
+ dirEntryPtr->name[i] = defaultString[i];
+ }
+
+ dirEntryPtr->dirclus = cwdptr->dirclus;
+ dirEntryPtr->dirccls = cwdptr->dirccls;
+ dirEntryPtr->cluster = 0;
+ dirEntryPtr->ccls = 0;
+ dirEntryPtr->dsk = cwdptr->dsk;
+
+ // Create a directory entry
+ if(CreateFileEntry(dirEntryPtr, &handle, DIRECTORY) != CE_GOOD)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (gNeedFATWrite)
+ if(WriteFAT (dirEntryPtr->dsk, 0, 0, TRUE))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+ // Zero that cluster
+ if (dirEntryPtr->dirclus == FatRootDirClusterValue)
+ dotdot = 0;
+ else
+ dotdot = dirEntryPtr->dirclus;
+ dirEntryPtr->dirccls = dirEntryPtr->dirclus;
+ dir = Cache_File_Entry(dirEntryPtr, &handle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return FALSE;
+ }
+
+ // Get the cluster
+ dot = GetFullClusterNumber(dir); // Get complete cluster number.
+
+ if (writeDotEntries (dirEntryPtr->dsk, dot, dotdot))
+ return TRUE;
+ else
+ return FALSE;
+
+ }
+}
+
+
+/***********************************************************************************
+ Function:
+ BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+ Summary:
+ Create dot and dotdot entries in a non-root directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - The global disk structure
+ dotAddress - The cluster the current dir is in
+ dotdotAddress - The cluster the previous directory was in
+ Return Values:
+ TRUE - The dot and dotdot entries were created
+ FALSE - The dot and dotdot entries could not be created in the new directory
+ Side Effects:
+ None
+ Description:
+ The writeDotEntries function will create and write dot and dotdot entries
+ to a newly created directory.
+ Remarks:
+ None.
+ ***********************************************************************************/
+
+BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+{
+ WORD i;
+ WORD size;
+ _DIRENTRY entry;
+ DIRENTRY entryptr = &entry;
+ DWORD sector;
+
+ gBufferOwner = NULL;
+
+ size = sizeof (_DIRENTRY);
+
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ entry.DIR_Name[0] = '.';
+
+ for (i = 1; i < 11; i++)
+ {
+ entry.DIR_Name[i] = 0x20;
+ }
+ entry.DIR_Attr = ATTR_DIRECTORY;
+ entry.DIR_NTRes = 0x00;
+
+ entry.DIR_FstClusLO = (WORD)(dotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+ entry.DIR_FileSize = 0x00;
+
+// Times need to be the same as the times in the directory entry
+
+// Set dir date for uncontrolled clock source
+#ifdef INCREMENTTIMESTAMP
+ entry.DIR_CrtTimeTenth = 0xB2;
+ entry.DIR_CrtTime = 0x7278;
+ entry.DIR_CrtDate = 0x32B0;
+ entry.DIR_LstAccDate = 0x0000;
+ entry.DIR_WrtTime = 0x0000;
+ entry.DIR_WrtDate = 0x0000;
+#endif
+
+#ifdef USEREALTIMECLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i) = *((char *)entryptr + i);
+ }
+ entry.DIR_Name[1] = '.';
+
+ entry.DIR_FstClusLO = (WORD)(dotdotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotdotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i + size) = *((char *)entryptr + i);
+ }
+
+ sector = Cluster2Sector (disk, dotAddress);
+
+ if (MDD_SectorWrite(sector, disk->buffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// This array is used to prevent a stack frame error
+#ifdef __18CXX
+ char tempArray[13] = " ";
+#endif
+
+
+/**************************************************************************
+ Function:
+ int FSrmdir (char * path)
+ Summary:
+ Delete a directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to remove
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdir function passes a RAM pointer to the path to the
+ rmdirhelper function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int FSrmdir (char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (0, path, NULL, rmsubdirs);
+}
+
+/**************************************************************************
+ Function:
+ int FSrmdirpgm (const rom char * path)
+ Summary:
+ Delete a directory with a path in ROM on PIC18
+ Conditions:
+ None.
+ Input:
+ path - The path of the directory to remove (ROM)
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdirpgm function passes a PIC18 ROM path pointer to the
+ rmdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSrmdirpgm (const rom char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (1, NULL, path, rmsubdirs);
+}
+#endif
+
+/************************************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+ // PIC18
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+ Summary:
+ Helper function for FSrmdir
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The path of the dir to delete
+ rmsubdirs -
+ - TRUE - Remove all sub-directories and files in the directory
+ - FALSE - Non-empty directories can not be removed
+ Return Values:
+ 0 - The specified directory was successfully removed.
+ EOF - The specified directory could not be removed.
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSmkdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first change to the
+ specified directory. If the rmsubdirs argument is FALSE the function
+ will search through the directory to ensure that it is empty and then
+ remove it. If the rmsubdirs argument is TRUE the function will also
+ search through the directory for subdirectories or files. When the
+ function finds a file, the file will be erased. When the function
+ finds a subdirectory, it will switch to the subdirectory and begin
+ removing all of the files in that subdirectory. Once the subdirectory
+ is empty, the function will switch back to the original directory.
+ return to the original position in that directory, and continue removing
+ files. Once the specified directory is empty, the function will
+ change to the parent directory, search through it for the directory
+ to remove, and then erase that directory.
+ Remarks:
+ None.
+ ************************************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+#else
+int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+#endif
+{
+ FILEOBJ tempCWD = &tempCWDobj;
+ FILEOBJ fo = &gFileTemp;
+ DIRENTRY entry;
+ WORD handle = 0;
+ WORD handle2;
+ WORD subDirDepth;
+ BYTE Index, Index2;
+
+#ifndef __18CXX
+ char tempArray[13] = " ";
+#else
+ char dotdotname[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ // Back up the current working directory
+ FileObjectCopy (tempCWD, cwdptr);
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ if (chdirhelper (1, NULL, romptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ }
+ else
+ {
+#endif
+ if (FSchdir (ramptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Make sure we aren't trying to remove the root dir or the CWD
+ if ((cwdptr->dirclus == FatRootDirClusterValue) || (cwdptr->dirclus == tempCWD->dirclus))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Don't remove subdirectories and sub-files
+ if (!rmsubdirs)
+ {
+ while (entry->DIR_Name[0] != 0)
+ {
+ if ((unsigned char)entry->DIR_Name[0] != 0xE5)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_EMPTY;
+ return -1;
+ }
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if ((entry == NULL))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ // Do remove subdirectories and sub-files
+ dirCleared = FALSE;
+ subDirDepth = 0;
+
+ while (!dirCleared)
+ {
+ if (entry->DIR_Name[0] != 0)
+ {
+ if (((unsigned char)entry->DIR_Name[0] != 0xE5) && (entry->DIR_Attr != ATTR_VOLUME) && (entry->DIR_Attr != ATTR_LONG_NAME))
+ {
+ if ((entry->DIR_Attr & ATTR_DIRECTORY) == ATTR_DIRECTORY)
+ {
+ // We have a directory
+ subDirDepth++;
+ for (Index = 0; (Index < DIR_NAMESIZE) && (entry->DIR_Name[Index] != 0x20); Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (entry->DIR_Name[8] != 0x20)
+ {
+ tempArray[Index++] = '.';
+ for (Index2 = 0; (Index2 < DIR_EXTENSION) && (entry->DIR_Name[Index2 + DIR_NAMESIZE] != 0x20); Index2++)
+ {
+ tempArray[Index++] = entry->DIR_Name[Index2 + DIR_NAMESIZE];
+ }
+ }
+ tempArray[Index] = 0;
+ // Change to the subdirectory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Make sure we're not trying to delete the CWD
+ if (cwdptr->dirclus == tempCWD->dirclus)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ handle = 2;
+ recache = TRUE;
+ }
+ else
+ {
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ fo->name[Index] = entry->DIR_Name[Index];
+ }
+
+ fo->dsk = &gDiskData;
+
+ fo->entry = handle;
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+ fo->cluster = 0;
+ fo->ccls = 0;
+
+ if (FILEerase(fo, &handle, TRUE))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ }
+ } // Check to see if it's a DIR entry
+ }// Check non-dir entry to see if its a valid file
+ else
+ {
+ handle++;
+ }
+ if (recache)
+ {
+ recache = FALSE;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ }
+ else
+ {
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ }
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ else
+ {
+ // We have reached the end of the directory
+ if (subDirDepth != 0)
+ {
+ handle2 = 0;
+
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle2, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ handle2 = GetFullClusterNumber(entry); // Get complete cluster number.
+
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ // Return to our previous position in this directory
+ handle = 2;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != handle2) ||
+ ((TempClusterCalc == handle2) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME))))
+ {
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // Erase the directory that we just cleared the subdirectories out of
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+
+ // Decrease the subdirectory depth
+ subDirDepth--;
+ }
+ else
+ {
+ dirCleared = TRUE;
+ } // Check subdirectory depth
+ } // Check until we get an empty entry
+ } // Loop until the whole dir is cleared
+ }
+
+ // Cache the current directory name
+ // tempArray is used so we don't disturb the
+ // global getcwd buffer
+ if (FSgetcwd (tempArray, 12) == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ memset(tempArray, 0x00, 12);
+
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = cwdptr->name[Index];
+ }
+
+ // If we're here, this directory is empty
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+}
+
+
+/****************************************************************
+ Function:
+ int eraseDir (char * path)
+ Summary:
+ FSrmdir helper function to erase dirs
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the directory to delete
+ Return Values:
+ 0 - Dir was deleted successfully
+ -1 - Dir could not be deleted.
+ Side Effects:
+ None
+ Description:
+ The eraseDir function is a helper function for the rmdirhelper
+ function. The eraseDir function will search for the
+ directory that matches the specified path name and then erase
+ it with the FILEerase function.
+ Remarks:
+ None.
+ *****************************************************************/
+
+int eraseDir (char * path)
+{
+ CETYPE result;
+ BYTE Index;
+ FSFILE tempCWDobj2;
+
+ if (MDD_WriteProtectState())
+ {
+ return (-1);
+ }
+
+ // preserve CWD
+ FileObjectCopy(&tempCWDobj2, cwdptr);
+
+ for (Index = 0; Index <11; Index++)
+ {
+ cwdptr->name[Index] = *(path + Index);
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, cwdptr);
+
+ // See if the file is found
+ result = FILEfind (cwdptr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+ result = FILEerase(cwdptr, &cwdptr->entry, TRUE);
+ if( result == CE_GOOD )
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return 0;
+ }
+ else
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+}
+#endif
+
+
+
+#endif
+
+
+#ifdef ALLOW_FILESEARCH
+
+
+/***********************************************************************************
+ Function:
+ int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Initial search function
+ Conditions:
+ None
+ Input:
+ fileName - The name to search for
+ - Parital string search characters
+ - * - Indicates the rest of the filename or extension can vary (e.g. FILE.*)
+ - ? - Indicates that one character in a filename can vary (e.g. F?LE.T?T)
+ attr - The attributes that a found file may have
+ - ATTR_READ_ONLY - File may be read only
+ - ATTR_HIDDEN - File may be a hidden file
+ - ATTR_SYSTEM - File may be a system file
+ - ATTR_VOLUME - Entry may be a volume label
+ - ATTR_DIRECTORY - File may be a directory
+ - ATTR_ARCHIVE - File may have archive attribute
+ - ATTR_MASK - All attributes
+ rec - pointer to a structure to put the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the specified criteria was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object
+ will be lost. The FSerrno variable will be changed.
+ Description:
+ The FindFirst function will search for a file based on parameters passed in
+ by the user. This function will use the FILEfind function to parse through
+ the current working directory searching for entries that match the specified
+ parameters. If a file is found, its parameters are copied into the SearchRec
+ structure, as are the initial parameters passed in by the user and the position
+ of the file entry in the current working directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling FindNext
+ ***********************************************************************************/
+
+int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ WORD fHandle;
+ BYTE j;
+ BYTE Index;
+
+ FSerrno = CE_GOOD;
+
+ if( !FormatFileName(fileName, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ rec->initialized = FALSE;
+
+ for (Index = 0; (Index < 12) && (fileName[Index] != 0); Index++)
+ {
+ rec->searchname[Index] = fileName[Index];
+ }
+ rec->searchname[Index] = 0;
+ rec->searchattr = attr;
+#ifdef ALLOW_DIRS
+ rec->cwdclus = cwdptr->dirclus;
+#else
+ rec->cwdclus = FatRootDirClusterValue;
+#endif
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = attr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ fHandle = fo->entry;
+ result = FILEopen (fo, &fHandle, 'r');
+ }
+ if (result == CE_GOOD)
+ {
+ // Copy as much name as there is
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (Index = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[Index++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[Index] = 0;
+ }
+ else
+ {
+ for (Index = 0; Index < DIR_NAMECOMP; Index++)
+ {
+ rec->filename[Index] = fo->name[Index];
+ }
+ rec->filename[Index] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ rec->initialized = TRUE;
+ return 0;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+}
+
+
+/**********************************************************************
+ Function:
+ int FindNext (SearchRec * rec)
+ Summary:
+ Sequential search function
+ Conditions:
+ None
+ Input:
+ rec - The structure to store the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No additional files matching the specified criteria were found
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FindNext function performs the same function as the FindFirst
+ funciton, except it does not copy any search parameters into the
+ SearchRec structure (only info about found files) and it begins
+ searching at the last directory entry offset at which a file was
+ found, rather than at the beginning of the current working
+ directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling this function
+ **********************************************************************/
+
+int FindNext (SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ BYTE i, j;
+
+ FSerrno = CE_GOOD;
+
+ // Make sure we called FindFirst on this object
+ if (rec->initialized == FALSE)
+ {
+ FSerrno = CE_NOT_INIT;
+ return -1;
+ }
+
+ // Make sure we called FindFirst in the cwd
+#ifdef ALLOW_DIRS
+ if (rec->cwdclus != cwdptr->dirclus)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#endif
+
+ if( !FormatFileName(rec->searchname, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ /* Brn: Copy the formatted name to "fo" which is necesary before calling "FILEfind" function */
+ //strcpy(fo->name,rec->searchname);
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = rec->entry + 1;
+ fo->attributes = rec->searchattr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (i = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[i++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[i] = 0;
+ }
+ else
+ {
+ for (i = 0; i < DIR_NAMECOMP; i++)
+ {
+ rec->filename[i] = fo->name[i];
+ }
+ rec->filename[i] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ return 0;
+ }
+}
+
+
+#endif
+
+
+
+#ifdef ALLOW_FSFPRINTF
+
+
+
+/**********************************************************************
+ Function:
+ int FSputc (char c, FSFILE * file)
+ Summary:
+ FSfprintf helper function to write a char
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ c - The character to write to the file.
+ file - The file to write to.
+ Return Values:
+ 0 - The character was written successfully
+ EOF - The character was not written to the file.
+ Side Effects:
+ None
+ Description:
+ This is a helper function for FSfprintf. It will write one
+ character to a file.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSputc (char c, FSFILE * file)
+{
+ if (FSfwrite ((void *)&c, 1, 1, file) != 1)
+ return EOF;
+ else
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ int str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+ Summary:
+ FSfprintf helper function to write a char multiple times
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - The file to write to.
+ n - The number of times to write that character to a file.
+ c - The character to write to the file.
+ Return Values:
+ 0 - The characters were written successfully
+ EOF - The characters were not written to the file.
+ Side Effects:
+ None
+ Description:
+ This funciton is used by the FSfprintf function to write multiple
+ instances of a single character to a file (for example, when
+ padding a format specifier with leading spacez or zeros).
+ Remarks:
+ None.
+ **********************************************************************/
+
+
+unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+{
+ while (n--)
+ if (FSputc (c, handle) == EOF)
+ return 1;
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSfprintf (FSFILE * fptr, const char * fmt, ...)
+ // PIC18
+ int FSfpritnf (FSFILE * fptr, const rom char * fmt, ...)
+ Summary:
+ Function to write formatted strings to a file
+ Conditions:
+ For PIC18, integer promotion must be enabled in the project build
+ options menu. File opened in a write mode.
+ Input:
+ fptr - A pointer to the file to write to.
+ fmt - A string of characters and format specifiers to write to
+ the file
+ ... - Additional arguments inserted in the string by format
+ specifiers
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Writes a specially formatted string to a file.
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSfprintf (FSFILE *fptr, const rom char *fmt, ...)
+#else
+int FSfprintf (FSFILE *fptr, const char * fmt, ...)
+#endif
+{
+ va_list ap;
+ int n;
+
+ va_start (ap, fmt);
+ n = FSvfprintf (fptr, fmt, ap);
+ va_end (ap);
+ return n;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSvfprintf (FSFILE * handle, const char * formatString, va_list ap)
+ // PIC18
+ int FSvfpritnf (auto FSFILE * handle, auto const rom char * formatString, auto va_list ap)
+ Summary:
+ Helper function for FSfprintf
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - A pointer to the file to write to.
+ formatString - A string of characters and format specifiers to write to
+ the file
+ ap - A structure pointing to the arguments on the stack
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function will access the elements passed to FSfprintf
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSvfprintf (auto FSFILE *handle, auto const rom char * formatString, auto va_list ap)
+#else
+int FSvfprintf (FSFILE *handle, const char * formatString, va_list ap)
+#endif
+{
+ unsigned char c;
+ int count = 0;
+
+ for (c = *formatString; c; c = *++formatString)
+ {
+ if (c == '%')
+ {
+ unsigned char flags = 0;
+ unsigned char width = 0;
+ unsigned char precision = 0;
+ unsigned char have_precision = 0;
+ unsigned char size = 0;
+#ifndef __18CXX
+ unsigned char size2 = 0;
+#endif
+ unsigned char space_cnt;
+ unsigned char cval;
+#ifdef __18CXX
+ unsigned long larg;
+ far rom char * romstring;
+#else
+ unsigned long long larg;
+#endif
+ char * ramstring;
+ int n;
+
+ FSerrno = CE_GOOD;
+
+ c = *++formatString;
+
+ while (c == '-' || c == '+' || c == ' ' || c == '#'
+ || c == '0')
+ {
+ switch (c)
+ {
+ case '-':
+ flags |= _FLAG_MINUS;
+ break;
+ case '+':
+ flags |= _FLAG_PLUS;
+ break;
+ case ' ':
+ flags |= _FLAG_SPACE;
+ break;
+ case '#':
+ flags |= _FLAG_OCTO;
+ break;
+ case '0':
+ flags |= _FLAG_ZERO;
+ break;
+ }
+ c = *++formatString;
+ }
+ /* the optional width field is next */
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n < 0)
+ {
+ flags |= _FLAG_MINUS;
+ width = -n;
+ }
+ else
+ width = n;
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ width = cval;
+ }
+
+ /* if '-' is specified, '0' is ignored */
+ if (flags & _FLAG_MINUS)
+ flags &= ~_FLAG_ZERO;
+
+ /* the optional precision field is next */
+ if (c == '.')
+ {
+ c = *++formatString;
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n >= 0)
+ {
+ precision = n;
+ have_precision = 1;
+ }
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ precision = cval;
+ have_precision = 1;
+ }
+ }
+
+ /* the optional 'h' specifier. since int and short int are
+ the same size for MPLAB C18, this is a NOP for us. */
+ if (c == 'h')
+ {
+ c = *++formatString;
+ /* if 'c' is another 'h' character, this is an 'hh'
+ specifier and the size is 8 bits */
+ if (c == 'h')
+ {
+ size = _FMT_BYTE;
+ c = *++formatString;
+ }
+ }
+ else if (c == 't' || c == 'z')
+ c = *++formatString;
+#ifdef __18CXX
+ else if (c == 'H' || c == 'T' || c == 'Z')
+ {
+ size = _FMT_SHRTLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l' || c == 'j')
+#else
+ else if (c == 'q' || c == 'j')
+ {
+ size = _FMT_LONGLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l')
+#endif
+ {
+ size = _FMT_LONG;
+ c = *++formatString;
+ }
+
+ switch (c)
+ {
+ case '\0':
+ /* this is undefined behaviour. we have a trailing '%' character
+ in the string, perhaps with some flags, width, precision
+ stuff as well, but no format specifier. We'll, arbitrarily,
+ back up a character so that the loop will terminate
+ properly when it loops back and we'll output a '%'
+ character. */
+ --formatString;
+ /* fallthrough */
+ case '%':
+ if (FSputc ('%', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ break;
+ case 'c':
+ space_cnt = 0;
+ if (width > 1)
+ {
+ space_cnt = width - 1;
+ count += space_cnt;
+ }
+ if (space_cnt && !(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ c = va_arg (ap, int);
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'S':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ romstring = va_arg (ap, rom far char *);
+ else
+ romstring = (far rom char*)va_arg (ap, rom near char *);
+ n = strlenpgm (romstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the
+ string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *romstring; c && cval < width; c = *++romstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+#endif
+ case 's':
+ ramstring = va_arg (ap, char *);
+ n = strlen (ramstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *ramstring; c && cval < width; c = *++ramstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'd':
+ case 'i':
+ flags |= _FLAG_SIGNED;
+ /* fall through */
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'b':
+ case 'B':
+ /* This is a bit of a trick. The 'l' and 'hh' size
+ specifiers are valid only for the integer conversions,
+ not the 'p' or 'P' conversions, and are ignored for the
+ latter. By jumping over the additional size specifier
+ checks here we get the best code size since we can
+ limit the size checks in the remaining code. */
+ if (size == _FMT_LONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, long int);
+ else
+ larg = va_arg (ap, unsigned long int);
+ goto _do_integer_conversion;
+ }
+ else if (size == _FMT_BYTE)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed char) va_arg (ap, int);
+ else
+ larg = (unsigned char) va_arg (ap, unsigned int);
+ goto _do_integer_conversion;
+ }
+#ifndef __18CXX
+ else if (size == _FMT_LONGLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed long long)va_arg (ap, long long);
+ else
+ larg = (unsigned long long) va_arg (ap, unsigned long long);
+ goto _do_integer_conversion;
+ }
+#endif
+ /* fall trough */
+ case 'p':
+ case 'P':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, short long int);
+ else
+ larg = va_arg (ap, unsigned short long int);
+ }
+ else
+#endif
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, int);
+ else
+ larg = va_arg (ap, unsigned int);
+ _do_integer_conversion:
+ /* default precision is 1 */
+ if (!have_precision)
+ precision = 1;
+ {
+ unsigned char digit_cnt = 0;
+ unsigned char prefix_cnt = 0;
+ unsigned char sign_char;
+ /* A 32 bit number will require at most 32 digits in the
+ string representation (binary format). */
+#ifdef __18CXX
+ char buf[33];
+ /* Start storing digits least-significant first */
+ char *q = &buf[31];
+ /* null terminate the string */
+ buf[32] = '\0';
+#else
+ char buf[65];
+ char *q = &buf[63];
+ buf[64] = '\0';
+#endif
+ space_cnt = 0;
+ size = 10;
+
+ switch (c)
+ {
+ case 'b':
+ case 'B':
+ size = 2;
+#ifndef __18CXX
+ size2 = 1;
+#endif
+ break;
+ case 'o':
+ size = 8;
+#ifndef __18CXX
+ size2 = 3;
+#endif
+ break;
+ case 'p':
+ case 'P':
+ /* from here on out, treat 'p' conversions just
+ like 'x' conversions. */
+ c += 'x' - 'p';
+ /* fall through */
+ case 'x':
+ case 'X':
+ size = 16;
+#ifndef __18CXX
+ size2 = 4;
+#endif
+ break;
+ }// switch (c)
+
+ /* if it's an unsigned conversion, we should ignore the
+ ' ' and '+' flags */
+ if (!(flags & _FLAG_SIGNED))
+ flags &= ~(_FLAG_PLUS | _FLAG_SPACE);
+
+ /* if it's a negative value, we need to negate the
+ unsigned version before we convert to text. Using
+ unsigned for this allows us to (ab)use the 2's
+ complement system to avoid overflow and be able to
+ adequately handle LONG_MIN.
+
+ We'll figure out what sign character to print, if
+ any, here as well. */
+#ifdef __18CXX
+ if (flags & _FLAG_SIGNED && ((long) larg < 0))
+ {
+ larg = -(long) larg;
+#else
+ if (flags & _FLAG_SIGNED && ((long long) larg < 0))
+ {
+ larg = -(long long) larg;
+#endif
+ sign_char = '-';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_PLUS)
+ {
+ sign_char = '+';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_SPACE)
+ {
+ sign_char = ' ';
+ ++digit_cnt;
+ }
+ else
+ sign_char = '\0';
+ /* get the digits for the actual number. If the
+ precision is zero and the value is zero, the result
+ is no characters. */
+ if (precision || larg)
+ {
+ do
+ {
+#ifdef __18CXX
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ larg /= size;
+#else
+ // larg is congruent mod size2 to its lower 16 bits
+ // for size2 = 2^n, 0 <= n <= 4
+ if (size2 != 0)
+ cval = s_digits[(unsigned int) larg % size];
+ else
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ if (size2 != 0)
+ larg = larg >> size2;
+ else
+ larg /= size;
+#endif
+ *q-- = cval;
+ ++digit_cnt;
+ } while (larg);
+ /* if the '#' flag was specified and we're dealing
+ with an 'o', 'b', 'B', 'x', or 'X' conversion,
+ we need a bit more. */
+ if (flags & _FLAG_OCTO)
+ {
+ if (c == 'o')
+ {
+ /* per the standard, for octal, the '#' flag
+ makes the precision be at least one more
+ than the number of digits in the number */
+ if (precision <= digit_cnt)
+ precision = digit_cnt + 1;
+ }
+ else if (c == 'x' || c == 'X' || c == 'b' || c == 'B')
+ prefix_cnt = 2;
+ }
+ }
+ else
+ digit_cnt = 0;
+
+ /* The leading zero count depends on whether the '0'
+ flag was specified or not. If it was not, then the
+ count is the difference between the specified
+ precision and the number of digits (including the
+ sign character, if any) to be printed; otherwise,
+ it's as if the precision were equal to the max of
+ the specified precision and the field width. If a
+ precision was specified, the '0' flag is ignored,
+ however. */
+ if ((flags & _FLAG_ZERO) && (width > precision)
+ && !have_precision)
+ precision = width;
+ /* for the rest of the processing, precision contains
+ the leading zero count for the conversion. */
+ if (precision > digit_cnt)
+ precision -= digit_cnt;
+ else
+ precision = 0;
+ /* the space count is the difference between the field
+ width and the digit count plus the leading zero
+ count. If the width is less than the digit count
+ plus the leading zero count, the space count is
+ zero. */
+ if (width > precision + digit_cnt + prefix_cnt)
+ space_cnt = width - precision - digit_cnt - prefix_cnt;
+
+ /* for output, we check the justification, if it's
+ right justified and the space count is positive, we
+ emit the space characters first. */
+ if (!(flags & _FLAG_MINUS) && space_cnt)
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ count += space_cnt;
+ space_cnt = 0;
+ }
+ /* if we have a sign character to print, that comes
+ next */
+ if (sign_char)
+ if (FSputc (sign_char, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if we have a prefix (0b, 0B, 0x or 0X), that's next */
+ if (prefix_cnt)
+ {
+ if (FSputc ('0', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ }
+ /* if we have leading zeros, they follow. the prefix, if any
+ is included in the number of digits when determining how
+ many leading zeroes are needed. */
+// if (precision > prefix_cnt)
+ // precision -= prefix_cnt;
+ if (str_put_n_chars (handle, precision, '0'))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* print the actual number */
+ for (cval = *++q; cval; cval = *++q)
+ if (FSputc (cval, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if there are any spaces left, they go to right-pad
+ the field */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ count += precision + digit_cnt + space_cnt + prefix_cnt;
+ }
+ break;
+ case 'n':
+ switch (size)
+ {
+ case _FMT_LONG:
+ *(long *) va_arg (ap, long *) = count;
+ break;
+#ifdef __18CXX
+ case _FMT_SHRTLONG:
+ *(short long *) va_arg (ap, short long *) = count;
+ break;
+#else
+ case _FMT_LONGLONG:
+ *(long long *) va_arg (ap, long long *) = count;
+ break;
+#endif
+ case _FMT_BYTE:
+ *(signed char *) va_arg (ap, signed char *) = count;
+ break;
+ default:
+ *(int *) va_arg (ap, int *) = count;
+ break;
+ }
+ break;
+ default:
+ /* undefined behaviour. we do nothing */
+ break;
+ }
+ }
+ else
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ }
+ }
+ return count;
+}
+
+
+
+#endif
+
+
+
+
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.d b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.d new file mode 100644 index 00000000..11aa75db --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.d @@ -0,0 +1,60 @@ +FSIO.o: FSIO.c FSIO.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h FSconfig.h \
+ C:/Microchip\ Solutions/Microchip/Include/Compiler.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/string.h \
+ HardwareProfile.h FSDefs.h SD-SPI.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/ctype.h \
+ C:/Microchip\ Solutions/Microchip/Include/MDD\ File\ System\FSDefs.h
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.h new file mode 100644 index 00000000..5c2e4cea --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSIO.h @@ -0,0 +1,1364 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: FSIO.h
+ * Dependencies: GenericTypeDefs.h
+ * FSconfig.h
+ * FSDefs.h
+ * stddef.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#ifndef FS_DOT_H
+#define FS_DOT_H
+
+#include "GenericTypeDefs.h"
+#include "FSconfig.h"
+#include "FSDefs.h"
+#include "stddef.h"
+
+#ifdef USE_SD_INTERFACE_WITH_SPI
+ #include "SD-SPI.h"
+#endif
+#ifdef USE_CF_INTERFACE_WITH_PMP
+ #include "MDD File System\CF-PMP.h"
+#endif
+#ifdef USE_MANUAL_CF_INTERFACE
+ #include "MDD File System\CF- Bit transaction.h"
+#endif
+#ifdef USE_USB_INTERFACE
+ #include "USB\usb_host_msd_scsi.h"
+#endif
+
+
+/*******************************************************************/
+/* Strunctures and defines */
+/*******************************************************************/
+
+#ifndef FALSE
+ // Summary: False value
+ // Description: This macro will indicate that a condition is false.
+ #define FALSE 0
+#endif
+#ifndef TRUE
+ // Summary: True value
+ // Description: This macro will indicate that a condition is true.
+ #define TRUE !FALSE // True value
+#endif
+
+
+
+
+#ifndef SEEK_SET
+ // Summary: Macro for the FSfseek SEEK_SET base location.
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the beginning of the file.
+ #define SEEK_SET 0
+
+#endif
+#ifndef SEEK_CUR
+
+ // Summary: Macro for the FSfseek SEEK_CUR base location.
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the current location of the file
+ #define SEEK_CUR 1
+
+#endif
+#ifndef SEEK_END
+
+ // Summary: Macro for the FSfseek SEEK_END base location
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the end of the file. For this macro, the offset value will be subtracted from
+ // the end location of the file by default.
+ #define SEEK_END 2
+
+#endif
+
+
+
+
+// Summary: Macro for the FSfopen APPEND mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it's file information will be loaded and the
+// current location in the file will be set to the end. The user will then be able to write to the file.
+#define APPEND "a"
+
+// Summary: Macro for the FSfopen WRITE mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it will be erased and replaced by an empty file
+// of the same name. The user will then be able to write to the file.
+#define WRITE "w"
+
+// Summary: Macro for the FSfopen READ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file information for the
+// specified file will be loaded. If the file does not exist, the FSfopen function will fail. The user
+// will then be able to read from the file.
+#define READ "r"
+
+// Summary: Macro for the FSfopen APPEND+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it's file information will be loaded and the
+// current location in the file will be set to the end. The user will then be able to write to the file
+// or read from the file.
+#define APPENDPLUS "a+"
+
+// Summary: Macro for the FSfopen WRITE+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it will be erased and replaced by an empty file
+// of the same name. The user will then be able to write to the file or read from the file.
+#define WRITEPLUS "w+"
+
+// Summary: Macro for the FSfopen READ+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file information for the
+// specified file will be loaded. If the file does not exist, the FSfopen function will fail. The user
+// will then be able to read from the file or write to the file.
+#define READPLUS "r+"
+
+
+
+#ifndef intmax_t
+ #ifdef __PIC24F__
+ // Summary: A data type indicating the maximum integer size in an architecture
+ // Description: The intmax_t data type refers to the maximum-sized data type on any given architecture. This
+ // data type can be specified as a format specifier size specification for the FSfprintf function.
+ #define intmax_t long long
+ #elif defined __PIC24H__
+ #define intmax_t long long
+ #elif defined __dsPIC30F__
+ #define intmax_t long long
+ #elif defined __dsPIC33F__
+ #define intmax_t long long
+ #endif
+#endif
+
+
+
+// Summary: Indicates flag conditions for a file object
+// Description: The FILEFLAGS structure is used to indicate conditions in a file. It contains three flags: 'write' indicates
+// that the file was opened in a mode that allows writes, 'read' indicates that the file was opened in a mode
+// that allows reads, and 'FileWriteEOF' indicates that additional data that is written to the file will increase
+// the file size.
+typedef struct
+{
+ unsigned write :1; // Indicates a file was opened in a mode that allows writes
+ unsigned read :1; // Indicates a file was opened in a mode that allows reads
+ unsigned FileWriteEOF :1; // Indicates the current position in a file is at the end of the file
+}FILEFLAGS;
+
+
+
+// Summary: Indicates how to search for file entries in the FILEfind function
+// Description: The values in the SEARCH_TYPE enumeration are used internally by the library to indicate how the FILEfind function
+// how to perform a search. The 'LOOK_FOR_EMPTY_ENTRY' value indicates that FILEfind should search for an empty file entry.
+// The 'LOOK_FOR_MATCHING_ENTRY' value indicates that FILEfind should search for an entry that matches the FSFILE object
+// that was passed into the FILEfind function.
+typedef enum{
+ LOOK_FOR_EMPTY_ENTRY = 0,
+ LOOK_FOR_MATCHING_ENTRY
+} SEARCH_TYPE;
+
+
+
+// Summary: Macro indicating the length of a 8.3 file name
+// Description: The TOTAL_FILE_SIZE macro indicates the maximum number of characters in an 8.3 file name. This value includes
+// 8 characters for the name, three for the extentsion, and 1 for the radix ('.')
+#define TOTAL_FILE_SIZE 8+3+1
+
+// Summary: A mask that indicates the limit of directory entries in a sector
+// Description: The MASK_MAX_FILE_ENTRY_LIMIT_BITS is used to indicate to the Cache_File_Entry function that a new sector needs to
+// be loaded.
+#define MASK_MAX_FILE_ENTRY_LIMIT_BITS 0x0f
+
+// Summary: Value used for shift operations to calculate the sector offset in a directory
+// Description: The VALUE_BASED_ON_ENTRIES_PER_CLUSTER macro is used to calculate sector offsets for directories. The position of the
+// entry is shifted by 4 bits (divided by 16, since there are 16 entries in a sector) to calculate how many sectors a
+// specified entry is offset from the beginning of the directory.
+#define VALUE_BASED_ON_ENTRIES_PER_CLUSTER 4
+
+// Summary: A value that will indicate that a dotdot directory entry points to the root.
+// Description: The VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT macro is used as an absolute address when writing information to a dotdot entry
+// in a newly created directory. If a dotdot entry points to the root directory, it's cluster value must be set to 0,
+// regardless of the actual cluster number of the root directory.
+#define VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT 0
+
+// Summary: MAcro indicating the length of an 8.3 file name in a directory entry
+// Description: The FILE_NAME_SIZE macro indicates the number of characters that an 8.3 file name will take up when packed in
+// a directory entry. This value includes 8 characters for the name and 3 for the extension. Note that the radix is not
+// stored in the directory entry.
+#define FILE_NAME_SIZE 11
+
+
+
+// Summary: Contains file information and is used to indicate which file to access.
+// Description: The FSFILE structure is used to hold file information for an open file as it's being modified or accessed. A pointer to
+// an open file's FSFILE structure will be passeed to any library function that will modify that file.
+typedef struct
+{
+ DISK * dsk; // Pointer to a DISK structure
+ DWORD cluster; // The first cluster of the file
+ DWORD ccls; // The current cluster of the file
+ WORD sec; // The current sector in the current cluster of the file
+ WORD pos; // The position in the current sector
+ DWORD seek; // The absolute position in the file
+ DWORD size; // The size of the file
+ FILEFLAGS flags; // A structure containing file flags
+ WORD time; // The file's last update time
+ WORD date; // The file's last update date
+ char name[FILE_NAME_SIZE]; // The name of the file
+ WORD entry; // The position of the file's directory entry in it's directory
+ WORD chk; // File structure checksum
+ WORD attributes; // The file attributes
+ DWORD dirclus; // The base cluster of the file's directory
+ DWORD dirccls; // The current cluster of the file's directory
+} FSFILE;
+
+
+
+// Summary: A structure used for searching for files on a device.
+// Description: The SearchRec structure is used when searching for file on a device. It contains parameters that will be loaded with
+// file information when a file is found. It also contains the parameters that the user searched for, allowing further
+// searches to be perfomed in the same directory for additional files that meet the specified criteria.
+typedef struct
+{
+ char filename[FILE_NAME_SIZE + 2]; // The name of the file that has been found
+ unsigned char attributes; // The attributes of the file that has been found
+ unsigned long filesize; // The size of the file that has been found
+ unsigned long timestamp; // The last modified time of the file that has been found (create time for directories)
+
+ unsigned int entry; // The directory entry of the last file found that matches the specified attributes. (Internal use only)
+ char searchname[FILE_NAME_SIZE + 2]; // The name specified when the user began the search. (Internal use only)
+ unsigned char searchattr; // The attributes specified when the user began the search. (Internal use only)
+ unsigned long cwdclus; // The directory that this search was performed in. (Internal use only)
+ unsigned char initialized; // Check to determine if the structure was initialized by FindFirst (Internal use only)
+} SearchRec;
+
+
+/***************************************************************************
+* Prototypes *
+***************************************************************************/
+
+
+
+
+/*************************************************************************
+ Function:
+ int FSInit(void)
+ Summary:
+ Function to initialize the device.
+ Conditions:
+ The physical device should be connected to the microcontroller.
+ Input:
+ None
+ Return Values:
+ TRUE - Initialization successful
+ FALSE - Initialization unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Initializes the static or dynamic memory slots for holding file
+ structures. Initializes the device with the DISKmount function. Loads
+ MBR and boot sector information. Initializes the current working
+ directory to the root directory for the device if directory support
+ is enabled.
+ Remarks:
+ None
+ *************************************************************************/
+
+int FSInit(void);
+
+
+/*********************************************************************
+ Function:
+ FSFILE * FSfopen (const char * fileName, const char *mode)
+ Summary:
+ Open a file
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to open
+ mode -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ - WRITEPLUS - Create a new file or replace an existing file (reads also enabled)
+ - READPLUS - Read data from an existing file (writes also enabled)
+ - APPENDPLUS - Append data to an existing file (reads also enabled)
+ Return Values:
+ FSFILE * - The pointer to the file object
+ NULL - The file could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will open a file or directory. First, RAM in the
+ dynamic heap or static array will be allocated to a new FSFILE object.
+ Then, the specified file name will be formatted to ensure that it's
+ in 8.3 format. Next, the FILEfind function will be used to search
+ for the specified file name. If the name is found, one of three
+ things will happen: if the file was opened in read mode, its file
+ info will be loaded using the FILEopen function; if it was opened in
+ write mode, it will be erased, and a new file will be constructed in
+ its place; if it was opened in append mode, its file info will be
+ loaded with FILEopen and the current location will be moved to the
+ end of the file using the FSfseek function. If the file was not
+ found by FILEfind, it will be created if the mode was specified as
+ a write or append mode. In these cases, a pointer to the heap or
+ static FSFILE object array will be returned. If the file was not
+ found and the mode was specified as a read mode, the memory
+ allocated to the file will be freed and the NULL pointer value
+ will be returned.
+ Remarks:
+ None.
+ *********************************************************************/
+
+FSFILE * FSfopen(const char * fileName, const char *mode);
+
+
+
+#ifdef ALLOW_PGMFUNCTIONS
+
+/******************************************************************************
+ Function:
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+ Summary:
+ Open a file named with a ROM string on PIC18
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to be opened (ROM)
+ mode - The mode the file will be opened in (ROM)
+ Return Values:
+ FSFILE * - A pointer to the file object
+ NULL - File could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfopenpgm function will copy a PIC18 ROM fileName and mode argument
+ into RAM arrays, and then pass those arrays to the FSfopen function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ ******************************************************************************/
+
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode);
+
+
+/**************************************************************************************
+ Function:
+ int FindFirstpgm (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Find a file named with a ROM string on PIC18
+ Conditions:
+ None
+ Input:
+ fileName - The name of the file to be found (ROM)
+ attr - The attributes of the file to be found
+ rec - Pointer to a search record to store the file info in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the given parameters was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object will be lost.
+ The FSerrno variable will be changed.
+ Description:
+ The FindFirstpgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FindFirst function.
+ Remarks:
+ Call FindFirstpgm or FindFirst before calling FindNext.
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************************/
+
+ int FindFirstpgm (const rom char * fileName, unsigned int attr, SearchRec * rec);
+
+
+/**************************************************************************
+ Function:
+ int FSchdirpgm (const rom char * path)
+ Summary:
+ Changed the CWD with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to (ROM)
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdirpgm function passes a PIC18 ROM path pointer to the
+ chdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM
+ **************************************************************************/
+
+ int FSchdirpgm (const rom char * path);
+
+ #ifdef ALLOW_WRITES
+
+
+/*************************************************************
+ Function:
+ int FSremovepgm (const rom char * fileName)
+ Summary:
+ Delete a file named with a ROM string on PIC18
+ Conditions:
+ File not opened; file exists
+ Input:
+ fileName - The name of the file to be deleted (ROM)
+ Return Values:
+ 0 - File was removed successfully
+ -1 - File could not be removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremovepgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FSremove function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *************************************************************/
+
+ int FSremovepgm (const rom char * fileName);
+
+
+/**************************************************************************
+ Function:
+ int FSmkdirpgm (const rom char * path)
+ Summary:
+ Create a directory with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create (ROM)
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdirpgm function passes a PIC18 ROM path pointer to the
+ mkdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arugments in ROM
+ **************************************************************************/
+
+ int FSmkdirpgm (const rom char * path);
+
+
+/**************************************************************************
+ Function:
+ int FSrmdirpgm (const rom char * path)
+ Summary:
+ Delete a directory with a path in ROM on PIC18
+ Conditions:
+ None.
+ Input:
+ path - The path of the directory to remove (ROM)
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdirpgm function passes a PIC18 ROM path pointer to the
+ rmdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************/
+
+ int FSrmdirpgm (const rom char * path, unsigned char rmsubdirs);
+
+
+/*****************************************************************
+ Function:
+ int FSrenamepgm(const rom char * fileName, FSFILE * fo)
+ Summary:
+ Rename a file named with a ROM string on PIC18
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file (in ROM)
+ fo - The file to rename
+ Return Values:
+ 0 - File renamed successfully
+ -1 - File could not be renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The Fsrenamepgm function will copy the rom fileName specified
+ by the user into a RAM array and pass that array into the
+ FSrename function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *****************************************************************/
+
+ int FSrenamepgm (const rom char * fileName, FSFILE * fo);
+ #endif
+#endif
+
+
+/************************************************************
+ Function:
+ int FSfclose(FSFILE *fo)
+ Summary:
+ Update file information and free FSFILE objects
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to the file to close
+ Return Values:
+ 0 - File closed successfully
+ EOF - Error closing the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will update the directory entry for the
+ file pointed to by 'fo' with the information contained
+ in 'fo,' including the new file size and attributes.
+ Timestamp information will also be loaded based on the
+ method selected by the user and written to the entry
+ as the last modified time and date. The file entry will
+ then be written to the device. Finally, the memory
+ used for the specified file object will be freed from
+ the dynamic heap or the array of FSFILE objects.
+ Remarks:
+ A function to flush data to the device without closing the
+ file can be created by removing the portion of this
+ function that frees the memory and the line that clears
+ the write flag.
+ ************************************************************/
+
+int FSfclose(FSFILE *fo);
+
+
+/*********************************************************
+ Function:
+ void FSrewind (FSFILE * fo)
+ Summary:
+ Set the current position in a file to the beginning
+ Conditions:
+ File opened.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ None
+ Side Effects:
+ None.
+ Description:
+ The FSrewind funciton will reset the position of the
+ specified file to the beginning of the file. This
+ functionality is faster than using FSfseek to reset
+ the position in the file.
+ Remarks:
+ None.
+ *********************************************************/
+
+void FSrewind (FSFILE *fo);
+
+
+/**************************************************************************
+ Function:
+ size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Read data from a file
+ Conditions:
+ File is opened in a read mode
+ Input:
+ ptr - Destination buffer for read bytes
+ size - Size of units in bytes
+ n - Number of units to be read
+ stream - File to be read from
+ Return:
+ size_t - number of units read
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfread function will read data from the specified file. First,
+ the appropriate sector of the file is loaded. Then, data is read into
+ the specified buffer until the specified number of bytes have been read.
+ When a cluster boundary is reached, a new cluster will be loaded. The
+ parameters 'size' and 'n' indicate how much data to read. 'Size'
+ refers to the size of one object to read (in bytes), and 'n' will refer
+ to the number of these objects to read. The value returned will be equal
+ to 'n' unless an error occured or the user tried to read beyond the end
+ of the file.
+ Remarks:
+ None.
+ **************************************************************************/
+
+size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream);
+
+
+/**********************************************************************
+ Function:
+ int FSfseek(FSFILE *stream, long offset, int whence)
+ Summary:
+ Change the current position in a file
+ Conditions:
+ File opened
+ Input:
+ stream - Pointer to file structure
+ offset - Offset from base location
+ whence -
+ - SEEK_SET - Seek from start of file
+ - SEEK_CUR - Seek from current location
+ - SEEK_END - Seek from end of file (subtract offset)
+ Return Values:
+ 0 - Operation successful
+ -1 - Operation unsuccesful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfseek function will change the current position in the file to
+ one specified by the user. First, an absolute offset is calculated
+ using the offset and base location passed in by the user. Then, the
+ position variables are updated, and the sector number that corresponds
+ to the new location. That sector is then loaded. If the offset
+ falls exactly on a cluster boundary, a new cluster will be allocated
+ to the file and the position will be set to the first byte of that
+ cluster.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSfseek(FSFILE *stream, long offset, int whence);
+
+
+/*******************************************************************
+ Function:
+ long FSftell (FSFILE * fo)
+ Summary:
+ Determine the current location in a file
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to file structure
+ Return: Current location in the file
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSftell function will return the current position in the
+ file pointed to by 'fo' by returning the 'seek' variable in the
+ FSFILE object, which is used to keep track of the absolute
+ location of the current position in the file.
+ Remarks:
+ None
+ *******************************************************************/
+
+long FSftell(FSFILE *fo);
+
+
+/****************************************************
+ Function:
+ int FSfeof( FSFILE * stream )
+ Summary:
+ Indicate whether the current file position is at the end
+ Conditions:
+ File is open in a read mode
+ Input:
+ stream - Pointer to the target file
+ Return Values:
+ Non-Zero - EOF reached
+ 0 - Not at end of File
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfeof function will indicate that the end-of-
+ file has been reached for the specified file by
+ comparing the absolute location in the file to the
+ size of the file.
+ Remarks:
+ None.
+ ****************************************************/
+
+int FSfeof( FSFILE * stream );
+
+
+#ifdef ALLOW_FORMATS
+/*******************************************************************
+ Function:
+ int FSformat (char mode, long int serialNumber, char * volumeID)
+ Summary:
+ Formats a device
+ Conditions:
+ The device must possess a valid master boot record.
+ Input:
+ mode - - 0 - Just erase the FAT and root
+ - 1 - Create a new boot sector
+ serialNumber - Serial number to write to the card
+ volumeID - Name of the card
+ Return Values:
+ 0 - Format was successful
+ EOF - Format was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSformat function can be used to create a new boot sector
+ on a device, based on the information in the master boot record.
+ This function will first initialize the I/O pins and the device,
+ and then attempts to read the master boot record. If the MBR
+ cannot be loaded successfully, the function will fail. Next, if
+ the 'mode' argument is specified as '0' the existing boot sector
+ information will be loaded. If the 'mode' argument is '1' an
+ entirely new boot sector will be constructed using the disk
+ values from the master boot record. Once the boot sector has
+ been successfully loaded/created, the locations of the FAT and
+ root will be loaded from it, and they will be completely
+ erased. If the user has specified a volumeID parameter, a
+ VOLUME attribute entry will be created in the root directory
+ to name the device.
+ Remarks:
+ FAT12 and FAT16 formatting is supported.
+ *******************************************************************/
+
+int FSformat (char mode, long int serialNumber, char * volumeID);
+#endif
+
+
+#ifdef ALLOW_WRITES
+/***************************************************************************
+ Function:
+ int FSattrib (FSFILE * file, unsigned char attributes)
+ Summary:
+ Change the attributes of a file
+ Conditions:
+ File opened
+ Input:
+ file - Pointer to file structure
+ attributes - The attributes to set for the file
+ - Attribute - Value - Indications
+ - ATTR_READ_ONLY - 0x01 - The read-only attribute
+ - ATTR_HIDDEN - 0x02 - The hidden attribute
+ - ATTR_SYSTEM - 0x04 - The system attribute
+ - ATTR_ARCHIVE - 0x20 - The archive attribute
+ Return Values:
+ 0 - Attribute change was successful
+ -1 - Attribute change was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSattrib funciton will set the attributes of the specified file
+ to the attributes passed in by the user. This function will load the
+ file entry, replace the attributes with the ones specified, and write
+ the attributes back. If the specified file is a directory, the
+ directory attribute will be preserved.
+ Remarks:
+ None
+ ***************************************************************************/
+
+int FSattrib (FSFILE * file, unsigned char attributes);
+
+
+/***************************************************************
+ Function:
+ int FSrename (const rom char * fileName, FSFILE * fo)
+ Summary:
+ Change the name of a file or directory
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file
+ fo - The file to rename
+ Return Values:
+ 0 - File was renamed successfully
+ EOF - File was not renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrename function will rename a file. First, it will
+ search through the current working directory to ensure the
+ specified new filename is not already in use. If it isn't,
+ the new filename will be written to the file entry of the
+ file pointed to by 'fo.'
+ Remarks:
+ None
+ ***************************************************************/
+
+int FSrename (const char * fileName, FSFILE * fo);
+
+
+/*********************************************************************
+ Function:
+ int FSremove (const char * fileName)
+ Summary:
+ Delete a file
+ Conditions:
+ File not opened, file exists
+ Input:
+ fileName - Name of the file to erase
+ Return Values:
+ 0 - File removed
+ EOF - File was not removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremove function will attempt to find the specified file with
+ the FILEfind function. If the file is found, it will be erased
+ using the FILEerase function.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSremove (const char * fileName);
+
+
+/*********************************************************************************
+ Function:
+ size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Write data to a file
+ Conditions:
+ File opened in WRITE, APPEND, WRITE+, APPEND+, READ+ mode
+ Input:
+ ptr - Pointer to source buffer
+ size - Size of units in bytes
+ n - Number of units to transfer
+ stream - Pointer to file structure
+ Return:
+ size_t - number of units written
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfwrite function will write data to a file. First, the sector that
+ corresponds to the current position in the file will be loaded (if it hasn't
+ already been cached in the global data buffer). Data will then be written to
+ the device from the specified buffer until the specified amount has been written.
+ If the end of a cluster is reached, the next cluster will be loaded, unless
+ the end-of-file flag for the specified file has been set. If it has, a new
+ cluster will be allocated to the file. Finally, the new position and filezize
+ will be stored in the FSFILE object. The parameters 'size' and 'n' indicate how
+ much data to write. 'Size' refers to the size of one object to write (in bytes),
+ and 'n' will refer to the number of these objects to write. The value returned
+ will be equal to 'n' unless an error occured.
+ Remarks:
+ None.
+ *********************************************************************************/
+
+size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream);
+
+#endif
+
+#ifdef ALLOW_DIRS
+
+
+/**************************************************************************
+ Function:
+ int FSchdir (char * path)
+ Summary:
+ Change the current working directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to.
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdir function passes a RAM pointer to the path to the
+ chdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSchdir (char * path);
+
+
+/**************************************************************
+ Function:
+ char * FSgetcwd (char * path, int numchars)
+ Summary:
+ Get the current working directory name
+ Conditions:
+ None
+ Input:
+ path - Pointer to the array to return the cwd name in
+ numchars - Number of chars in the path
+ Return Values:
+ char * - The cwd name string pointer (path or defaultArray)
+ NULL - The current working directory name could not be loaded.
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSgetcwd function will get the name of the current
+ working directory and return it to the user. The name
+ will be copied into the buffer pointed to by 'path,'
+ starting at the root directory and copying as many chars
+ as possible before the end of the buffer. The buffer
+ size is indicated by the 'numchars' argument. The first
+ thing this function will do is load the name of the current
+ working directory, if it isn't already present. This could
+ occur if the user switched to the dotdot entry of a
+ subdirectory immediately before calling this function. The
+ function will then copy the current working directory name
+ into the buffer backwards, and insert a backslash character.
+ Next, the function will continuously switch to the previous
+ directories and copy their names backwards into the buffer
+ until it reaches the root. If the buffer overflows, it
+ will be treated as a circular buffer, and data will be
+ copied over existing characters, starting at the beginning.
+ Once the root directory is reached, the text in the buffer
+ will be swapped, so that the buffer contains as much of the
+ current working directory name as possible, starting at the
+ root.
+ Remarks:
+ None
+ **************************************************************/
+
+char * FSgetcwd (char * path, int numbchars);
+
+
+#ifdef ALLOW_WRITES
+
+/**************************************************************************
+ Function:
+ int FSmkdir (char * path)
+ Summary:
+ Create a directory
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create.
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdir function passes a RAM pointer to the path to the
+ mkdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSmkdir (char * path);
+
+
+/**************************************************************************
+ Function:
+ int FSrmdir (char * path)
+ Summary:
+ Delete a directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to remove
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdir function passes a RAM pointer to the path to the
+ rmdirhelper function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int FSrmdir (char * path, unsigned char rmsubdirs);
+#endif
+
+#endif
+
+#ifdef USERDEFINEDCLOCK
+
+
+/***********************************************************************************************************
+ Function:
+ int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+ Summary:
+ Manually set timestamp variables
+ Conditions:
+ USERDEFINEDCLOCK macro defined in FSconfig.h.
+ Input:
+ year - The year (1980\-2107)
+ month - The month (1\-12)
+ day - The day of the month (1\-31)
+ hour - The hour (0\-23)
+ minute - The minute (0\-59)
+ second - The second (0\-59)
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ Lets the user manually set the timing variables. The values passed in will be converted to the format
+ used by the FAT timestamps.
+ Remarks:
+ Call this before creating a file or directory (set create time) and
+ before closing a file (set last access time, last modified time)
+ ***********************************************************************************************************/
+
+int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second);
+#endif
+
+
+#ifdef ALLOW_FILESEARCH
+
+/***********************************************************************************
+ Function:
+ int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Initial search function
+ Conditions:
+ None
+ Input:
+ fileName - The name to search for
+ - Parital string search characters
+ - * - Indicates the rest of the filename or extension can vary (e.g. FILE.*)
+ - ? - Indicates that one character in a filename can vary (e.g. F?LE.T?T)
+ attr - The attributes that a found file may have
+ - ATTR_READ_ONLY - File may be read only
+ - ATTR_HIDDEN - File may be a hidden file
+ - ATTR_SYSTEM - File may be a system file
+ - ATTR_VOLUME - Entry may be a volume label
+ - ATTR_DIRECTORY - File may be a directory
+ - ATTR_ARCHIVE - File may have archive attribute
+ - ATTR_MASK - All attributes
+ rec - pointer to a structure to put the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the specified criteria was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object
+ will be lost. The FSerrno variable will be changed.
+ Description:
+ The FindFirst function will search for a file based on parameters passed in
+ by the user. This function will use the FILEfind function to parse through
+ the current working directory searching for entries that match the specified
+ parameters. If a file is found, its parameters are copied into the SearchRec
+ structure, as are the initial parameters passed in by the user and the position
+ of the file entry in the current working directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling FindNext
+ ***********************************************************************************/
+
+int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec);
+
+
+/**********************************************************************
+ Function:
+ int FindNext (SearchRec * rec)
+ Summary:
+ Sequential search function
+ Conditions:
+ None
+ Input:
+ rec - The structure to store the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No additional files matching the specified criteria were found
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FindNext function performs the same function as the FindFirst
+ funciton, except it does not copy any search parameters into the
+ SearchRec structure (only info about found files) and it begins
+ searching at the last directory entry offset at which a file was
+ found, rather than at the beginning of the current working
+ directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling this function
+ **********************************************************************/
+
+int FindNext (SearchRec * rec);
+#endif
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSfprintf (FSFILE * fptr, const char * fmt, ...)
+ // PIC18
+ int FSfpritnf (FSFILE * fptr, const rom char * fmt, ...)
+ Summary:
+ Function to write formatted strings to a file
+ Conditions:
+ For PIC18, integer promotion must be enabled in the project build
+ options menu. File opened in a write mode.
+ Input:
+ fptr - A pointer to the file to write to.
+ fmt - A string of characters and format specifiers to write to
+ the file
+ ... - Additional arguments inserted in the string by format
+ specifiers
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Writes a specially formatted string to a file.
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef ALLOW_FSFPRINTF
+ #ifdef __18CXX
+ int FSfprintf (FSFILE *fptr, const rom char *fmt, ...);
+ #else
+ int FSfprintf (FSFILE *fptr, const char * fmt, ...);
+ #endif
+#endif
+
+
+/**************************************************************************
+ Function:
+ int FSerror (void)
+ Summary:
+ Return an error code for the last function call
+ Conditions:
+ The return value depends on the last function called.
+ Input:
+ None
+ Side Effects:
+ None.
+ Return Values:
+ FSInit -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The physical media could not be initialized
+ - CE_BAD_SECTOR_READ � The MBR or the boot sector could not be
+ read correctly
+ - CE_BAD_PARITION � The MBR signature code was incorrect.
+ - CE_NOT_FORMATTED � The boot sector signature code was incorrect or
+ indicates an invalid number of bytes per sector.
+ - CE_CARDFAT32 � The physical media is FAT32 type (only an error
+ when FAT32 support is disabled).
+ - CE_UNSUPPORTED_FS � The device is formatted with an unsupported file
+ system (not FAT12 or 16).
+ FSfopen -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The device has not been initialized.
+ - CE_TOO_MANY_FILES_OPEN � The function could not allocate any
+ additional file information to the array
+ of FSFILE structures or the heap.
+ - CE_INVALID_FILENAME � The file name argument was invalid.
+ - CE_INVALID_ARGUMENT � The user attempted to open a directory in a
+ write mode or specified an invalid mode argument.
+ - CE_FILE_NOT_FOUND � The specified file (which was to be opened in read
+ mode) does not exist on the device.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_ERASE_FAIL � The existing file could not be erased (when opening
+ a file in WRITE mode).
+ - CE_DIR_FULL � The directory is full.
+ - CE_DISK_FULL� The data memory section is full.
+ - CE_WRITE_ERROR � A write to the device failed.
+ - CE_SEEK_ERROR � The current position in the file could not be set to
+ the end (when the file was opened in APPEND mode).
+ FSfclose -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer or the new file
+ entry information could not be written to the device.
+ - CE_BADCACHEREAD � The file entry information could not be cached
+ FSfread -
+ - CE_GOOD � No Error
+ - CE_WRITEONLY � The file was opened in a write-only mode.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_BAD_SECTOR_READ � The data sector could not be read.
+ - CE_EOF � The end of the file was reached.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be loaded.
+ FSfwrite -
+ - CE_GOOD � No Error
+ - CE_READONLY � The file was opened in a read-only mode.
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_WRITE_ERROR � There was an error writing data to the device.
+ - CE_BADCACHEREAD � The data sector to be modified could not be read from
+ the device.
+ - CE_DISK_FULL � All data clusters on the device are in use.
+ FSfseek -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_INVALID_ARGUMENT � The specified offset exceeds the size of the file.
+ - CE_BADCACHEREAD � The sector that contains the new current position
+ could not be loaded.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be
+ loaded/allocated.
+ FSftell -
+ - CE_GOOD � No Error
+ FSattrib -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The attribute argument was invalid.
+ - CE_BADCACHEREAD � The existing file entry information could not be
+ loaded.
+ - CE_WRITE_ERROR � The file entry information could not be written to
+ the device.
+ FSrename -
+ - CE_GOOD � No Error
+ - CE_FILENOTOPENED � A null file pointer was passed into the function.
+ - CE_INVALID_FILENAME � The file name passed into the function was invalid.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_FILENAME_EXISTS � A file with the specified name already exists.
+ - CE_WRITE_ERROR � The new file entry data could not be written to the
+ device.
+ FSfeof -
+ - CE_GOOD � No Error
+ FSformat -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The device could not be initialized.
+ - CE_BADCACHEREAD � The master boot record or boot sector could not be
+ loaded successfully.
+ - CE_INVALID_ARGUMENT � The user selected to create their own boot sector on
+ a device that has no master boot record, or the mode
+ argument was invalid.
+ - CE_WRITE_ERROR � The updated MBR/Boot sector could not be written to
+ the device.
+ - CE_BAD_PARTITION � The calculated number of sectors per clusters was
+ invalid.
+ - CE_NONSUPPORTED_SIZE � The card has too many sectors to be formatted as
+ FAT12 or FAT16.
+ FSremove -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � The specified file could not be found.
+ - CE_ERASE_FAIL � The file could not be erased.
+ FSchdir -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The path string was mis-formed or the user tried to
+ change to a non-directory file.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_FOUND � Could not find a directory in the path.
+ FSgetcwd -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The user passed a 0-length buffer into the function.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the current working directory.
+ FSmkdir -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_ARGUMENT � The path string was mis-formed.
+ - CE_BADCACHEREAD � Could not successfully change to a recently created
+ directory to store its dir entry information, or
+ could not cache directory entry information.
+ - CE_INVALID_FILENAME � One or more of the directory names has an invalid
+ format.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device or the dot/dotdot entries could
+ not be written to a newly created directory.
+ - CE_DIR_FULL � There are no available dir entries in the CWD.
+ - CE_DISK_FULL � There are no available clusters in the data region of
+ the device.
+ FSrmdir -
+ - CE_GOOD � No Error
+ - CE_DIR_NOT_FOUND � The directory specified could not be found or the
+ function could not change to a subdirectory within
+ the directory to be deleted (when recursive delete is
+ enabled).
+ - CE_INVALID_ARGUMENT � The user tried to remove the CWD or root directory.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_EMPTY � The directory to be deleted was not empty and
+ recursive subdirectory removal was disabled.
+ - CE_ERASE_FAIL � The directory or one of the directories or files
+ within it could not be deleted.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the CWD.
+ SetClockVars -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The time values passed into the function were
+ invalid.
+ FindFirst -
+ - CE_GOOD � No Error
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ - CE_BADCACHEREAD � The file information for the file that was found
+ could not be cached.
+ FindNext -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The SearchRec object was not initialized by a call to
+ FindFirst.
+ - CE_INVALID_ARGUMENT � The SearchRec object was initialized in a different
+ directory from the CWD.
+ - CE_INVALID_FILENAME � The filename is invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ FSfprintf -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � Characters could not be written to the file.
+ Description:
+ The FSerror function will return the FSerrno variable. This global
+ variable will have been set to an error value during the last call of a
+ library function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSerror (void);
+
+
+/*********************************************************************************
+ Function:
+ int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+ Summary:
+ Creates a master boot record
+ Conditions:
+ The I/O pins for the device have been initialized by the InitIO function.
+ Input:
+ firstSector - The first sector of the partition on the device (cannot
+ be 0; that's the MBR)
+ numSectors - The number of sectors available in memory (including the
+ MBR)
+ Return Values:
+ 0 - MBR was created successfully
+ EOF - MBR could not be created
+ Side Effects:
+ None
+ Description:
+ This function can be used to create a master boot record for a device. Note
+ that this function should not be used on a device that is already formatted
+ with a master boot record (i.e. most SD cards, CF cards, USB keys). This
+ function will fill the global data buffer with appropriate partition information
+ for a FAT partition with a type determined by the number of sectors available
+ to the partition. It will then write the MBR information to the first sector
+ on the device. This function should be followed by a call to FSformat, which
+ will create a boot sector, root dir, and FAT appropriate the the information
+ contained in the new master boot record. Note that FSformat only supports
+ FAT12 and FAT16 formatting at this time, and so cannot be used to format a
+ device with more than 0x3FFD5F sectors.
+ Remarks:
+ This function can damage the device being used, and should not be called
+ unless the user is sure about the size of the device and the first sector value.
+ *********************************************************************************/
+
+int FSCreateMBR (unsigned long firstSector, unsigned long numSectors);
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSconfig.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSconfig.h new file mode 100644 index 00000000..abf6a18f --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/FSconfig.h @@ -0,0 +1,291 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: FSconfig.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Dependencies: None
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+
+#ifndef _FS_DEF_
+
+#include "Compiler.h"
+#include "HardwareProfile.h"
+
+
+// Summary: A macro indicating the maximum number of concurrently open files
+// Description: The FS_MAX_FILES_OPEN #define is only applicable when dynamic memory allocation is not used (FS_DYNAMIC_MEM is not defined).
+// This macro defines the maximum number of open files at any given time. The amount of RAM used by FSFILE objects will
+// be equal to the size of an FSFILE object multipled by this macro value. This value should be kept as small as possible
+// as dictated by the application. This will reduce memory usage.
+#define FS_MAX_FILES_OPEN 3
+
+
+// Summary: A macro defining the size of a sector
+// Description: The MEDIA_SECTOR_SIZE macro will define the size of a sector on the FAT file system. This value must equal 512 bytes,
+// 1024 bytes, 2048 bytes, or 4096 bytes. The value of a sector will usually be 512 bytes.
+#define MEDIA_SECTOR_SIZE 512
+
+
+
+/* *******************************************************************************************************/
+/************** Compiler options to enable/Disable Features based on user's application ******************/
+/* *******************************************************************************************************/
+
+
+// Summary: A macro to enable/disable file search functions.
+// Description: The ALLOW_FILESEARCH definition can be commented out to disable file search functions in the library. This will
+// prevent the use of the FindFirst and FindNext functions and reduce code size.
+#define ALLOW_FILESEARCH
+
+// Summary: A macro to enable/disable write functionality
+// Description: The ALLOW_WRITES definition can be commented out to disable all operations that write to the device. This will
+// greatly reduce code size.
+#define ALLOW_WRITES
+
+
+// Summary: A macro to enable/disable format functionality
+// Description: The ALLOW_FORMATS definition can be commented out to disable formatting functionality. This will prevent the use of
+// the FSformat function. If formats are enabled, write operations must also be enabled by uncommenting ALLOW_WRITES.
+#define ALLOW_FORMATS
+
+// Summary: A macro to enable/disable directory operations.
+// Description: The ALLOW_DIRS definition can be commented out to disable all directory functionality. This will reduce code size.
+// If directories are enabled, write operations must also be enabled by uncommenting ALLOW_WRITES in order to use
+// the FSmkdir or FSrmdir functions.
+#define ALLOW_DIRS
+
+// Summary: A macro to enable/disable PIC18 ROM functions.
+// Description: The ALLOW_PGMFUNCTIONS definition can be commented out to disable all PIC18 functions that allow the user to pass string
+// arguments in ROM (denoted by the suffix -pgm). Note that this functionality must be disabled when not using PIC18.
+//#define ALLOW_PGMFUNCTIONS
+
+// Summary: A macro to enable/disable the FSfprintf function.
+// Description: The ALLOW_FSFPRINTF definition can be commented out to disable the FSfprintf function. This will save code space. Note that
+// if FSfprintf is enabled and the PIC18 architecture is used, integer promotions must be enabled in the Project->Build Options
+// menu. Write operations must be enabled to use FSfprintf.
+//#define ALLOW_FSFPRINTF
+
+// Summary: A macro to enable/disable FAT32 support.
+// Description: The SUPPORT_FAT32 definition can be commented out to disable support for FAT32 functionality. This will save a small amount
+// of code space.
+#define SUPPORT_FAT32
+
+
+
+/**************************************************************************************************/
+// Select a method for updating file timestamps
+/**************************************************************************************************/
+
+// Summary: A macro to enable RTCC based timestamp generation
+// Description: The USEREALTIMECLOCK macro will configure the code to automatically
+// generate timestamp information for files from the RTCC module. The user
+// must enable and configure the RTCC module before creating or modifying
+// files.
+#define USEREALTIMECLOCK
+
+// Summary: A macro to enable manual timestamp generation
+// Description: The USERDEFINEDCLOCK macro will allow the user to manually set
+// timestamp information using the SetClockVars function. The user will
+// need to set the time variables immediately before creating or closing a
+// file or directory.
+//#define USERDEFINEDCLOCK
+
+// Summary: A macro to enable don't-care timestamp generation
+// Description: The INCREMENTTIMESTAMP macro will set the create time of a file to a
+// static value and increment it when a file is updated. This timestamp
+// generation method should only be used in applications where file times
+// are not necessary.
+//#define INCREMENTTIMESTAMP
+
+
+#ifdef __18CXX
+ #ifdef USEREALTIMECLOCK
+ #error The PIC18 architecture does not have a Real-time clock and calander module
+ #endif
+#endif
+
+#ifdef ALLOW_PGMFUNCTIONS
+ #ifndef __18CXX
+ #error The pgm functions are unneccessary when not using PIC18
+ #endif
+#endif
+
+#ifndef USEREALTIMECLOCK
+ #ifndef USERDEFINEDCLOCK
+ #ifndef INCREMENTTIMESTAMP
+ #error Please enable USEREALTIMECLOCK, USERDEFINEDCLOCK, or INCREMENTTIMESTAMP
+ #endif
+ #endif
+#endif
+
+/************************************************************************/
+// Set this preprocessor option to '1' to use dynamic FSFILE object allocation. It will
+// be necessary to allocate a heap when dynamically allocating FSFILE objects.
+// Set this option to '0' to use static FSFILE object allocation.
+/************************************************************************/
+
+#if 0
+ // Summary: A macro indicating that FSFILE objects will be allocated dynamically
+ // Description: The FS_DYNAMIC_MEM macro will cause FSFILE objects to be allocated from a dynamic heap. If it is undefined,
+ // the file objects will be allocated using a static array.
+ #define FS_DYNAMIC_MEM
+ #ifdef __18CXX
+ // Description: Function pointer to a dynamic memory allocation function
+ #define FS_malloc SRAMalloc
+ // Description: Function pointer to a dynamic memory free function
+ #define FS_free SRAMfree
+ #else
+ #define FS_malloc malloc
+ #define FS_free free
+ #endif
+#endif
+
+
+// Function definitions
+// Associate the physical layer functions with the correct physical layer
+#ifdef USE_SD_INTERFACE_WITH_SPI // SD-SPI.c and .h
+
+ // Description: Function pointer to the Media Initialize Physical Layer function
+ #define MDD_MediaInitialize MDD_SDSPI_MediaInitialize
+
+ // Description: Function pointer to the Media Detect Physical Layer function
+ #define MDD_MediaDetect MDD_SDSPI_MediaDetect
+
+ // Description: Function pointer to the Sector Read Physical Layer function
+ #define MDD_SectorRead MDD_SDSPI_SectorRead
+
+ // Description: Function pointer to the Sector Write Physical Layer function
+ #define MDD_SectorWrite MDD_SDSPI_SectorWrite
+
+ // Description: Function pointer to the I/O Initialization Physical Layer function
+ #define MDD_InitIO MDD_SDSPI_InitIO
+
+ // Description: Function pointer to the Media Shutdown Physical Layer function
+ #define MDD_ShutdownMedia MDD_SDSPI_ShutdownMedia
+
+ // Description: Function pointer to the Write Protect Check Physical Layer function
+ #define MDD_WriteProtectState MDD_SDSPI_WriteProtectState
+
+ // Description: Function pointer to the Read Capacity Physical Layer function
+ #define MDD_ReadCapacity MDD_SDSPI_ReadCapacity
+
+ // Description: Function pointer to the Read Sector Size Physical Layer Function
+ #define MDD_ReadSectorSize MDD_SDSPI_ReadSectorSize
+
+#elif defined USE_CF_INTERFACE_WITH_PMP // CF-PMP.c and .h
+
+ // Description: Function pointer to the Media Initialize Physical Layer function
+ #define MDD_MediaInitialize MDD_CFPMP_MediaInitialize
+
+ // Description: Function pointer to the Media Detect Physical Layer function
+ #define MDD_MediaDetect MDD_CFPMP_MediaDetect
+
+ // Description: Function pointer to the Sector Read Physical Layer function
+ #define MDD_SectorRead MDD_CFPMP_SectorRead
+
+ // Description: Function pointer to the Sector Write Physical Layer function
+ #define MDD_SectorWrite MDD_CFPMP_SectorWrite
+
+ // Description: Function pointer to the I/O Initialization Physical Layer function
+ #define MDD_InitIO MDD_CFPMP_InitIO
+
+ // Description: Function pointer to the Media Shutdown Physical Layer function
+ #define MDD_ShutdownMedia MDD_CFPMP_ShutdownMedia
+
+ // Description: Function pointer to the Write Protect Check Physical Layer function
+ #define MDD_WriteProtectState MDD_CFPMP_WriteProtectState
+
+ // Description: Function pointer to the CompactFlash Wait Physical Layer function
+ #define MDD_CFwait MDD_CFPMP_CFwait
+
+ // Description: Function pointer to the CompactFlash Write Physical Layer function
+ #define MDD_CFwrite MDD_CFPMP_CFwrite
+
+ // Description: Function pointer to the CompactFlash Read Physical Layer function
+ #define MDD_CFread MDD_CFPMP_CFread
+
+#elif defined USE_MANUAL_CF_INTERFACE // CF-Bit transaction.c and .h
+
+ // Description: Function pointer to the Media Initialize Physical Layer function
+ #define MDD_MediaInitialize MDD_CFBT_MediaInitialize
+
+ // Description: Function pointer to the Media Detect Physical Layer function
+ #define MDD_MediaDetect MDD_CFBT_MediaDetect
+
+ // Description: Function pointer to the Sector Read Physical Layer function
+ #define MDD_SectorRead MDD_CFBT_SectorRead
+
+ // Description: Function pointer to the Sector Write Physical Layer function
+ #define MDD_SectorWrite MDD_CFBT_SectorWrite
+
+ // Description: Function pointer to the I/O Initialization Physical Layer function
+ #define MDD_InitIO MDD_CFBT_InitIO
+
+ // Description: Function pointer to the Media Shutdown Physical Layer function
+ #define MDD_ShutdownMedia MDD_CFBT_ShutdownMedia
+
+ // Description: Function pointer to the Write Protect Check Physical Layer function
+ #define MDD_WriteProtectState MDD_CFBT_WriteProtectState
+
+ // Description: Function pointer to the CompactFlash Wait Physical Layer function
+ #define MDD_CFwait MDD_CFBT_CFwait
+
+ // Description: Function pointer to the CompactFlash Write Physical Layer function
+ #define MDD_CFwrite MDD_CFBT_CFwrite
+
+ // Description: Function pointer to the CompactFlash Read Physical Layer function
+ #define MDD_CFread MDD_CFBT_CFread
+
+#elif defined USE_USB_INTERFACE // USB host MSD library
+
+ // Description: Function pointer to the Media Initialize Physical Layer function
+ #define MDD_MediaInitialize USBHostMSDSCSIMediaInitialize
+
+ // Description: Function pointer to the Media Detect Physical Layer function
+ #define MDD_MediaDetect USBHostMSDSCSIMediaDetect
+
+ // Description: Function pointer to the Sector Read Physical Layer function
+ #define MDD_SectorRead USBHostMSDSCSISectorRead
+
+ // Description: Function pointer to the Sector Write Physical Layer function
+ #define MDD_SectorWrite USBHostMSDSCSISectorWrite
+
+ // Description: Function pointer to the I/O Initialization Physical Layer function
+ #define MDD_InitIO();
+
+ // Description: Function pointer to the Media Shutdown Physical Layer function
+ #define MDD_ShutdownMedia USBHostMSDSCSIMediaReset
+
+ // Description: Function pointer to the Write Protect Check Physical Layer function
+ #define MDD_WriteProtectState USBHostMSDSCSIWriteProtectState
+
+#endif
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/G_Code.c b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/G_Code.c new file mode 100644 index 00000000..94f74b6e --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/G_Code.c @@ -0,0 +1,530 @@ +/**********************************************************************
+ *************************** G_Code.c *******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+#include "G_Code.h"
+#include "Stepper.h"
+#include "Extruder.h"
+
+#define FastFeed 960
+#define SlowFeed 240
+
+//Internal
+void G_Code_G0(void);
+void G_Code_G1(void);
+void G_Code_G2(void);
+void G_Code_G3(void);
+void G_Code_G4(void);
+//void G_Code_G10(void);
+void G_Code_G20(void);
+void G_Code_G21(void);
+void G_Code_G28(void); //Go Home.
+void G_Code_G90(void); //Absolute Positioning
+void G_Code_G91(void); //Incremental Positioning
+void G_Code_G92(void); //Set current as home
+
+void M_Code_M101(void); //M101 Turn extruder on.
+void M_Code_M103(void); //M103 Turn extruder off.
+//see header for M104 external
+//void M_Code_M104(void); //M104 S145.0 Set temperature to 145.0 C.
+void M_Code_M106(void); //M106 Turn fan on.
+void M_Code_M107(void); //Turn fan off.
+void M_Code_M108(void); //M108 S210 Set extruder speed to 21.0RPM
+//*********************
+//BFB codes
+void M_Code_M220(void); //Turn off AUX
+void M_Code_M221(void); //Turn on AUX
+void M_Code_M222(void); //M122 S500 Set speed of fast XY moves
+void M_Code_M223(void); //M123 S500 Set speed of fast Z moves
+ //500fast - 2000slow
+void M_Code_M224(void); //Enable extruder motor during fast move
+void M_Code_M225(void); //Disable extruder motor during fast move
+void M_Code_M226(void); //Issue a Pause command from G-Code
+void M_Code_M227(void); //Enable Extruder Reverse S=Reverse time in ms P=Prime time in ms
+void M_Code_M228(void); //Disable Extruder Reverse
+//*********************
+
+//Glaobal variables
+int F_Code = 0; //copy of code numbers that are being worked on
+int G_Code;
+int M_Code;
+int Inch_mm = 0;
+
+
+
+float GX; //copy of Axis data being worked on
+float GY;
+float GZ;
+float GI_Val;
+float GJ_Val;
+float GP_Val;
+float GS_Val;
+
+int GX_On = 0;
+int GY_On = 0;
+int GZ_On = 0;
+int GI_On = 0;
+int GJ_On = 0;
+
+//TODO here:
+//Code in some data validation checks
+//const char LetterCode[18]={"DFGHIJKLMNPQRSTXYZ"};
+//const int GNumberCode[39]={
+//0,1,2,3,4,10,17,18,19,20,
+//21,40,41,42,43,49,53,45,55,56,
+//57,58,59,80,81,82,83,84,85,86,
+//87,88,89,90,91,92,93,94,98
+//};
+//const int MNumberCode[]={
+//0,1,2,3,4,5,6,7,8,9,26,27,30,48,49,60};
+/********************************************************/
+void G_CodeRun(char GC_L, int iGC_N, char GC_1L, float fGC_1, char GC_2L,
+ float fGC_2, char GC_3L, float fGC_3, char GC_4L,float fGC_4)
+{
+extern char EOF_Flag;
+//Going into this function we do not know where the axis data
+//appears in the line. The following sorts axis Data and stores
+//in local globals. It then issues function calls to run the code
+
+ while (SBR!= SBW)
+ {
+ if ((EOF_Flag == 1)&&(SBW+1 == SBR))
+ {//at end of file and one entry in buffer, let it go
+ SBW = SBR;
+ }
+ };
+
+ GX = 0;
+ if (GC_1L==0x58) GX=fGC_1; //checks for char "X"
+ if (GC_2L==0x58) GX=fGC_2;
+ if (GC_3L==0x58) GX=fGC_3;
+ if (GC_4L==0x58) GX=fGC_4;
+ if ((GC_1L==0x58)|(GC_2L==0x58)|(GC_3L==0x58)|(GC_4L==0x58))
+ {
+ GX_On=1;
+ }
+ else
+ GX_On=0;
+
+ GY = 0;
+ if (GC_1L==0x59) GY=fGC_1; //checks for char "Y"
+ if (GC_2L==0x59) GY=fGC_2;
+ if (GC_3L==0x59) GY=fGC_3;
+ if (GC_4L==0x59) GY=fGC_4;
+ if ((GC_1L==0x59)|(GC_2L==0x59)|(GC_3L==0x59)|(GC_4L==0x59))
+ {
+ GY_On=1;
+ }
+ else
+ GY_On=0;
+
+ GZ = 0;
+ if (GC_1L==0x5A) GZ=fGC_1; //checks for char "Z"
+ if (GC_2L==0x5A) GZ=fGC_2;
+ if (GC_3L==0x5A) GZ=fGC_3;
+ if (GC_4L==0x5A) GZ=fGC_4;
+ if ((GC_1L==0x5A)|(GC_2L==0x5A)|(GC_3L==0x5A)|(GC_4L==0x5A))
+ {
+ GZ_On = 1;
+ }
+ else
+ GZ_On = 0;
+
+ GI_Val = 0;
+ if (GC_1L==0x49) GI_Val=fGC_1; //checks for char "I"
+ if (GC_2L==0x49) GI_Val=fGC_2;
+ if (GC_3L==0x49) GI_Val=fGC_3;
+ if (GC_4L==0x49) GI_Val=fGC_4;
+ if ((GC_1L==0x49)|(GC_2L==0x49)|(GC_3L==0x49)|(GC_4L==0x49))
+ {
+ GI_On = 1;
+ }
+ else
+ GI_On = 0;
+ GJ_Val = 0;
+ if (GC_1L==0x4A) GJ_Val=fGC_1; //checks for char "J"
+ if (GC_2L==0x4A) GJ_Val=fGC_2;
+ if (GC_3L==0x4A) GJ_Val=fGC_3;
+ if (GC_4L==0x4A) GJ_Val=fGC_4;
+ if ((GC_1L==0x4A)|(GC_2L==0x4A)|(GC_3L==0x4A)|(GC_4L==0x4A))
+ {
+ GJ_On = 1;
+ }
+ else
+ GJ_On = 0;
+
+ //F_Code = 0;//F_Code persistes until its reset by Gcode
+ if (GC_1L==0x46) F_Code=fGC_1; //checks for char "F"
+ if (GC_2L==0x46) F_Code=fGC_2;
+ if (GC_3L==0x46) F_Code=fGC_3;
+ if (GC_4L==0x46) F_Code=fGC_4;
+
+ GP_Val = 0;
+ if (GC_1L==0x50) GP_Val=fGC_1; //checks for char "P"
+ if (GC_2L==0x50) GP_Val=fGC_2;
+ if (GC_3L==0x50) GP_Val=fGC_3;
+ if (GC_4L==0x50) GP_Val=fGC_4;
+
+ GS_Val = 0;
+ if (GC_1L==0x53) GS_Val=fGC_1; //checks for char "S"
+ if (GC_2L==0x53) GS_Val=fGC_2;
+ if (GC_3L==0x53) GS_Val=fGC_3;
+ if (GC_4L==0x53) GS_Val=fGC_4;
+/*
+ while (SBR!= SBW)
+ {
+ if ((EOF_Flag == 1)&&(SBW+1 == SBR))
+ {//at end of file and one entry in buffer, let it go
+ SBW = SBR;
+ }
+ };
+*/
+ switch(GC_L)
+ {
+ case 0x47: //G Code
+ G_Code=iGC_N;
+ if (G_Code==0) G_Code_G0();
+ if (G_Code==1) G_Code_G1();
+ if (G_Code==2) G_Code_G2();
+ if (G_Code==3) G_Code_G3();
+ if (G_Code==4) G_Code_G4();
+ //if (G_Code==10) G_Code_G10();//?
+ if (G_Code==20) G_Code_G20(); //Set Units Inches
+ if (G_Code==21) G_Code_G21(); //Set Units Metric
+ if (G_Code==28) G_Code_G28(); //Go Home.
+ if (G_Code==90) G_Code_G90(); //Absolute Positioning
+ if (G_Code==91) G_Code_G91(); //Incremental Positioning
+ if (G_Code==92) G_Code_G92(); //Set current as home
+ break;
+ case 0x4D: //M Code
+ M_Code = iGC_N; //Sets M code
+ G_Code=0, F_Code=0;
+
+ if (M_Code == 101) M_Code_M101(); //M101 Turn extruder on.
+ if (M_Code == 103) M_Code_M103(); //M103 Turn extruder off.
+ if (M_Code == 104) M_Code_M104(); //M104 Set temperature to S???
+ if (M_Code == 106) M_Code_M106(); //M106 Turn fan on
+ if (M_Code == 107) M_Code_M107(); //M107 Turn fan off.
+ if (M_Code == 108) M_Code_M108(); //M108 S210 Set extruder speed to 21.0RPM
+ if (M_Code == 220) M_Code_M220(); //Turn AUX off
+ if (M_Code == 221) M_Code_M221(); //Turn AUX On
+ if (M_Code == 222) M_Code_M222(); //Set speed of fast XY moves
+ if (M_Code == 223) M_Code_M223(); //Set speed of fast Z moves
+ if (M_Code == 224) M_Code_M224(); //Enable extruder motor during fast move
+ if (M_Code == 225) M_Code_M225(); //Disable extruder motor during fast move
+ if (M_Code == 226) M_Code_M226(); //Issue a Pause command from G-Code
+ if (M_Code == 227) M_Code_M227(); //Enable reverse extruder during extruder off
+ if (M_Code == 228) M_Code_M228(); //Disable reverse extruder during extruder off
+ break;
+ }//Switch
+}
+/********************************************************/
+// G Code Functions to be added here.
+// Please use same format and annotate.
+/********************************************************/
+void G_Code_G0(void)
+{ //G00 rapid positioning
+//Tool coordinates are set as Globals.
+// Sets variables and calls functions to execute the code
+
+ //if (M_Code == 0) M_Code = StopSpindle; //if not set, make default
+ if (F_Code == 0) F_Code = FastFeed; //if not set, make default
+ //Load values into Stepper control
+ Stepper_LoadNewValues(F_Code, M_Code);
+ if (ToolType == 1) ExtruderStatus = 1; //Switch to set normal feed rate
+ Stepper_CalcSteps(Inch_mm,0x00);
+ Stepper_Run3DLine();
+}
+/********************************************************/
+void G_Code_G1(void)
+{ //G01 linear interpolation
+//Tool coordinates are set as Globals.
+//Sets variables and calls functions to execute the code
+extern int ManualChange;
+
+ //if (M_Code == 0) M_Code = StopSpindle; //if not set, make default
+ if (F_Code == 0) F_Code = SlowFeed; //if not set, make slowest feed rate
+ if (FeedRate_ManualChange)
+ {
+ F_Code += ManualChange;
+ }
+
+ //Load values into Stepper control
+ Stepper_LoadNewValues(F_Code, M_Code);
+ if (ToolType == 1) ExtruderStatus = 1; //Switch to set normal feed rate
+ Stepper_CalcSteps(Inch_mm,0x00);
+ Stepper_Run3DLine(); //Linear machining
+}
+/********************************************************/
+void G_Code_G2(void)
+{ //G02 circular interpolation (clockwise)
+//The tool is already at the start position for this instruction
+// X,Y coordinates following G2 are the end position of the tool.
+// I X-axis offset to centre
+// J Y-axis offset to centre
+
+ //if (M_Code == 0) M_Code = StopSpindle; //if not set, make default
+ if (F_Code == 0) F_Code = SlowFeed; //if not set, make slowest feed rate
+ Stepper_LoadNewValues(F_Code, M_Code);
+ Stepper_CalcSteps(Inch_mm, 0x01);
+// Stepper_RunArcLine(2); //run as G2
+}
+/********************************************************/
+void G_Code_G3(void)
+{ //G03 circular interpolation (c-clockwise)
+//The tool is already at the start position for this instruction
+// X,Y coordinates following G3 are the end position of the tool.
+// I X-axis offset to centre
+// J Y-axis offset to centre
+
+ //if (M_Code == 0) M_Code = StopSpindle; //if not set, make default
+ if (F_Code == 0) F_Code = SlowFeed; //if not set, make slowest feed rate
+ Stepper_LoadNewValues(F_Code, M_Code);
+ Stepper_CalcSteps(Inch_mm,0x01);
+// Stepper_RunArcLine(3); //run as G3
+}
+/********************************************************/
+void G_Code_G4(void)
+{ //G4 Dwell time
+//P Dwell time in seconds
+int delay = 0;
+//TODO HERE: Time needs sorting out, values here are incorrect
+//ms function not scaled correctly and is running at 1/5th speed
+ if (GP_Val != 0)
+ {
+ delay = (int)GP_Val*200;
+ delay_ms(delay);
+ }
+}
+/********************************************************/
+//void G_Code_G10(void)
+//{ //G10 Coordinate system origin
+
+//}
+/********************************************************/
+void G_Code_G20(void)
+{ //G20 Set Units Inches
+ Inch_mm = 20;
+}
+/********************************************************/
+void G_Code_G21(void)
+{ //G21 Set Units Metric mm (This is the machine default setting)
+ Inch_mm = 21;
+}
+/********************************************************/
+void G_Code_G28(void)
+{//Go Home.TODO HERE
+// if(!RapMan_Home())
+// {
+ //home error
+// }
+}
+/********************************************************/
+void G_Code_G90(void)
+{//Absolute Positioning relative to machine home
+ ResetOrigin();
+}
+/********************************************************/
+void G_Code_G91(void)
+{//Incremental Positioning, X5 moves +5 units regardless of where the tool is
+ //TODO HERE
+}
+/********************************************************/
+void G_Code_G92(void)
+{//Set new origin point
+ //G92 X10 Y20 Z0 sets the new origin to these coordinates
+ G_Code_G0(); //Go to new origin
+ OriginOffset(); //Set new origin
+}
+
+/********************************************************/
+// M Code Functions to be added here.
+// Please use same format and annotate.
+/********************************************************/
+void M_Code_M101(void)
+{ //"101" Extruder on
+ //Switch to flag any special functions required when Extruder is ON
+ if (ToolType == 2) //2 is EXTRUDER
+ {
+ ExtruderStatus = 1;
+ }
+}
+/********************************************************/
+void M_Code_M103(void)
+{ //"103" Extruder off
+ //Switch to flag any special functions required when Extruder is OFF
+ if (ToolType == 2) //2 is EXTRUDER
+ {
+ ExtruderStatus = 0;
+ }
+}
+/********************************************************/
+void M_Code_M104(void)
+{ //M104 S145.0 Set temperature to 145.0 C
+extern X_Rest_mm;
+extern Y_Rest_mm;
+extern Z_Rest_mm;
+
+ if (ToolType == 2) //2 is EXTRUDER
+ {
+ OLED_ClearLine(4);
+ OLED_ClearLine(5);
+ OLED_ClearLine(6);
+ OLED_FastText57(5, 0, "TEMPERATURE CHANGE",0);
+
+ temperature_OK = FALSE; //assume temperature is false to start with
+ Change_M104 = 1; //Flag to indicate the temperature change is generated
+ //by this G-Code instruction
+
+ if (GS_Val != 0)SetTemperature = GS_Val;
+ GoToRest();
+ Extruder_Status(On); //enables the temperature interrupt
+ do
+ {
+ OLED_UpdateThermistorReading();
+ OLED_UpdateSetTemperature();
+ OLED_UpdateSetRPM();
+ }
+ while(temperature_OK == FALSE && SetTemperature != 0);
+ Change_M104 = 0; //Reset flag for normal temperature control
+ //Delayms(1000);
+ OLED_ClearLine(5); //Clear msg
+ }
+}
+/********************************************************/
+void M_Code_M106(void)
+{ // M106 Turn fan on.
+extern char EnableFanControl; //Set if Fan is to be active
+ EnableFanControl=TRUE;
+ FAN = On;
+}
+/********************************************************/
+void M_Code_M107(void)
+{ // M107 Turn fan off.
+extern char EnableFanControl; //Set if Fan is to be active
+ EnableFanControl=FALSE;
+ FAN = OFF;
+}
+/********************************************************/
+void M_Code_M108(void)
+{ //M108 S210 Set extruder speed to 21.0 RPM
+ if (ToolType == 2)
+ {
+ if (GS_Val > 0) RPM_Setting = GS_Val;
+ Control_Stepper_Motor();
+ RPM_Change = 1;//flag to indicate change in value
+ }
+}
+/********************************************************/
+void M_Code_M220(void)
+{ //M220 Aux OFF
+ AUX = OFF;
+}
+/********************************************************/
+void M_Code_M221(void)
+{ //M220 Aux ON
+ AUX = On;
+}
+/********************************************************/
+void M_Code_M222(void)
+{ //M222 S500 Set fast XY move to 500 Fast
+ if (ToolType == 2)
+ {
+ if (GS_Val > 0) G_CodeRapidXYMove = GS_Val;
+ }
+}
+/********************************************************/
+void M_Code_M223(void)
+{ //M223 S500 Set fast Z move to 500 Fast
+ if (ToolType == 2)
+ {
+ if (GS_Val > 0) G_CodeRapidZMove = GS_Val;
+ }
+}
+/********************************************************/
+void M_Code_M224(void) //Enable extruder motor during fast move
+{
+ FastMoveMotorEnable = TRUE;
+}
+/********************************************************/
+void M_Code_M225(void) //Disable extruder motor during fast move
+{//Defailt setting
+ FastMoveMotorEnable = FALSE;
+}
+/********************************************************/
+void M_Code_M226(void) //Issue a Pause command from G-Code
+{
+extern float Save3_X, Save3_Y; //defined in Stepper.c
+extern char EOF_Flag; //defined in RapMan.h
+
+ while (SBR!= SBW) //let buffer empty then continue
+ {
+ if ((EOF_Flag == 1)&&(SBW+1 == SBR))
+ {//at end of file and one entry in buffer, let it go
+ SBW = SBR;
+ }
+ };
+ Pause_Print();
+ while(!Manual_Select); //wait for key up
+ RapMan_MoveTo(Save3_X,Save3_Y,0,0); //move back to print.
+}
+/********************************************************/
+void M_Code_M227(void)
+{ //M228 Enable Extruder reverse during extruder off
+ //P=reverse time in ms S=prime time in ms P would
+ //normally be longer than S
+
+ if (ToolType == 2)
+ {
+ Ex_Reverse = TRUE;
+ if (GS_Val > 0) Reverse_Steps = ceil(GS_Val);
+ if (GP_Val > 0) Prime_Steps = ceil(GP_Val);
+ }
+}
+/********************************************************/
+void M_Code_M228(void)
+{ //M228 Disable Extruder reverse during extruder off
+ if (ToolType == 2)
+ {
+ Ex_Reverse = FALSE;
+ }
+}
+/********************************************************/
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/G_Code.d b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/G_Code.d new file mode 100644 index 00000000..845132cd --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/G_Code.d @@ -0,0 +1,7 @@ +G_Code.o: G_Code.c G_Code.h Stepper.h Extruder.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h \
+ Enviroment.h
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/G_Code.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/G_Code.h new file mode 100644 index 00000000..ce99f44e --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/G_Code.h @@ -0,0 +1,194 @@ +/**********************************************************************
+ *************************** G_Code.h *******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+//List of G-Codes.
+//See G_Code.c for list of the ones implemented
+/*
+RS274NGC G-CODE PROGRAMMING
+
+G and M Code Modal Groups
+group 1 = {G0, G1, G2, G3, G80, G81, G82, G83, G84, G85, G86, G87, G88, G89} - motion
+group 2 = {G17, G18, G19} - plane selection
+group 3 = {G90, G91} - distance mode
+group 5 = {G93, G94} - spindle speed mode
+group 6 = {G20, G21} - units
+group 7 = {G40, G41, G42} - cutter diameter compensation
+group 8 = {G43, G49} - tool length offset
+group 10 = {G98, G99} - return mode in canned cycles
+group12 = {G54, G55, G56, G57, G58, G59, G59.1, G59.2, G59.3} coordinate system selection
+
+group 2 = {M26, M27} - axis clamping
+group 4 = {M0, M1, M2, M30, M60} - stopping
+group 6 = {M6} - tool change
+group 7 = {M3, M4, M5} - spindle turning
+group 8 = {M7, M8, M9} - coolant
+group 9 = {M48, M49} - feed and speed override bypass
+
+
+Words acceptable to the interpreter
+No D Tool radius compensation number
+Yes F Feedrate
+Yes G General function see list below
+No H Tool length offset
+No I X-axis offset for arcs
+No J Y-axis offset for arcs
+No K Z-axis offset for arcs
+No L Number of repetitions in canned cycles
+Yes M Miscellanious function
+No N Line Number
+Yes P Dwell time in G4 and canned cycles
+No Q Feed increment in G83 canned cycle
+ Key used with G10
+No R arc radius
+Yes S canned cycle plane
+No T Tool selection
+Yes X X-axis of machine
+Yes Y Y-axis of machine
+Yes Z Z-axis of machine
+*/
+
+/*
+Yes G00 rapid positioning
+Yes G01 linear interpolation
+No G02 circular/helical interpolation (clockwise)
+No G03 circular/helical interpolation (c-clockwise)
+Yes G04 dwell
+Yes G10 coordinate system origin setting
+No G17 xy plane selection
+No G18 xz plane selection
+No G19 yz plane selection
+Yes G20 inch system selection
+Yes G21 millimeter system selection
+No G40 cancel cutter diameter compensation
+No G41 start cutter diameter compensation left
+No G42 start cutter diameter compensation right
+No G43 tool length offset (plus)
+No G49 cancel tool length offset
+No G53 motion in machine coordinate system
+G54 use preset work coordinate system 1
+G55 use preset work coordinate system 2
+G56 use preset work coordinate system 3
+G57 use preset work coordinate system 4
+G58 use preset work coordinate system 5
+G59 use preset work coordinate system 6
+G59.1 use preset work coordinate system 7
+G59.2 use preset work coordinate system 8
+G59.3 use preset work coordinate system 9
+G80 cancel motion mode (includes canned)
+G81 drilling canned cycle
+G82 drilling with dwell canned cycle
+G83 chip-breaking drilling canned cycle
+G84 right hand tapping canned cycle
+G85 boring, no dwell, feed out canned cycle
+G86 boring, spindle stop, rapid out canned
+G87 back boring canned cycle
+G88 boring, spindle stop, manual out canned
+G89 boring, dwell, feed out canned cycle
+Yes G90 absolute distance mode
+Yes G91 incremental distance mode
+Yes G92 offset coordinate systems
+G92.2 cancel offset coordinate systems
+G93 inverse time feed mode
+G94 feed per minute mode
+G98 initial level return in canned cycles
+
+M0 program stop
+M1 optional program stop
+M2 program end
+M3 turn spindle clockwise
+M4 turn spindle counterclockwise
+M5 stop spindle turning
+M6 tool change
+M7 mist coolant on
+M8 flood coolant on
+M9 mist and flood coolant off
+M26 enable automatic b-axis clamping
+M27 disable automatic b-axis clamping
+M30 program end, pallet shuttle, and reset
+M48 enable speed and feed overrides
+M49 disable speed and feed overrides
+M60 pallet shuttle and program stop
+
+RepRap special codes
+GCode generated by March 29,2007 Skeinforge
+M100 P210 Set extruder speed to 210.0
+M103 Turn extruder off.
+M101 Turn extruder on.
+M104 P145.0 Set temperature to 145.0 C.
+M105 Custom code for temperature reading.
+M106 Turn fan on.
+M107 Turn fan off.
+M108 P0.8 Set extrusion diameter to 0.8 mm.
+**********************
+BFB codes
+**********************
+M220 Turn off AUX
+M221 Turn on AUX
+M222 Set speed of fast XY moves
+M223 Set speed of fast Z moves
+M224
+M225
+**********************
+*/
+
+extern char ToolType; //1 Pen, 2 Extruder1 , 3 Extruder2, 4 Not Defined, 5 Router, 0 No Tool fitted
+extern long SetTemperature; //value for extruder
+extern int temperature_OK;
+extern int RPM_Setting; //value for extruder
+extern int SBR, SBW; //Buffer pointers
+
+extern int Ex_Reverse;
+extern int Reverse_Steps;
+extern int Prime_Steps;
+
+char Change_M104;
+char FeedRate_ManualChange;
+char FastMoveMotorEnable;//Flag to switch motor on/off during fast move
+
+
+/*****************************************************************************/
+/* External Functions */
+/*****************************************************************************/
+extern void G_CodeRun(char GC_L, int iGC_N, char GC_1L, float fGC_1, char GC_2L,
+ float fGC_2, char GC_3L, float fGC_3, char GC_4L,float fGC_4);
+
+extern void M_Code_M104(void); //enable external tremperature control
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/HIDBootLoader.exe b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/HIDBootLoader.exe Binary files differnew file mode 100644 index 00000000..0a6c7178 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/HIDBootLoader.exe diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/HardwareProfile.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/HardwareProfile.h new file mode 100644 index 00000000..1170c6fd --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/HardwareProfile.h @@ -0,0 +1,60 @@ +
+#ifndef _HARDWAREPROFILE_H_
+#define _HARDWAREPROFILE_H_
+
+
+#define RUN_AT_80MHZ
+#define GetSystemClock() (80000000ul)
+#define GetPeripheralClock() (GetSystemClock()/2)
+#define GetInstructionClock() (GetSystemClock())
+#define MILLISECONDS_PER_TICK 10
+#define TIMER_PRESCALER TIMER_PRESCALER_8
+#define TIMER_PERIOD 37500
+
+
+#define USE_SD_INTERFACE_WITH_SPI
+
+//I guess here we need SPI2 as PIC32MX440H only has SPI2
+#define MDD_USE_SPI_2
+
+#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON)
+#define SPI_START_CFG_2 (SPI_ENABLE)
+#define SPI_FREQUENCY (20000000)
+
+// SD-SPI
+#define SD_CS PORTBbits.RB1 // Chip Select Output bit
+#define SD_CD PORTEbits.RE4 // Card Detect Input bit
+#define SD_WE PORTEbits.RE3 // Write Protect Check Input bit
+
+#define SD_CS_TRIS TRISBbits.TRISB1 // Chip Select TRIS bit
+#define SD_CD_TRIS TRISEbits.TRISE4 // Card Detect TRIS bit
+#define SD_WE_TRIS TRISEbits.TRISE3 // Write Protect Check TRIS bit
+
+
+#define SPICON1 SPI2CON
+#define SPISTAT SPI2STAT
+#define SPIBUF SPI2BUF
+#define SPISTAT_RBF SPI2STATbits.SPIRBF
+#define SPICON1bits SPI2CONbits
+#define SPISTATbits SPI2STATbits
+#define SPIENABLE SPI2CONbits.ON
+#define SPIBRG SPI2BRG
+
+// Tris pins for SCK/SDI/SDO lines
+#define SPICLOCK TRISGbits.TRISG6 // The TRIS bit for the SCK pin
+#define SPIIN TRISGbits.TRISG7 // The TRIS bit for the SDI pin
+#define SPIOUT TRISGbits.TRISG8 // The TRIS bit for the SDO pin
+#define putcSPI putcSPI2
+#define getcSPI getcSPI2
+#define OpenSPI(config1, config2) OpenSPI2(config1, config2)
+
+/* added from newer BfB code: */
+
+// Description: The main SPI 2 control register
+#define SPICON2 SPI2CON
+#define SPICON2bits SPI2CONbits
+
+
+/* end of added code */
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/OLED.c b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/OLED.c new file mode 100644 index 00000000..71c88b35 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/OLED.c @@ -0,0 +1,654 @@ +/**********************************************************************
+ *************************** OLED.c *********************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+#include <p32xxxx.h>
+#include "OLED.h"
+#include "Screens.h"
+#include "stepper.h"
+#include "extruder.h"
+
+//SPI2 pins for OLED
+#define OLED_CS PORTBbits.RB5 //Analog pin
+#define DC PORTEbits.RE6 //Digital
+#define RES PORTEbits.RE7 //Digital
+
+
+extern int RPM_Setting;
+extern long SetTemperature;
+extern float temperature1;
+extern int HeaterON;
+extern int LineNumber;
+extern char SaveFileName[12];
+
+float ExtrusionRate;
+/**************************************************/
+/* Forward Declarations */
+/**************************************************/
+int WriteSPI(int i);
+void write_command(unsigned char command);
+void write_data(unsigned char data);
+void Fill_RAM(unsigned char Data);
+
+/***********************************************************/
+void OLED_Printing_Screen(void) //Static Lables only
+{
+extern int ToolType;
+
+ OLED_FastText57(0, 0, OLED_Header_VerNo,0);
+ OLED_FastText57(1, 28, SaveFileName,0);
+ OLED_FastText57(2, 0, "G-Code Line:",0); //Display G Code line number
+ OLED_FastText57(3, 0, "Head Speed:",0); //Display Feed Rate
+ if (ToolType==2)OLED_FastText57(4, 0, "Ext. Rate:",0); //Display Extrusion Rate
+
+}//OLED_Printing_Screen
+
+/***********************************************************/
+void OLED_UpdatePrintScreen(void) //Info updated every G_Code line
+{
+char AsciiString[10];
+float data1;
+extern int S_F_Code;
+extern int ToolType;
+
+ sprintf(AsciiString, "%1u", LineNumber); //Converts number to text
+ OLED_FastText57(2, 90, AsciiString,0); //Write the new number
+
+ if (S_F_Code > 0 )
+ {
+ data1 = (float)S_F_Code/60;
+ sprintf(AsciiString, "%5.1fmm/s", data1); //Converts number to text
+ OLED_FastText57(3, 75, AsciiString,0); //Write the new number
+ ExtrusionRate = (float)RPM_Setting*0.056; //factor is 0.0563814
+ sprintf(AsciiString, "%5.1fmm/s", ExtrusionRate); //Converts number to text
+ OLED_FastText57(4, 75, AsciiString,0); //Write the new number
+ }
+ else
+ OLED_FastText57(3, 75, "Not Set",0);
+
+
+ ShowBufferFillState(); //ln6 Show how full the look ahead buffer is
+ ShowPrintProgress(); //ln5 Progress through the file
+
+ if (ToolType==2)//Extruder
+ {
+ OLED_UpdateThermistorReading();
+ if (Temp_Change)OLED_UpdateSetTemperature(); //Update only if changed
+ if (RPM_Change)OLED_UpdateSetRPM(); //Update only if changed
+ }
+
+}//OLED_UpdatePrintScreen
+
+/***********************************************************/
+void OLED_Extruder_Screen(void)
+{
+ OLED_FastText57(0, 0, OLED_Header_VerNo,0);
+ OLED_FastText57(1, 0, "Extruder Control",0);
+
+ if(HEATER)OLED_FastText57(5, 0, "Heater On ",0);
+ else OLED_FastText57(5, 0, "Heater Off",0);
+
+ if (temperature1 < 100)
+ {
+ OLED_FastText57(3, 0, " <100C Motor OFF",0);
+ }
+ else
+ OLED_ClearLine(3);
+
+ OLED_UpdateSetTemperature();
+ OLED_UpdateThermistorReading();
+ OLED_UpdateSetRPM();
+
+}//OLED_Extruder_Screen
+
+/***********************************************************/
+void OLED_UpdateThermistorReading(void)
+{
+char AsciiString[10];
+int data1;
+
+ if (temperature1 == 999||temperature1 == -1){
+ OLED_ClearLine(7);
+ if (temperature1 == 999)OLED_FastText57(7, 10,"TEMPERATURE ERROR",0);
+ if (temperature1 == -1)OLED_FastText57(7, 10, "THERMISTOR ERROR",0);
+ return;
+ }
+
+ data1=(int)temperature1; //Display actual temperature
+ sprintf(AsciiString, "%3uC", (int)data1); //Converts number to text
+ OLED_FastText57(7, 45, AsciiString,0); //Write the new number
+ if(HEATER)OLED_FastText57(7, 35, "*",0); //Heater indication
+ else OLED_FastText57(7, 35, " ",0);
+
+}// OLED_UpdateThermistorReading
+
+/***********************************************************/
+void OLED_UpdateSetRPM(void)
+{
+char AsciiString[10];
+int data1;
+extern char RPM_Change; //set if RPM has changed
+
+ data1=RPM_Setting/10; //Display RPM Setting
+ sprintf(AsciiString, "%3uRPM", (int)data1); //Converts number to text
+ OLED_FastText57(7, 85, AsciiString,0); //Write the new number
+
+ OLED_FastText57(4, 0, "Ext. Rate:",0); //Display Extrusion Rate
+ ExtrusionRate= (float)RPM_Setting*0.04643;
+ sprintf(AsciiString, "%5.1fmm/s", ExtrusionRate); //Converts number to text
+ OLED_FastText57(4, 75, AsciiString,0); //Write the new number
+
+ RPM_Change = 0;
+
+}//OLED_UpdateSetRPM
+
+/***********************************************************/
+void OLED_UpdateSetTemperature(void)
+{
+char AsciiString[10];
+extern char Temp_Change; //set if Temperature has changed
+
+ if (SetTemperature <0)SetTemperature = 0;
+ sprintf(AsciiString, "%3uC", (int)SetTemperature); //Converts number to text
+ OLED_FastText57(7, 0, AsciiString,0); //Write the new number
+ Temp_Change = 0;
+
+}//OLED_UpdateSetTemperature
+
+/***********************************************************/
+void OLED_Fill_RAM(unsigned char Data)
+{
+unsigned char i,j;
+
+ for(i=0;i<8;i++){
+ write_command(0xB0+i);
+ write_command(0x00);
+ write_command(0x10);
+ for(j=0;j<128;j++)write_data(Data);
+ }
+}//OLED_Fill_RAM
+
+/***********************************************************/
+void OLED_ProgressBar(unsigned char Line, int Value)
+{
+unsigned char j;
+
+ write_command(0xB0+Line);
+ write_command(0x00);
+ write_command(0x10);
+
+ for(j=0;j<Value;j++)
+ {
+ write_data(0x18);
+ }
+ for(j=Value;j<128;j++)
+ {
+ write_data(0x00);
+ }
+}//OLEDProgressBar
+
+/***********************************************************/
+void OLED_ClearLine(unsigned char Line) {
+
+unsigned char j;
+
+ write_command(0xB0+Line);
+ write_command(0x00);
+ write_command(0x10);
+
+ for(j=0;j<128;j++)
+ {
+ write_data(0x00);
+ }
+}//OLEDClearLine
+
+/***********************************************************/
+void OLED_BitMapFill_RAM(unsigned char screen)
+{
+unsigned char i,j;
+const unsigned char *screen_ptr;
+int offset;
+
+switch(screen)
+ {
+ case DSP_RAPMAN_LOGO:
+ {
+ screen_ptr = RAPMAN_LOGO;
+ break;
+ }
+ case DSP_BfB_LOGO:
+ {
+ screen_ptr = BfB_LOGO;
+ break;
+ }
+ case DSP_EXTRUDER_SCREEN:
+ {
+ screen_ptr = EXTRUDER_SCREEN;
+ break;
+ }
+ }
+
+ for(i=0;i<8;i++) //loop through 8 pages
+ {
+ offset = i*128;
+ write_command(0xB0+i); //set start of page
+ write_command(0x00);
+ write_command(0x10);
+
+ for(j=0;j<128;j++) //loop through each col on page
+ {
+ write_data(screen_ptr[offset+j]);
+ }
+ }
+}//BitMapFill_RAM
+
+/***********************************************************/
+void OLED_FastText57(int txtpage, int txtcol, unsigned char* textptr, unsigned char colour)
+{
+
+unsigned char add, lAddr, hAddr;
+int i, j, k; // Loop counters
+unsigned char pixelData[5]; // Stores character data
+
+ k = 0;
+ add = txtcol;
+ lAddr = 0x0F & add; // Low address
+ hAddr = 0x10 | (add >> 4); // High address
+
+ write_command(0xB0 + txtpage); //set start page
+ write_command(lAddr);
+ write_command(hAddr);
+
+ for(i=0; textptr[i] != '\0'; ++i) // Loop through the passed string
+ {
+ if(textptr[i] < 'S') // Checks if the letter is in the first text array
+ memcpy(pixelData, TEXT[textptr[i]-' '], 5);
+ else
+ if(textptr[i] <= '~') // Check if the letter is in the second array
+ {
+ if (textptr[i]>91)//if ascii char is > [ then realign
+ {
+ memcpy(pixelData, TEXT2[textptr[i]- 84], 5); //1 more than S to realign the lower case letters
+ }
+ else
+ memcpy(pixelData, TEXT2[textptr[i]-'S'], 5);
+ }
+ else
+ memcpy(pixelData, TEXT[0], 5); // Default to space
+
+ for(j=0; j<5; ++j) // Loop through character byte data
+ {
+ if (k <128){
+ if (colour == 0)
+ {
+ write_data(pixelData[j]);
+ }
+ else
+ {
+ write_data(~pixelData[j]);
+ }
+ ++k;
+ }
+ else{ //text wrap if required
+ write_command(0xB0 + txtpage+1);
+ write_data(pixelData[j]);
+ }
+ }
+ write_data(0x00);
+ ++k;
+ }
+}//OLED_FastText
+
+/***********************************************************/
+void OLED_Start_Menu(void)
+{
+ OLED_Fill_RAM(BLANK_SCREEN); //clear screen
+ OLED_FastText57(0, 10, OLED_Header_VerNo,0);
+ OLED_FastText57(1, 20, OLED_Menu_Title0,0);
+ OLED_FastText57(2, 20, OLED_Menu_0,0);
+ OLED_FastText57(3, 20, OLED_Menu_1,0);
+ OLED_FastText57(4, 20, OLED_Menu_2,0);
+ OLED_FastText57(5, 20, OLED_Menu_3,0);
+
+}//OLED_Start_Menu
+
+/***********************************************************/
+void OLED_Manual_Screen(void)
+{
+ OLED_Fill_RAM(BLANK_SCREEN); //clear screen
+ OLED_FastText57(0, 10, OLED_Header_VerNo,0);
+ OLED_FastText57(1, 0, "MANUAL", 0);
+ OLED_FastText57(4, 0, "X_Step:",0);
+ OLED_FastText57(5, 0, "Y_Step:",0);
+ OLED_FastText57(6, 0, "Z_Step:",0);
+
+}//OLED_Manual_Screen
+
+/***********************************************************/
+void OLED_Auto_Screen(void)
+{
+ OLED_Fill_RAM(BLANK_SCREEN); //clear screen
+ OLED_FastText57(0, 10, OLED_Header_VerNo,0);
+ OLED_FastText57(1, 20,OLED_Auto_Load,0);
+
+}//OLED_Auto_Screen
+
+/***********************************************************/
+ void OLED_ToolSetup_Screen(void)
+{
+ OLED_ClearLine(1);
+ OLED_FastText57(1, 20,OLED_ToolSet,0);
+
+}//OLED_ToolSetup_Screen
+
+/***********************************************************/
+void OLED_Home_Screen(void)
+{
+ OLED_Fill_RAM(BLANK_SCREEN); //clear screen
+ OLED_FastText57(1, 0,OLED_Home,0);
+
+}//OLED_Home_Screen
+
+/***********************************************************/
+void OLED_RapManMove_Screen(float X_pos, float Y_pos, float Z_pos, char DoZmove)
+{
+char AsciiString[10];
+
+ OLED_Fill_RAM(BLANK_SCREEN); //clear screen
+ OLED_FastText57(1, 0, "MOVE TO:",0);
+ sprintf(AsciiString, "X=%6.2f",X_pos); // Converts number to text
+ OLED_FastText57(3, 0, AsciiString,0); // Write the new number
+ sprintf(AsciiString, "Y=%6.2f",Y_pos); // Converts number to text
+ OLED_FastText57(4, 0, AsciiString,0); // Write the new number
+ if (DoZmove)
+ {
+ sprintf(AsciiString, "Z=%6.2f",Z_pos); // Converts number to text
+ OLED_FastText57(5, 0, AsciiString,0); // Write the new number
+ }
+ else OLED_FastText57(5, 0, "NO Z MOVE",0);
+
+}//OLED_Home_Screen
+
+/***********************************************************/
+void OLED_FileEnd_Screen(void)
+{
+ OLED_Fill_RAM(BLANK_SCREEN);
+ OLED_FastText57(0, 0, "Prog.End",0);
+ OLED_FastText57(2, 0, "Return to Menu",0);
+ OLED_FastText57(4, 0, "<<< Press Esc.",0);
+
+}//OLED_FileEnd_Screen
+
+/***********************************************************/
+void OLED_SetCursor(int txtpage, int txtcol, unsigned char colour)
+{
+ //Cursor
+ switch (txtpage)
+ {
+ case 0: //txtpage 0 reserved for headings
+ {
+ // OLED_FastText57(0, txtcol, OLED_Cursor, colour);
+ // OLED_FastText57(1, txtcol, " ",0);
+ // OLED_FastText57(2, txtcol, " ",0);
+ // OLED_FastText57(3, txtcol, " ",0);
+ // OLED_FastText57(4, txtcol, " ",0);
+ // OLED_FastText57(5, txtcol, " ",0);
+ // OLED_FastText57(6, txtcol, " ",0);
+ // OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 1:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 2:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 3:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 4:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 5:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 6:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 7:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, OLED_Cursor, colour);
+ break;
+ }
+ }
+
+}//OLED_SetCursor
+
+/***********************************************************/
+//SCREEN DRIVER
+//Col address 0 to 127 is made up of a high and low nibble screen address
+//col 1 is lower nibble 1, higher nibble 0
+//col 127 is lower nibble = f, higher nibble 7
+/***********************************************************/
+int WriteSPI(int i) {
+
+ SPI2BUF = i;
+ while( !SPI2STATbits.SPIRBF);
+ return SPI2BUF;
+
+}//WriteSPI
+
+/***********************************************************/
+void write_command(unsigned char command){
+
+ DC = 0; //When Low send Display command
+ OLED_CS = 0; //OLED chip select
+ WriteSPI(command);
+ OLED_CS = 1;
+ DC =1;
+
+}//write_command
+
+/***********************************************************/
+void write_data(unsigned char data) {
+
+ DC =1;
+ OLED_CS = 0;
+ WriteSPI(data);
+ OLED_CS = 1;
+ DC =1;
+
+}//write_data
+
+/***********************************************************/
+void Fill_RAM(unsigned char Data)
+{
+unsigned char i,j;
+
+ for(i=0;i<8;i++)
+ {
+ write_command(0xB0+i);
+ write_command(0x00);
+ write_command(0x10);
+
+ for(j=0;j<128;j++)
+ {
+ write_data(Data);
+ }
+ }
+}//Fill_RAM
+
+/***********************************************************/
+int OLED_Init(void)
+{
+unsigned int i = 0;
+
+ SPI2CON = 0x8120; //Enable & configure SPI port
+
+ DC = 0; //When Low D7-D0 is Display command
+ OLED_CS = 0; //Communication with chip only when Low
+ RES = 0; //Reset when pin is low
+ for(i=0;i<2000;i++); //10ms delay
+ RES = 1; //Reset complete
+ for(i=0;i<2000;i++); //10ms delay
+ OLED_CS = 1;
+
+//LCD commands
+//panel_128x64
+ write_command(0xd5); //SetDisplayClock(0x10)
+ write_command(0x10);
+
+ write_command(0xd3); //SetDisplayOffset(0)
+ write_command(0);
+
+ write_command(0xa8); //SetMultiplex(63)
+ write_command(63);
+
+ write_command(0xd8); //SetAreaColor(0)
+ write_command(0);
+
+ write_command(0x40); //SetStartLine(0)
+
+ write_command(0xa0); //SetSegmentReMap(0)
+
+ write_command(0xc8); //SetCOMScan(8)
+
+ write_command(0xda); //SetCOMHWConfig(0x12)
+ write_command(0x12);
+
+ write_command(0x81); //SetContrast(0xff)
+ write_command(0xf0);
+
+ write_command(0xa4); //SetEntireDisplay(0)
+
+ write_command(0xd9); //Setprecharge(0xf2)
+ write_command(0xf2);
+
+ write_command(0xa6); //SetNormal_Inverse_Display(0xa6 or 0xa7)
+
+ write_command(0x26); //horizontal scroll setup
+ write_command(0x01);
+ write_command(0x00);
+ write_command(0x00);
+ write_command(0x01);
+
+ Fill_RAM(0x00); //Clear screen
+ for(i=0;i<2000;i++);
+ write_command(0xAF); //display on
+
+}//InitOLED
+
+/***********************************************************/
+void OLED_Start_Msg(void)
+{
+ // Start Message
+ OLED_Fill_RAM(BLANK_SCREEN); //Clear screen
+ OLED_BitMapFill_RAM(DSP_BfB_LOGO);
+ Delayms(200);
+ OLED_Fill_RAM(BLANK_SCREEN); //Clear screen
+ OLED_BitMapFill_RAM(DSP_RAPMAN_LOGO);
+ Delayms(200);
+
+}//OLED_Start_Msg
+
+/***********************************************************/
+
+
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/OLED.d b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/OLED.d new file mode 100644 index 00000000..4038c91a --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/OLED.d @@ -0,0 +1,8 @@ +OLED.o: OLED.c \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h OLED.h \
+ Screens.h stepper.h extruder.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h \
+ Enviroment.h
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/OLED.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/OLED.h new file mode 100644 index 00000000..f45056e0 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/OLED.h @@ -0,0 +1,79 @@ +/**********************************************************************
+ *************************** OLED.h *********************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+#define OLED_Header_VerNo "RapMan v1.0.8-Erik" //UPDATE VERSION NUMBER HERE (1.0.8)
+#define OLED_Auto_Load "AUTO: Loading.."
+#define OLED_ToolSet "TOOL SETUP"
+#define OLED_Home "HOMING PLEASE WAIT"
+#define OLED_Menu_Title0 "MENU"
+#define OLED_Menu_0 "RUN FILE"
+#define OLED_Menu_1 "MANUAL MOVE"
+#define OLED_Menu_2 "TOOL SETUP"
+#define OLED_Menu_3 "HOME TOOL HEAD"
+#define OLED_Cursor ">"
+
+#define BLANK_SCREEN 0x00
+#define DSP_RAPMAN_LOGO 0
+#define DSP_BfB_LOGO 1
+#define DSP_EXTRUDER_SCREEN 2
+
+extern void OLED_Fill_RAM(unsigned char Data);
+extern void OLED_BitMapFill_RAM(unsigned char screen);
+extern void OLED_ProgressBar(unsigned char Line, int Value);
+extern void OLED_ClearLine(unsigned char Line);
+extern void OLED_FastText57(int txtpage, int txtcol, unsigned char* textptr, unsigned char colour);
+extern void OLED_Start_Menu(void);
+extern void OLED_Auto_Screen(void);
+extern void OLED_Manual_Screen(void);
+extern void OLED_ToolSetup_Screen(void);
+extern void OLED_Home_Screen(void);
+extern void OLED_RapManMove_Screen(float X_pos, float Y_pos, float Z_pos, char DoZmove);
+extern void OLED_FileEnd_Screen(void);
+extern void OLED_SetCursor(int txtpage, int txtcol, unsigned char colour);
+extern void OLED_Printing_Screen(void);
+extern int OLED_Init(void);
+extern void OLED_Start_Msg(void);
+
+extern void OLED_Extruder_Screen(void);
+extern void OLED_UpdatePrintScreen(void);
+extern void OLED_UpdateThermistorReading(void);
+extern void OLED_UpdateSetTemperature(void);
+extern void OLED_UpdateSetRPM(void);
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan.c b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan.c new file mode 100644 index 00000000..362047a4 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan.c @@ -0,0 +1,1015 @@ +/**********************************************************************
+ *************************** RapMan.c *******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+
+/***********************************************************
+************************Rap_Man*****************************
+************************************************************
+*
+*Notes for G_Code syntax for input file.
+*The Progamme has been developed using:
+*ACE DXF Converter
+*Eagle PCB
+*Enrique's Skienforge STL to G_Code
+*
+*Performance with other converters or G_Code from other
+*sources should be checked before running.
+*
+*Basic File requirement.
+* 1) Max line length is 50 characters long.
+* 2) Alows Blank lines
+* 3) One instruction per line
+* 4) G0 feed fast feed
+* G1 - If no F code is found the default slowest feed
+* rate will be used
+* 5) M Codes should be added to the file as required.
+* This should be the only instruction on the line.
+* If more than one Mcode is required, each should be
+* placed on a new line
+* 6) The default filenames on the SD-Card are *.bfb or *.gco
+* 7) Any line started with a open bracket is ignored
+* as comment
+* 8) GCode format is with a space between axis data.
+
+************************************************************
+************************Rap_Man*****************************
+************************************************************/
+
+#pragma config POSCMOD=XT, FNOSC=PRIPLL, FSOSCEN = OFF
+#pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_20, FPLLODIV=DIV_1 //(8MHz/2)=4 *20=80 /1=80MHz
+#pragma config FWDTEN=OFF, CP=OFF, BWP=OFF
+
+#include <p32xxxx.h>
+#include "RapMan.h"
+#include "OLED.h"
+#include <int.h>
+
+#define NUNBER_OF_MENU_ITEMS 3 //equals number of menu items -1
+#define PRINT_OBJECT 0
+#define MANUAL_MOVE_HEAD 1
+#define TOOL_CONTROL 2
+#define SEND_TO_HOME 3
+//Tool Head Defines
+#define NO_TOOL 0
+#define PEN 1
+#define EXTRUDER 2
+#define EXTRUDER2 3
+#define NOT_DEFINED 4
+#define ROUTER 5
+
+int Start_Menu(void);
+int GetMenuSelection(void);
+void Print_Gcode_File(void);
+void Pause_Print(void);
+void ErrorCondition(int ErrNo);
+
+char CharBuffer[1];
+unsigned char LineBuffer[50];
+
+int ADC_readingToolID = 0;
+int SampleCountToolID = 0;
+long AveSamplesToolID = 0;
+int Operation_Mode = 0;
+
+char ToolType = 0; //1 Pen, 2 Extruder1 , 3 Extruder2
+ //4 Not Defined, 5 Router, 0 No Tool fitted
+
+int SetTemp = 0; //value for extruder
+int SetRPM = 0; //value for extruder
+
+int GoToRestSpeed = 0;
+
+//File type switch
+int FileType = INVALID_FILE; //init to invalid file type
+
+/***********************************************************
+ * Function: int main(void)
+ *
+ * PreCondition: None
+ *
+ * Input: None
+ *
+ * Output: None
+ *
+ * Overview:
+ *
+ * Note: Modules:Stepper, Manual, G_Code External
+ * functions are prefixed with the module name, internal functions
+ * have no prefix. This does not apply to third party modules like
+ * SPI, FSIO and LCD.
+ *
+ ************************************************************/
+//*************************************************************
+/*
+int main( void )
+{
+// Setup(); //Configure the IO etc
+TRISDbits.TRISD11 = OUTPUT_PIN; //FET
+// OLED_Start_Msg();
+ while(TRUE) //restart prog
+ {
+PORTDbits.RD11 = On;
+Delayms(200);
+PORTDbits.RD11 = OFF;
+
+ }
+} // main
+*/
+int main( void )
+{
+int Operation_Mode;
+
+ Setup(); //Configure the IO etc
+ OLED_Start_Msg();
+ while(TRUE) //restart prog
+ {
+ while(!XPlusRight_Btn); //wait for key up
+ Operation_Mode = Start_Menu();
+ switch(Operation_Mode)
+ {
+ case PRINT_OBJECT: Print_Gcode_File(); break;
+ case MANUAL_MOVE_HEAD: Manual_Mode(SHOW_POSITIONS); break; //Maunal control of the tool head
+ case TOOL_CONTROL: if (ToolType==2)Manual_Extruder(); break; //Manual control of the extruder
+ case SEND_TO_HOME: RapMan_Home(); break; //Move to home and reset position
+ }
+ }
+} // main
+
+//*************************************************************
+void Print_Gcode_File(void)
+{
+extern float Save3_X, Save3_Y;
+
+ PauseFlag == 0; //Initialise flag
+ FeedRate_ManualChange = 0;
+
+ if(GetTool_ID() != NO_TOOL){
+ OLED_Fill_RAM(BLANK_SCREEN); //Clear screen
+ OLED_FastText57(0, 10, OLED_Header_VerNo,0);
+ while(!XPlusRight_Btn); //wait for key up
+
+ while (!MDD_SDSPI_MediaDetect())
+ {//Handle no card error
+ OLED_FastText57(2, 0, "Insert SD-Card or",0);
+ OLED_FastText57(4, 0, "<<ESC TO RESUME",0);
+ Delayms(250);
+ if(!Manual_Select) return;
+ }
+ OLED_ClearLine(2); //ensure error msg lines are clear
+ OLED_ClearLine(4);
+
+ OpenReadSDFile(); //sets the file name to open
+ while(!XPlusRight_Btn); //wait for key up
+ if(!Manual_Select) return;
+ if ((FileType == BFB_FILE) || (FileType == GCO_FILE))
+ {
+ if(!RapMan_Home()) return; //Test home completed normally.
+ Operation_Mode = AUTO_MODE;
+ OLED_Fill_RAM(BLANK_SCREEN); //Clear screen
+ OLED_Printing_Screen(); //Static lables
+
+ Stepper_InitIO ();
+ Axis_Stepper_Motors(On);
+
+ do { //MAIN LOOP
+
+ if(!Manual_Select){
+ Pause_Print();
+ while(!Manual_Select);
+ while (SBR!= SBW)
+ {
+ if ((EOF_Flag == 1)&&(SBW+1 == SBR))
+ {//at end of file and one entry in buffer, let it go
+ SBW = SBR;
+ }
+ };
+ RapMan_MoveTo(Save3_X,Save3_Y,0,0);
+ }
+ OLED_UpdatePrintScreen();
+
+ do{ReadData();}while (LineBuffer[1] == 40); //skip comment lines
+ GetCodes(); //Words from the line put into globals
+ //Control now passed to the G_Code module
+ G_CodeRun(Inst_Code_Letter, iInst_Code, Dim_1_Letter, fDim_1, Dim_2_Letter, fDim_2, Dim_3_Letter, fDim_3, Dim_4_Letter,fDim_4);
+
+ FlushBuffer(); //Flush buffer ready for new data
+ if (ToolType==2)
+ {
+ Control_Stepper_Motor();//if the current action is not a fast move
+ }
+
+ if (!ZPlus_up_Btn){FeedRate_ManualChange = 1; ManualChange += 10;}
+ if (!ZMinus_down_Btn){FeedRate_ManualChange = 1; ManualChange -= 10;}
+
+ }//MAIN LOOP
+ while ((EOF_Flag !=1)|(ItemsRead != 0)); //loop to end of file
+ }
+ else{
+ OLED_Fill_RAM(BLANK_SCREEN);
+ OLED_FastText57(2, 0, "Invalid File Type",0);
+ OLED_FastText57(3, 0, "Please only use",0);
+ OLED_FastText57(4, 0, "*.BFB or *.GCO Files",0);
+ while(Manual_Select);
+ }
+ Extruder_Status(OFF); //Disable Stepper
+ Axis_Stepper_Motors(OFF);
+ pointer = FilePointer; //set the file pointer
+ FSfclose (pointer); //close the file
+
+ Setup();
+ OLED_FileEnd_Screen();
+
+ while(Manual_Select);
+ }
+}//Print_Gcode_File
+
+/************************************************************/
+void Pause_Print(void)
+{
+ while(!Manual_Select); //wait for key up
+ OLED_ClearLine(4);
+ OLED_ClearLine(5);
+ OLED_ClearLine(6);
+ OLED_FastText57(5, 0, "PAUSE",0);
+
+ PauseFlag = 1; //to stop heater going on
+ RapMan_MoveTo(X_Rest_mm,Y_Rest_mm,Z_Rest_mm,0); //Move to rest, No Z move
+
+ OLED_FastText57(5, 0, "<<ESC TO RESUME",0);
+
+ do
+ {
+ OLED_UpdateSetTemperature();
+ OLED_UpdateThermistorReading(); //monitor temperature during pause
+ Delayms(500);
+ }
+ while(Manual_Select); //Release from pause
+ PauseFlag = 0;
+ OLED_ClearLine(5); //Clear pause msg
+ Extruder_Status(On); //Heater and motor back on
+ M_Code_M104(); //Hold for temp change
+
+}// Pause_Print
+
+/************************************************************/
+void ErrorCondition(int ErrNo)
+{
+ //Puts the machine in a safe condition if an error is detected
+ OLED_ClearLine(2);
+ OLED_ClearLine(3);
+ OLED_ClearLine(4);
+ OLED_ClearLine(5);
+ OLED_ClearLine(6);
+ OLED_ClearLine(7);
+
+ switch(ErrNo)
+ { //Definitions in RapMan.h
+ case TEST:
+ OLED_FastText57(3, 0, "Error TEST",0);
+ if (ToolType == 2 )//Extruder
+ {
+ Extruder_Status(OFF);
+ OLED_FastText57(4, 0, "Extruder OFF",0);
+ }
+ RapMan_MoveTo(X_Rest_mm,Y_Rest_mm,Z_Rest_mm,0); //Move to rest, No Z move
+ EOF_Flag = 1;
+ break;
+
+ case SEEK_POINT_ERR: //File error
+ OLED_FastText57(3, 0, "File Error :seek pt",0);
+ if (ToolType == 2 )//Extruder
+ {
+ Extruder_Status(OFF);
+ OLED_FastText57(4, 0, "Extruder OFF",0);
+ }
+ RapMan_MoveTo(X_Rest_mm,Y_Rest_mm,Z_Rest_mm,0); //Move to rest, No Z move
+ EOF_Flag = 1;
+ break;
+
+ default: //unknown error
+ OLED_FastText57(3, 0, "Unknown Error",0);
+ break;
+ }//switch
+
+ do
+ {
+ OLED_FastText57(5, 0, " <ESC TO RESUME",0);
+ Delayms(150);
+ OLED_FastText57(5, 0, "<",0);
+ Delayms(150);
+ }
+ while(Manual_Select);
+ while(!Manual_Select);//wait for keyup
+
+}//ErrorCondition
+
+/************************************************************/
+void Setup(void)
+{
+
+ //OLED setup I/O
+ AD1PCFGbits.PCFG5 = 1; //AtoD port cfg AN5/B5 digital for OLED chip select
+ TRISBbits.TRISB5 = OUTPUT_PIN; //OLED chip Select
+
+ TRISEbits.TRISE6 = OUTPUT_PIN; //Display DC
+ TRISEbits.TRISE7 = OUTPUT_PIN; //Display RES
+ //SPI IN OUT and CLK are in Hardware Profile
+
+ //THERMISTOR
+ AD1PCFGbits.PCFG11 = 0; //AtoD port cfg AN11/B11 Analog
+ TRISBbits.TRISB11 = INPUT_PIN; //Thermistor Input
+
+ //Tool ID
+ AD1PCFGbits.PCFG12 = 0; //AtoD port cfg AN12/B12 Analog
+ TRISBbits.TRISB12 = INPUT_PIN; //Tool ID input
+
+ //Fillament switch
+ AD1PCFGbits.PCFG0 = 1; //AtoD port cfg AN0 make digital for switch
+ TRISBbits.TRISB0 = INPUT_PIN; //Fillament switch Input
+
+ //Push Buttons on Analog pins
+ AD1PCFGbits.PCFG2 = 1; //AtoD port cfg AN2 make digital for btn
+ AD1PCFGbits.PCFG3 = 1; //AtoD port cfg AN3 make digital for btn
+ AD1PCFGbits.PCFG4 = 1; //AtoD port cfg AN4 make digital for btn
+ AD1PCFGbits.PCFG15 = 1; //AtoD port cfg AN15 make digital for btn
+
+ //TRIS for buttons
+ TRISBbits.TRISB2 = INPUT_PIN; //Button
+ TRISBbits.TRISB3 = INPUT_PIN; //Button
+ TRISBbits.TRISB4 = INPUT_PIN; //Button
+ TRISBbits.TRISB15 = INPUT_PIN; //Button
+
+ TRISFbits.TRISF4 = INPUT_PIN; //Button
+ TRISFbits.TRISF5 = INPUT_PIN; //Button
+ TRISGbits.TRISG9 = INPUT_PIN; //Button
+
+ //Weak Pullups - Buttons
+ CNPUEbits.CNPUE4=1; //B2
+ CNPUEbits.CNPUE5=1; //B3
+ CNPUEbits.CNPUE6=1; //B4
+ CNPUEbits.CNPUE12=1; //B15
+ CNPUEbits.CNPUE17=1; //F4
+ CNPUEbits.CNPUE18=1; //F5
+ CNPUEbits.CNPUE11=1; //G9
+
+ //Limit switches
+ TRISDbits.TRISD4 = INPUT_PIN; //switch
+ TRISCbits.TRISC13 = INPUT_PIN; //switch
+ TRISCbits.TRISC14 = INPUT_PIN; //switch
+
+ //Weak Pullups - Switch
+ CNPUEbits.CNPUE13 = 1; //X limit D4
+ CNPUEbits.CNPUE1 = 1; //Y limit C13
+ CNPUEbits.CNPUE0 = 1; //Z Limit C14
+
+ //Setup AtoD
+ AD1CON1 = 0x0000; //Auto conversion sequence start after sampling
+ AD1CON2 = 0; //use MUXA, AVss and AVdd are used for VRef+/-
+ AD1CON3 = 0x1F02; //Tad =
+ AD1CSSL = 0; //no scanning required
+ //Once set up, turn on A to D
+ AD1CON1bits.ADON = 1; //turn on ADC
+
+ //Drive all FET's to off state on Start up
+ TRISFbits.TRISF0 = OUTPUT_PIN; //FET
+ HEATER = OFF;
+ TRISEbits.TRISE5 = OUTPUT_PIN; //FET
+ FAN = OFF;
+ TRISDbits.TRISD11 = OUTPUT_PIN; //FET
+ AUX = OFF;
+
+ PMCON = 0x00; //disable PMP
+ Stepper_InitIO();
+ InitExtruder();
+ OLED_Init();
+ INTEnableSystemMultiVectoredInt();
+
+ FeedRate_ManualChange = 0;
+ ManualChange = 0 ;//No manual change applied to gcode feed rates
+
+ X_Rest_mm = X_REST_ABS_MM;
+ Y_Rest_mm = Y_REST_ABS_MM;
+ Z_Rest_mm = Z_REST_ABS_MM;
+
+}//Setup
+
+/************************************************************/
+ char GetTool_ID(void) {
+//Any tool attached has an Identification resistor. The voltage drop accross it
+//is the tool ID.
+//Descriotion Resistor A/D
+//976 Ohm resistor for PEN 1K (90)
+//4.7K Ohm resistor for Extruder 4K7 (320)
+//9.9K Ohm resistor for Extruder2 10K (500)
+//22K Ohm resistor for Not Defined 22K (700)
+//47K to 100K Ohm resistor for Router 47K to 100K (840 to 920)
+//1M Ohm resistor for No Tool 1M to open circuit(1010 to 1024)
+
+int Reading = 0;
+char type = 0;
+
+ while(Reading == 0){
+ ADC_readingToolID = Read_Analog(TOOL_ID);
+ AveSamplesToolID += ADC_readingToolID;
+ ++SampleCountToolID;
+ if (SampleCountToolID > 3){
+ Reading = AveSamplesToolID / 4;
+ SampleCountToolID = 0;
+ AveSamplesToolID = 0;
+ }
+ }
+
+ if((Reading >= 0)&&(Reading <= 200)) {type = 1; OLED_FastText57(1, 20, "Tool: Pen",0);} //Pen
+ if((Reading >= 200)&&(Reading <= 400)) {type = 2; OLED_FastText57(1, 20, "Tool: Extruder",0);} //Extruder - Primary material
+ if((Reading >= 400)&&(Reading <= 600)) {type = 3; OLED_FastText57(1, 20, "Tool: Extruder2",0);} //Extruder2 - Fill
+ if((Reading >= 600)&&(Reading <= 800)) {type = 4; OLED_FastText57(1, 20, "Tool: Not Defined",0);} //Not Defined
+ if((Reading >= 800)&&(Reading <= 1000)) {type = 5; OLED_FastText57(1, 20, "Tool: Router",0);} //Router
+ if(Reading >= 1020) {type = 0; OLED_FastText57(1, 20, "Tool: None",0);} //No tool fitted
+ return type;
+
+}//GetTool_ID
+
+/************************************************************/
+int Start_Menu(void)
+{
+int mode = 0;
+
+ ToolType = GetTool_ID();
+ OLED_Start_Menu(); //Draw the menu screen
+ mode = GetMenuSelection();
+ return mode;
+
+}//Start_Menu
+
+/************************************************************/
+int GetMenuSelection(void)
+{
+int mode = 0;
+ while(XPlusRight_Btn == NOT_PRESSED){ //Run this until a menu item is selected
+ delay_ms(5);
+
+ if (YMinusBot_Btn == PRESSED){ //Move cursor up & down the menu choices
+ delay_ms(5);
+ while(YMinusBot_Btn == PRESSED); //wait for key up
+ mode += 1;
+ if (mode >NUNBER_OF_MENU_ITEMS) mode = 0;
+ }
+ if (YPlusTop_Btn == PRESSED){ //key down
+ delay_ms(5);
+ while(YPlusTop_Btn == PRESSED); //wait for key up
+ mode -= 1;
+ if (mode <0) mode = NUNBER_OF_MENU_ITEMS;
+ }
+ switch(mode){ //Move the Cursor on the screen
+ case 0: {OLED_SetCursor(2, 0, 1); break;} //Print Object
+ case 1: {OLED_SetCursor(3, 0, 1); break;} //Manual
+ case 2: {OLED_SetCursor(4, 0, 1); break;} //Tool Setup
+ case 3: {OLED_SetCursor(5, 0, 1); break;} //Home
+ }
+ }//while
+
+ return mode;
+
+}//GetMenuSelection
+
+/************************************************************/
+void RapMan_MoveTo(float X_pos, float Y_pos, float Z_pos, char DoZmove) {
+
+ //Move to coordinate
+ //With Z move (1)
+ //Without Z move (0)
+
+ mT4IntEnable(TRUE);
+ GoToRestSpeed = 1; //flag to switch in the speed
+
+ Inst_Code_Letter = 0x47; //"G" //G0 to coordeinate
+ iInst_Code = 0;
+ Dim_1_Letter = 0x58; //"X"
+ fDim_1 = X_pos;
+ Dim_2_Letter = 0x59; //"Y"
+ fDim_2 = Y_pos;
+
+ if (DoZmove)
+ {
+ Dim_3_Letter = 0x5A; //"Z" Z move
+ fDim_3 = Z_pos;
+ }
+ else
+ {
+ Dim_3_Letter = 0; //"Z" No Z move
+ fDim_3 = 0;
+ }
+
+ Dim_4_Letter = 0x46; //"F"
+ fDim_4 = 0; //note, this value is set to the defaut fast.
+
+ G_CodeRun(Inst_Code_Letter, iInst_Code, Dim_1_Letter, fDim_1, Dim_2_Letter,
+ fDim_2, Dim_3_Letter, fDim_3, Dim_4_Letter,fDim_4);
+
+ Inst_Code_Letter = 0; //"G"
+ iInst_Code = 0;
+ Dim_1_Letter = 0; //"X"
+ fDim_1 = 0;
+ Dim_2_Letter = 0; //"Y"
+ fDim_2 = 0;
+ Dim_3_Letter = 0; //"Z"
+ fDim_3 = 0;
+ Dim_4_Letter = 0; //"F"
+ fDim_4 = 0;
+
+ GoToRestSpeed = 0;
+ Delayms(250);
+
+}//RapMan_MoveTo
+
+/************************************************************/
+void OpenReadSDFile(void)
+{
+ if (EOF_Flag == 1)
+ { //It may be after restart
+ EOF_Flag = 0;
+ FilePointer = 0;
+ ItemsRead = 0;
+ PosInFile = 0;
+ LineNumber = 0;
+ }
+ //Initialize the SD/MMC library
+ while (!FSInit());
+ GetFileToOpen(); //select file to open and save as global
+ if(!Manual_Select) return;
+ //File type returned is *.*
+ FileType = Get_file_Type(); //file types defined as
+ // 1 = .TXT
+ // 2 = .BIN
+ // 0 = Invalid type
+
+ pointer = FSfopen ( SaveFileName, "r");
+
+ FilePointer = pointer; //save file pointer as global
+
+ if ((pointer == NULL)|(pointer == 0x0000))
+ {
+ do
+ {//Handle file error
+ OLED_FastText57(2, 0, "File Error ",0);
+ OLED_FastText57(3, 40,"File Not Found",0);
+ OLED_FastText57(4, 0, "<<ESC TO RESUME",0);
+ Delayms(250);
+ if(!Manual_Select) return;
+ }
+ while(1);
+
+ } //file open error
+
+ OLED_FastText57(2, 90, "Open",0);
+
+}//OpenReadSDFile
+
+/************************************************************/
+void GetFileToOpen(void)
+{
+//Searches the SD card root directory for :
+//Flies with File attribute set to archive
+SearchRec rec;
+unsigned char attributes = ATTR_ARCHIVE;
+char name[] = "*.*";
+int result = 1;
+static int FileNumber = 0;
+static int FilesOnCard = 0;
+int i =0;
+int SkipFindLast = 0;
+char AsciiString[10];
+
+do
+{
+ //Test SD card for valid file type
+ result = FindFirst(name,attributes,&rec); //Test for first file
+ if (result == 0)
+ {//if success
+ //FILE COUNT
+ FilesOnCard = 1;
+ do
+ {//Loop to end of file table
+ result = FindNext(&rec);//check to see if there is another file
+ if (result == 0)FilesOnCard++;
+ }
+ while(result==0);
+ if (!SkipFindLast)//find last file only first time through
+ {
+ //FIND LAST FILE
+ result = FindFirst(name,attributes,&rec); //reset to first
+ FileNumber = 1;
+ for (i=1;i<FilesOnCard;i++) //loop to last file
+ {
+ result = FindNext(&rec);
+ }
+ FileNumber = FilesOnCard; //set file number to last
+ OLED_FastText57(2, 0,rec.filename,0); //show last file
+ }
+ }
+ if (result!=0)
+ {//failure
+ FilesOnCard=0;
+ FileNumber = 0;
+
+ do
+ { //Crash with "File Error"
+ OLED_FastText57(2, 0,"Find First Error",0);
+ OLED_FastText57(3, 0,"No files on card",0);
+ OLED_FastText57(5, 0, "Switch OFF/ON",0);
+ OLED_FastText57(6, 0, "to Reset",0);
+ Delayms(250);
+ if(!Manual_Select) return;
+ }
+ while(1);
+ }
+
+ do
+ {
+ if (result == 0)
+ {
+ if (YMinusBot_Btn == 0)
+ { //FIND NEXT FILE
+ while (YMinusBot_Btn==0); //wait for key up
+ Delayms(30);
+
+ result = FindNext(&rec);//check to see if there is another file
+ if (result==0)
+ {//success
+ if (FileNumber > FilesOnCard)FileNumber = FilesOnCard;
+ else
+ FileNumber++;
+ }
+ else
+ {
+ result = FindFirst(name,attributes,&rec);
+ FileNumber = 1;
+ }
+ OLED_ClearLine(2);
+ OLED_FastText57(2, 0,rec.filename,0);
+ }
+
+ if (YPlusTop_Btn == 0)
+ { //FIND PREVIOUS FILE
+ while (YPlusTop_Btn==0); //wait for key up
+ Delayms(30);
+ do
+ { //Loop to end of file table
+ result = FindNext(&rec);//check to see if there is another file
+ }
+ while(result==0);
+ result = FindFirst(name,attributes,&rec);
+ --FileNumber;
+ if (FileNumber == 0)//If less than first file show last file
+ {
+ FileNumber = FilesOnCard;
+ SkipFindLast = 1;
+ }
+ for (i=1;i<FileNumber;i++)
+ {
+ result = FindNext(&rec);
+ }
+ OLED_ClearLine(2);
+ OLED_FastText57(2, 0,rec.filename,0);
+ }
+
+ OLED_FastText57(6, 0,"File",0);
+ sprintf(AsciiString, "%3u", FileNumber); //Converts number to text
+ OLED_FastText57(6, 25,AsciiString,0); //Write the new number
+ OLED_FastText57(6, 65,"of",0);
+ sprintf(AsciiString, "%3u", FilesOnCard); //Converts number to text
+ OLED_FastText57(6, 90,AsciiString,0); //Write the new number
+ }
+ if(!Manual_Select) return;
+ }
+ while ((XPlusRight_Btn == 1)&(result==0));
+}
+while (XPlusRight_Btn == 1);
+
+//save the selected filename & filesize to global
+strcpy(SaveFileName, rec.filename);
+SaveFileSize = rec.filesize;
+
+}//GetFileToOpen
+
+/************************************************************/
+int Get_file_Type(void)
+{
+BYTE type;
+BYTE f;
+//file name is 12 chars long 0-11 4 back from end is index 8
+//this is the first possible site of the "."
+//then work back in the filename array to find the "."
+ for(f=8; f; --f)
+ { //Flush line Buffer
+ if (SaveFileName[f] == 46)
+ { //look for full stop before file extension
+ if ((SaveFileName[f+1] == 'G') &
+ (SaveFileName[f+2] == 'C') &
+ (SaveFileName[f+3] == 'O'))
+ {
+ return type = GCO_FILE; //Set for TXT file type
+ }
+
+ if ((SaveFileName[f+1] == 'B') &
+ (SaveFileName[f+2] == 'F') &
+ (SaveFileName[f+3] == 'B'))
+ {
+ return type = BFB_FILE; //Set for BIN file type
+ }
+ return type = 0; //Invalid file type
+ }
+ }
+}//Get_file_Type
+
+/************************************************************/
+void ReadData(void)
+{
+unsigned char AsciiString[9];
+int CharNum=1;
+int n=0;
+
+ //Read into buffer, Num.of bytes, Num.of Items, File handle
+ //FSfread returns the number of items read from the file
+ EOF_Flag=0;
+ pointer = FilePointer; //set the file pointer
+ LineNumber += 1; //move on line counter
+ LineBuffer[0] = 0x3E; //fill with >
+
+ //pointer is the file, pos in file, zero offset from file beginning
+ if(FSfseek(pointer,PosInFile,0) !=0)
+ { //set file pos to last char & test
+ ErrorCondition(SEEK_POINT_ERR);
+ EOF_Flag = 1;
+ }
+
+ if (EOF_Flag == 0)
+ {
+ do
+ {
+ ItemsRead = FSfread (CharBuffer, 1, 1, pointer);
+ LineBuffer[CharNum]=CharBuffer[0];
+ CharNum++;
+
+ if (CharBuffer[0]== 40)
+ { //Open bracket - GCode comment line
+ //loop through and discard the data.
+ do
+ {
+ ItemsRead = FSfread (CharBuffer, 1, 1, pointer);
+ if (FSfeof (pointer))break;
+ }
+ while (CharBuffer[0] !=10); //read line checking for line feed
+ }
+
+ if (FSfeof (pointer)){// Check if this is the end of the file
+ FSfclose (pointer);
+ EOF_Flag = 1;
+ break;
+ }
+ }
+ while (CharBuffer[0] !=10); //while charbuffer is not line feed char.
+ PosInFile=FSftell(pointer); //where we are after reading line
+ }//end if
+
+}//ReadData
+
+/********************************************************/
+void GetCodes(void)
+{
+//Runs through the contents of the LineBuffer and splits out the G-code words.
+//Note code looks for a space between words, edit if Gcode
+//runs words together
+//Code words saved as globals for use in other functions
+
+int CharPosLine = 1; //Caracter position in line
+int CharPosWord = 0;
+
+ Word_Count = 1; //to get first word
+ do
+ { //Search for first character
+ if (LineBuffer[1] == 13)
+ {//13Carriage return so exit loop
+ break;
+ }
+
+ if (Word_Count == 1)
+ {
+ if (CharPosWord == 0)
+ { //its the letter code
+ Inst_Code_Letter = LineBuffer[CharPosLine];
+ CharPosLine++;
+ }
+ Inst_Code[CharPosWord] = LineBuffer[CharPosLine];
+ CharPosWord++;
+ if (LineBuffer[CharPosLine] == 32)
+ {
+ CharPosLine++; //skip space
+ CharPosWord=0; //reset
+ Word_Count=2; //spot space at end of word
+ }
+ }
+ if (Word_Count == 2)
+ {
+ if (CharPosWord == 0)
+ { //its the letter code
+ Dim_1_Letter = LineBuffer[CharPosLine];
+ CharPosLine++;
+ }
+ Dim_1[CharPosWord] = LineBuffer[CharPosLine];
+ CharPosWord++;
+ if (LineBuffer[CharPosLine] == 32)
+ {
+ CharPosLine++; //skip space
+ CharPosWord=0; //reset
+ Word_Count=3; //spot space at end of word
+ }
+ }
+ if (Word_Count == 3)
+ {
+ if (CharPosWord == 0)
+ { //its the letter code
+ Dim_2_Letter=LineBuffer[CharPosLine];
+ CharPosLine++;
+ }
+ Dim_2[CharPosWord]=LineBuffer[CharPosLine];
+ CharPosWord++;
+ if (LineBuffer[CharPosLine] == 32)
+ {
+ CharPosLine++; //skip space
+ CharPosWord = 0; //reset
+ Word_Count = 4; //spot space at end of word
+ }
+ }
+ if (Word_Count == 4)
+ {
+ if (CharPosWord == 0)
+ { //its the letter code
+ Dim_3_Letter = LineBuffer[CharPosLine];
+ CharPosLine++;
+ }
+ Dim_3[CharPosWord] = LineBuffer[CharPosLine];
+ CharPosWord++;
+ if (LineBuffer[CharPosLine] == 32)
+ {
+ CharPosLine++; //skip space
+ CharPosWord=0; //reset
+ Word_Count=5; //spot space at end of word
+ }
+ }
+ if (Word_Count == 5)
+ {
+ if (CharPosWord == 0)
+ { //its the letter code
+ Dim_4_Letter = LineBuffer[CharPosLine];
+ CharPosLine++;
+ }
+ Dim_4[CharPosWord] = LineBuffer[CharPosLine];
+ CharPosWord++;
+ }
+
+ if (LineBuffer[CharPosLine]== 10) break; //to deal with space at end of line
+ CharPosLine++;
+ }
+ while (LineBuffer[CharPosLine]!= 13); //spot end of line
+
+ //recast the data from ascii to integer or float
+ iInst_Code = atoi(Inst_Code);
+ fDim_1=atof(Dim_1);
+ fDim_2=atof(Dim_2);
+ fDim_3=atof(Dim_3);
+ fDim_4=atof(Dim_4);
+
+}//GetCodes
+
+/********************************************************/
+void FlushBuffer(void)
+{
+//Clears out all old data ready for a new line
+int f;
+
+ //LineBuffer
+ for(f=49; f; --f)
+ { //Flush line Buffer
+ LineBuffer[f]=0;
+ }
+ if (f==0) LineBuffer[0]=0; //to clear remaining character
+
+ //Inst_Code
+ Inst_Code_Letter=0;
+ for(f=7; f; --f)
+ {
+ Inst_Code[f]=0;
+ }
+ if (f==0) Inst_Code[0]=0; //to clear remaining character
+
+ //Dim_1
+ Dim_1_Letter=0;
+ for(f=7; f; --f)
+ {
+ Dim_1[f]=0;
+ }
+ if (f==0) Dim_1[0]=0; //to clear remaining character
+
+ //Dim_2
+ Dim_2_Letter=0;
+ for(f=7; f; --f)
+ {
+ Dim_2[f]=0;
+ }
+ if (f==0) Dim_2[0]=0; //to clear remaining character
+
+ //Dim_3
+ Dim_3_Letter=0;
+ for(f=7; f; --f)
+ {
+ Dim_3[f]=0;
+ }
+ if (f==0) Dim_3[0]=0; //to clear remaining character
+
+ //Dim_4
+ Dim_4_Letter=0;
+ for(f=7; f; --f)
+ {
+ Dim_4[f]=0;
+ }
+ if (f==0) Dim_4[0]=0; //to clear remaining character
+
+}//FlushBuffer
+
+/********************************************************/
+void ShowBufferFillState(void) { //Step buffer fill status
+
+float FillStat = 0;
+extern int SBR,SBW;
+
+ if (SBW>SBR)
+ {
+ FillStat = SBW-SBR;
+ }
+ else
+ FillStat = (SB_SIZE - SBR)+SBW;
+
+ FillStat /= SB_SIZE;
+ FillStat *= (int) 127;
+
+ OLED_ProgressBar(6,FillStat); //Bar on line number , Value to show relative to 127
+
+}//ShowBufferFillState
+
+/********************************************************/
+void ShowPrintProgress(void)
+{
+float FillStat = 0;
+
+ FillStat = (float)PosInFile / SaveFileSize;
+ FillStat *= (int) 127;
+ if (FillStat >127) FillStat = 127;
+
+ OLED_ProgressBar(5,FillStat); //Bar on line number , Value to show relative to 127
+
+}//ShowPrintProgress
+
+/********************************************************/
+
+
+
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan.d b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan.d new file mode 100644 index 00000000..0a74dbdf --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan.d @@ -0,0 +1,61 @@ +RapMan.o: RapMan.c \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ RapMan.h Enviroment.h FSIO.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h FSconfig.h \
+ C:/Microchip\ Solutions/Microchip/Include/Compiler.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/string.h \
+ HardwareProfile.h FSDefs.h SD-SPI.h Stepper.h G_Code.h Extruder.h \
+ OLED.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan.h new file mode 100644 index 00000000..f7fade33 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan.h @@ -0,0 +1,138 @@ +/**********************************************************************
+ *************************** RapMan.h *******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+//add in below as required
+#include "Enviroment.h"
+#include "FSIO.h"
+#include "Stepper.h" //Stepper motor functions and defines
+#include "G_Code.h" //G code table
+#include "Extruder.h"
+#include "stdlib.h"
+#include "stdio.h" //for printf **See note
+//To use printf the build options need to show a heap.
+//for output printf ONLY the heap can be set to 0
+//add to end of compile line --heap=0
+
+#include "OLED.h"
+
+//General Defines
+#define PRESSED 0
+#define NOT_PRESSED 1
+
+//File types
+#define INVALID_FILE 0
+#define GCO_FILE 1
+#define BIN_FILE 2
+#define BFB_FILE 3
+
+//Error Conditions
+#define TEST 0
+#define SEEK_POINT_ERR 1
+
+int PosInFile = 0; //character count in file
+int LineNumber = 0; //Line count in file
+
+int Word_Count=0;
+char Inst_Code_Letter;
+char Inst_Code[8];
+int iInst_Code;
+char Dim_1_Letter;
+char Dim_1[8];
+float fDim_1;
+char Dim_2_Letter;
+char Dim_2[8];
+float fDim_2;
+char Dim_3_Letter;
+char Dim_3[8];
+float fDim_3;
+char Dim_4_Letter;
+char Dim_4[8];
+float fDim_4;
+
+float X_Rest_mm;
+float Y_Rest_mm;
+float Z_Rest_mm;
+
+char EOF_Flag = 0; //end of file
+
+char ExtruderStatus;
+
+FSFILE * pointer;
+
+char SaveFileName[12];
+int SaveFileSize;
+
+FSFILE *FilePointer;
+
+int ItemsRead = 0;
+
+extern int GX_On;
+extern int GY_On;
+extern int GZ_On;
+extern int GI_On;
+extern int GJ_On;
+extern signed long lX_Steps,lY_Steps,lZ_Steps;
+extern int Feed_Rate;
+
+int ManualChange;
+
+char PauseFlag; //Used to prevent heater going on during pause
+
+signed int Ops_mode;
+
+void Setup(void);
+char GetTool_ID(void);
+
+//**********************************************************************
+// Functions
+//**********************************************************************
+void RapMan_MoveTo(float X_pos, float Y_pos, float Z_pos, char DoZmove);
+void OpenReadSDFile(void);
+void GetFileToOpen(void);
+int Get_file_Type(void);
+void ReadBinData(void);
+void ReadData(void);
+void GetCodes(void);
+void FlushBuffer(void);
+extern void ShowBufferFillState(void);
+extern void ShowPrintProgress(void);
+char RapMan_Mode();
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan1_0_8-factory.hex b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan1_0_8-factory.hex new file mode 100644 index 00000000..59683f95 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan1_0_8-factory.hex @@ -0,0 +1,6979 @@ +:020000040000fa +:020000041fc01b +:042ff400d9fff8ff0a +:020000040000fa +:020000041fc01b +:042ff800dbfd7fff7f +:020000040000fa +:020000041fc01b +:042ffc00ffffff7f55 +:020000040000fa +:020000041d00dd +:10600000009d1a3c90645a270800400300000000dd +:020000040000fa +:020000041d00dd +:10638000029d1a3c50b55a27080040030000000047 +:020000040000fa +:020000041d00dd +:10518000029d1a3cf4aa5a270800400300000000c0 +:020000040000fa +:020000041d00dd +:08530000af5d400b000000004e +:020000040000fa +:020000041d00dd +:08538000725e400b000000000a +:020000040000fa +:020000041d00dd +:085400008726400b00000000ac +:020000040000fa +:020000041d00dd +:1064900000601a40c0045a7f05004013000000004d +:1064a000029d1a3c68b55a2708004003000000000e +:1064b00001a01d3c0080bd2701a01c3cf0809c2752 +:1064c0000260094020582001801e2a7d8449497db0 +:1064d0000260894000e0dc4102608b40029d083c84 +:1064e00058b5082509f800010000000000a0083c8c +:1064f0002001082500a0093c84122925060000106f +:1065000000000000000000ad040000ad080000ad78 +:106510000c0000ad100008252b080901f9ff20141c +:1065200000000000029d083c8018082500a0093cde +:106530000000292500a00a3c20014a250500001082 +:106540000000000000000b8d00002bad04000825aa +:10655000040029252b082a01faff2014000000005e +:106560000000093c000029251d002011000000004a +:10657000029d083ca019082500a0093c00202925ff +:1065800000a00a3c00204a2500000b8d00002bad26 +:1065900004000825040029252b082a01faff2014ed +:1065a000000000000000093c0020292588bf0a3cab +:1065b00010204a25000049ad0100093c0080292532 +:1065c00088bf0a3c20204a25000049ad0100093c53 +:1065d0000080292588bf0a3c30204a25000049adab +:1065e00000488040ffff0a2400588a40009d093c73 +:1065f00000502925017889400000093c0100292527 +:1066000000000a2444492a7d01608a408000093c38 +:1066100000688940008008408005097d404c0900e1 +:10662000006008405800013c244001012540280139 +:1066300000608840029d083c60b5082509f800010b +:106640000000000000600840bfff013cffff213454 +:106650002440010100608840000084300000a53023 +:10666000009d083c006a08250800000100000000a9 +:020000040000fa +:020000041d00dd +:106a0000861a400f00000000496b400f0000000094 +:106a1000ffff001000000000e0ffbd271c00bfaf1b +:106a20001800beaf21f0a003ab1c400f0000000017 +:106a30005b69400f0000000088bf023c5060428c40 +:106a4000c000427c0300401400000000faff001068 +:106a500000000000111e400f000000001000c2af37 +:106a60001000c28f1400c2af010002241400c38fb3 +:106a700018006210000000001400c38f020062289a +:106a800006004010000000001400c28f0d004010ee +:106a900000000000e8ff00100000000002000224d7 +:106aa0001400c38f100062100000000003000224d5 +:106ab0001400c38f1400621000000000deff0010fd +:106ac00000000000c61a400f00000000daff0010ae +:106ad00000000000010004244923400f00000000d2 +:106ae000d5ff0010000000005480838302000224c0 +:106af000d1ff6214000000006161400f000000003f +:106b0000cdff0010000000008f24400f00000000a7 +:106b1000c9ff001000000000d0ffbd272c00bfaf50 +:106b20002800beaf21f0a003448180a3831d400f45 +:106b300000000000010140100000000021200000c2 +:106b4000f463400f00000000212000000a0005242b +:106b5000029d023c6000462421380000d864400faa +:106b60000000000088bf023c5060428cc000427ca4 +:106b70000300401400000000faff001000000000b5 +:106b8000165a400f000000001900401400000000d9 +:106b90000200042421280000029d023c74004624c7 +:106ba00021380000d864400f0000000004000424d5 +:106bb00021280000029d023c880046242138000064 +:106bc000d864400f00000000fa000424365c400f37 +:106bd0000000000088bf023c9061428c4002427c71 +:106be000e7ff401400000000d40000100000000087 +:106bf000020004245964400f000000000400042433 +:106c00005964400f00000000f41e400f0000000017 +:106c100088bf023c5060428cc000427c030040149c +:106c200000000000faff00100000000088bf023cd6 +:106c30009061428c4002427c03004014000000003e +:106c4000be000010000000006480838f0300022457 +:106c500007006210000000006480838f010002249e +:106c600003006210000000007f0000100000000020 +:106c70008f24400f000000000300401400000000bb +:106c8000ae0000100000000003000224508082af1c +:106c900021200000f463400f000000004262400f1a +:106ca000000000008628400f0000000001000424be +:106cb0005a24400f0000000088bf023c9061428cc3 +:106cc0004002427c2100401400000000d51b400f10 +:106cd0000000000088bf023c9061428c4002427c70 +:106ce0000300401400000000faff00100000000044 +:106cf000cc81838ff081828f0e0062100000000033 +:106d00003c80838301000224f9ff6214000000002c +:106d1000f081828f01004324cc81828ff4ff6214c2 +:106d200000000000cc81828ff08182aff0ff001064 +:106d3000000000009080848f9480858f21300000b7 +:106d4000213800009d1e400f000000007362400fbc +:106d500000000000ed20400f0000000000a0023cf9 +:106d60008804422401004390280002240300621496 +:106d700000000000f7ff0010000000005021400f4d +:106d8000000000005481838399818683648182831b +:106d90001000a2af4081828f1400a2af7c81828359 +:106da0001800a2af9c81828f1c00a2af5581828304 +:106db0002000a2af3c81828f2400a2af212060007e +:106dc0002c81858f1881878f4c2d400f000000008b +:106dd0006622400f000000005480838302000224da +:106de0000300621400000000d05e400f00000000ad +:106df00088bf023c5061428c4001427c0600401436 +:106e00000000000001000224448182a36881828f77 +:106e10000a004224688182af88bf023c5061428ce4 +:106e20000001427c06004014000000000100022422 +:106e3000448182a36881828ff6ff4224688182aff9 +:106e40003c808283010042382b1802004080828ff0 +:106e50002b100200251062002200401000000000ec +:106e600095ff00100000000021200000f463400f97 +:106e7000000000000200042421280000029d023cc2 +:106e80009800462421380000d864400f000000001c +:106e90000300042421280000029d023cac0046248b +:106ea00021380000d864400f0000000004000424d2 +:106eb00021280000029d023cbc004624213800002d +:106ec000d864400f0000000088bf023c9061428cf3 +:106ed0004002427c0300401000000000faff001056 +:106ee00000000000212000006f60400f0000000043 +:106ef000212000005a24400f000000003081828fc2 +:106f00005c8182af5c81848f0e3f400f00000000e7 +:106f1000ab1c400f000000009c66400f000000000a +:106f200088bf023c9061428c4002427c03004010ca +:106f300000000000faff00100000000021e8c0037c +:106f40002c00bf8f2800be8f3000bd270800e00353 +:106f500000000000e8ffbd271400bfaf1000beaf67 +:106f600021f0a00388bf023c9061428c4002427c29 +:106f70000300401400000000faff001000000000b1 +:106f8000040004245964400f00000000050004249c +:106f90005964400f00000000060004245964400fab +:106fa000000000000500042421280000029d023c8e +:106fb000d400462421380000d864400f00000000af +:106fc00001000224a08182a32881848f6081858fa3 +:106fd0008081868f213800009d1e400f0000000038 +:106fe0000500042421280000029d023c880046245c +:106ff00021380000d864400f00000000d963400f22 +:10700000000000002c63400f00000000f401042485 +:10701000365c400f0000000088bf023c9061428c4b +:107020004002427c0300401000000000f3ff00100b +:1070300000000000a08180a3050004245964400fd3 +:1070400000000000010004246f60400f00000000f9 +:107050004e30400f0000000021e8c0031400bf8f35 +:107060001000be8f1800bd270800e00300000000dc +:10707000e0ffbd271c00bfaf1800beaf21f0a0038a +:107080002000c4af020004245964400f0000000037 +:10709000030004245964400f00000000040004248d +:1070a0005964400f00000000050004245964400f9b +:1070b00000000000060004245964400f0000000096 +:1070c000070004245964400f000000002000c28f14 +:1070d0001000c2af1000c38f070060100000000056 +:1070e000010002241000c38f220062100000000083 +:1070f0003f000010000000000300042421280000cd +:10710000029d023cdc00462421380000d864400f78 +:107110000000000054808383020002240b006214ec +:1071200000000000212000006f60400f0000000000 +:107130000400042421280000029d023ce8004624ab +:1071400021380000d864400f000000002881848f9f +:107150006081858f8081868f213800009d1e400fc1 +:1071600000000000010002243c8082a327000010e0 +:10717000000000000300042421280000029d023cbe +:10718000f800462421380000d864400f00000000b9 +:1071900054808383020002240b006214000000006c +:1071a000212000006f60400f000000000400042454 +:1071b00021280000029d023ce800462421380000fe +:1071c000d864400f000000002881848f6081858f83 +:1071d0008081868f213800009d1e400f0000000036 +:1071e000010002243c8082a308000010000000007f +:1071f0000300042421280000029d023c0c014624c7 +:1072000021380000d864400f00000000050004246d +:1072100021280000029d023c1c0146242138000068 +:10722000d864400f0000000096000424365c400f34 +:10723000000000000500042421280000029d023cfb +:107240002c01462421380000d864400f00000000c3 +:1072500096000424365c400f0000000088bf023c0a +:107260009061428c4002427c03004010000000000c +:10727000e6ff00100000000088bf023c9061428cd5 +:107280004002427c0300401400000000faff00109e +:107290000000000021e8c0031c00bf8f1800be8f53 +:1072a0002000bd270800e00300000000e8ffbd2724 +:1072b0001400bfaf1000beaf21f0a00381bf033c9c +:1072c0006090629020004234609062a088bf043ccd +:1072d00040608390dfff022424106200406082a09f +:1072e00088bf043c00618390bfff02242410620029 +:1072f000006182a088bf033c006162907f00423041 +:10730000006162a081bf043c61908390f7ff02247a +:1073100024106200619082a088bf033c41606290ab +:1073200008004234416062a081bf043c61908390b8 +:10733000efff022424106200619082a088bf033c0a +:107340004160629010004234416062a081bf033c02 +:107350006090629001004234609062a088bf033c5c +:107360004060629001004234406062a081bf033cf3 +:107370006090629004004234609062a081bf033c40 +:107380006090629008004234609062a081bf033c2c +:107390006090629010004234609062a081bf043c13 +:1073a0006190839080ff022425106200619082a08a +:1073b00088bf033c4060629004004234406062a099 +:1073c00088bf033c4060629008004234406062a085 +:1073d00088bf033c4060629010004234406062a06d +:1073e00088bf043c4160839080ff02242510620026 +:1073f000416082a088bf033c40616290100042342b +:10740000406162a088bf033c40616290200042342a +:10741000406162a088bf033c8161629002004234f7 +:10742000816162a088bf033ce06162901000423439 +:10743000e06162a088bf033ce061629020004234ba +:10744000e06162a088bf033ce0616290400042348a +:10745000e06162a088bf033ce161629010004234a9 +:10746000e16162a088bf033ce261629002004234a5 +:10747000e26162a088bf033ce26162900400423492 +:10748000e26162a088bf033ce1616290080042347f +:10749000e16162a088bf033cc0606290100042348a +:1074a000c06062a088bf033c8160629020004234cb +:1074b000816062a088bf033c8160629040004234da +:1074c000816062a088bf033ce16162902000423489 +:1074d000e16162a088bf033ce06162900200423437 +:1074e000e06162a088bf033ce06162900100423429 +:1074f000e06162a081bf023c009040ac81bf023cd1 +:10750000109040ac81bf033c021f0224209062ac6b +:1075100081bf023c509040ac81bf043c01908390fd +:1075200080ff022425106200019082a088bf043ce5 +:1075300040618390feff022424106200406182a01b +:1075400088bf043c50618390feff02242410620037 +:10755000506182a088bf043c00618390dfff022459 +:1075600024106200006182a088bf043c10618390f7 +:10757000dfff022424106200106182a088bf043c57 +:10758000c1608390f7ff022424106200c16082a0d2 +:1075900088bf043cd1608390f7ff0224241062006e +:1075a000d16082a080bf023c007040ac8628400fb2 +:1075b00000000000c160400f00000000ca68400fda +:1075c00000000000bf7d400f00000000448180a348 +:1075d000688180af029d023c3001428c288182afdd +:1075e000029d023c3401428c608182af2110000078 +:1075f000808182af21e8c0031400bf8f1000be8fce +:107600001800bd270800e00300000000d8ffbd27d8 +:107610002400bfaf2000beaf21f0a0031000c0af18 +:107620001400c0a31000c28f1f004014000000000f +:107630000c0004244560400f00000000448082af2d +:107640004c80838f4480828f211062004c8082aff7 +:107650004880828f01004224488082af4880828f18 +:1076600004004228efff4014000000004c80828f8d +:107670001800c2af1800c28f0400410400000000cf +:107680001800c38f030063241800c3af1800c38f12 +:10769000831003001000c2af488080af4c8080afe1 +:1076a000e0ff0010000000001000c28f0e00400438 +:1076b000000000001000c28fc90042280a004010dc +:1076c00000000000010002241400c2a301000424f1 +:1076d00014000524029d023c380146242138000094 +:1076e000d864400f000000001000c28fc80042287c +:1076f0000e004014000000001000c28f91014228cb +:107700000a00401000000000020002241400c2a37e +:107710000100042414000524029d023c4401462477 +:1077200021380000d864400f000000001000c28f14 +:10773000900142280e004014000000001000c28f8b +:10774000590242280a0040100000000003000224f1 +:107750001400c2a30100042414000524029d023c6d +:107760005401462421380000d864400f0000000076 +:107770001000c28f580242280e0040140000000082 +:107780001000c28f210342280a00401000000000b0 +:10779000040002241400c2a30100042414000524e0 +:1077a000029d023c6401462421380000d864400f49 +:1077b000000000001000c28f200342280e00401479 +:1077c000000000001000c28fe90342280a004010a8 +:1077d00000000000050002241400c2a301000424dc +:1077e00014000524029d023c780146242138000043 +:1077f000d864400f000000001000c28ffc03422834 +:1078000009004014000000001400c0a3010004247b +:1078100014000524029d023c880146242138000002 +:10782000d864400f000000001400c28321e8c003a8 +:107830002400bf8f2000be8f2800bd270800e00372 +:1078400000000000e0ffbd271c00bfaf1800beaf66 +:1078500021f0a0031000c0af831d400f0000000006 +:10786000548082a39d65400f00000000251e400f3c +:10787000000000001000c2af1000c28f21e8c0035a +:107880001c00bf8f1800be8f2000bd270800e0033a +:1078900000000000e0ffbd271c00bfaf1800beaf16 +:1078a00021f0a0031000c0af88bf023c5060428ca2 +:1078b000c000437c01000224670062140000000045 +:1078c00005000424ce61400f0000000088bf023c88 +:1078d0005060428c0001427c130040140000000004 +:1078e00005000424ce61400f0000000088bf023c68 +:1078f0005060428c0001427c0300401400000000f4 +:10790000faff0010000000001000c28f01004224a6 +:107910001000c2af1000c28f0400422802004014c1 +:10792000000000001000c0af88bf023c5060428cd5 +:10793000c003427c13004014000000000500042432 +:10794000ce61400f0000000088bf023c5060428cb6 +:10795000c003427c0300401400000000faff001046 +:10796000000000001000c28fffff42241000c2afd1 +:107970001000c28f03004104000000000300022435 +:107980001000c2af1000c28f1400c2af0100022469 +:107990001400c38f1b006210000000001400c38f8e +:1079a0000200622806004010000000001400c28f90 +:1079b0000d00401000000000bbff001000000000a0 +:1079c000020002241400c38f1500621000000000a2 +:1079d000030002241400c38f18006210000000008e +:1079e000b1ff001000000000020004242128000064 +:1079f00001000624be66400f00000000aaff001030 +:107a000000000000030004242128000001000624d7 +:107a1000be66400f00000000a3ff00100000000041 +:107a2000040004242128000001000624be66400f43 +:107a3000000000009cff001000000000050004246e +:107a40002128000001000624be66400f000000004f +:107a500095ff0010000000001000c28f21e8c00355 +:107a60001c00bf8f1800be8f2000bd270800e00358 +:107a700000000000d0ffbd272c00bfaf2800beaf24 +:107a800021f0a0033000c4af3400c5af3800c6af4a +:107a90002110e0003c00c2a388bf033c0100023c6f +:107aa000641062ac88bf033c0100023c681062ac09 +:107ab00001000224608082af47000224548182a327 +:107ac0002c8180af58000224998182a33000c28f9c +:107ad000188182af59000224648182a33400c28fce +:107ae000408182af3c00c2830700401000000000cc +:107af0005a0002247c8182a33800c28f9c8182af0d +:107b000004000010000000007c8180a32110000010 +:107b10009c8182af46000224558182a3211000007f +:107b20003c8182af5481838399818683648182837f +:107b30001000a2af4081828f1400a2af7c818283ab +:107b40001800a2af9c81828f1c00a2af5581828356 +:107b50002000a2af3c81828f2400a2af21206000d0 +:107b60002c81858f1881878f4c2d400f00000000dd +:107b7000548180a32c8180af998180a321100000c3 +:107b8000188182af648180a321100000408182af00 +:107b90007c8180a3211000009c8182af558180a34d +:107ba000211000003c8182af608080affa00042485 +:107bb000365c400f0000000021e8c0032c00bf8f9e +:107bc0002800be8f3000bd270800e0030000000041 +:107bd000e8ffbd271400bfaf1000beaf21f0a00327 +:107be0003c80838301000224060062140000000030 +:107bf0003c8080a3308180af408080af308080aff8 +:107c0000348080afa931400f000000000300401411 +:107c100000000000fbff0010000000004e1f400f9e +:107c20000000000088bf023c9061428c4002427c10 +:107c300003004014000000003900001000000000a4 +:107c40009020400f00000000648082af00a0023c42 +:107c5000bc044424029d023c94014524df41400fb2 +:107c6000000000005c8182af5c81828f308182af36 +:107c70005c81828f000042380100422c25104200b6 +:107c80002000401000000000020004242128000011 +:107c9000029d023c9801462421380000d864400f20 +:107ca000000000000300042428000524029d023c7b +:107cb000a801462421380000d864400f00000000cd +:107cc0000400042421280000029d023c8800462470 +:107cd00021380000d864400f00000000fa0004249e +:107ce000365c400f0000000088bf023c9061428c6f +:107cf0004002427ce4ff4014000000000800001035 +:107d000000000000020004245a000524029d023ce9 +:107d1000b801462421380000d864400f000000005c +:107d200021e8c0031400bf8f1000be8f1800bd27cc +:107d30000800e0030000000080ffbd277c00bfaf0b +:107d40007800beaf21f0a003200002244800c2a3a7 +:107d5000029d023cc001428c5000c2af01000224cf +:107d60005800c2af5c00c0af6000c0af5000c22777 +:107d70004800c39321204000212860001000c6273e +:107d80001958400f000000005800c2af5800c28fc1 +:107d90003700401400000000010002246c8082af14 +:107da0001000c4272859400f000000005800c2af3f +:107db0005800c28f04004014000000006c80828fc5 +:107dc000010042246c8082af5800c28f030040142f +:107dd00000000000f2ff0010000000006000c28ff1 +:107de00023004014000000005000c2274800c39345 +:107df00021204000212860001000c6271958400f9c +:107e0000000000005800c2af01000224688082af69 +:107e1000010002245c00c2af5c00c28f6c80838fc3 +:107e20002a1043000a004010000000001000c42780 +:107e30002859400f000000005800c2af5c00c28ffc +:107e4000010042245c00c2aff3ff001000000000fc +:107e50006c80828f688082af020004242128000099 +:107e60001000c62721380000d864400f0000000031 +:107e70005800c28f22004010000000006c8080afcc +:107e8000688080af0200042421280000029d023c8b +:107e9000c401462421380000d864400f00000000cf +:107ea0000300042421280000029d023cd80146243e +:107eb00021380000d864400f0000000005000424b1 +:107ec00021280000029d023c880046242138000041 +:107ed000d864400f00000000fa000424365c400f14 +:107ee0000000000088bf023c9061428c4002427c4e +:107ef000e4ff401400000000cb0000100000000070 +:107f00005800c28fa50040140000000088bf023c4a +:107f10005060428c0001427c33004014000000009d +:107f200088bf023c5060428c0001427c0300401438 +:107f300000000000faff0010000000001e000424f2 +:107f4000365c400f000000001000c4272859400f85 +:107f5000000000005800c2af5800c28f0f0040144c +:107f6000000000006880828f6c80838f2a1062007e +:107f700005004010000000006c80828f688082af96 +:107f800010000010000000006880828f0100422471 +:107f9000688082af0b000010000000005000c22774 +:107fa0004800c39321204000212860001000c6270c +:107fb0001958400f000000005800c2af0100022411 +:107fc000688082af020004245964400f0000000062 +:107fd00002000424212800001000c62721380000d8 +:107fe000d864400f0000000088bf023c5060428c03 +:107ff000c003427c3f0040140000000088bf023ce8 +:108000005060428cc003427c03004014000000001a +:10801000faff0010000000001e000424365c400f30 +:10802000000000001000c4272859400f0000000085 +:108030005800c2af5800c28f030040140000000077 +:10804000f8ff0010000000005000c2274800c39352 +:1080500021204000212860001000c6271958400f39 +:10806000000000005800c2af6880828fffff4224ea +:10807000688082af6880828f050040140000000095 +:108080006c80828f688082af010002246000c2afe2 +:10809000010002245c00c2af5c00c28f6880838f45 +:1080a0002a1043000a004010000000001000c427fe +:1080b0002859400f000000005800c2af5c00c28f7a +:1080c000010042245c00c2aff3ff0010000000007a +:1080d000020004245964400f000000000200042440 +:1080e000212800001000c62721380000d864400f66 +:1080f000000000000600042421280000029d023c2c +:10810000ec01462421380000d864400f0000000034 +:108110006800c22721204000029d023cf401452452 +:108120006880868f106d400f000000006800c22735 +:1081300006000424190005242130400021380000e5 +:10814000d864400f0000000006000424410005240c +:10815000029d023cf801462421380000d864400ffb +:10816000000000006800c22721204000029d023c60 +:10817000f40145246c80868f106d400f00000000d4 +:108180006800c227060004245a000524213040005c +:1081900021380000d864400f0000000088bf023c76 +:1081a0009061428c4002427c0300401400000000b9 +:1081b0001d0000100000000088bf023c5060428c8f +:1081c000c000427c010042380100432c5800c28f9d +:1081d000000042380100422c2410620003004010cd +:1081e0000000000046ff00100000000088bf023cb5 +:1081f0005060428cc000437c0100022403006214e2 +:1082000000000000d9fe00100000000000a0023ca9 +:10821000bc0444241000c527fb69400f0000000087 +:108220002000c28f488182af21e8c0037c00bf8f4d +:108230007800be8f8000bd270800e003000000002a +:10824000f0ffbd270800beaf21f0a0030800022404 +:108250000100c2a30100c2935000401000000000c2 +:1082600000a0023c0100c393bc0442242110620020 +:10827000000043802e00022443006214000000002e +:1082800000a0023c0100c393bc0442242110620000 +:1082900001004280470042380100442c00a0023c0b +:1082a0000100c393bc0442242110620002004280fa +:1082b000430042380100422c2420820000a0023cee +:1082c0000100c393bc0442242110620003004280d9 +:1082d0004f0042380100422c241082000700401059 +:1082e00000000000010002240000c2a301000224db +:1082f0000400c2af290000100000000000a0023cf2 +:108300000100c393bc04422421106200010042809a +:10831000420042380100442c00a0023c0100c393fb +:10832000bc04422421106200020042804600423810 +:108330000100422c2420820000a0023c0100c393d3 +:10834000bc044224211062000300428042004238f3 +:108350000100422c241082000700401000000000a1 +:10836000030002240000c2a3030002240400c2afe1 +:108370000a000010000000000000c0a30400c0af0d +:1083800006000010000000000100c293ffff42241d +:108390000100c2a3afff0010000000000400c28f64 +:1083a00021e8c0030800be8f1000bd270800e003cd +:1083b00000000000d0ffbd272c00bfaf2800beafdb +:1083c00021f0a003010002242000c2af2400c0afae +:1083d0003c8080a33081828f5c8182af3480828f29 +:1083e00001004224348082af00a0033c3e000224fe +:1083f000880462a05c81848f3080858f21300000ea +:10840000054a400f00000000060040100000000078 +:10841000010004241c1c400f000000000100022485 +:108420003c8082a33c8082833f0040140000000017 +:108430009881842701000524010006245c81878f30 +:108440003d47400f00000000408082af00a0023c8a +:108450002000c38f880442242118620098818293ef +:10846000000062a02000c28f010042242000c2afa1 +:108470009881838328000224150062140000000004 +:108480009881842701000524010006245c81878fe0 +:108490003d47400f00000000408082af5c81848f28 +:1084a0002d47400f000000000300401000000000b6 +:1084b0000700001000000000988183830a00022456 +:1084c0000300621000000000edff0010000000003b +:1084d0005c81848f2d47400f000000000800401091 +:1084e000000000005c81848f0e3f400f0000000000 +:1084f000010002243c8082a307000010000000005d +:10850000988183830a0002240300621000000000a7 +:10851000c7ff0010000000005c81848f8b43400f78 +:1085200000000000308082af21e8c0032c00bf8f24 +:108530002800be8f3000bd270800e00300000000c7 +:10854000e0ffbd271c00bfaf1800beaf21f0a003a5 +:10855000010002241000c2af1400c0af01000224c9 +:10856000388082af00a0023c88044224010043907e +:108570000d0002240300621400000000dc00001063 +:10858000000000003880838f01000224270062145d +:10859000000000001400c28f0a0040140000000018 +:1085a00000a0023c1000c38f880442242110620006 +:1085b00000004290548182a31000c28f0100422427 +:1085c0001000c2af1400c38f3481822721206200c3 +:1085d00000a0023c1000c38f8804422421106200d6 +:1085e00000004290000082a01400c28f01004224cb +:1085f0001400c2af00a0023c1000c38f88044224c4 +:108600002110620000004390200002240700621441 +:10861000000000001000c28f010042241000c2af11 +:108620001400c0af02000224388082af3880838fec +:108630000200022427006214000000001400c28f10 +:108640000a0040140000000000a0023c1000c38f8c +:10865000880442242110620000004290998182a384 +:108660001000c28f010042241000c2af1400c38f5b +:10867000a48182272120620000a0023c1000c38f49 +:10868000880442242110620000004290000082a071 +:108690001400c28f010042241400c2af00a0023cab +:1086a0001000c38f88044224211062000000439010 +:1086b0002000022407006214000000001000c28f96 +:1086c000010042241000c2af1400c0af0300022416 +:1086d000388082af3880838f030002242700621421 +:1086e000000000001400c28f0a00401400000000c7 +:1086f00000a0023c1000c38f8804422421106200b5 +:1087000000004290648182a31000c28f01004224c5 +:108710001000c2af1400c38f748182272120620031 +:1087200000a0023c1000c38f880442242110620084 +:1087300000004290000082a01400c28f0100422479 +:108740001400c2af00a0023c1000c38f8804422472 +:1087500021106200000043902000022407006214f0 +:10876000000000001000c28f010042241000c2afc0 +:108770001400c0af04000224388082af3880838f99 +:108780000400022427006214000000001400c28fbd +:108790000a0040140000000000a0023c1000c38f3b +:1087a0008804422421106200000042907c8182a350 +:1087b0001000c28f010042241000c2af1400c38f0a +:1087c000908182272120620000a0023c1000c38f0c +:1087d000880442242110620000004290000082a020 +:1087e0001400c28f010042241400c2af00a0023c5a +:1087f0001000c38f880442242110620000004390bf +:108800002000022407006214000000001000c28f44 +:10881000010042241000c2af1400c0af05000224c2 +:10882000388082af3880838f0500022419006214db +:10883000000000001400c28f0a0040140000000075 +:1088400000a0023c1000c38f880442242110620063 +:1088500000004290558182a31000c28f0100422483 +:108860001000c2af1400c38f208182272120620034 +:1088700000a0023c1000c38f880442242110620033 +:1088800000004290000082a01400c28f0100422428 +:108890001400c2af00a0023c1000c38f8804422421 +:1088a00021106200000043900a00022403006214b9 +:1088b000000000000e000010000000001000c28f39 +:1088c000010042241000c2af00a0023c1000c38f80 +:1088d0008804422421106200000043900d0002240d +:1088e00003006210000000001eff001000000000e6 +:1088f00034818427d16b400f000000002c8182afaf +:10890000a4818427ca6b400f000000002120400092 +:1089100021286000f278400f00000000188182af2b +:1089200074818427ca6b400f0000000021204000a2 +:1089300021286000f278400f00000000408182afe3 +:1089400090818427ca6b400f000000002120400066 +:1089500021286000f278400f000000009c8182af67 +:1089600020818427ca6b400f0000000021204000b6 +:1089700021286000f278400f000000003c8182afa7 +:1089800021e8c0031c00bf8f1800be8f2000bd2748 +:108990000800e00300000000f0ffbd270800beafa4 +:1089a00021f0a003310002240000c2af0000c28ffa +:1089b0000b0040100000000000a0023c0000c38f2c +:1089c0008804422421106200000040a00000c28ff1 +:1089d000ffff42240000c2aff4ff001000000000bf +:1089e0000000c28f030040140000000000a0023c01 +:1089f000880440a0548180a3070002240000c2af75 +:108a00000000c28f0a004010000000000000c38f69 +:108a10003481822721106200000040a00000c28f34 +:108a2000ffff42240000c2aff5ff0010000000006d +:108a30000000c28f0200401400000000348180a3b7 +:108a4000998180a3070002240000c2af0000c28ffa +:108a50000a004010000000000000c38fa48182279c +:108a600021106200000040a00000c28fffff4224de +:108a70000000c2aff5ff0010000000000000c28f30 +:108a80000200401400000000a48180a3648180a340 +:108a9000070002240000c2af0000c28f0a0040108d +:108aa000000000000000c38f748182272110620043 +:108ab000000040a00000c28fffff42240000c2afb0 +:108ac000f5ff0010000000000000c28f02004014fb +:108ad00000000000748180a37c8180a30700022431 +:108ae0000000c2af0000c28f0a004010000000006a +:108af0000000c38f9081822721106200000040a0f7 +:108b00000000c28fffff42240000c2aff5ff00103b +:108b1000000000000000c28f0200401400000000ae +:108b2000908180a3558180a3070002240000c2af7a +:108b30000000c28f0a004010000000000000c38f38 +:108b40002081822721106200000040a00000c28f17 +:108b5000ffff42240000c2aff5ff0010000000003c +:108b60000000c28f0200401400000000208180a39a +:108b700021e8c0030800be8f1000bd270800e003f5 +:108b800000000000e0ffbd271c00bfaf1800beaf13 +:108b900021f0a003211000001000c2aff081828fed +:108ba000cc81838f2a1062000a0040100000000070 +:108bb000f081838fcc81828f2310620021204000be +:108bc000767b400f000000001000c2af09000010cb +:108bd00000000000f081838fcc81828f231062001f +:108be0000002422421204000767b400f000000005c +:108bf0001000c2af029d023c1000c48ffc01458ce6 +:108c0000eb7a400f000000001000c2af029d023c52 +:108c10001000c48f0002458c7d7a400f00000000d8 +:108c20001000c2af1000c48fa07b400f00000000f6 +:108c300006000424212840002464400f00000000a6 +:108c400021e8c0031c00bf8f1800be8f2000bd2785 +:108c50000800e00300000000d8ffbd272000bfafe0 +:108c60001c00beaf1800b0af21f0a003211000001f +:108c70001000c2af3080848f767b400f0000000070 +:108c8000218040004881848f767b400f00000000e7 +:108c90002120000221284000eb7a400f0000000054 +:108ca0001000c2af029d023c1000c48f0402458c2c +:108cb0007d7a400f000000001000c2af029d023c10 +:108cc0000402448c1000c58fdb7b400f00000000c5 +:108cd0000300400400000000040000100000000039 +:108ce000029d023c0402428c1000c2af1000c48fef +:108cf000a07b400f00000000050004242128400054 +:108d00002464400f0000000021e8c0032000bf8f52 +:108d10001c00be8f1800b08f2800bd270800e0039c +:108d200000000000c8ffbd273400bfaf3000beaf59 +:108d300021f0a003211080003800c2a32110000000 +:108d40002000c2af211000002400c2af211000009b +:108d50002800c2afcc81838ff081828f0300621024 +:108d600000000000fbff00100000000088bf033c73 +:108d70000100023c641062ac88bf023c681040ac49 +:108d800060ea02348c8182afa48080a3a58080a396 +:108d9000a68080a3010004245a24400f0000000094 +:108da000d465400f0000000088bf023c5060428c38 +:108db000c000427c0300401400000000faff0010d5 +:108dc0000000000088bf023c9061428c4002437c5e +:108dd00001000224d80062140000000001000224f7 +:108de000a88082af8c81828fe9034228040040145e +:108df000000000008c81828fb5ff42248c8182affd +:108e00008c81828f6500422804004014000000001d +:108e10008c81828ffbff42248c8182af8c81828f78 +:108e2000900142280300401000000000900102243d +:108e30008c8182af88bf023c5060428cc000427c73 +:108e40000400401400000000088280af01000224ea +:108e5000a48082a388bf023c5060428c8000427c88 +:108e6000050040140000000001000224088282afc7 +:108e700001000224a48082a388bf023c5060428c7f +:108e8000c000427c070040100000000088bf023c88 +:108e90005060428c8000427c0200401000000000c4 +:108ea000a48080a388bf023c5060428cc003427cf7 +:108eb0000400401400000000e88180af010002249b +:108ec000a58082a388bf023c5060428c0001427c96 +:108ed000050040140000000001000224e88182af78 +:108ee00001000224a58082a388bf023c5060428c0e +:108ef000c003427c070040100000000088bf023c15 +:108f00005060428c0001427c0200401000000000d2 +:108f1000a58080a388bf023c5061428c4001427c06 +:108f20000400401400000000f48180af010002241e +:108f3000a68082a388bf023c5061428c0001427c23 +:108f4000050040140000000001000224f48182affb +:108f500001000224a68082a388bf023c5061428c9b +:108f60004001427c070040100000000088bf023c26 +:108f70005061428c0001427c020040100000000061 +:108f8000a68080a3a4808283090040140000000012 +:108f9000a58082830600401400000000a680828322 +:108fa000030040140000000060ea02348c8182afac +:108fb0003800c28383ff401000000000b881848f16 +:108fc000767b400f0000000021204000c978400f50 +:108fd00000000000029d063c212040002128600086 +:108fe0001402c78c1002c68c6b77400f0000000083 +:108ff0002120400021286000f278400f000000008e +:109000002000c2af2000c48fc978400f00000000cc +:1090100021304000213860001000c427029d023c2e +:1090200008024524106d400f0000000004000424d5 +:10903000400005241000c62721380000d864400fe6 +:1090400000000000ec81848f767b400f0000000060 +:1090500021204000c978400f00000000029d063c1e +:1090600021204000212860001402c78c1002c68c09 +:109070006b77400f00000000212040002128600095 +:10908000f278400f000000002400c2af2400c48f1b +:10909000c978400f000000002130400021386000f6 +:1090a0001000c427029d023c08024524106d400fa9 +:1090b0000000000005000424400005241000c6271d +:1090c00021380000d864400f00000000c081848f68 +:1090d000767b400f00000000029d033c21204000f1 +:1090e0001802658ceb7a400f000000002800c2af28 +:1090f0002800c48fc978400f0000000021304000d4 +:10910000213860001000c427029d023c080245245b +:10911000106d400f000000000600042440000524ec +:109120001000c62721380000d864400f000000005e +:1091300024ff001000000000a88080af88bf023c20 +:109140000100033c641043ac88bf023c681040ac93 +:1091500021e8c0033400bf8f3000be8f3800bd2728 +:109160000800e00300000000f8ffbd270000beafcc +:1091700021f0a0030800c4af0800c38f010002243f +:10918000180062140000000088bf043cd060839087 +:10919000f7ff022424106200d06082a088bf043c44 +:1091a000d1608390fbff022424106200d16082a072 +:1091b00088bf043c51608390dfff022424106200ca +:1091c000516082a088bf033c0100023c641062ac85 +:1091d00088bf033c0100023c681062ac1200001022 +:1091e0000000000088bf033cd06062900800423459 +:1091f000d06062a088bf033cd1606290040042341a +:10920000d16062a088bf033c51606290200042346c +:10921000516062a088bf033c0100023c641062ac54 +:1092200088bf023c681040ac21e8c0030000be8f3c +:109230000800bd270800e00300000000e0ffbd2794 +:109240001c00bfaf1800beaf21f0a0033366400f73 +:1092500000000000a48080a3a58080a3a68080a336 +:109260008628400f00000000010004245a24400f0b +:109270000000000001000224a88082aff401022453 +:109280008c8182af0300042421280000029d023c4f +:109290001c02462421380000d864400f0000000062 +:1092a00001000224f48182af01000224a68082a37f +:1092b0001000c0af1000c38f0300023c3f0d4234ca +:1092c0002a10430006004014000000001000c28f66 +:1092d000010042241000c2aff6ff001000000000a1 +:1092e000a68080a30300042421280000029d023ce4 +:1092f0002802462421380000d864400f00000000f6 +:10930000e80302248c8182af01000224e88182af4d +:1093100001000224a58082a31000c0af1000c28ffc +:109320005fea03342a1062000600401400000000c7 +:109330001000c28f010042241000c2aff7ff0010de +:1093400000000000a58080a3030004242128000061 +:10935000029d023c3402462421380000d864400fac +:1093600000000000e80302248c8182af88bf023c29 +:10937000d060428c0001427c2100401400000000bb +:1093800088bf023c9061428c4002427c1c0040102d +:109390000000000001000224088282af88bf023c66 +:1093a000d060428c0001427c0a00401400000000a2 +:1093b00088bf023c9061428c4002427c0500401014 +:1093c0000000000001000224a48082a3f3ff00102b +:1093d00000000000a48080a31000c0af1000c28f66 +:1093e000204e4228e1ff4010000000001000c28f14 +:1093f000010042241000c2aff8ff0010000000007e +:1094000001000224a48082a31000c0af1000c28f0c +:109410001027422806004010000000001000c28ff4 +:10942000010042241000c2aff8ff0010000000004d +:10943000a48080a360ea02348c8182af88bf023ca2 +:10944000d060428c0001427c2600401000000000e9 +:1094500088bf023c9061428c4002427c2100401057 +:1094600000000000088280af88bf023cd060428cc0 +:109470000001427c0a0040100000000088bf023c4e +:109480009061428c4002427c0500401000000000c8 +:1094900001000224a48082a3f3ff0010000000005a +:1094a000a48080a31000c0af1000c28fd007422854 +:1094b00006004010000000001000c28f010042248e +:1094c0001000c2aff8ff001000000000d2d102244b +:1094d000b88182afb881828fbc8182afd7ff001084 +:1094e000000000000300042421280000029d023c2b +:1094f0004002462421380000d864400f00000000dc +:10950000e80302248c8182af88bf023c9060428cc9 +:109510004003427c200040140000000088bf023c51 +:109520009061428c4002427c1b0040100000000011 +:10953000e88180af88bf023c9060428c4003427c4f +:109540000a0040140000000088bf023c9061428c79 +:109550004002427c0500401000000000010002248f +:10956000a58082a3f3ff001000000000a58080a367 +:109570001000c0af1000c28f204e4228e2ff401002 +:10958000000000001000c28f010042241000c2af92 +:10959000f8ff00100000000001000224a58082a353 +:1095a0001000c0af1000c28f1027422806004010e4 +:1095b000000000001000c28f010042241000c2af62 +:1095c000f8ff001000000000a58080a360ea0234cc +:1095d0008c8182af88bf023c9060428c4003427c09 +:1095e000270040100000000088bf023c9061428cc0 +:1095f0004002427c220040100000000001000224d2 +:10960000e88182af88bf023c9060428c4003427c7c +:109610000a0040100000000088bf023c9061428cac +:109620004002427c050040100000000001000224be +:10963000a58082a3f3ff001000000000a58080a396 +:109640001000c0af1000c28fd007422806004010a3 +:10965000000000001000c28f010042241000c2afc1 +:10966000f8ff00100000000035220224ec8182afd8 +:10967000ec81828fd48182afd6ff00100000000001 +:109680000300042421280000029d023c4c024624d1 +:1096900021380000d864400f00000000f4010224cb +:1096a0008c8182af88bf023c9060428c8003427cf8 +:1096b000200040140000000088bf023c9061428cf2 +:1096c0004002427c1b00401000000000f48180af8b +:1096d00088bf023c9060428c8003427c0a004014a8 +:1096e0000000000088bf023c9061428c4002427c36 +:1096f000050040100000000001000224a68082a3a3 +:10970000f3ff001000000000a68080a31000c0af8f +:109710001000c28fd0074228e2ff40100000000076 +:109720001000c28f010042241000c2aff8ff0010e9 +:109730000000000001000224a68082a31000c0af38 +:109740001000c28f102742280600401000000000c1 +:109750001000c28f010042241000c2aff8ff0010b9 +:1097600000000000a68080a3881302248c8182afb1 +:1097700088bf023c9060428c8003427c26004010ef +:109780000000000088bf023c9061428c4002427c95 +:10979000210040100000000001000224f48182af8b +:1097a00088bf023c9060428c8003427c0a004010db +:1097b0000000000088bf023c9061428c4002427c65 +:1097c000050040100000000001000224a68082a3d2 +:1097d000f3ff001000000000a68080a31000c0afbf +:1097e0001000c28fd0074228060040100000000081 +:1097f0001000c28f010042241000c2aff8ff001019 +:1098000000000000c08180afc081828fe08182af04 +:10981000d7ff001000000000a88080af88bf033c85 +:109820000100023c641062ac88bf023c681040ac8e +:1098300088bf023c9061428c4002427c1700401479 +:10984000000000000300042421280000029d023cc7 +:109850005802462421380000d864400f0000000060 +:109860001000c0af1000c38f1e00023c7f84423442 +:109870002a10430006004014000000001000c28fb0 +:10988000010042241000c2aff6ff001000000000eb +:109890001400c0af160000100000000003000424f4 +:1098a00021280000029d023c680246242138000065 +:1098b000d864400f000000001000c0af1000c38f3c +:1098c0001e00023c7f8442342a10430006004014ec +:1098d000000000001000c28f010042241000c2af3f +:1098e000f6ff001000000000010002241400c2afc7 +:1098f0001400c28f21e8c0031c00bf8f1800be8f68 +:109900002000bd270800e00300000000e8ffbd279d +:109910001400bfaf1000beaf21f0a003010002246d +:10992000c08082af01000224c48082afc88080afb3 +:10993000f40102248c8182af2881848fc978400f82 +:1099400000000000029d063c21204000212860000c +:109950007c02c78c7802c68ca176400f0000000004 +:109960002120400021286000f278400f0000000014 +:10997000e48182af6081848fc978400f00000000cd +:10998000029d063c21204000212860007c02c78cfb +:109990007802c68ca176400f000000002120400014 +:1099a00021286000f278400f00000000d88182afcb +:1099b000e481848fc22c400f00000000b48182af8c +:1099c000d881848fc22c400f00000000048282af37 +:1099d00088bf033c0100023c641062ac88bf033cba +:1099e0000100023c681062ac642a400f00000000d5 +:1099f000c08080afc48080affa000424365c400f82 +:109a00000000000021e8c0031400bf8f1000be8fcb +:109a10001800bd270800e0030000000000e85d41d9 +:109a200000681a4000701b40c0ffbd273c00bbaf60 +:109a300000601b4082d21a003800bbaf847a5b7f83 +:109a400044201b7c00609b403400beaf3000a4afbc +:109a50002c00a3af2800a2af21f0a0030400c0a3f4 +:109a6000a880828f9800401000000000a080828fa4 +:109a70000800c2af010002240800c38f2600621054 +:109a8000000000000800c38f02006228060040109a +:109a9000000000000800c28f090040100000000014 +:109aa0008200001000000000020002240800c38fa2 +:109ab0006b006210000000007c000010000000003d +:109ac00088bf043cd060828c0882838fc439627c5a +:109ad000d06082ac88bf043cd060828ce881838fe8 +:109ae000444a627cd06082ac88bf043c5060828c67 +:109af000f481838f444a627c506082ac80bf033c17 +:109b000005000224200c62ac01000224a08082af78 +:109b10006600001000000000a48082831200401044 +:109b20000000000088bf033cd06062900400423413 +:109b3000d06062a00882828f0600401400000000fe +:109b4000b881828f01004224b88182af0b000010df +:109b500000000000b881828fffff4224b88182afed +:109b6000060000100000000088bf043cd060839015 +:109b7000fbff022424106200d06082a0a5808283b3 +:109b8000120040100000000088bf033cd1606290ca +:109b900001004234d16062a0e881828f0600401447 +:109ba00000000000ec81828f01004224ec8182af32 +:109bb0000b00001000000000ec81828fffff4224a8 +:109bc000ec8182af060000100000000088bf043c5a +:109bd000d1608390feff022424106200d16082a035 +:109be000a6808283120040100000000088bf033c62 +:109bf0005160629001004234516062a0f481828f12 +:109c00000600401400000000c081828f0100422441 +:109c1000c08182af0b00001000000000c081828f65 +:109c2000ffff4224c08182af060000100000000048 +:109c300088bf043c51608390feff02242410620020 +:109c4000516082a080bf023c0a000324200c43ac78 +:109c500002000224a08082af140000100000000067 +:109c600080bf033c8c81828f200c62ac88bf043c97 +:109c7000d0608390fbff022424106200d06082a099 +:109c800088bf043cd1608390feff02242410620050 +:109c9000d16082a088bf043c51608390feff022403 +:109ca00024106200516082a0a08080af80bf023c7f +:109cb000100c40ac88bf033c0100023c341062ac85 +:109cc00048010010000000009c80828f2400c2af79 +:109cd000010002242400c38fa500621000000000d0 +:109ce0002400c38f0200622806004010000000001c +:109cf0002400c28f09004010000000003401001051 +:109d000000000000020002242400c38f0d01621035 +:109d1000000000002e01001000000000b081828fc2 +:109d20008c00401400000000cc81838ff081828f72 +:109d3000880062100000000000a0043ccc81828feb +:109d400080180200c8048224211062000000428ca6 +:109d5000d08182af00a0043ccc81828f80180200a9 +:109d6000c804822421106200000040accc81828fa4 +:109d700001004224cc8182afcc81828f0c00c2af23 +:109d80000c00c38f1000c3af1000c28f0400410449 +:109d9000000000001000c38fff0163241000c3af58 +:109da0001000c38f43120300401202000c00c38f47 +:109db00023106200cc8182af01000224b08182af07 +:109dc0000008023c0000c2af030002240400c2a34a +:109dd000d081828f0000c38f241043002a004010de +:109de000000000000400c2931400c2af050002246a +:109df0001400c38f17006210000000001400c38f0e +:109e00000600622807004010000000000300022442 +:109e10001400c38f0900621000000000420000100f +:109e200000000000070002241400c38f0f0062101e +:109e3000000000003c0000100000000088bf023c51 +:109e40005160439002006334516043a0360000101b +:109e50000000000088bf023cd160439002006334e0 +:109e6000d16043a0300000100000000088bf043c17 +:109e7000d060839080ff022425106200d06082a011 +:109e800029000010000000000400c2931800c2afb7 +:109e9000050002241800c38f1800621000000000a3 +:109ea0001800c38f06006228070040100000000061 +:109eb000030002241800c38f090062100000000094 +:109ec0001900001000000000070002241800c38fd2 +:109ed00011006210000000001300001000000000dc +:109ee00088bf043c51608390fdff0224241062006f +:109ef000516082a00c0000100000000088bf043cec +:109f0000d1608390fdff022424106200d16082a002 +:109f1000050000100000000088bf023cd0604390a4 +:109f20007f006330d06043a00400c293020042244b +:109f30000400c2a30000c28f801002000000c2af64 +:109f40000000c28f0300401000000000a0ff0010be +:109f50000000000080bf023c05000324200c43ac3d +:109f6000010002249c8082af9900001000000000d4 +:109f7000b081828f6c004010000000000004023ca1 +:109f80000000c2af020002240400c2a3d081828f6d +:109f90000000c38f241043002d004010000000007b +:109fa0000400c2931c00c2af040002241c00c38f33 +:109fb00017006210000000001c00c38f050062281b +:109fc0000700401000000000020002241c00c38fa4 +:109fd00009006210000000004800001000000000ae +:109fe000060002241c00c38f110062100000000054 +:109ff000420000100000000088bf023c5160439006 +:10a0000001006334516043a03c00001000000000d8 +:10a0100088bf033cd160629001004234d16062a0ed +:10a02000010002240600c2a334000010000000005a +:10a0300088bf033cd060629004004234d06062a0cc +:10a04000010002240500c2a32c0000100000000043 +:10a050000400c2932000c2af040002242000c38f7a +:10a0600018006210000000002000c38f0500622865 +:10a070000700401000000000020002242000c38fef +:10a0800009006210000000001c0000100000000029 +:10a09000060002242000c38f12006210000000009e +:10a0a000160000100000000088bf043c516083903f +:10a0b000feff022424106200516082a00f000010f5 +:10a0c0000000000088bf043cd1608390feff0224a2 +:10a0d00024106200d16082a00600c0a30700001017 +:10a0e0000000000088bf043cd0608390fbff022486 +:10a0f00024106200d06082a00500c0a30400c293b7 +:10a10000020042240400c2a30000c28f801002009b +:10a110000000c2af0000c28f03004010000000002a +:10a120009aff00100000000080bf023c0a000324d8 +:10a13000200c43ac020002249c8082af240000105b +:10a1400000000000b081828f0c0040100000000071 +:10a15000ffff02340000c2afd081838f0000c28fa6 +:10a16000241062000c8082af80bf033c0c80828f81 +:10a17000200c62ac040000100000000080bf033c13 +:10a1800088130224200c62ac88bf043cd06083900a +:10a19000fbff022424106200d06082a088bf043c30 +:10a1a000d1608390feff022424106200d16082a05f +:10a1b00088bf043c51608390feff0224241062009b +:10a1c000516082a09c8080afb08180afd08180af91 +:10a1d00080bf023c100c40ac88bf033c0100023c35 +:10a1e000341062ac21e8c0033400be8f3000a48f6d +:10a1f0002c00a38f2800a28f00606041c0000000e7 +:10a200003c00ba8f00709a403800ba8f4000bd27da +:10a2100000609a4018000042e8ffbd271400bfaf5d +:10a220001000beaf21f0a00380bf033c3080023499 +:10a23000000662ac81bf043c00f28390f7ff022469 +:10a240002410620000f282a081bf033c6190629002 +:10a2500001004234619062a088bf043c4160839059 +:10a26000feff022424106200416082a081bf033cf3 +:10a270006190629002004234619062a088bf043c09 +:10a2800041608390fdff022424106200416082a09f +:10a2900081bf033c6190629020004234619062a0d3 +:10a2a00088bf043c41608390dfff022424106200d9 +:10a2b000416082a088bf033cc060629010004234bd +:10a2c000c06062a088bf043cc1608390feff02248e +:10a2d00024106200c16082a088bf043cc1608390ea +:10a2e000fdff022424106200c16082a088bf043cec +:10a2f000c1608390fbff022424106200c16082a031 +:10a3000088bf033c8160629020004234816062a07b +:10a3100088bf043cc0608390fbff022424106200cd +:10a32000c06082a088bf033cc06062907f00423062 +:10a33000c06062a088bf043cc0608390f7ff022425 +:10a3400024106200c06082a088bf033c81606290dc +:10a3500040004234816062a088bf033cd0606290bc +:10a3600008004234d06062a088bf033cd160629094 +:10a3700004004234d16062a088bf033c5160629007 +:10a3800020004234516062a080bf023c000c40ac0f +:10a3900080bf033c10000224080c62ac80bf023c6a +:10a3a000100c40ac80bf033cf4010224200c62acd2 +:10a3b00088bf033c1c000224d41062ac88bf033c5d +:10a3c0001c000224d81062acbf7d400f00000000ca +:10a3d00088bf033c0100023c341062ac80bf033ce8 +:10a3e00000800234080c62ac88bf033c0100023cd0 +:10a3f000641062ac88bf023c681040accc8180af76 +:10a40000f08180af708180af508180af21e8c003c0 +:10a410001400bf8f1000be8f1800bd270800e00396 +:10a4200000000000e0ffbd271c00bfaf1800beaf5a +:10a4300021f0a0032000c4af2400c5af2000c28fcc +:10a440001c8182af2400c28ff88182af2000c38fad +:10a450008888023c8988423418006200101000008d +:10a460002110430043210200c31703002310820080 +:10a470002000c2af2000c28f090040100000000081 +:10a4800006df03342000c28f1a006200f40140008e +:10a49000121000008c8182af030000100000000049 +:10a4a000d00702248c8182af5081828f0500401832 +:10a4b000000000005081828f748082af0300001082 +:10a4c00000000000ee020224748082af8c81848f31 +:10a4d0009878400f00000000029d063c21204000bb +:10a4e000212860008402c78c8002c68ca176400fb0 +:10a4f0000000000021204000212860003079400f3a +:10a5000000000000708082af7d8182831a004014b9 +:10a51000000000007081828f0500401800000000dc +:10a520007081828f8c8182af0300001000000000d8 +:10a53000ee0202248c8182af4c818283150040148c +:10a54000000000001080838f0100022403006214c9 +:10a5500000000000df61400f0000000088bf023ce7 +:10a560001061439001006334106143a0108080affc +:10a5700008000010000000001080828f03004014cb +:10a58000000000000562400f0000000001000224ee +:10a59000108082af6080828f1200401000000000a7 +:10a5a0007081828f07004018000000007081828f48 +:10a5b0008c8182af7081828f708082af0500001025 +:10a5c00000000000ee0202248c8182afee02022421 +:10a5d000708082af88bf023c1061439001006334f9 +:10a5e000106143a021e8c0031c00bf8f1800be8f7c +:10a5f0002000bd270800e00300000000e8ffbd27a1 +:10a600001400bfaf1000beaf21f0a0031800c4af0c +:10a610002110a0001c00c2a31800c38f1400022444 +:10a620000300621000000000210000100000000084 +:10a63000029d023c3082848f8802458c7d7a400fd7 +:10a6400000000000e48182af029d023c1882848fea +:10a650008802458c7d7a400f00000000d88182afcf +:10a66000029d023c2482848f8802458c7d7a400fb3 +:10a67000000000000c8282afe481848fc22c400f66 +:10a6800000000000b48182afd881848fc22c400fbb +:10a6900000000000048282af0c82848fc22c400f25 +:10a6a00000000000dc8182af3100001000000000db +:10a6b0003082848fc978400f00000000029d063c64 +:10a6c00021204000212860009402c78c9002c68c93 +:10a6d000a176400f000000002120400021286000ea +:10a6e000f278400f00000000e48182af1882848f6e +:10a6f000c978400f00000000029d063c2120400068 +:10a70000212860009402c78c9002c68ca176400f6d +:10a71000000000002120400021286000f278400f56 +:10a7200000000000d88182af029d023c2482848f09 +:10a730009802458c7d7a400f000000000c8282afa9 +:10a74000e481848fc22c400f00000000b48182afee +:10a75000d881848fc22c400f00000000048282af99 +:10a760000c82848fc22c400f00000000dc8182af7d +:10a7700021e8c0031400bf8f1000be8f1800bd2752 +:10a780000800e00300000000d8ffbd272400bfaf91 +:10a790002000beaf21f0a003bc81838fb881828fdf +:10a7a00023106200ac8082afd481838fec81828fd2 +:10a7b00023106200b08082afe081838fc081828fde +:10a7c00023106200b48082afb88180afec8180af8b +:10a7d000c08180afac80848f9878400f000000006b +:10a7e000029d063c2120400021286000a402c78c65 +:10a7f000a002c68c6b77400f0000000021204000b3 +:10a8000021286000f278400f000000001000c2af65 +:10a81000b080848f9878400f00000000029d063cb5 +:10a820002120400021286000a402c78ca002c68c11 +:10a830006b77400f000000002120400021286000bd +:10a84000f278400f000000001400c2afb480848f83 +:10a850006666023c676642341800820010100000f1 +:10a86000831a0200c3170400231062002120400055 +:10a87000767b400f000000001800c2af029d023c32 +:10a880001000c48fa802458ce279400f0000000040 +:10a89000288182af029d023c1400c48fac02458c1b +:10a8a000e279400f00000000608182af1800c48f81 +:10a8b00021280000e279400f00000000808182af73 +:10a8c00021e8c0032400bf8f2000be8f2800bd27d1 +:10a8d0000800e00300000000f8ffbd270000beaf45 +:10a8e00021f0a003b881838fbc81828f07006210a2 +:10a8f00000000000bc81838fac80828f231862002f +:10a90000b881828f21104300b88182afec81838fa0 +:10a91000d481828f0700621000000000d481838ff1 +:10a92000b080828f23186200ec81828f2110430057 +:10a93000ec8182afc081838fe081828f070062103b +:10a9400000000000e081838fb480828f23186200b2 +:10a95000c081828f21104300c08182af029d023ce2 +:10a96000b002428c288182af029d023cb402428c2c +:10a97000608182af21100000808182af21e8c00396 +:10a980000000be8f0800bd270800e00300000000a3 +:10a99000e0ffbd271c00bfaf1800beaf21f0a00331 +:10a9a000ec81828f1000a2afc081828f1400a2af11 +:10a9b000b481848f0482858fdc81868fb881878ff4 +:10a9c0007a2a400f00000000642c400f00000000b5 +:10a9d00021e8c0031c00bf8f1800be8f2000bd27d8 +:10a9e0000800e0030000000098ffbd276400bfaf2f +:10a9f0006000beaf21f0a0036800c4af6c00c5af1b +:10aa00007000c6af7400c7af1000c0af01000224d1 +:10aa10001400c2af010002241800c2af01000224da +:10aa20001c00c2af7400c38f6800c28f2310620085 +:10aa30002000c2af7800c38f6c00c28f2310620069 +:10aa40002400c2af7c00c38f7000c28f231062004d +:10aa50002800c2af2000c38f2000c28f21106200e7 +:10aa60002c00c2af2400c38f2400c28f21106200cb +:10aa70003000c2af2800c38f2800c28f21106200af +:10aa80003400c2af6800c28f3800c2af6c00c28f02 +:10aa90003c00c2af7000c28f4000c2af4400c0afe4 +:10aaa0004800c0af4c00c0af5000c0af5400c0afb2 +:10aab0005800c0af5c00c0a3c080828f0300401468 +:10aac000000000002000c0af2c00c0afc480828f07 +:10aad00003004014000000002400c0af3000c0afed +:10aae000c880828f03004014000000002800c0af1f +:10aaf0003400c0af2000c28f0700401400000000e7 +:10ab00007400c28f6800c2afb881828fb48182aff7 +:10ab10007880828f308282af2400c28f0700401479 +:10ab2000000000007800c28f6c00c2afec81828f01 +:10ab3000048282af7c80828f188282af2800c28f0d +:10ab400007004014000000007c00c28f7000c2affc +:10ab5000c081828fdc8182af8080828f248282af2d +:10ab60002000c28f130041040000000088bf033c96 +:10ab7000d06062907f004230d06062a07f000324ea +:10ab80005c00c293241043005c00c2a3ffff0224b8 +:10ab90001400c2af2000c28f231002002000c2aff9 +:10aba0002c00c28f231002002c00c2af0a0000103c +:10abb0000000000088bf043cd060839080ff022426 +:10abc00025106200d06082a05c00c39380ff022445 +:10abd000251062005c00c2a32400c28f140041044f +:10abe0000000000088bf043cd1608390fdff022478 +:10abf00024106200d16082a05c00c393dfff0224b6 +:10ac0000241062005c00c2a3ffff02241800c2af40 +:10ac10002400c28f231002002400c2af3000c28f74 +:10ac2000231002003000c2af080000100000000036 +:10ac300088bf033cd160629002004234d16062a0c0 +:10ac40005c00c293200042345c00c2a32800c28f83 +:10ac5000120041040000000088bf033c5160629074 +:10ac600002004234516062a05c00c293080042348a +:10ac70005c00c2a3ffff02241c00c2af2800c28fe9 +:10ac8000231002002800c2af3400c28f231002003c +:10ac90003400c2af0a0000100000000088bf043c6e +:10aca00051608390fdff022424106200516082a055 +:10acb0005c00c393f7ff0224241062005c00c2a36f +:10acc0002000c28f000042380100432c2400c28fb4 +:10acd000000042380100422c24106200060040109f +:10ace000000000002800c28f030040100000000098 +:10acf0007480828f8c8182af2800c38f2000c28f26 +:10ad00002a106200010044382800c38f2400c28f3b +:10ad10002a10620001004238241082000300401013 +:10ad200000000000010002241000c2af2000c38f09 +:10ad30002800c28f2a106200010044382000c38f0f +:10ad40002400c28f2a1062000100423824108200c1 +:10ad50000300401000000000020002241000c2aff7 +:10ad60002400c38f2000c28f2a10620001004438e3 +:10ad70002400c38f2800c28f2a10620001004238cd +:10ad80002410820003004010000000000300022491 +:10ad90001000c2af2000c28f000042380100432cd7 +:10ada0002400c28f000042380100422c24186200a7 +:10adb0002800c28f000042380100422c241062009b +:10adc00002004010000000001000c0af1000c38f50 +:10add000010002244a006214000000004000c38ffa +:10ade0001c00c28f211062004000c2af4400c38f1c +:10adf0002c00c28f211062004400c2af4800c38ff4 +:10ae00003000c28f211062004800c2af4400c38fdf +:10ae10002800c28f2a1043000e00401000000000de +:10ae20003800c38f1400c28f211062003800c2aff7 +:10ae30004400c38f3400c28f231062004400c2afad +:10ae4000010002245000c2af5c00c29340004234b3 +:10ae50005c00c2a34800c28f2800c38f2a10620082 +:10ae60000e004010000000003c00c38f1800c28f8d +:10ae7000211062003c00c2af4800c38f3400c28f73 +:10ae8000231062004800c2af010002245400c2af88 +:10ae90005c00c293100042345c00c2a35c00c29309 +:10aea000040042345c00c2a35c00c3935000c28f14 +:10aeb000202c027c5400c28f2014027c21206000d0 +:10aec00021304000f92c400f000000005000c0afbe +:10aed0005400c0af5800c0af5c00c393abff022466 +:10aee000241062005c00c2a34000c38f7c00c28fac +:10aef0000300621000000000b8ff00100000000016 +:10af00001000c38f020002244a00621400000000f7 +:10af10003800c38f1400c28f211062003800c2af06 +:10af20004c00c38f3400c28f211062004c00c2afae +:10af30004800c38f3000c28f211062004800c2afaa +:10af40004c00c38f2000c28f2a1043000e00401017 +:10af5000000000004000c38f1c00c28f211062005f +:10af60004000c2af4c00c38f2c00c28f2310620080 +:10af70004c00c2af010002245800c2af5c00c29373 +:10af8000040042345c00c2a34800c28f2000c38f7b +:10af90002a1062000e004010000000003c00c38f29 +:10afa0001800c28f211062003c00c2af4800c38f5e +:10afb0002c00c28f231062004800c2af010002249f +:10afc0005400c2af5c00c293100042345c00c2a3c4 +:10afd0005c00c293400042345c00c2a35c00c39397 +:10afe0005000c28f202c027c5400c28f2014027c9f +:10aff0002120600021304000f92c400f00000000ab +:10b000005000c0af5400c0af5800c0af5c00c39345 +:10b01000abff0224241062005c00c2a33800c38f7f +:10b020007400c28f0300621000000000b8ff00101f +:10b03000000000001000c38f030002244e006214c1 +:10b04000000000003c00c38f7800c28f4a006210ed +:10b05000000000003c00c38f1800c28f2110620066 +:10b060003c00c2af4400c38f2c00c28f211062008d +:10b070004400c2af4c00c38f3400c28f2110620065 +:10b080004c00c2af4400c38f2400c28f2a1043007b +:10b090000e004010000000003800c38f1400c28f63 +:10b0a000211062003800c2af4400c38f3000c28f4d +:10b0b000231062004400c2af010002245000c2af5e +:10b0c0005c00c293400042345c00c2a34c00c28fbb +:10b0d0002400c38f2a1062000e0040100000000000 +:10b0e0004000c38f1c00c28f211062004000c2af1d +:10b0f0004c00c38f3000c28f231062004c00c2afdf +:10b10000010002245800c2af5c00c2930400423424 +:10b110005c00c2a35c00c293100042345c00c2a376 +:10b120005c00c3935000c28f202c027c5400c28f5d +:10b130002014027c2120600021304000f92c400fb7 +:10b14000000000005000c0af5400c0af5800c0afb6 +:10b150005c00c393abff0224241062005c00c2a316 +:10b160003c00c38f7800c28f030062100000000013 +:10b17000b8ff00100000000021e8c0036400bf8f8a +:10b180006000be8f6800bd270800e00300000000db +:10b19000f8ffbd270000beaf21f0a003b481828f6d +:10b1a000b88182af0482828fec8182afdc81828f92 +:10b1b000c08182af8480828f908082af8880828fae +:10b1c000948082af8c80828f988082af7880828fcb +:10b1d000848082af7c80828f888082af8080828fe3 +:10b1e0008c8082af3082828f788082af1882828f8b +:10b1f0007c8082af2482828f808082af2110000009 +:10b20000008282af21100000c88182af21100000af +:10b21000c48182af21100000e48182af21100000c0 +:10b22000d88182af211000000c8282afb48180af40 +:10b23000048280afdc8180af21e8c0030000be8fb4 +:10b240000800bd270800e00300000000d0ffbd2774 +:10b250002c00bfaf2800beaf21f0a0033000c4af68 +:10b260003000c48fc978400f00000000212040004a +:10b27000212860001000c6271075400f0000000054 +:10b280001800c2af1c00c3af1000c48f1400c58fdc +:10b290003079400f000000002000c2af029d023c48 +:10b2a000b802448cbc02458c1800c68f1c00c78fa6 +:10b2b0007379400f000000000300401800000000f8 +:10b2c00008000010000000002000c28f010042248e +:10b2d0002000c2af2000c28f2400c2af03000010c4 +:10b2e000000000002000c28f2400c2af2400c28fe3 +:10b2f00021e8c0032c00bf8f2800be8f3000bd277f +:10b300000800e00300000000d0ffbd272c00bfaf05 +:10b310002800beaf21f0a0033000c4af3000c48fbe +:10b32000c978400f00000000212040002128600063 +:10b330001000c6271075400f000000001800c2afb3 +:10b340001c00c3af1000c48f1400c58f3079400fac +:10b35000000000002000c2af029d023cc002448ced +:10b36000c402458c1800c68f1c00c78f7379400f2c +:10b37000000000000300401800000000040000105e +:10b38000000000002000c28f010042242000c2af54 +:10b39000029d023c1800c48f1c00c58fc802468c59 +:10b3a000cc02478c7379400f000000000300401866 +:10b3b0000000000004000010000000002000c28f08 +:10b3c000ffff42242000c2af2000c28f21e8c0034b +:10b3d0002c00bf8f2800be8f3000bd270800e0037f +:10b3e00000000000e0ffbd271800beaf21f0a00361 +:10b3f000211080002118a0002120c0002000c2a33d +:10b400002400c3a32800c4a30000c0af2000c2933f +:10b410000000c2af0000c28f001602000000c2afe1 +:10b420002400c28308004010000000002800c283ee +:10b4300005004010000000007080828f0400c2af41 +:10b4400003000010000000008c81828f0400c2af56 +:10b450000000c28f0400c38f251043000000c2af5c +:10b46000f081828f010042240800c2af0800c28f21 +:10b470000c00c2af0c00c38f040061040000000088 +:10b480000c00c48fff0184240c00c4af0c00c38fd8 +:10b4900043120300401202000800c48f23188200e8 +:10b4a000cc81828f0300621400000000ecff0010ca +:10b4b0000000000000a0043cf081828f8018020090 +:10b4c000c8048224211862000000c28f000062ac10 +:10b4d000f081828f01004224f08182aff081828f5f +:10b4e0001000c2af1000c38f1400c3af1400c48f8c +:10b4f00004008104000000001400c28fff014224f8 +:10b500001400c2af1400c38f4312030040120200a4 +:10b510001000c48f23108200f08182af21e8c003a5 +:10b520001800be8f2000bd270800e00300000000c7 +:10b53000e0ffbd271c00bfaf1800beaf21f0a00385 +:10b54000214080002400c5af2128c0002c00c7afd7 +:10b550003000c28f3800c38f4000c48f2000c8a3c2 +:10b560002800c5a31000c2a31100c3a31200c4a3e6 +:10b57000cc81838ff081828f0e006210000000006a +:10b580003c80838301000224f9ff62140000000064 +:10b59000f081828f01004324cc81828ff4ff6214fa +:10b5a00000000000cc81828ff08182aff0ff00109c +:10b5b0000000000021100000308282af2800c38309 +:10b5c0005800022403006214000000002c00c28f07 +:10b5d000308282af1000c38358000224030062143b +:10b5e000000000003400c28f308282af1100c3839c +:10b5f0005800022403006214000000003c00c28fc7 +:10b60000308282af1200c383580002240300621408 +:10b61000000000004400c28f308282af2800c28345 +:10b62000580042380100432c1000c28358004238b1 +:10b630000100422c251862001100c28358004238d4 +:10b640000100422c251862001200c28358004238c3 +:10b650000100422c2510620005004010000000008f +:10b6600001000224c08082af020000100000000030 +:10b67000c08080af21180000188283af2800c383e8 +:10b680005900022403006214000000002c00c28f45 +:10b69000188282af1000c383590002240300621491 +:10b6a000000000003400c28f188282af1100c383f3 +:10b6b0005900022403006214000000003c00c28f05 +:10b6c000188282af1200c38359000224030062145f +:10b6d000000000004400c28f188282af2800c2839d +:10b6e000590042380100432c1000c28359004238ef +:10b6f0000100422c251862001100c2835900423813 +:10b700000100422c251862001200c2835900423801 +:10b710000100422c251062000500401000000000ce +:10b7200001000224c48082af02000010000000006b +:10b73000c48080af21100000248282af2800c38320 +:10b740005a00022403006214000000002c00c28f83 +:10b75000248282af1000c3835a00022403006214c3 +:10b76000000000003400c28f248282af1100c38326 +:10b770005a00022403006214000000003c00c28f43 +:10b78000248282af1200c3835a0002240300621491 +:10b79000000000004400c28f248282af2800c283d0 +:10b7a0005a0042380100432c1000c2835a0042382c +:10b7b0000100422c251862001100c2835a00423851 +:10b7c0000100422c251862001200c2835a00423840 +:10b7d0000100422c2510620005004010000000000e +:10b7e00001000224c88082af0200001000000000a7 +:10b7f000c88080af211800001c8283af2800c3835b +:10b800004900022403006214000000002c00c28fd3 +:10b810001c8282af1000c38349000224030062141b +:10b82000000000003400c28f1c8282af1100c3836d +:10b830004900022403006214000000003c00c28f93 +:10b840001c8282af1200c3834900022403006214e9 +:10b85000000000004400c28f1c8282af2800c28317 +:10b86000490042380100432c1000c283490042388d +:10b870000100422c251862001100c28349004238a1 +:10b880000100422c251862001200c2834900423890 +:10b890000100422c2510620005004010000000004d +:10b8a00001000224cc8082af0200001000000000e2 +:10b8b000cc8080af21100000208282af2800c3839b +:10b8c0004a00022403006214000000002c00c28f12 +:10b8d000208282af1000c3834a0002240300621456 +:10b8e000000000003400c28f208282af1100c383a9 +:10b8f0004a00022403006214000000003c00c28fd2 +:10b90000208282af1200c3834a0002240300621423 +:10b91000000000004400c28f208282af2800c28352 +:10b920004a0042380100432c1000c2834a004238ca +:10b930000100422c251862001100c2834a004238df +:10b940000100422c251862001200c2834a004238ce +:10b950000100422c2510620005004010000000008c +:10b9600001000224d08082af02000010000000001d +:10b97000d08080af2800c3834600022405006214f3 +:10b98000000000002c00c48fa07b400f00000000ce +:10b99000b88082af1000c383460002240500621401 +:10b9a000000000003400c48fa07b400f00000000a6 +:10b9b000b88082af1100c3834600022405006214e0 +:10b9c000000000003c00c48fa07b400f000000007e +:10b9d000b88082af1200c3834600022405006214bf +:10b9e000000000004400c48fa07b400f0000000056 +:10b9f000b88082af21180000288283af2800c3835b +:10ba00005000022403006214000000002c00c28fca +:10ba1000288282af1000c383500002240300621406 +:10ba2000000000003400c28f288282af1100c3835f +:10ba30005000022403006214000000003c00c28f8a +:10ba4000288282af1200c3835000022403006214d4 +:10ba5000000000004400c28f288282af2110000045 +:10ba60002c8282af2800c383530002240300621497 +:10ba7000000000002c00c28f2c8282af1000c38314 +:10ba80005300022403006214000000003400c28f3f +:10ba90002c8282af1100c38353000224030062147e +:10baa000000000003c00c28f2c8282af1200c383d2 +:10bab0005300022403006214000000004400c28fff +:10bac0002c8282af2000c3831400c3af470002243e +:10bad0001400c38f07006210000000004d00022414 +:10bae0001400c38f4800621000000000a400001082 +:10baf000000000002400c28f148282af1482828f63 +:10bb00000300401400000000662f400f00000000fa +:10bb10001482838f010002240300621400000000dd +:10bb2000852f400f000000001482838f0200022442 +:10bb30000300621400000000ab2f400f0000000063 +:10bb40001482838f030002240300621400000000ab +:10bb5000c22f400f000000001482838f04000224d3 +:10bb60000300621400000000d92f400f0000000005 +:10bb70001482838f1400022403006214000000006a +:10bb8000f52f400f000000001482838f150002245f +:10bb90000300621400000000ff2f400f00000000af +:10bba0001482838f1c000224030062140000000032 +:10bbb0000930400f000000001482838f5a000224d5 +:10bbc00003006214000000001130400f000000006c +:10bbd0001482838f5b0002240300621400000000c3 +:10bbe0001d30400f000000001482838f5c0002248f +:10bbf00063006214000000002530400f00000000c8 +:10bc00005f000010000000002400c28f108282af8d +:10bc1000148280afb88080af1082838f65000224c9 +:10bc200003006214000000003330400f00000000e9 +:10bc30001082838f6700022403006214000000005a +:10bc40004130400f000000001082838f6800022402 +:10bc500003006214000000004e30400f000000009e +:10bc60001082838f6a000224030062140000000027 +:10bc70009230400f000000001082838f6b0002247e +:10bc80000300621400000000a030400f000000001c +:10bc90001082838f6c0002240300621400000000f5 +:10bca000ae30400f000000001082838fdc000224c1 +:10bcb0000300621400000000cc30400f00000000c0 +:10bcc0001082838fdd000224030062140000000054 +:10bcd000d930400f000000001082838fde00022464 +:10bce0000300621400000000e530400f0000000077 +:10bcf0001082838fdf000224030062140000000022 +:10bd0000ff30400f000000001082838fe00002240b +:10bd100003006214000000001931400f0000000011 +:10bd20001082838fe10002240300621400000000ef +:10bd30002331400f000000001082838fe2000224b4 +:10bd400003006214000000002c31400f00000000ce +:10bd50001082838fe30002240300621400000000bd +:10bd60006431400f000000001082838fe400022441 +:10bd700003006214000000009c31400f000000002e +:10bd800021e8c0031c00bf8f1800be8f2000bd2714 +:10bd90000800e00300000000e8ffbd271400bfaf6b +:10bda0001000beaf21f0a003b880828f03004014c2 +:10bdb00000000000c0030224b88082afb880848fe6 +:10bdc0001082858f0929400f000000005480838372 +:10bdd000010002240300621400000000010002249c +:10bde0007d8182a3bc80848f212800007f29400fa1 +:10bdf00000000000642a400f0000000021e8c0039a +:10be00001400bf8f1000be8f1800bd270800e0038c +:10be100000000000e8ffbd271400bfaf1000beaf58 +:10be200021f0a003b880828f0300401400000000be +:10be3000f0000224b88082af448182830500401064 +:10be400000000000b880828f6881838f211043003a +:10be5000b88082afb880848f1082858f0929400f07 +:10be60000000000054808383010002240300621458 +:10be700000000000010002247d8182a3bc80848f29 +:10be8000212800007f29400f00000000642a400f95 +:10be90000000000021e8c0031400bf8f1000be8f17 +:10bea0001800bd270800e00300000000e8ffbd27e0 +:10beb0001400bfaf1000beaf21f0a003b880828f86 +:10bec0000300401400000000f0000224b88082af9c +:10bed000b880848f1082858f0929400f00000000f0 +:10bee000bc80848f010005247f29400f00000000e2 +:10bef00021e8c0031400bf8f1000be8f1800bd27bb +:10bf00000800e00300000000e8ffbd271400bfaff9 +:10bf10001000beaf21f0a003b880828f0300401450 +:10bf200000000000f0000224b88082afb880848f47 +:10bf30001082858f0929400f00000000bc80848f8b +:10bf4000010005247f29400f0000000021e8c00304 +:10bf50001400bf8f1000be8f1800bd270800e0033b +:10bf600000000000e0ffbd271c00bfaf1800beafff +:10bf700021f0a0031000c0af2882848f2128000088 +:10bf8000db7b400f000000000300401400000000b5 +:10bf90000a000010000000002882848fa07b400f60 +:10bfa00000000000c8000324021043701000c2af5c +:10bfb0001000c48fce61400f0000000021e8c003d4 +:10bfc0001c00bf8f1800be8f2000bd270800e003b3 +:10bfd00000000000f8ffbd270000beaf21f0a00365 +:10bfe00014000224bc8082af21e8c0030000be8f91 +:10bff0000800bd270800e00300000000f8ffbd278f +:10c000000000beaf21f0a00315000224bc8082af67 +:10c0100021e8c0030000be8f0800bd270800e00330 +:10c0200000000000f8ffbd270000beaf21f0a00314 +:10c0300021e8c0030000be8f0800bd270800e00310 +:10c0400000000000e8ffbd271400bfaf1000beaf26 +:10c0500021f0a003362a400f0000000021e8c003b1 +:10c060001400bf8f1000be8f1800bd270800e0032a +:10c0700000000000f8ffbd270000beaf21f0a003c4 +:10c0800021e8c0030000be8f0800bd270800e003c0 +:10c0900000000000e8ffbd271400bfaf1000beafd6 +:10c0a00021f0a003662f400f00000000e229400f9e +:10c0b0000000000021e8c0031400bf8f1000be8ff5 +:10c0c0001800bd270800e00300000000f8ffbd27ae +:10c0d0000000beaf21f0a00354808383020002243d +:10c0e0000300621400000000010002247d8182a38d +:10c0f00021e8c0030000be8f0800bd270800e00350 +:10c1000000000000f8ffbd270000beaf21f0a00333 +:10c1100054808383020002240200621400000000a5 +:10c120007d8180a321e8c0030000be8f0800bd27e9 +:10c130000800e00300000000e8ffbd271400bfafc7 +:10c140001000beaf21f0a0035480838302000224bc +:10c150003700621400000000040004245964400ffa +:10c1600000000000050004245964400f0000000096 +:10c17000060004245964400f000000000500042458 +:10c1800021280000029d023cd002462421380000f4 +:10c19000d864400f00000000f48080af010002244a +:10c1a000888182a32c82848f21280000db7b400fb2 +:10c1b0000000000003004014000000000500001013 +:10c1c000000000002c82848fa07b400f0000000044 +:10c1d000fc8082af4326400f0000000001000424d1 +:10c1e0006f60400f000000002c63400f0000000053 +:10c1f000d963400f000000009063400f0000000072 +:10c20000f480828f0600401400000000fc80828fc2 +:10c210000300401000000000f3ff001000000000c9 +:10c22000888180a3050004245964400f00000000a9 +:10c2300021e8c0031400bf8f1000be8f1800bd2777 +:10c240000800e00300000000f8ffbd270000beafbb +:10c2500021f0a003010002246c8182a388bf033c6b +:10c260001061629020004234106162a021e8c00396 +:10c270000000be8f0800bd270800e003000000009a +:10c28000f8ffbd270000beaf21f0a0036c8180a3a2 +:10c2900088bf043c10618390dfff022424106200f9 +:10c2a000106182a021e8c0030000be8f0800bd27f6 +:10c2b0000800e00300000000e8ffbd271400bfaf46 +:10c2c0001000beaf21f0a00354808383020002243b +:10c2d0001100621400000000212000002c82858fd4 +:10c2e000db7b400f00000000030040040000000062 +:10c2f00005000010000000002c82848fa07b400ffe +:10c3000000000000208082afd05e400f00000000df +:10c3100001000224898182a321e8c0031400bf8f99 +:10c320001000be8f1800bd270800e00300000000c9 +:10c33000f8ffbd270000beaf21f0a00388bf043c7a +:10c34000d1608390f7ff022424106200d16082a0a4 +:10c3500021e8c0030000be8f0800bd270800e003ed +:10c3600000000000f8ffbd270000beaf21f0a003d1 +:10c3700088bf023cd160439008006334d16043a081 +:10c3800021e8c0030000be8f0800bd270800e003bd +:10c3900000000000e8ffbd271400bfaf1000beafd3 +:10c3a00021f0a00354808383020002240d00621454 +:10c3b00000000000212000002c82858fdb7b400fd5 +:10c3c0000000000003004004000000000500001011 +:10c3d000000000002c82848fa07b400f0000000032 +:10c3e000708182af21e8c0031400bf8f1000be8fa0 +:10c3f0001800bd270800e00300000000e8ffbd278b +:10c400001400bfaf1000beaf21f0a003548083839f +:10c41000020002240d006214000000002120000030 +:10c420002c82858fdb7b400f00000000030040045e +:10c430000000000005000010000000002c82848f26 +:10c44000a07b400f00000000508182af21e8c003b4 +:10c450001400bf8f1000be8f1800bd270800e00336 +:10c4600000000000f8ffbd270000beaf21f0a003d0 +:10c47000010002244c8182a321e8c0030000be8f8a +:10c480000800bd270800e00300000000f8ffbd27fa +:10c490000000beaf21f0a0034c8180a321e8c003bf +:10c4a0000000be8f0800bd270800e0030000000068 +:10c4b000d8ffbd272400bfaf2000beaf1c00b1af26 +:10c4c0001800b0af21f0a003cc81838ff081828f60 +:10c4d0000e006210000000003c80838301000224f3 +:10c4e000f9ff621400000000f081828f01004324f4 +:10c4f000cc81828ff4ff621400000000cc81828f17 +:10c50000f08182aff0ff001000000000d51b400f4b +:10c510000000000088bf023c9061428c4002427cd7 +:10c520000300401400000000faff001000000000ab +:10c530009080848fc978400f000000002180400067 +:10c54000218860009480848fc978400f000000002b +:10c550001000a0af1400a0af21200002212820026b +:10c5600021304000213860009d1e400f0000000077 +:10c5700021e8c0032400bf8f2000be8f1c00b18fb4 +:10c580001800b08f2800bd270800e003000000005d +:10c59000e8ffbd271400bfaf1000beaf21f0a0031d +:10c5a00054808383020002242b00621400000000e8 +:10c5b00001000224848182af212000002c82858f1b +:10c5c000db7b400f0000000003004004000000007f +:10c5d0000d000010000000002c82848fc978400fed +:10c5e0000000000021204000212860005775400f06 +:10c5f0000000000021204000212860003079400f19 +:10c6000000000000608282af212000002882858f18 +:10c61000db7b400f0000000003004004000000002e +:10c620000d000010000000002882848fc978400fa0 +:10c630000000000021204000212860005775400fb5 +:10c640000000000021204000212860003079400fc8 +:10c65000000000006c8282af21e8c0031400bf8f8d +:10c660001000be8f1800bd270800e0030000000086 +:10c67000f8ffbd270000beaf21f0a00354808383e4 +:10c68000020002240200621400000000848180afd6 +:10c6900021e8c0030000be8f0800bd270800e003aa +:10c6a00000000000e0ffbd271c00bfaf1800beafb8 +:10c6b00021f0a0031000c0af1000c28f0300422879 +:10c6c0000b004010000000001000c38f348282274e +:10c6d0002118620001000224000062a01000c28f35 +:10c6e000010042241000c2aff3ff00100000000060 +:10c6f000de8080a3395a400f0000000000a0023cf9 +:10c70000041244240634400f00000000300040149e +:10c71000000000001c80838f00a0023c0412422411 +:10c72000000062ac1c80828f0c0040a41c80828fb1 +:10c730000e0040a41c80828f100040ac1c80828fb1 +:10c74000140040ac1c80838f5c000224200062a097 +:10c75000010002241000c2af1000c28f0b0042285b +:10c760000b004010000000001c80838f1000c28f5f +:10c770002118620020000224200062a01000c28f55 +:10c78000010042241000c2aff3ff001000000000bf +:10c790001c80828f2c0040a41c80838f10000224f8 +:10c7a000300062a41c80838f3c82828f340062ac94 +:10c7b0001c80838f3c82828f380062ac4c8280a3c5 +:10c7c000010002241400c2af0200001000000000ab +:10c7d0001400c0af1400c28f21e8c0031c00bf8f3b +:10c7e0001800be8f2000bd270800e00300000000f5 +:10c7f000c8ffbd273000bfaf2c00beaf2800b0afd0 +:10c8000021f0a0033800c4af3c00c5af2110c00028 +:10c810002118e0004000c2a34400c3a33800c28f27 +:10c820002c0042941400c2a70b0002241800c2afcf +:10c830003800c38f3800c28f3400428c380062ac9d +:10c840003c00c28f30004294271002001200c2a7a1 +:10c850001400c2970d004014000000001400c2270d +:10c860003800c48f2128400001000624a63b400f59 +:10c870000000000013004014000000001b00022410 +:10c880001800c2af0f000010000000001400c29793 +:10c890000f0042300b004010000000001400c227bf +:10c8a0003800c48f2128400001000624a63b400f19 +:10c8b0000000000003004014000000001b000224e0 +:10c8c0001800c2af1800c38f1b000224cc006210f6 +:10c8d000000000001800c28fc900401000000000d6 +:10c8e0001400c2273800c48f21284000863f400f23 +:10c8f000000000001600c2a31600c3930200022429 +:10c900000300621400000000bd00001000000000e1 +:10c910001600c293b1004014000000003800c28f1e +:10c92000300042941000c2a71000c2973f0042306e +:10c930001000c2a74400c2932000c2af2000c38fe2 +:10c940000700601000000000010002242000c38fd7 +:10c950002d00621000000000a40000100000000084 +:10c960001000c39708000224a0006210000000001d +:10c970001800c0af6d0002241c00c2a31700c0a3a2 +:10c980001700c2930b00422c9800401000000000da +:10c990003800c38f1700c29321106200200042901c +:10c9a0001c00c2a33c00c38f1700c2932110620079 +:10c9b000200042901d00c2a31c00c2932120400011 +:10c9c000706b400f00000000218040001d00c293ea +:10c9d00021204000706b400f000000000500021293 +:10c9e000000000000b0002241800c2af7f000010fe +:10c9f000000000001700c293010042241700c2a3e8 +:10ca0000dfff0010000000001000c3971200c29763 +:10ca100024106200ffff4230740040140000000048 +:10ca20001000c3970f000224700062100000000085 +:10ca30001800c0af6d0002241c00c2a33c00c28fce +:10ca4000200043802a0002242e0062100000000013 +:10ca50001700c0a31700c2930800422c2900401001 +:10ca6000000000003800c38f1700c293211062003d +:10ca7000200042901c00c2a33c00c38f1700c29349 +:10ca800021106200200042901d00c2a31d00c3932c +:10ca90002a000224030062140000000019000010a4 +:10caa000000000001d00c3933f000224100062102c +:10cab000000000001c00c29321204000706b400f5a +:10cac00000000000218040001d00c2932120400092 +:10cad000706b400f00000000050002120000000013 +:10cae0000b0002241800c2af060000100000000076 +:10caf0001700c293010042241700c2a3d5ff001003 +:10cb0000000000003c00c28f280043802a0002245d +:10cb100036006210000000001800c28f330040147d +:10cb200000000000080002241700c2a31700c293ef +:10cb30000b00422c2d004010000000003800c38f75 +:10cb40001700c29321106200200042901c00c2a373 +:10cb50003c00c38f1700c293211062002000429056 +:10cb60001d00c2a31d00c3932a0002240300621407 +:10cb7000000000001d000010000000001d00c39315 +:10cb80003f00022410006210000000001c00c2934d +:10cb900021204000706b400f000000002180400009 +:10cba0001d00c29321204000706b400f0000000068 +:10cbb00005000212000000000b0002241800c2afa2 +:10cbc0000a000010000000001700c2930100422478 +:10cbd0001700c2a3d5ff0010000000004000c29360 +:10cbe00002004014000000001800c0af1400c297fb +:10cbf000010042241400c2a736ff0010000000000c +:10cc00001800c28f21e8c0033000bf8f2c00be8ff8 +:10cc10002800b08f3800bd270800e00300000000a6 +:10cc2000d0ffbd272c00bfaf2800beaf21f0a0036e +:10cc30003000c4af3400c5af2110c0003800c2a31b +:10cc40001c00c0af3000c28f0000428c1000c2af89 +:10cc50001000c28f21004290050040140000000027 +:10cc6000070002241c00c2af860000100000000074 +:10cc70003000c38f3000c28f3400428c380062ac69 +:10cc80003400c28f000042940c00401400000000e9 +:10cc90003000c48f3400c58f01000624a63b400f2e +:10cca0000000000013004014000000001b000224dc +:10ccb0001c00c2af0f000010000000003400c28f43 +:10ccc000000042940f0042300a00401000000000b3 +:10ccd0003000c48f3400c58f01000624a63b400fee +:10cce0000000000003004014000000001b000224ac +:10ccf0001c00c2af3000c48f3400c58f863f400f88 +:10cd0000000000001400c2a31400c29305004010ec +:10cd1000000000000b0002241c00c2af59000010ec +:10cd2000000000003000c28f100040ac3000c38f04 +:10cd30003000c28f0400428c080062ac3000c28f09 +:10cd40000c0040a43000c28f0e0040a41400c39316 +:10cd50000100022405006214000000000b00022400 +:10cd60001c00c2af24000010000000003000c28f81 +:10cd70001000c48f0800458c4c45400f0000000097 +:10cd80001800c2afdc808293090040100000000050 +:10cd90000447400f000000000500401000000000a4 +:10cda000090002242000c2af38000010000000007b +:10cdb0003000c28fd88082af1880838f1800c28f56 +:10cdc0000d00621000000000de8080a31000c28f02 +:10cdd0001800c48f0000458c285b400f0000000045 +:10cde0000300401400000000080002241c00c2af31 +:10cdf0001800c28f188082af3000c48f1800838c57 +:10ce0000fbff022424106200180082ac3800c383a8 +:10ce10007700022407006210000000003800c3837e +:10ce20006100022403006210000000000c000010ea +:10ce3000000000003000c38f1800628c01004234f3 +:10ce4000180062ac3000c48f1800838cfdff0224f0 +:10ce500024106200180082ac0a00001000000000dc +:10ce60003000c48f1800838cfeff0224241062005f +:10ce7000180082ac3000c38f1800628c020042346c +:10ce8000180062ac1c00c28f2000c2af2000c28f0d +:10ce900021e8c0032c00bf8f2800be8f3000bd27c3 +:10cea0000800e00300000000c8ffbd273400bfaf4a +:10ceb0003000beaf21f0a0033800c4af3c00c5afc6 +:10cec0002000c0a33800c28f0000428c2400c2aff3 +:10ced0002400c28f200042902800c2af010002242b +:10cee0002800c38f0f00621000000000030002241e +:10cef0002800c38f03006210000000000f00001024 +:10cf000000000000ff0f023cf8ff42341c00c2afdb +:10cf1000ff0f023cffff42341800c2af0b000010ad +:10cf200000000000f80f02241c00c2afffff023413 +:10cf30001800c2af0500001000000000f8ff023426 +:10cf40001c00c2afffff02341800c2af3800c28f0e +:10cf50000800428c1400c2af2400c48f1400c58f97 +:10cf6000f04a400f000000001000c2af1000c38f55 +:10cf70001800c28f0500621400000000080002249f +:10cf80002000c2a310000010000000002400c28f87 +:10cf90001800438c1000c28f2b1043000300401474 +:10cfa000000000000a0002242000c2a31000c28f6b +:10cfb0001c00c38f2b10430003004014000000002e +:10cfc0003c0002242000c2a33800c38f1000c28f8f +:10cfd000080062ac3c00c28fffff42243c00c2af9d +:10cfe00006004010000000002000c293030040141f +:10cff00000000000d5ff0010000000002000c293d8 +:10d0000021e8c0033400bf8f3000be8f3800bd2739 +:10d010000800e00300000000e0ffbd271c00bfafd8 +:10d020001800beaf21f0a0032000c4af1000c0a3c1 +:10d030002000c28f210040a02000c38f00a0023c2e +:10d04000c80c4224000062acba5c400f0000000033 +:10d0500021184000010002240700621000000000b7 +:10d06000060002241000c2a3060002244c8282a300 +:10d0700012000010000000002000c48f3634400f62 +:10d08000000000001000c2a31000c2930b00401467 +:10d09000000000002000c48f1435400f0000000085 +:10d0a0001000c2a31000c29304004014000000004e +:10d0b0002000c38f01000224210062a01000c2934f +:10d0c00021e8c0031c00bf8f1800be8f2000bd27c1 +:10d0d0000800e00300000000d0ffbd272c00bfaf18 +:10d0e0002800beaf21f0a0033000c4af1400c0a3dd +:10d0f0003000c28f212000000000458c285b400fcb +:10d100000000000021184000010002240700621006 +:10d1100000000000080002241400c2a3080002243a +:10d120004c8282a3c1000010000000003000c28fba +:10d130000000428c1800c2af1800c28ffe0143905d +:10d140005500022470006214000000001800c28f15 +:10d15000ff014390aa0002246b006214000000004b +:10d160003000c28f0000448c36000524f944400f83 +:10d170000000000021184000460002242d00621427 +:10d18000000000003000c28f0000448c37000524ee +:10d19000f944400f00000000211840004100022423 +:10d1a00024006214000000003000c28f0000448c94 +:10d1b00038000524f944400f000000002118400009 +:10d1c000540002241b006214000000003000c28fd3 +:10d1d0000000448c39000524f944400f0000000091 +:10d1e00021184000310002241200621400000000e7 +:10d1f0003000c28f0000448c26000524f944400f03 +:10d2000000000000211840002900022409006214d7 +:10d21000000000003000c28f040040ac3000c38f1b +:10d2200002000224200062a01c00c0af8100001098 +:10d23000000000003000c28f0000448c5200052422 +:10d24000f944400f0000000021184000460002246d +:10d250002d006214000000003000c28f0000448cda +:10d2600053000524f944400f00000000211840003d +:10d270004100022424006214000000003000c28f2c +:10d280000000448c54000524f944400f00000000c5 +:10d2900021184000540002241b006214000000000a +:10d2a0003000c28f0000448c55000524f944400f23 +:10d2b0000000000021184000330002241200621414 +:10d2c000000000003000c28f0000448c42000524a2 +:10d2d000f944400f000000002118400029000224fa +:10d2e00009006214000000003000c28f040040ac4e +:10d2f0003000c38f03000224200062a01c00c0afd6 +:10d300004c000010000000003000c28f0000428c72 +:10d310001000c2af1000c28ffe01439055000224de +:10d3200008006214000000001000c28fff0143904b +:10d33000aa0002240300621400000000070000108d +:10d3400000000000040002244c8282a30400022496 +:10d350001400c2a335000010000000003000c48f8c +:10d360001000c28fc9014388c60143982110600094 +:10d37000040082ac1000c28fc20142901500c2a30b +:10d380001500c2932000c2af2000c38f0f00622c93 +:10d390002200401000000000010002242000c38f82 +:10d3a000041062002400c2af2400c38f50406230da +:10d3b00010004014000000002400c38f00186230e9 +:10d3c00011004014000000002400c38f02006230ee +:10d3d00003004014000000001000001000000000d6 +:10d3e0003000c38f01000224200062a00f00001053 +:10d3f000000000003000c38f02000224200062a061 +:10d400000a000010000000003000c38f0300022457 +:10d41000200062a0050000100000000005000224aa +:10d420004c8282a3050002241400c2a31400c293fc +:10d430001c00c2af1c00c28f21e8c0032c00bf8fac +:10d440002800be8f3000bd270800e0030000000068 +:10d45000c0ffbd273800bfaf3400beaf3000b0af53 +:10d4600021f0a0034000c4af1c00c0a34000c28f45 +:10d470004000c38f0400448c0000658c285b400f83 +:10d480000000000021184000010002240700621083 +:10d4900000000000080002244c8282a3080002243d +:10d4a0001c00c2a3d3000010000000004000c28f87 +:10d4b0000000428c2000c2af2000c28ffe014390ca +:10d4c0005500022408006214000000002000c28ff2 +:10d4d000ff014390aa000224030062140000000030 +:10d4e0000700001000000000030002244c8282a309 +:10d4f000030002241c00c2a3be00001000000000b4 +:10d500004000c28f0000448c0e0005240845400fe7 +:10d51000000000002600c2a74000d08f4000c28f4c +:10d520000000448c0d000524f944400f0000000069 +:10d530001f0002a24000c48f4000c28f2600c39784 +:10d540000400428c21104300080082ac4000d08fc0 +:10d550004000c28f0000448c10000524f944400fa5 +:10d56000000000001e0002a24000d08f4000c28fc9 +:10d570000000448c160005240845400f0000000000 +:10d580001c0002a64000c28f1c00429408004014f8 +:10d59000000000004000d08f4000c28f0000448c8b +:10d5a000240005242745400f000000001c0002a6af +:10d5b0004000c48f4000c58f4000c28f1e004390c2 +:10d5c0004000c28f1c004294021862700800a28cb6 +:10d5d000211043000c0082ac4000d08f4000c28f6d +:10d5e0000000448c110005240845400f0000000095 +:10d5f000140002a64000c28f0000448c13000524d2 +:10d600000845400f000000001400c2af1400c28f94 +:10d6100007004014000000004000c28f0000448c4e +:10d62000200005242745400f000000001400c2af71 +:10d630004000c28f0000448c0b0005240845400fb9 +:10d64000000000002400c2a72400c2970700401079 +:10d65000000000002400c297010042300300401483 +:10d66000000000000700001000000000030002247a +:10d670004c8282a3030002242800c2af5f00001086 +:10d68000000000004000c28f1400429440190200c4 +:10d690002400c29721106200ffff43242400c29798 +:10d6a0001a006200f4014000121000001000c2af26 +:10d6b0002600c4974000c28f1e0043904000c28fd6 +:10d6c0001c00429402106270211882001000c28f68 +:10d6d000211862001400c28f231043001800c2af4b +:10d6e0004000c48f4000c28f1f0043901800c28fbb +:10d6f0001b004300f401600012100000180082ac0f +:10d700004000c28f1800428cf50f422c06004010da +:10d71000000000004000c38f01000224200062a02e +:10d720000f000010000000004000c28f1800438c62 +:10d73000f4ff02342b1043000600401400000000e8 +:10d740004000c38f02000224200062a004000010e9 +:10d75000000000004000c38f03000224200062a0ec +:10d760004000c28f20004390030002240f00621487 +:10d77000000000004000c28f0000448c2c000524f3 +:10d780002745400f000000003c8282af4000c48f5c +:10d790004000c28f0c00438c1000c28f2110620029 +:10d7a000100082ac0b000010000000003c8280af33 +:10d7b0004000c58f4000c48f4000c28f14004294c7 +:10d7c00002110200ffff43300c00828c2110430045 +:10d7d0001000a2ac2400c3970002022405006210ce +:10d7e00000000000030002241c00c2a30300022466 +:10d7f0004c8282a31c00c2932800c2af2800c28fb3 +:10d8000021e8c0033800bf8f3400be8f3000b08fd6 +:10d810004000bd270800e00300000000f0ffbd2726 +:10d820000800beaf21f0a0031000c4af0000c0afdd +:10d830001000c28f140042940000c2af0000c28fdb +:10d84000001402000000c2af1000c28f1a004394ff +:10d850000000c28f251043000000c2af0000c28f3d +:10d8600021e8c0030800be8f1000bd270800e003b8 +:10d8700000000000d8ffbd272400bfaf2000beafce +:10d8800021f0a0032800c4af2c00c5af1400c0af26 +:10d890002800c28f07004010000000002c00c28f3b +:10d8a0000200422c0300401400000000050000109c +:10d8b00000000000ffff02241c00c2aff6000010b1 +:10d8c000000000002c00c28fffff43242800c28ffd +:10d8d0002b1062000500401000000000ffff022432 +:10d8e0001c00c2afec00001000000000dc8082933e +:10d8f00009004010000000000447400f0000000035 +:10d900000500401000000000ffff02241c00c2af11 +:10d91000e10000100000000000a0023cc80c4424fc +:10d920002128000000020624d169400f00000000f9 +:10d9300000a0023cc80c42241000c2af2800c28fd5 +:10d940001800c2af1800c48f1505023c5b56423464 +:10d9500019008200101800002310830042100200fa +:10d960002110620042130200801302001400c2afb3 +:10d970001800c58f1505023c5b5642341900a20001 +:10d98000101800002310a3004210020021106200b2 +:10d990004223020021108000801902002318640035 +:10d9a00000120300231043002310a2001800c2af8e +:10d9b0001800c48f1004023c054142341900820053 +:10d9c0001018000023108300421002002110620092 +:10d9d00042110200801902001400c28f251043007a +:10d9e0001400c2af1800c48f1004023c0541423439 +:10d9f000190082001018000023108300421002005a +:10da00002110620042190200211060008011020002 +:10da100023104300231082001800c2af1800c28fe9 +:10da2000010043241400c28f251043001400c2af2c +:10da300000a0023cc80c43241400c28f0214020050 +:10da4000bf0162a000a0023cc80c43241400c28f96 +:10da500002120200c00162a000a0023cc80c4324d4 +:10da60001400c28fc10162a01000c28f2c00c48fad +:10da70002800c38f23188300cd0143a8ca0143b8ef +:10da80001000c28fcd014388ca0143982110600065 +:10da90003910422c06004010000000001000c38f17 +:10daa00001000224c20162a0120000100000000068 +:10dab0001000c28fcd014388ca0143983f00023c49 +:10dac0005ffd42342b1043000600401400000000ac +:10dad0001000c38f06000224c20162a005000010de +:10dae00000000000ffff02241c00c2af6a0000100b +:10daf000000000001000c28f2800c38fc90143a896 +:10db0000c60143b82800c38f2c00c28f21106200c9 +:10db1000ffff42241800c2af1800c48f1505023c55 +:10db20005b56423419008200101800002310830055 +:10db30004210020021106200421302008013020012 +:10db40001400c2af1800c58f1505023c5b56423465 +:10db50001900a200101800002310a30042100200b8 +:10db6000211062004223020021108000801902006f +:10db70002318640000120300231043002310a200a6 +:10db80001800c2af1800c48f1004023c0541423493 +:10db900019008200101800002310830042100200b8 +:10dba0002110620042110200801902001400c28f8d +:10dbb000251043001400c2af1800c48f1004023cab +:10dbc0000541423419008200101800002310830020 +:10dbd0004210020021106200421902002110600070 +:10dbe0008011020023104300231082001800c2afee +:10dbf0001800c28f010043241400c28f2510430077 +:10dc00001400c2af00a0023cc80c43241400c28f11 +:10dc100002140200c30162a000a0023cc80c43240d +:10dc20001400c28f02120200c40162a000a0023cd4 +:10dc3000c80c43241400c28fc50162a01000c28f1b +:10dc4000be0140a01000c38f55000224fe0162a057 +:10dc50001000c38faaff0224ff0162a02120000050 +:10dc600000a0023cc80c452401000624b05b400f14 +:10dc7000000000002118400001000224050062108d +:10dc800000000000ffff02241c00c2af02000010d1 +:10dc9000000000001c00c0af1c00c28f21e8c003c0 +:10dca0002400bf8f2000be8f2800bd270800e0039e +:10dcb0000000000068ffbd279400bfaf9000beaf1a +:10dcc00021f0a003211080009c00c5afa000c6afca +:10dcd0009800c2a32800c2275000c2af4c8280a384 +:10dce0005000c38f00a0023cc80c4224000062ac6c +:10dcf000395a400f00000000ba5c400f00000000dd +:10dd000021184000010002240700621000000000fa +:10dd1000060002244c8282a3ffff02246400c2afeb +:10dd20007e030010000000002120000000a0023c43 +:10dd3000c80c4524285b400f000000000700401479 +:10dd4000000000001b0002244c8282a3ffff03247a +:10dd50006400c3af71030010000000005000c28fc8 +:10dd60000000428c2000c2af2000c28ffe01439011 +:10dd7000550002245a006214000000002000c28fe7 +:10dd8000ff014390aa000224550062140000000025 +:10dd90005000c28f0000448c36000524f944400f27 +:10dda00000000000211840004600022443006214d5 +:10ddb000000000005000c28f0000448c3700052492 +:10ddc000f944400f000000002118400041000224e7 +:10ddd0003a006214000000005000c28f0000448c22 +:10dde00038000524f944400f0000000021184000cd +:10ddf0005400022431006214000000005000c28f61 +:10de00000000448c39000524f944400f0000000054 +:10de10002118400031000224280062140000000094 +:10de20005000c28f0000448c26000524f944400fa6 +:10de30000000000021184000290002241f00621485 +:10de4000000000009800c2836800c2af6800c38f62 +:10de50000d00601000000000010002246800c38f64 +:10de600003006210000000001d0000100000000010 +:10de70001f0002244c8282a3ffff02246400c2af71 +:10de800026030010000000005000c28f040040acc8 +:10de90005000c48f1435400f0000000010004010e7 +:10dea000000000001b0002244c8282a3ffff032419 +:10deb0006400c3af190300100000000000a0023c82 +:10dec000c80c42241000c2af5000c48f1000c28f93 +:10ded000c9014388c601439821106000040082ac48 +:10dee0009800c2838400c2af8400c38f090260100f +:10def00000000000010002248400c38f03006210b0 +:10df0000000000000e020010000000001000c28f90 +:10df1000cd014388ca014398211060001400c2afac +:10df20001400c28f3910422c2d0040100000000058 +:10df30005000c38f01000224200062a01000c38f94 +:10df400001000224c20162a02120000000a0023cc6 +:10df5000c80c452401000624b05b400f00000000ff +:10df60000700401400000000090002244c8282a334 +:10df7000ffff02246400c2afe802001000000000ae +:10df80001400c28f2810422c06004014000000002c +:10df90005000c38f020002241f0062a00400001082 +:10dfa000000000005000c38f010002241f0062a087 +:10dfb00000a0023cc80c44242128000000020624d2 +:10dfc000d169400f0000000000a0023cc80c4324af +:10dfd000320002243a0062a04d0000100000000050 +:10dfe0001400c38f3f00023c5ffd42342b104300fe +:10dff00041004014000000005000c38f02000224c2 +:10e00000200062a01000c38f06000224c20162a09b +:10e010002120000000a0023cc80c45240100062479 +:10e02000b05b400f0000000007004014000000003b +:10e03000090002244c8282a3ffff03246400c3afc3 +:10e04000b6020010000000001400c28fe8fd422458 +:10e050001800c2af5000c38f010002241f0062a04d +:10e060001800c28fedff03342b1062000b0040102c +:10e07000000000005000c38f5000c28f1f0042906c +:10e08000401002001f0062a01800c28f4210020060 +:10e090001800c2aff2ff0010000000005000c28f55 +:10e0a0001f0042908100422c070040140000000035 +:10e0b000040002244c8282a3ffff02246400c2af4a +:10e0c000960200100000000000a0023cc80c44248e +:10e0d0002128000000020624d169400f0000000042 +:10e0e00000a0023cc80c4324360002243a0062a07f +:10e0f0000700001000000000170002244c8282a3d9 +:10e10000ffff03246400c3af84020010000000007e +:10e110005000c28f1f004290401802001400c28fae +:10e1200021106200dfff42245800c2af5000c28fae +:10e130002000439001000224090062140000000046 +:10e140005000c28f1f0043905501022402106270dc +:10e15000020042245c00c2af060000100000000074 +:10e160005000c28f1f0042900012020002004224a1 +:10e170005c00c2af5c00c38f5800c28f21106200e8 +:10e18000ffff43245c00c28f1b006200f4014000cb +:10e19000121000005800c2af00a0033cebff0224a5 +:10e1a000c80c62a000a0023cc80c43243c0002241e +:10e1b000010062a000a0023cc80c432490ff02248e +:10e1c000020062a000a0023cc80c43244d000224bf +:10e1d000030062a000a0023cc80c432443000224b8 +:10e1e000040062a000a0023cc80c432448000224a2 +:10e1f000050062a000a0023cc80c43245000022489 +:10e20000060062a000a0023cc80c432420000224a7 +:10e21000070062a000a0023cc80c43244600022470 +:10e22000080062a000a0023cc80c43244100022464 +:10e23000090062a000a0023cc80c43245400022440 +:10e240000a0062a000a0023cc80c42240b0040a0bf +:10e2500000a0023cc80c4324020002240c0062a06f +:10e2600000a0023cc80c43245000c28f1f00429003 +:10e270000d0062a000a0023cc80c43240800022448 +:10e280000e0062a000a0023cc80c42240f0040a077 +:10e290005000c38f5000c28f0400428c08004224fb +:10e2a000080062ac00a0023cc80c43240200022417 +:10e2b000100062a05000c38f020002241e0062a062 +:10e2c00000a0023cc80c4224110040a000a0023c67 +:10e2d000c80c432402000224120062a05000c38f25 +:10e2e00000020224140062a400a0023cc80c4224d4 +:10e2f000130040a000a0023cc80c4224140040a01f +:10e3000000a0023cc80c4324f8ff0224150062a0c0 +:10e3100000a0023cc80c43245800c28f160062a023 +:10e3200000a0023cc80c43245800c28f0212020015 +:10e33000170062a05000c38f5800c28f1c0062a457 +:10e3400000a0023cc80c43243f000224180062a035 +:10e3500000a0023cc80c4224190040a000a0023cce +:10e36000c80c4324ffff02241a0062a000a0023c54 +:10e37000c80c42241b0040a000a0023cc80c43244f +:10e380005000c28f0400428c1c0062a000a0023c1e +:10e39000c80c43245000c28f0400428c02120200b9 +:10e3a0001d0062a000a0023cc80c43245000c28f94 +:10e3b0000400428c021402001e0062a000a0023c75 +:10e3c000c80c43245000c28f0400428c0216020085 +:10e3d0001f0062a000a0023cc80c43241400c28f9e +:10e3e000200062a000a0023cc80c43241400c28f8d +:10e3f00002120200210062a000a0023cc80c4324cb +:10e400001400c28f02140200220062a000a0023c8d +:10e41000c80c43241400c28f02160200230062a01d +:10e4200000a0023cc80c4224240040a000a0023cf2 +:10e43000c80c4224250040a000a0023cc80c432484 +:10e4400029000224260062a000a0023cc80c44243b +:10e450009c00c28fffff032424104300270082a0ea +:10e4600000a0023cc80c42246c00c2af9c00c28fca +:10e470007000c2af7000c28f0400410400000000b1 +:10e480007000c38fff0063247000c3af7000c38fa0 +:10e4900003120300ffff0324241043006c00c38f0a +:10e4a000280062a000a0023cc80c42247400c2af45 +:10e4b0009c00c28f7800c2af7800c28f0500410473 +:10e4c00000000000ffff02347800c38f21186200b3 +:10e4d0007800c3af7800c38f03140300ffff032449 +:10e4e000241043007400c38f290062a000a0023ce6 +:10e4f000c80c42247c00c2af9c00c28f8000c2af17 +:10e500008000c28f0600410400000000ff00023cb2 +:10e51000ffff42348000c38f211862008000c3af28 +:10e520008000c38f03160300ffff03242410430061 +:10e530007c00c38f2a0062a0a000c28f2900401077 +:10e54000000000006000c0a36000c393a000c28f61 +:10e550002110620000004280130040100000000003 +:10e560006000c2930b00422c0f004010000000001e +:10e5700000a0023c6000c393c80c4224212062002a +:10e580006000c393a000c28f21106200000042907f +:10e590002b0082a06000c293010042246000c2a34d +:10e5a000e9ff0010000000006000c2930b00422c45 +:10e5b0001b0040100000000000a0043c6000c3935a +:10e5c000010062246000c2a3ff006330c80c8224f3 +:10e5d00021186200200002242b0062a0f2ff00102c +:10e5e000000000006000c0a36000c2930b00422c3a +:10e5f0000b0040100000000000a0023c6000c3932c +:10e60000c80c4224211062002b0040a06000c2937d +:10e61000010042246000c2a3f3ff001000000000cc +:10e6200000a0023cc80c432446000224360062a02d +:10e6300000a0023cc80c432441000224370062a021 +:10e6400000a0023cc80c432454000224380062a0fd +:10e6500000a0023cc80c432431000224390062a00f +:10e6600000a0023cc80c4324200002243b0062a00e +:10e6700000a0023cc80c4324200002243c0062a0fd +:10e6800000a0023cc80c4324200002243d0062a0ec +:10e6900000a0023cc80c432455000224fe0162a0e5 +:10e6a00000a0023cc80c4324aaff0224ff0162a080 +:10e6b0005000c48f5000c58f5000c28f1e00439081 +:10e6c0005000c28f1c004294021862700800a28c95 +:10e6d000211043000c0082ac5000c28f0400448c17 +:10e6e00000a0023cc80c452421300000b05b400f64 +:10e6f000000000001800401400000000090002247f +:10e700004c8282a3ffff02246400c2af0301001009 +:10e71000000000005000c48f1435400f00000000be +:10e720000d004010000000001b0002244c8282a358 +:10e73000ffff03246400c3aff800001000000000d6 +:10e740001f0002244c8282a3ffff02246400c2af98 +:10e75000f20000100000000000a0023cc80c44249d +:10e760002128000000020624d169400f00000000ab +:10e7700000a0033cf8ff0224c80c62a000a0023ce9 +:10e78000c80c4324ffff0224010062a000a0023c49 +:10e79000c80c4324ffff0224020062a05000c28f75 +:10e7a00020004390020002240500621400000000d3 +:10e7b00000a0023cc80c4324ffff0224030062a017 +:10e7c0005000c28f1e004290ffff42245400c2a797 +:10e7d0005400c397ffff02341900621000000000cc +:10e7e0005000c48f5400c3975000c28f1c00429445 +:10e7f000021862700800828c211062002120400003 +:10e8000000a0023cc80c452421300000b05b400f42 +:10e81000000000000500401400000000ffff02247b +:10e820006400c2afbd000010000000005400c29799 +:10e83000ffff42245400c2a7e5ff001000000000c3 +:10e8400000a0023cc80c4424212800000400062437 +:10e85000d169400f000000005000c28f0800428cb8 +:10e86000010042246000c2a36000c5935000c48f21 +:10e870005000c28f1c0043940800828c211062005b +:10e880002b10a20025004010000000005000c28f95 +:10e890001e004290ffff42245400c2a75400c397b9 +:10e8a000ffff023418006210000000006000c493f3 +:10e8b0005400c3975000c28f1c0042940210627033 +:10e8c000211082002120400000a0023cc80c4524f9 +:10e8d00021300000b05b400f000000000500401434 +:10e8e00000000000ffff02246400c2af8b00001094 +:10e8f000000000005400c297ffff42245400c2a74a +:10e90000e6ff0010000000006000c29301004224f6 +:10e910006000c2a3d4ff0010000000005000c28fae +:10e920001400429440110200ff0142248800c2af4b +:10e930008800c38f04006104000000008800c28fbb +:10e94000ff0142248800c2af8800c38f4312030036 +:10e950001c00c2af010002246000c2a36000c29389 +:10e960001c00c38f2b104300160040100000000055 +:10e970005000c28f6000c3930c00428c21106200d3 +:10e980002120400000a0023cc80c4524213000009a +:10e99000b05b400f000000000500401400000000c4 +:10e9a000ffff02246400c2af5c0000100000000002 +:10e9b0006000c293010042246000c2a3e7ff001080 +:10e9c00000000000a000c28f4600401000000000c0 +:10e9d0006000c0a36000c393a000c28f211062003a +:10e9e0000000428013004010000000006000c2934d +:10e9f0000b00422c0f0040100000000000a0023c61 +:10ea00006000c393c80c4224212062006000c393bd +:10ea1000a000c28f2110620000004290000082a07e +:10ea20006000c293010042246000c2a3e9ff00100d +:10ea3000000000006000c2930b00422c0c0040104c +:10ea40000000000000a0043c6000c39301006224a9 +:10ea50006000c2a3ff006330c80c8224211862004a +:10ea600020000224000062a0f2ff0010000000005d +:10ea700000a0023cc80c4324080002240b0062a042 +:10ea800000a0023cc80c432411000224110062a023 +:10ea900000a0023cc80c432411000224130062a011 +:10eaa00000a0023cc80c432411000224170062a0fd +:10eab0005000c28f0c00448c00a0023cc80c4524be +:10eac00021300000b05b400f000000001200401435 +:10ead00000000000ffff03246400c3af0f0000101c +:10eae000000000005000c28f0c00448c00a0023ccb +:10eaf000c80c452421300000b05b400f000000002e +:10eb00000500401400000000ffff02246400c2afb3 +:10eb100002000010000000006400c0af6400c28f5b +:10eb200021e8c0039400bf8f9000be8f9800bd27de +:10eb30000800e00300000000d0ffbd272c00bfaf9d +:10eb40002800beaf21f0a0033000c4af3400c5af31 +:10eb50003000c28f0000428c1000c2af3000c28f64 +:10eb60003800428c1c00c2af3400c28f00004294b7 +:10eb7000021102001500c2a31000c28f20004290b3 +:10eb80002000c2af2000c38f010062281f00401484 +:10eb9000000000002000c38f030062281000401412 +:10eba00000000000030002242000c38f0300621055 +:10ebb0000000000015000010000000001000c28fcf +:10ebc0001500c3931f0042901b006200f401400037 +:10ebd000101000001500c2a30c000010000000007f +:10ebe0001c00c38f3c82828f08006210000000006e +:10ebf0001000c28f1500c3931f0042901b006200db +:10ec0000f4014000101000001500c2a31000c48fd2 +:10ec10001c00c58f4c45400f000000001800c2af1b +:10ec20001500c3931800c28f211062001000c38f1b +:10ec3000212040000000658c21300000b05b400fb7 +:10ec40000000000004004014000000001400c0a3f5 +:10ec50000300001000000000010002241400c2a301 +:10ec60001400c29321e8c0032c00bf8f2800be8f80 +:10ec70003000bd270800e00300000000d0ffbd27e2 +:10ec80002c00bfaf2800beaf21f0a0033000c4affe +:10ec90003400c5af1c00c0af3400c28f20004290ca +:10eca0002400c2af020002242400c38f19006210a6 +:10ecb000000000002400c38f0300622807004010fa +:10ecc00000000000010002242400c38f170062101e +:10ecd00000000000190000100000000003000224e2 +:10ece0002400c38f03006210000000001300001016 +:10ecf00000000000ff0f023cffff42341800c2afcb +:10ed0000ff0f023cf8ff42341400c2af0b000010aa +:10ed100000000000ffff02341800c2aff8ff023409 +:10ed20001400c2af0500001000000000ffff023415 +:10ed30001800c2aff80f02241400c2af3000c28f17 +:10ed400007004010000000003000c38f01000224c3 +:10ed50000300621000000000050000100000000029 +:10ed6000020002241c00c2af3500001000000000a9 +:10ed70001c00c28f32004014000000003400c48f19 +:10ed80003000c58ff04a400f000000001000c2aff5 +:10ed90001000c38f1800c28f05006214000000002d +:10eda000010002241c00c2aff1ff001000000000af +:10edb0001000c28f07004010000000001000c38f39 +:10edc0000100022403006210000000000500001092 +:10edd00000000000020002241c00c2afe4ff00108b +:10ede000000000001000c28f1400c38f2b104300de +:10edf0000300401400000000020002241c00c2af07 +:10ee00003400c48f3000c58f21300000213800004d +:10ee1000124c400f00000000211840001800c28f63 +:10ee20000300621400000000010002241c00c2afb5 +:10ee30001000c28f3000c2afcdff001000000000f4 +:10ee40003400c48f21280000213000000100072475 +:10ee5000124c400f000000001c00c38f020002246f +:10ee60000500621400000000010002242000c2af6f +:10ee700002000010000000002000c0af2000c28f80 +:10ee800021e8c0032c00bf8f2800be8f3000bd27b3 +:10ee90000800e00300000000c0ffbd273c00bfaf3a +:10eea0003800beaf21f0a0034000c4af4400c5af9e +:10eeb0002110c0004800c2a34000c28f0000428c55 +:10eec0001400c2af4000c28f3400428c1c00c2af9d +:10eed0004000c28f3800428c2400c2af4400c28f71 +:10eee00000004294021102002800c2a31400c28f45 +:10eef000200042903000c2af3000c38f0100622872 +:10ef000023004014000000003000c38f030062287b +:10ef10001300401400000000030002243000c38fdf +:10ef20000300621000000000190000100000000043 +:10ef30001400c28f2800c3931f0042901b00620080 +:10ef4000f4014000101000002800c2a3ff0f023c93 +:10ef5000f8ff42342000c2af0d0000100000000096 +:10ef60001c00c28f08004010000000001400c28f77 +:10ef70002800c3931f0042901b006200f401400070 +:10ef8000101000002800c2a3f8ff02342000c2af16 +:10ef90004800c29306004014000000004400c28fe5 +:10efa000000042940f0042308f0040140000000027 +:10efb0002800c29306004014000000004400c28fe5 +:10efc000000042941000422c060040100000000097 +:10efd0004800c29303004014000000002c00001001 +:10efe000000000001c00c28f04004014000000005c +:10eff0002400c0af26000010000000004800c293ab +:10f000000d004010000000004400c38f1400c28fa8 +:10f010001f0042900011020000006394ffff423085 +:10f020001b006200f4014000121000002900c2a37e +:10f030000300001000000000010002242900c2a308 +:10f040002900c29312004010000000001400c48f79 +:10f050002400c58ff04a400f000000002400c2af1a +:10f060002400c38f2000c28f2b10620003004014c5 +:10f070000000000006000010000000002900c293fc +:10f08000ffff42242900c2a3edff00100000000092 +:10f090002400c28f2000c38f2b1043004d0040106e +:10f0a000000000004000c38f2400c28f380062ac13 +:10f0b0001400c48f2400c58f4c45400f0000000091 +:10f0c0001800c2af2400c38f3c82828f11006214eb +:10f0d000000000002800c3931800c28f21186200ae +:10f0e0001400c28f1000428c2b10620009004014e3 +:10f0f000000000001400c28f20004390030002248f +:10f1000004006210000000001000c0af3f000010bb +:10f1100000000000dc808293080040100000000026 +:10f120000447400f000000000400401000000000f1 +:10f130002c00c0af3700001000000000d88080af66 +:10f14000de8080a32800c3931800c28f21106200c4 +:10f150001400c38f212040000000658c285b400f05 +:10f160000000000021184000010002240400621089 +:10f17000000000001000c0af1200001000000000ee +:10f180004800c2930c004010000000001400c48f1f +:10f190004400c28f000042940f004230ffff423013 +:10f1a000401902000000828c211043001000c2af01 +:10f1b00004000010000000001400c28f0000428c08 +:10f1c0001000c2afffff0224188082af0f000010b2 +:10f1d0000000000001000224dd8082a31000c0af07 +:10f1e0000a000010000000001400c48f4400c28f09 +:10f1f000000042940f004230ffff423040190200ed +:10f200000000828c211043001000c2af1000c28f9a +:10f210002c00c2af2c00c28f21e8c0033c00bf8f7e +:10f220003800be8f4000bd270800e003000000004a +:10f23000d0ffbd272c00bfaf2800beaf21f0a00338 +:10f240003000c4af3400c5af2110c0003800c2a3e5 +:10f250001400c0af4c8280a31000c0a31000c29362 +:10f260000b00422c0e004010000000001000c39361 +:10f270001000c227212062003000c38f1000c2930b +:10f280002110620020004290080082a01000c2936a +:10f29000010042241000c2a3f0ff00100000000093 +:10f2a0003400c28f000040a43000c48f3400c58fea +:10f2b000033d400f0000000013004010000000005c +:10f2c0001800c2273800c3933000c48f21284000a3 +:10f2d0003400c68f213860009e3d400f00000000c2 +:10f2e0001400c2af1400c28f0900401400000000d7 +:10f2f0003000c48fcd3c400f000000001400c2afae +:10f300000300001000000000140002241400c2af2b +:10f310001400c28f4c8282a31400c28f21e8c00364 +:10f320002c00bf8f2800be8f3000bd270800e003ef +:10f3300000000000d0ffbd272c00bfaf2800beafeb +:10f3400021f0a0033000c4af3000c28f2c004294e3 +:10f350001c00c2a71400c2273000c48f212840001f +:10f360004f44400f000000001000c2af1000c28fd9 +:10f370001f004014000000001c00c2273000c48f92 +:10f38000212840003c40400f000000002000c2af98 +:10f390002000c38f1400c28f1a0062a41400c38f10 +:10f3a000ff0f023c241062001800c2af1800c28f89 +:10f3b000021402001800c2af2000c38f1800c28fd1 +:10f3c000140062a41c00c2273000c48f2128400012 +:10f3d000ce3a400f00000000211840000100022436 +:10f3e0000300621000000000090002241000c2aff8 +:10f3f0001000c28f21e8c0032c00bf8f2800be8ff1 +:10f400003000bd270800e00300000000d0ffbd274a +:10f410002c00bfaf2800beaf21f0a0033000c4af66 +:10f420003400c5af010002241000c2a33000c38f16 +:10f430003000c28f3400428c380062ac3000c48f80 +:10f440003400c58f01000624a63b400f00000000d9 +:10f450001c00c2af1c00c28f050040140000000059 +:10f460001b0002241000c2a3740000100000000062 +:10f470001000c393010002246d006214000000001c +:10f480001100c0a33400c28f000042941400c2a730 +:10f490003000c48f3400c58f21300000a63b400fe0 +:10f4a000000000001c00c2af1c00c28f0000429090 +:10f4b0001200c2a33400c38f3400c28f00004294f4 +:10f4c00001004224000062a41200c393e50002245c +:10f4d00004006210000000001200c2930c004014ef +:10f4e000000000001c00c28f090040100000000056 +:10f4f0001100c293010042241100c2a3ff00423058 +:10f500000300401400000000e1ff001000000000b4 +:10f510001c00c28f3c004014000000003000c28f6d +:10f520003800428c1800c2af1800c38f3c82828f13 +:10f5300020006214000000003000c28f0000428ce6 +:10f540002000439003000224050062100000000028 +:10f55000020002241000c2a3c5ff0010000000003a +:10f560003000c38f1800c28f080062ac3000c48f17 +:10f5700001000524443e400f000000002118400017 +:10f58000150002240500621400000000020002249d +:10f590001000c2a3b6ff0010000000003400c38fab +:10f5a0001400c297000062a41000c0a3b0ff0010b6 +:10f5b000000000003000c38f1800c28f080062ac4a +:10f5c0003000c48f01000524443e400f00000000bd +:10f5d00021184000150002240500621400000000fc +:10f5e000020002241000c2a3a1ff001000000000ce +:10f5f0003400c38f1400c297000062a41000c0a39f +:10f600009bff0010000000001100c39301000224c2 +:10f6100097ff6214000000001000c0a33400c38fe5 +:10f620001400c297000062a491ff001000000000c7 +:10f630003400c38f1400c297000062a41000c2936c +:10f640000500401400000000010002242000c2afa9 +:10f6500002000010000000002000c0af2000c28f98 +:10f6600021e8c0032c00bf8f2800be8f3000bd27cb +:10f670000800e00300000000d8ffbd272400bfaf52 +:10f680002000beaf21f0a0032800c4af2c00c5affe +:10f690003000c6af2110e0003400c2a31000c0a3a8 +:10f6a0002800c38f2800c28f3400428c380062ac1f +:10f6b0002800c48f3000c58f01000624a63b400ff0 +:10f6c000000000001400c2af1400c28f05004014f7 +:10f6d000000000001b0002241800c2af5a000010f6 +:10f6e000000000001400c48f2c00c58f0b000624fe +:10f6f000f16a400f000000003400c393120002249e +:10f7000006006214000000001400c38f10000224e1 +:10f710000b0062a004000010000000001400c38f62 +:10f72000200002240b0062a01400c28f0c0040a035 +:10f730001400c28f140040a41400c28f1a0040a409 +:10f740001400c28f1c0040ac193e400f00000000a6 +:10f750001400c38f378282930d0062a01400c38f00 +:10f76000388282970e0062a41400c38f428282976f +:10f77000100062a43400c393120002240c00621033 +:10f78000000000001400c38f4a828297120062a416 +:10f790001400c38f4e828297160062a41400c38f98 +:10f7a00040828297180062a4070000100000000049 +:10f7b0001400c28f120040a41400c28f160040a48f +:10f7c0001400c28f180040a42800c38f1400c28ff9 +:10f7d0001c00428c140062ac2800c38f1400c28f3e +:10f7e0000e0042941c0062a42800c38f1400c28f34 +:10f7f000100042941e0062a42800c38f1400c28f20 +:10f800000b004290300062a42800c38f3000c28fea +:10f81000000042942c0062a42800c48f3000c58fe1 +:10f82000ce3a400f000000002118400001000224e1 +:10f830000300621000000000090002241000c2a3af +:10f840001000c2931800c2af1800c28f21e8c00395 +:10f850002400bf8f2000be8f2800bd270800e003d2 +:10f8600000000000e0ffbd271800beaf21f0a0039c +:10f870000800deaf0400c2270c00c2af80bf023c0c +:10f880003002428c1400c2af80bf023c2002428c86 +:10f890001000c2af0800c38f80bf023c2002428c20 +:10f8a000000062ac0c00c38f80bf023c3002428c6f +:10f8b000000062ac0c00c28f1400c38f0000428ca9 +:10f8c000eeff6214000000000800c28f1000c38f1a +:10f8d0000000428ce9ff6214000000000200c397a0 +:10f8e0000000c29725106200388282a70600c397e5 +:10f8f0000000c29725106200408282a721e8c00361 +:10f900001800be8f2000bd270800e00300000000a3 +:10f91000d8ffbd272400bfaf2000beaf21f0a00359 +:10f920002800c4af2110a0002c00c2a32800c28f61 +:10f930000000428c1000c2af2800c28f0800428c29 +:10f940001400c2af2800c48f9c3e400f000000008e +:10f950001400c2af1400c28f050040140000000064 +:10f96000150002241c00c2af3a0000100000000085 +:10f970001000c28f2000439001000224090062148d +:10f98000000000001000c48f1400c58ff80f06247b +:10f9900021380000124c400f00000000150000103c +:10f9a000000000001000c28f2000439002000224db +:10f9b00009006214000000001000c48f1400c58ffd +:10f9c000f8ff063421380000124c400f0000000000 +:10f9d00008000010000000001000c48f1400c58f44 +:10f9e000ff0f023cf8ff463421380000124c400f54 +:10f9f000000000002800c28f0800428c1800c2af2f +:10fa00001000c48f1800c58f1400c68f2138000065 +:10fa1000124c400f000000002800c38f1400c28f5a +:10fa2000080062ac2c00c393010002240800621499 +:10fa3000000000001000c48f1400c58fae44400fba +:10fa4000000000001c00c2af020000100000000017 +:10fa50001c00c0af1c00c28f21e8c0032400bf8f70 +:10fa60002000be8f2800bd270800e0030000000032 +:10fa7000c8ffbd273400bfaf3000beaf21f0a003e8 +:10fa80003800c4af1400c0af3800c28f0000428cf1 +:10fa90001000c2af3800c28f0800428c1800c2affd +:10faa0001000c28f200042902800c2af0200022442 +:10fab0002800c38f19006210000000002800c38fc7 +:10fac000030062280700401000000000010002242b +:10fad0002800c38f170062100000000019000010fa +:10fae00000000000030002242800c38f03006210fe +:10faf000000000001300001000000000ff0f023c97 +:10fb0000f7ff42342000c2afff0f023cffff423438 +:10fb10002400c2af0b00001000000000f7ff023409 +:10fb20002000c2afffff02342400c2af0500001066 +:10fb300000000000f70f02242000c2afffff0234d4 +:10fb40002400c2af1800c28f0200422c03004010f4 +:10fb500000000000020002241800c2af1800c28f8b +:10fb60001c00c2af1000c48f1800c58ff04a400fb0 +:10fb7000000000001800c28f2800401000000000a4 +:10fb80001000c48f1800c58ff04a400f000000001d +:10fb90001400c2af1400c38f2400c28f040062148b +:10fba000000000001800c0af1c00001000000000a2 +:10fbb0001400c28f03004014000000001700001062 +:10fbc000000000001800c28f010042241800c2afdc +:10fbd0001400c38f2000c28f0900621000000000d3 +:10fbe0001000c28f1800438c1800c28f2b104300e6 +:10fbf000030040100000000003000010000000009f +:10fc0000020002241800c2af1800c38f1c00c28f6c +:10fc1000d8ff6214000000001800c0af1800c28fa7 +:10fc200021e8c0033400bf8f3000be8f3800bd27ed +:10fc30000800e00300000000d8ffbd272400bfaf8c +:10fc40002000beaf21f0a0032800c4af480002246a +:10fc50001400c2af4c8280a32800c28f2c004294b3 +:10fc60001000c2a72800c28f1800428c0000427cfe +:10fc70004200401000000000dc8082930a00401027 +:10fc8000000000000447400f000000000600401084 +:10fc900000000000090002244c8282a3ffff02241e +:10fca000570000101c00c2af2800c28f0000448c17 +:10fcb0002128000021300000124c400f01000724d1 +:10fcc0002800c48f3c40400f1000c5271800c2af69 +:10fcd0001800c28f08004014000000001b0002241e +:10fce0004c8282a3ffff02241400c2af1400c28f13 +:10fcf000430000101c00c2af193e400f000000007e +:10fd00001800c38f4e828297160062a41800c38f1a +:10fd100040828297180062a4000000001800c38f80 +:10fd20002800c28f1400428c1c0062ac1800c38fe4 +:10fd30002800c28f300042940b0062a02800c48fbc +:10fd4000ce3a400f1000c52703004010000000000d +:10fd5000050000101400c0af090002244c8282a3e9 +:10fd6000ffff02241400c2af2800c48f1800838c48 +:10fd7000feff022424106200180082ac1200c0a70b +:10fd80001200c2970300422c160040100000000031 +:10fd90001200c397211060000011020023104300dd +:10fda0008018020000a0023c501142242118620079 +:10fdb0002800c28f07006214000000001200c397e1 +:10fdc00034828227211862000100022405000010fd +:10fdd000000062a01200c29701004224e8ff001058 +:10fde0001200c2a71400c38f48000224020062144c +:10fdf000000000001400c0af1400c28f1c00c2af8e +:10fe00001c00c28f21e8c0032400bf8f2000be8fda +:10fe10000800e0032800bd27d0ffbd272800bfafa2 +:10fe20002400beaf2000b0af21f0a0033000c4af6b +:10fe30003400c5af1800c0a33400c28f0000429444 +:10fe40000f00423011004014000000003400c28f47 +:10fe5000000042940d004010000000003000c38fed +:10fe60003000c28f3400428c380062ac3000c48f46 +:10fe70003400c58f01000624a63b400f000000009f +:10fe80001000c2af07000010000000003000c48f57 +:10fe90003400c58f21300000a63b400f0000000059 +:10fea0001000c2af1000c28f000042901500c2a324 +:10feb0001000c28f04004010000000001500c29323 +:10fec0000500401400000000020002241700c2a335 +:10fed0007f000010000000001500c393e50002241d +:10fee0000500621400000000010002241700c2a3f4 +:10fef00077000010000000001000c28f0b0042903d +:10ff00001500c2a31400c0a31400c2930800422c21 +:10ff100018004010000000001000c38f1400c293ae +:10ff200021104300000042901600c2a31600c293a5 +:10ff300021204000786b400f000000001600c2a393 +:10ff40003000c48f1800c393010062241800c2a3bc +:10ff5000ff006230211882001600c293200062a0c8 +:10ff60001400c293010042241400c2a3e6ff001053 +:10ff7000000000001000c28f0b0042901500c2a3c9 +:10ff80001000c28f080042901600c2a31400c0a344 +:10ff90001400c2930300422c18004010000000001f +:10ffa0001000c38f1400c293211062000800429019 +:10ffb0001600c2a31600c29321204000786b400fa8 +:10ffc000000000001600c2a33000c48f1800c393c5 +:10ffd000010062241800c2a3ff00623021188200d1 +:10ffe0001600c293200062a01400c29301004224b4 +:10fff0001400c2a3e6ff0010000000003000c38f11 +:020000041d01dc +:100000003400c28f000042942c0062a41000c28f02 +:10001000000042901500c2a31500c393e50002241e +:100020000500621400000000010002241700c2a3b2 +:1000300002000010000000001700c0a33000c38fb2 +:100040001000c28f1c00428c140062ac3000d08fb4 +:100050001000c48f0736400f00000000040002aefd +:100060001000c28f0b0042901500c2a33000c38f56 +:100070001500c293300062a41500c29310004230f4 +:100080000b004010000000003000c38f1000c28f32 +:100090000e0042941c0062a43000c38f1000c28f77 +:1000a000100042941e0062a409000010000000002d +:1000b0003000c38f1000c28f160042941c0062a44f +:1000c0003000c38f1000c28f180042941e0062a43b +:1000d0001700c29321e8c0032800bf8f2400be8f01 +:1000e0002000b08f3000bd270800e00300000000b2 +:1000f000d8ffbd272400bfaf2000beaf21f0a00372 +:100100002800c4af2c00c5af2800c38f2800c28fc1 +:100110003400428c380062ac2800c48f2c00c58f9c +:1001200001000624a63b400f000000001000c2aff3 +:100130001000c28f04004014000000001800c0af7f +:1001400031000010000000001000c28f000042903b +:100150001400c2a31400c293020040140000000067 +:100160001000c0af1000c28f25004010000000003a +:100170001400c393e5000224040062140000000090 +:100180001000c0af1e000010000000001000c28f61 +:100190000b0042901400c2a31400c3930f0002246a +:1001a00017006214000000002c00c38f2c00c28fc7 +:1001b0000000429401004224000062a42800c48f81 +:1001c0002c00c58f21300000a63b400f000000002e +:1001d0001000c2af1000c28f0400401400000000e5 +:1001e0001800c0af08000010000000001000c28f0f +:1001f0000b0042901400c2a3e7ff001000000000b3 +:100200001000c28f1800c2af1800c28f21e8c003cf +:100210002400bf8f2000be8f2800bd270800e00308 +:1002200000000000d0ffbd272c00bfaf2800beafec +:1002300021f0a0033000c4af3400c5af2110c000ce +:100240003800c2a31800c0af3000c28f0000428c3b +:100250002000c2af3000c28f3400428c1c00c2affd +:100260003000c38f1c00c28f380062ac3000c48fd6 +:100270003400c58f01000624a63b400f000000009b +:100280001000c2af1000c28f070040140000000031 +:10029000010002244c8282a31b0002242400c2af6e +:1002a00045000010000000001000c28f00004290c6 +:1002b0001400c2a31000c28f040040100000000010 +:1002c0001400c29305004014000000000b0002243b +:1002d0001800c2af2e000010000000001400c393ed +:1002e000e500022405006214000000000b00022457 +:1002f0001800c2af26000010000000001000c28fde +:100300000b0042901400c2a31000c38fe5ff02242b +:10031000000062a01000c48f0736400f00000000ec +:100320001c00c2af1800c28f07004014000000007c +:100330003000c48f3400c58fce3a400f000000005b +:100340000500401400000000010002241800c2afa4 +:100350000f000010000000001c00c38f3c82828f41 +:100360000b006210000000003800c293080040102b +:10037000000000001c00c48f2000c58f1f3b400ff1 +:1003800000000000000042380100422c1800c2affb +:100390001800c28f04004014000000004c8280a3ab +:1003a0000300001000000000010002244c8282a320 +:1003b0001800c28f2400c2af2400c28f21e8c003fe +:1003c0002c00bf8f2800be8f3000bd270800e0033f +:1003d00000000000c0ffbd273c00bfaf3800beaf2b +:1003e00021f0a0034000c4af4400c5af1100c0a37a +:1003f000010002242800c2a74c8280a34400c28fbf +:100400000700401400000000190002244c8282a35f +:10041000ffff02243000c2afd10000100000000036 +:100420004400c28f200042244000c48f2128400095 +:10043000213000000848400f000000000700401471 +:1004400000000000120002244c8282a3ffff02245d +:100450003000c2afc2000010000000001000c0a3b6 +:100460001000c2930b00422c0e0040100000000050 +:100470001000c3931000c227212062004400c38fe4 +:100480001000c2932110620020004290080082a058 +:100490001000c293010042241000c2a3f0ff00101c +:1004a000000000004400c28f2c0042942a00c2a722 +:1004b0002800c0a74400c38f4400c28f3400428c80 +:1004c000380062ac2800c2274400c48f21284000b5 +:1004d00001000624a63b400f000000002c00c2af24 +:1004e0002c00c28f07004014000000001b000224f3 +:1004f0004c8282a3ffff02243000c2af980000109c +:10050000000000001000c0a31000c2930b00422c9a +:1005100012004010000000002c00c38f1000c29396 +:10052000212043001000c3931000c2272110620055 +:100530000000838008004280030062100000000079 +:10054000010002241100c2a31000c2930100422442 +:100550001000c2a3ecff0010000000001100c293c5 +:100560000700401400000000110002244c8282a306 +:10057000ffff02243000c2af79000010000000002d +:100580001100c0a3dd8080a32800c2274400c48fcf +:100590002128400021300000a63b400f0000000051 +:1005a0002c00c2af2c00c28f0d00401400000000d0 +:1005b000dd80839301000224030062140000000028 +:1005c00032000010000000001b0002244c8282a3b5 +:1005d000ffff02243000c2af6100001000000000e5 +:1005e0002c00c28f00004280030040140000000075 +:1005f00026000010000000001000c0a31000c293ed +:100600000b00422c12004010000000002c00c38f91 +:100610001000c293212043001000c3931000c22792 +:1006200021106200000083800800428003006210f5 +:1006300000000000010002241100c2a31000c293b8 +:10064000010042241000c2a3ecff001000000000d3 +:100650001100c293070040140000000011000224a2 +:100660004c8282a3ffff02243000c2af3c00001086 +:10067000000000001100c0a32800c297010042241e +:100680002800c2a7c0ff0010000000002a00c29787 +:100690002800c2a74400c38f4400c28f3400428c9c +:1006a000380062ac2800c2274400c48f21284000d3 +:1006b0003c40400f000000002c00c2af2c00c28f55 +:1006c00007004014000000001b0002244c8282a39b +:1006d000ffff02243000c2af210000100000000024 +:1006e0001000c0a31000c2930b00422c0e0040105b +:1006f000000000002c00c38f1000c2932120430093 +:100700004400c38f1000c293211062002000429069 +:10071000000082a01000c293010042241000c2a376 +:10072000f0ff0010000000002800c2274400c48f22 +:1007300021284000ce3a400f00000000070040147e +:1007400000000000090002244c8282a3ffff022463 +:100750003000c2af02000010000000003000c0af47 +:100760003000c28f21e8c0033c00bf8f3800be8f2d +:100770004000bd270800e00300000000d0ffbd27b7 +:100780002c00bfaf2800beaf21f0a0033000c4afe3 +:100790003400c5af1000c0af1400c0af1400c28f4a +:1007a000030042281b004010000000001400c38f0b +:1007b0003482822721106200000042901000401015 +:1007c000000000001400c38f3482822721106200d1 +:1007d000000040a01400c38f21106000001102002f +:1007e000231043008018020000a0023c5011422454 +:1007f000211062001000c2af0600001000000000cf +:100800001400c28f010042241400c2afe3ff0010a5 +:10081000000000001000c28f06004014000000001d +:10082000200002244c8282a32000c0af7801001077 +:10083000000000001000c28f200042243000c48f4e +:1008400021284000213000000848400f000000002f +:100850000b004014000000001400c38f3482822774 +:100860002118620001000224000062a0120002248c +:100870004c8282a32000c0af650100100000000080 +:100880003400c28f000042901800c2a31000c38f32 +:1008900000a0023c04124224000062ac1000c28f8f +:1008a000040040ac1000c28f080040ac1000c28fa2 +:1008b0002c0040a41000c38f20000224300062a44a +:1008c0001000c38f1c80828f3400428c340062acd5 +:1008d0001000c38f1c80828f3800428c380062acbd +:1008e00000a0023c281244241000c58f2c44400f65 +:1008f000000000001000c48f00a0023c2812452414 +:100900000100062421380000fc31400f00000000e7 +:10091000db004014000000001800c293bfff422417 +:100920002400c2af2400c38f3700622cce004010d9 +:10093000000000002400c28f80180200029d023ccb +:10094000e4024224211062000000428c08004000b2 +:10095000000000001000c28f2c0042941a00c2a7b1 +:100960001a00c2271000c48f21284000010006246d +:100970008940400f000000001c00c2af1c00c28f65 +:100980000c014014000000001a00c2271000c48fa0 +:1009900021284000213000008c3c400f0000000066 +:1009a0001c00c2af1c00c28f0201401400000000f6 +:1009b0001a00c2271000c48f2128400077000624a7 +:1009c0000833400f000000001c00c2af1000c28faf +:1009d000300042941000423005004010000000003a +:1009e0001f0002244c8282a3ff0002241c00c2af1d +:1009f0001c00c28fef004014000000001000c48fe4 +:100a00002128000002000624054a400f00000000d3 +:100a10001c00c2af3400c28f010043802b000224af +:100a2000e4006214000000001000c28f1800438c24 +:100a300002006334180043acde0000100000000028 +:100a40001000c28f1400428c2d00401000000000e6 +:100a50001000c28f2c0042941a00c2a71a00c227ad +:100a60001000c48f21284000770006240833400f6f +:100a7000000000001c00c2af1000c28f3000429482 +:100a80001000423005004010000000001f0002244a +:100a90004c8282a3ff0002241c00c2af1c00c28f44 +:100aa000c4004014000000001000c48f2128000082 +:100ab00002000624054a400f000000001c00c2afdf +:100ac0001c00c28f03004010000000001a00022426 +:100ad0004c8282a33400c28f010043802b00022489 +:100ae000b4006214000000001000c28f1800438c94 +:100af00002006334180043acae0000100000000098 +:100b00001000c28f2c0042941a00c2a71a00c227fc +:100b10001000c48f21284000010006248940400fa6 +:100b2000000000001c00c2af1c00c28fa1004014d6 +:100b3000000000001a00c2271000c48f21284000c6 +:100b4000213000008c3c400f000000001c00c2afb0 +:100b50001c00c28f97004014000000001a00c2273a +:100b60001000c48f21284000770006240833400f6e +:100b7000000000001c00c2af1000c28f3000429481 +:100b80001000423005004010000000001f00022449 +:100b90004c8282a3ff0002241c00c2af1c00c28f43 +:100ba00084004014000000001000c48f21280000c1 +:100bb00002000624054a400f000000001c00c2afde +:100bc0001c00c28f03004010000000001a00022425 +:100bd0004c8282a33400c28f010043802b00022488 +:100be00074006214000000001000c28f1800438cd3 +:100bf00002006334180043ac6e00001000000000d7 +:100c00001000c28f2c0042941a00c2a71a00c227fb +:100c10001000c48f21284000720006240833400fc2 +:100c2000000000001c00c2af3400c28f01004380ee +:100c30002b0002245f006214000000001000c28f2d +:100c400030004294100042305a004014000000006e +:100c50001000c28f1800438c01006334180043acad +:100c600054000010000000001f0002244c8282a3e8 +:100c7000ff0002241c00c2af4e0000100000000064 +:100c80001000c48f00a0023c281245242c44400fc1 +:100c9000000000001800c393770002240f006210c8 +:100ca000000000001800c393570002240b006210dc +:100cb000000000001800c3936100022407006210c6 +:100cc000000000001800c3934100022403006210da +:100cd0000000000035000010000000001a00c0a74e +:100ce0001a00c2271000c48f2128400021300000c4 +:100cf0008c3c400f000000001c00c2af1c00c28fe3 +:100d00002c004014000000001a00c2271000c48ffd +:100d100021284000770006240833400f000000001f +:100d20001c00c2af1000c28f30004294100042304d +:100d300005004010000000001f0002244c8282a326 +:100d4000ff0002241c00c2af1c00c28f1900401417 +:100d5000000000001000c48f2128000002000624bb +:100d6000054a400f000000001c00c2af1c00c28feb +:100d700003004010000000001a0002244c8282a3ed +:100d80003400c28f010043802b000224090062144a +:100d9000000000001000c28f1800438c0200633472 +:100da000180043ac03000010000000000b000224f8 +:100db0001c00c2af2a5c400f00000000060040107b +:100dc000000000001000c48f1800838cfeff022476 +:100dd00024106200180082ac1c00c28f0900401071 +:100de000000000001400c38f3482822721186200a3 +:100df00001000224000062a01000c0af0200001039 +:100e0000000000004c8280a31000c28f2000c2afff +:100e10002000c28f21e8c0032c00bf8f2800be8fa6 +:100e20003000bd270800e00300000000f8ffbd27e8 +:100e30000000beaf21f0a0030800c4af4c8280a325 +:100e40000800c28f1000428c21e8c0030000be8f52 +:100e50000800bd270800e00300000000d8ffbd2700 +:100e60002400bfaf2000beaf21f0a0032800c4af14 +:100e700000a0023c140f42241000c2af4c8280a399 +:100e80002a5c400f00000000070040100000000036 +:100e9000180002244c8282a3ffff02241800c2af74 +:100ea00058000010000000001000c28f20004224f3 +:100eb0002800c48f21284000213000000848400f3e +:100ec000000000000700401400000000120002248f +:100ed0004c8282a3ffff02241800c2af4900001019 +:100ee000000000001000c38f00a0023c0412422446 +:100ef000000062ac1000c28f040040ac1000c28f32 +:100f0000080040ac1000c28f2c0040a41000c38f1a +:100f100020000224300062a41000c38f1c80828f46 +:100f20003400428c340062ac1000c38f1c80828f6e +:100f30003800428c380062ac00a0023c28124424e5 +:100f40001000c58f2c44400f000000001000c48f1b +:100f500000a0023c2812452401000624213800008c +:100f6000fc31400f000000001400c2af1400c28f1b +:100f700007004010000000000b0002244c8282a3f6 +:100f8000ffff02241800c2af1e0000100000000086 +:100f90001000c28f30004294100042300700401011 +:100fa00000000000130002244c8282a3ffff0224f1 +:100fb0001800c2af13000010000000001000c28f24 +:100fc0002c0042241000c48f212840000100062478 +:100fd0008940400f000000001400c2af1400c28f0f +:100fe00004004014000000001800c0af050000100d +:100ff00000000000010002244c8282a3ffff0224b3 +:101000001800c2af1800c28f21e8c0032400bf8fb0 +:101010002000be8f2800bd270800e003000000006c +:10102000e8ffbd271400bfaf1000beaf21f0a00342 +:101030001800c4afdc808293030040100000000061 +:101040000447400f000000001800c28f100040aca1 +:101050001800c28f0e0040a41800c28f0c0040a4dc +:101060001800c38f1800c28f0400428c080062acc5 +:10107000d88080af21e8c0031400bf8f1000be8f5e +:101080001800bd270800e00300000000f8ffbd279e +:101090000000beaf21f0a0034c82829321e8c00380 +:1010a0000000be8f0800bd270800e003000000001c +:1010b000e8ffbd271000beaf21f0a0031800c4afa9 +:1010c0001c00c5af1800c28f0400c2af1c00c28f45 +:1010d0000800c2af3c0002240000c2a30c00c0a361 +:1010e0000c00c2930000c3932b1043000e0040106d +:1010f000000000000c00c3930400c28f2120620096 +:101100000c00c3930800c28f2110620000004290bf +:10111000000082a00c00c293010042240c00c2a374 +:10112000efff00100000000021e8c0031000be8f98 +:101130001800bd270800e00300000000e0ffbd2705 +:101140001c00bfaf1800beaf21f0a0032000c4af49 +:101150002400c5af1400c0af2000c28f0000428c35 +:101160001000c2af2000c48f9c3e400f0000000062 +:10117000211840002400c28f000043ac2400c28f1d +:101180000000428c050040140000000015000224fd +:101190001400c2af41000010000000001000c28f18 +:1011a000200043900100022410006214000000009f +:1011b0002400c28f1000c48f0000458cf80f062455 +:1011c00021380000124c400f0000000021184000a0 +:1011d000ffff02342800621400000000090002240e +:1011e0001400c2af24000010000000001000c28fe5 +:1011f000200043900200022410006214000000004e +:101200002400c28f1000c48f0000458cf8ff063404 +:1012100021380000124c400f00000000211840004f +:10122000ffff0234140062140000000009000224d1 +:101230001400c2af10000010000000002400c28f94 +:101240001000c48f0000458cff0f023cf8ff4634ad +:1012500021380000124c400f00000000211840000f +:10126000ff0f023cffff4234030062140000000045 +:10127000090002241400c2af1400c28f07004014fa +:10128000000000002400c28f1000c48f0000458cb5 +:10129000ae44400f000000001400c2af1400c28f23 +:1012a00021e8c0031c00bf8f1800be8f2000bd279f +:1012b0000800e00300000000d8ffbd272400bfaff6 +:1012c0002000beaf21f0a0032800c4af2c00c5afa2 +:1012d0001800c0a32800c48f2c00c58f4c45400fb8 +:1012e000000000001400c2afdc80829309004010af +:1012f000000000000447400f0000000005004010ff +:1013000000000000090002241c00c2af2e000010e3 +:1013100000000000d88080afde8082930900401476 +:10132000000000002800c28f0000448c212800002b +:1013300000020624d169400f0000000001000224d1 +:10134000de8082a31000c0a32800c28f1f0043903c +:101350001000c2932b104300190040100000000041 +:101360001800c29316004014000000001400c327a8 +:101370000000628c2120400001004224000062ac89 +:101380002800c28f0000458c21300000b05b400f68 +:101390000000000021184000010002240300621038 +:1013a00000000000090002241800c2a31000c2932c +:1013b000010042241000c2a3e3ff0010000000005f +:1013c0001800c2931c00c2af1c00c28f21e8c003ea +:1013d0002400bf8f2000be8f2800bd270800e00337 +:1013e00000000000f8ffbd270000beaf21f0a00301 +:1013f0000800c4af2110a0000c00c2a70c00c397c6 +:101400000800c28f211062000000429021e8c00352 +:101410000000be8f0800bd270800e00300000000a8 +:10142000f0ffbd270800beaf21f0a0031000c4af3d +:101430002110a0001400c2a71400c3971000c28f8f +:1014400021106200000042900000c2a31400c39764 +:101450001000c28f21106200010042900100c2a35f +:101460000100c2930200c2a70200c297001202004c +:101470000200c2a70000c3930200c29725104300d8 +:101480000200c2a70200c29721e8c0030800be8f75 +:101490001000bd270800e00300000000e0ffbd27aa +:1014a0001c00bfaf1800beaf21f0a0032000c4afe6 +:1014b0002110a0002400c2a72400c2972000c48fde +:1014c000212840000845400f000000001000c2a77e +:1014d0002400c29702004224ffff42302000c48f44 +:1014e000212840000845400f000000001200c2a75c +:1014f0001200c2971400c2af1400c28f0014020081 +:101500001400c2af1000c3971400c28f251043000f +:101510001400c2af1400c28f21e8c0031c00bf8fab +:101520001800be8f2000bd270800e0030000000067 +:10153000f0ffbd270800beaf21f0a0031000c4af2c +:101540001400c5af1000c28f200042900400c2af4b +:101550000400c38f010062282f0040140000000027 +:101560000400c38f03006228120040140000000032 +:10157000030002240400c38f030062100000000077 +:1015800025000010000000001400c28ffeff43245d +:101590001000c28f1f004290021862701000c28fac +:1015a0001000428c211062000000c2af1a0000102f +:1015b000000000001400c28f07004010000000006f +:1015c0001400c38f01000224030062100000000019 +:1015d00008000010000000001000c28f0c00438cb7 +:1015e0001400c28f211062000000c2af0a00001078 +:1015f000000000001400c28ffeff43241000c28fc1 +:101600001f004290021862701000c28f1000428cbe +:10161000211062000000c2af0000c28f21e8c003a9 +:101620000800be8f1000bd270800e0030000000086 +:10163000d8ffbd272400bfaf2000beaf21f0a0031c +:101640002800c4af2110a0002c00c2a34c8280a3ac +:101650002c00c393d8ff022424106200070040101e +:10166000000000001f0002244c8282a3ffff02241e +:101670001800c2af3c000010000000002800c28f1c +:101680002c0042941000c2a72800c38f2800c28fec +:101690003400428c380062ac2800c48f1000c5278b +:1016a0003c40400f000000001400c2af1400c28f85 +:1016b00007004014000000001b0002244c8282a39b +:1016c000ffff02241800c2af270000100000000036 +:1016d0001400c28f0b0042900800423007004010f7 +:1016e000000000001f0002244c8282a3ffff02249e +:1016f0001800c2af1c000010000000002800c28fbc +:1017000030004294100042300700401000000000fa +:101710001400c28f2c00c393100063340b0043a04d +:1017200004000010000000001400c38f2c00c293be +:101730000b0062a02800c48f1000c527ce3a400fce +:10174000000000000700401400000000090002240f +:101750004c8282a3ffff02241800c2af02000010d7 +:10176000000000001800c0af1800c28f21e8c003bd +:101770002400bf8f2000be8f2800bd270800e00393 +:1017800000000000c0ffbd273c00bfaf3800beaf67 +:1017900021f0a0034000c4af4400c5af4800c6af6d +:1017a0004c00c7af4400c38f4800c28f0210627064 +:1017b0001000c2af4000c28f1400c2af1c00c0af07 +:1017c0003000c0a74c00c28f1800428c0000427c41 +:1017d00008004014000000001d0002244c8282a377 +:1017e000090002241c00c2af3400c0af0101001088 +:1017f000000000001000c28f040040140000000030 +:101800003400c0affb000010000000002a5c400f55 +:101810000000000008004010000000001800022432 +:101820004c8282a3180002241c00c2af3400c0af57 +:10183000f000001000000000de8080a34c00c28f8a +:101840000000428c1800c2af4c00c28f0e004294c0 +:101850002000c2a74c00c28f1000428c2800c2afeb +:101860004c00c28f1800c48f0800458c4c45400fb7 +:10187000000000002400c2af4c00c28f0c00439453 +:101880002400c28f211043002400c2afd880838f70 +:101890004c00c28f0f00621000000000dc808293b9 +:1018a0000a004010000000000447400f0000000044 +:1018b0000600401000000000090002244c8282a3b0 +:1018c0003400c0afcb000010000000004c00c28ffd +:1018d000d88082af1880838f2400c28f1b006210d3 +:1018e00000000000dc8082930a004010000000002d +:1018f0000447400f000000000600401000000000f8 +:10190000090002244c8282a33400c0afb900001049 +:1019100000000000de8080a31800c28f2400c48f66 +:101920000000458c285b400f0000000005004014bb +:10193000000000001b0002244c8282a30800022445 +:101940001c00c2af2400c28f188082af4c00c28f2f +:101950001400428c2c00c2af1c00c28f96004014b1 +:10196000000000001000c28f930040100000000033 +:101970002800c38f2c00c28f0500621400000000f5 +:101980004c00c28f1800438c04006334180043ac31 +:101990002000c397000202246200621400000000cd +:1019a000010002243200c2a3dc8082930a004010ae +:1019b000000000000447400f000000000600401037 +:1019c00000000000090002244c8282a33400c0af52 +:1019d00088000010000000002000c0a74c00c38f4a +:1019e0004c00c28f0c004294010042240c0062a4ff +:1019f0004c00c38f1800c28f1f0042900c006394ec +:101a0000ffff423015006214000000004c00c28f3e +:101a10000c0040a44c00c28f1800428c8000427c15 +:101a200009004010000000004c00c48f2128000075 +:101a3000443e400f000000001c00c2af3200c0a3b3 +:101a400006000010000000004c00c48f01000524b7 +:101a5000aa33400f000000001c00c2af1c00c38f5f +:101a60001500022406006214000000001500022484 +:101a70004c8282a33400c0af5e0000100000000062 +:101a80001c00c28f27004014000000004c00c28fd1 +:101a90001800c48f0800458c4c45400f0000000022 +:101aa0002400c2af4c00c28f0c0043942400c28fac +:101ab000211043002400c2af4c00c28fd88082aff7 +:101ac0003200c29315004010000000001800c28fc1 +:101ad0002400c48f0000458c285b400f00000000ec +:101ae0000a004014000000001b0002244c8282a364 +:101af000080002241c00c2afffff0224188082af3e +:101b00003400c0af3b000010000000002400c28f72 +:101b1000188082af03000010000000002400c28f74 +:101b2000188082af1c00c28f8bff401400000000a1 +:101b30001800c48f2000c397010062242000c2a7b0 +:101b4000ffff63300000828c211862001400c28ff6 +:101b500000004290000062a01400c28f01004224e5 +:101b60001400c2af2800c28f010042242800c2af77 +:101b70001000c28fffff42241000c2af3000c29796 +:101b8000010042243000c2a74c00c28f1800428cd2 +:101b90008000427c04004010000000002c00c28f36 +:101ba000010042242c00c2af01000224dc8082a389 +:101bb00069ff0010000000004c00c38f2000c29796 +:101bc0000e0062a44c00c38f2800c28f100062accc +:101bd0004c00c38f2c00c28f140062ac3000c3973e +:101be0004400c28f1b006200f4014000121000008c +:101bf0003400c2af3400c28f21e8c0033c00bf8f65 +:101c00003800be8f4000bd270800e0030000000040 +:101c1000d8ffbd272400bfaf2000beaf21f0a00336 +:101c2000d880828f1800c2af1800c28f0000428c8b +:101c30001400c2af1800c28f1400c48f0800458c76 +:101c40004c45400f000000001000c2af1800c28fca +:101c50000c0043941000c28f211043001000c2af4b +:101c60001400c28f1000c48f0000458c213000008a +:101c7000b05b400f000000000500401400000000b1 +:101c8000090002241c00c2af030000100000000085 +:101c9000dc8080a31c00c0af1c00c28f21e8c00301 +:101ca0002400bf8f2000be8f2800bd270800e0035e +:101cb00000000000f8ffbd270000beaf21f0a00328 +:101cc0000800c4af4c8280a30800c28f0800c38ff5 +:101cd0001000448c1400628c261082000100422cfb +:101ce00021e8c0030000be8f0800bd270800e00304 +:101cf00000000000c0ffbd273c00bfaf3800beaff2 +:101d000021f0a0034000c4af4400c5af4800c6aff7 +:101d10004c00c7af4400c38f4800c28f02106270ee +:101d20001000c2af4000c28f1400c2af2800c0af85 +:101d30002c00c0a74c8280a34c00c28f0000428cb4 +:101d40001800c2af4c00c28f0e0042942400c2a7fc +:101d50004c00c28f1000428c1c00c2af4c00c28fde +:101d60001800428c4000427c060040140000000035 +:101d70001e0002244c8282a33000c0afa1000010dc +:101d800000000000dc8082930a0040100000000088 +:101d90000447400f00000000060040100000000053 +:101da000090002244c8282a33000c0af95000010cd +:101db00000000000d880838f4c00c28f2300621087 +:101dc000000000002400c397000202241f006210dc +:101dd000000000004c00c28fd88082af4c00c28f40 +:101de0001800c48f0800458c4c45400f00000000cf +:101df0002000c2af4c00c28f0c0043942000c28f61 +:101e0000211043002000c2afde8080a31800c28fe3 +:101e10002000c48f0000458c285b400f00000000ac +:101e20000800401400000000080002244c8282a335 +:101e3000080002242800c2af3000c0af71000010bb +:101e4000000000002000c28f188082af1000c28ff7 +:101e500060004010000000004c00c28f1400438c52 +:101e60001c00c28f07006214000000003d00022425 +:101e70004c8282a33d0002242800c2af550000100e +:101e8000000000002400c3970002022439006214fd +:101e9000000000002400c0a74c00c38f4c00c28f7c +:101ea0000c004294010042240c0062a44c00c38f39 +:101eb0001800c28f1f0042900c006394ffff423055 +:101ec0000f006214000000004c00c28f0c0040a400 +:101ed0004c00c48f01000524aa33400f000000000d +:101ee0002800c2af2800c28f05004010000000008b +:101ef0000f0002244c8282a3360000100000000074 +:101f00004c00c28f1800c48f0800458c4c45400f10 +:101f1000000000002000c2af4c00c28f0c004394b0 +:101f20002000c28f211043002000c2af4c00c28f9e +:101f3000d88082afde8080a31800c28f2000c48fbb +:101f40000000458c285b400f000000000700401493 +:101f500000000000080002244c8282a30800022432 +:101f60002800c2af1b000010000000002000c28f3c +:101f7000188082af1400c58f1800c48f2400c39747 +:101f8000010062242400c2a7ffff63300000828c9e +:101f900021106200000042900000a2a01400c28f35 +:101fa000010042241400c2af1c00c28f0100422471 +:101fb0001c00c2af2c00c297010042242c00c2a713 +:101fc0001000c28fffff42241000c2af9fff00101d +:101fd000000000004c00c38f2400c2970e0062a4d2 +:101fe0004c00c38f1c00c28f100062ac2c00c39742 +:101ff0004400c28f1b006200f40140001210000078 +:102000003000c2af3000c28f21e8c0033c00bf8f58 +:102010003800be8f4000bd270800e003000000002c +:10202000c0ffbd273800bfaf3400beaf3000b0af37 +:1020300021f0a0034000c4af4400c5af2110c00090 +:102040004800c2a32800c0a32800c2930b00422c62 +:102050000b004010000000002800c3934400c28f12 +:102060002118620020000224000062a02800c29310 +:10207000010042242800c2a3f3ff0010000000006a +:102080004000c28f000043802e0002240500621031 +:10209000000000004000c28f000042800400401495 +:1020a000000000002c00c0af730000100000000012 +:1020b0004000c48f636a400f000000001400c2a7f4 +:1020c0001400c2970d00422c0800401000000000d0 +:1020d0001800c227212040004000c58ffb69400f37 +:1020e0000000000004000010000000002c00c0af41 +:1020f00061000010000000001800c2274800c393d0 +:1021000021204000212860003649400f00000000d7 +:1021100004004014000000002c00c0af5600001066 +:10212000000000001800c227212040002e000524d6 +:10213000256b400f000000001000c2af1000c28fde +:102140000f004010000000001000c28f000040a0ef +:102150001000c28f010042241000c2af1000c48fd3 +:10216000636a400f000000000400422c0400401489 +:10217000000000002c00c0af3f0000100000000075 +:102180001800c22721204000636a400f00000000b1 +:102190000900422c04004014000000002c00c0afd5 +:1021a00035000010000000002800c0a32800d093d4 +:1021b0001800c22721204000636a400f0000000081 +:1021c0002b1002020e004010000000002800c393f4 +:1021d0004400c28f212062002800c3931000c22750 +:1021e0002110620008004290000082a02800c293e3 +:1021f000010042242800c2a3ecff001000000000f0 +:102200001000c28f1a004010000000001000c28fa2 +:102210000000428016004010000000002800c0a30b +:102220002800d0931000c48f636a400f00000000a4 +:102230002b1002020e004010000000002800c39383 +:102240004400c28f212062002800c3931000c28f77 +:102250002110620000004290080082a02800c29372 +:10226000010042242800c2a3edff0010000000007e +:10227000010002242c00c2af2c00c28f21e8c00351 +:102280003800bf8f3400be8f3000b08f4000bd27b4 +:102290000800e00300000000c8ffbd273400bfaf06 +:1022a0003000beaf21f0a0033800c4af2110a00061 +:1022b0003c00c2a33c00c2933800c48f21284000d8 +:1022c0003649400f000000000400401400000000e8 +:1022d0002800c0af79000010000000001000c0a36b +:1022e0001000c2930800422c1b00401000000000a8 +:1022f0001000c3933800c28f211062000000438099 +:102300002e00022414006210000000001000c3938d +:102310003800c28f21106200000042800e00401081 +:10232000000000001000c3931000c22721206200ab +:102330001000c3933800c28f211062000000429049 +:10234000080082a01000c293010042241000c2a322 +:10235000e3ff0010000000001000c2931100c2a3b0 +:102360001000c2930800422c0b0040100000000037 +:102370001000c393010062241000c2a3ff00633069 +:102380001000c2272118620020000224080062a069 +:10239000f3ff0010000000001100c3933800c28f4b +:1023a00021106200000043802e0002241a006214f3 +:1023b000000000001100c293010042241100c2a3da +:1023c0001100c3933800c28f2110620000004280c8 +:1023d00011004010000000001000c39301006224af +:1023e0001000c2a3ff0063301000c227212062004a +:1023f0001100c393010062241100c2a3ff006330e7 +:102400003800c28f2110620000004290080082a0b4 +:10241000ebff0010000000001000c2930b00422ce4 +:102420000b004010000000001000c3930100622464 +:102430001000c2a3ff0063301000c2272118620001 +:1024400020000224080062a0f3ff0010000000003a +:102450002300c0a31800c3832000022403006214d9 +:10246000000000005f0002241800c2a31000c0a3f7 +:102470001000c2930c00422c0e004010000000001f +:102480001000c3933800c28f212062001000c39354 +:102490001000c2272110620008004290000082a0b4 +:1024a0001000c293010042241000c2a3f0ff0010ec +:1024b00000000000010002242800c2af2800c28fe3 +:1024c00021e8c0033400bf8f3000be8f3800bd2725 +:1024d0000800e00300000000d8ffbd272400bfafc4 +:1024e0002000beaf21f0a0032800c4af2110a0003f +:1024f0002c00c2a31800c0a32800c48f636a400f39 +:10250000000000001000c2af1400c0af1400c28f62 +:102510001000c38f2a104300b500401000000000d7 +:102520001400c38f2800c28f211062000000428077 +:102530002100422808004010000000001400c38f52 +:102540002800c28f21106200000043800500022491 +:1025500069006214000000001400c38f2800c28fbd +:1025600021106200000043802200022462006210f9 +:10257000000000001400c38f2800c28f21106200e9 +:10258000000043802b0002245b006210000000006a +:102590001400c38f2800c28f211062000000438006 +:1025a0002c00022454006210000000001400c38fad +:1025b0002800c28f21106200000043802f000224f7 +:1025c0004d006210000000001400c38f2800c28f6d +:1025d00021106200000043803a000224460062108d +:1025e000000000001400c38f2800c28f2110620079 +:1025f000000043803b0002243f0062100000000006 +:102600001400c38f2800c28f211062000000438095 +:102610003c00022438006210000000001400c38f48 +:102620002800c28f21106200000043803d00022478 +:1026300031006210000000001400c38f2800c28f18 +:1026400021106200000043803e0002242a00621034 +:10265000000000001400c38f2800c28f2110620008 +:10266000000043805b000224230062100000000091 +:102670001400c38f2800c28f211062000000438025 +:102680005c0002241c006210000000001400c38fd4 +:102690002800c28f21106200000043805d000224e8 +:1026a00015006210000000001400c38f2800c28fc4 +:1026b00021106200000043807c0002240e006210a2 +:1026c000000000001400c38f2800c28f2110620098 +:1026d000000043802e0002240a0062140000000063 +:1026e0001800c393010002240300621000000000e0 +:1026f00004000010000000001c00c0af3e000010ed +:10270000000000002c00c2931400401400000000e0 +:102710001400c38f2800c28f211062000000438084 +:102720002a0002240a006210000000001400c38f77 +:102730002800c28f21106200000043803f00022465 +:102740000300621000000000040000100000000000 +:102750001c00c0af28000010000000001400c38f50 +:102760002800c28f21106200000043802e00022446 +:102770000300621400000000010002241800c2a33c +:102780001400c38f2800c28f211062000000428015 +:102790006100422811004014000000001400c38fa3 +:1027a0002800c28f21106200000042807b00422876 +:1027b0000a004010000000001400c38f2800c28fe0 +:1027c000212062001400c38f2800c28f21106200f4 +:1027d00000004290e0ff4224000082a01400c28f5b +:1027e000010042241400c2af48ff001000000000a6 +:1027f000010002241c00c2af1c00c28f21e8c003ec +:102800002400bf8f2000be8f2800bd270800e003f2 +:1028100000000000c8ffbd273400bfaf3000beafce +:1028200021f0a0033800c4af3c00c5af4000c6afe4 +:102830003c00c28f2000c2af3800c28f0000428c23 +:102840001800c2af4000c28f2800c2af01000224ae +:102850002800c38f0700621000000000020002245d +:102860002800c38f0a006210000000000d00001055 +:10287000000000003800c28f2000c38f1000428c7f +:10288000211062002000c2af06000010000000000e +:102890003800c28f1400438c2000c28f23106200c6 +:1028a0002000c2afdc8082930b00401000000000cb +:1028b0000447400f00000000070040100000000027 +:1028c000090002244c8282a3ffff02242400c2af2d +:1028d000b4000010000000003800c28f0400428cd9 +:1028e0001400c2af3800c38f1400c28f080062ac5e +:1028f0003800c28f1400428c1400c2af2000c38f76 +:102900001400c28f2b10430007004010000000008d +:102910001f0002244c8282a3ffff03242400c3afc4 +:10292000a0000010000000003800c48f1800838c45 +:10293000fbff022424106200180082ac3800c38f11 +:102940002000c28f100062ac2000c28f2c00c2afea +:102950002c00c28f04004104000000002c00c38f33 +:10296000ff0163242c00c3af2c00c38f431203006c +:102970001000c2af1000c28f401a02002000c28fa8 +:10298000231043002000c2af3800c38f2000c28f45 +:102990000e0062a41800c28f1f0043901000c28f67 +:1029a0001b004300f4016000121000001400c2afcd +:1029b0001800c28f1f0043901400c28f021862706b +:1029c0001000c28f231043001000c2af3800c38f25 +:1029d0001000c28f0c0062a41400c28f510040107e +:1029e000000000003800c48f1400c58faa33400fc8 +:1029f000000000001c00c2a31c00c293490040104c +:102a0000000000001c00c3933c0002243f0062143d +:102a1000000000003800c28f1800428c0000427c89 +:102a20001c004010000000003800c38f3800c28f27 +:102a30000400428c080062ac1400c38f0100022421 +:102a400008006210000000001400c28fffff422443 +:102a50003800c48f21284000aa33400f0000000036 +:102a60001c00c2a33800c48f21280000443e400f40 +:102a7000000000002b004010000000000f000224a6 +:102a80004c8282a3ffff02242400c2af4500001045 +:102a9000000000003800c38f3800c28f0400428c51 +:102aa000080062ac1400c28fffff42243800c48fbc +:102ab00021284000aa33400f000000001c00c2a3e0 +:102ac0001c00c29307004010000000000f00022409 +:102ad0004c8282a3ffff03242400c3af3100001007 +:102ae000000000003800c38f000202240e0062a420 +:102af0003800c38f1800c28f1f004290ffff42248e +:102b00000c0062a407000010000000000f00022467 +:102b10004c8282a3ffff02242400c2af21000010d8 +:102b2000000000003800c28f1800c48f0800458cd8 +:102b30004c45400f000000001400c2af3800c28fa7 +:102b40000c0042941000c2af1400c38f1000c28f5b +:102b5000211062001400c2afd88080afde8080a355 +:102b60001800c28f1400c48f0000458c285b400ff2 +:102b70000000000007004014000000001b000224b9 +:102b80004c8282a3ffff03242400c3af0500001082 +:102b9000000000001400c28f188082af4c8280a316 +:102ba0002400c0af2400c28f21e8c0033400bf8fcf +:102bb0003000be8f3800bd270800e0030000000091 +:102bc000c0ffbd273c00bfaf3800beaf21f0a0035f +:102bd0004000c4af4400c5afde8080a34000c28f78 +:102be000200042903000c2af010002243000c38fa9 +:102bf0001200621000000000030002243000c38fa6 +:102c000003006210000000001d0000100000000022 +:102c10004400c28f801002001400c2afff0f023cbc +:102c2000ffff42342400c2afff0f023cf8ff4234e2 +:102c30002800c2af19000010000000004400c38f3c +:102c40002110600040100200211043001400c2afa8 +:102c50001400c28f010042301000c2a31400c28fc2 +:102c6000421002001400c2afffff02342400c2afc2 +:102c7000f80f02242800c2af080000100000000076 +:102c80004400c28f401002001400c2afffff0234a4 +:102c90002400c2aff8ff02342800c2af4000c48f46 +:102ca0001400c28f421a02000800828c21104300d7 +:102cb0001800c2af1400c28fff0142301400c2af2f +:102cc0001480838f1800c28f6c0062140000000013 +:102cd0004000c28f200043900300022409006214c8 +:102ce000000000001400c38f00a0023c500f4224db +:102cf000211062000000428c1c00c2afc200001014 +:102d0000000000004000c28f200043900200022417 +:102d100009006214000000001400c38f00a0023cf0 +:102d2000500f422421106200000042941c00c2afe8 +:102d3000b5000010000000004000c28f200043904a +:102d400001000224b0006214000000001400c38fd0 +:102d500000a0023c500f422421106200000042906b +:102d60001c00c2af1000c29304004010000000001d +:102d70001c00c28f021102001c00c2af1400c28fdf +:102d800001004224ff0142301400c2af1400c28f80 +:102d90002200401400000000d48082930d004010f7 +:102da000000000004000c48f2128000021300000f6 +:102db00001000724124c400f0000000005004010e5 +:102dc000000000002400c28f2c00c2af970000104a +:102dd000000000001800c28f0100422421204000a2 +:102de00000a0023c500f4524285b400f000000006b +:102df0000700401400000000ffff0234148082af7f +:102e00002400c28f2c00c2af880000100000000018 +:102e10001800c28f01004224148082af1400c38fb7 +:102e200000a0023c500f422421106200000042909a +:102e30002000c2af1000c293080040100000000044 +:102e40002000c28f001902001c00c28f2110430015 +:102e50001c00c2af6c000010000000002000c28ff8 +:102e60000f004230001a02001c00c28f21104300e4 +:102e70001c00c2af6400001000000000d4808293e8 +:102e80000d004010000000004000c48f2128000009 +:102e90002130000001000724124c400f0000000008 +:102ea00005004010000000002400c28f2c00c2afbb +:102eb0005e000010000000001800c48f00a0023c5b +:102ec000500f4524285b400f00000000070040140d +:102ed00000000000ffff0234148082af2400c28f84 +:102ee0002c00c2af51000010000000001800c28f7b +:102ef000148082af4000c28f200043900300022460 +:102f000009006214000000001400c38f00a0023cfe +:102f1000500f4224211062000000428c1c00c2affe +:102f200039000010000000004000c28f20004390d4 +:102f30000200022409006214000000001400c38f84 +:102f400000a0023c500f4224211062000000429475 +:102f50001c00c2af2c000010000000004000c28f17 +:102f600020004390010002242700621400000000aa +:102f70001400c38f00a0023c500f422421106200b5 +:102f8000000042901c00c2af1000c2930400401029 +:102f9000000000001c00c28f021102001c00c2af22 +:102fa0001400c28f01004224ff0142301400c2af5e +:102fb0001400c38f00a0023c500f42242110620075 +:102fc000000042902000c2af1000c29308004010e1 +:102fd000000000002000c28f001902001c00c28ff8 +:102fe000211043001c00c2af0700001000000000c9 +:102ff0002000c28f0f004230001a02001c00c28f56 +:10300000211043001c00c2af1c00c28f2800c38fd8 +:103010002b10430003004014000000002800c28f62 +:103020001c00c2af1c00c28f2c00c2af2c00c28f8c +:1030300021e8c0033c00bf8f3800be8f4000bd2791 +:103040000800e00300000000c8ffbd273400bfaf48 +:103050003000beaf21f0a0033800c4af3c00c5afc4 +:103060004000c6af2110e0004400c2a33800c28f68 +:1030700020004390030002241000621000000000b2 +:103080003800c28f20004390020002240b0062101f +:10309000000000003800c28f20004390010002248d +:1030a0000600621000000000ff0f023cffff4234e8 +:1030b0002400c2af41010010000000003800c28fa0 +:1030c000200042902800c2af2800c38f0100622870 +:1030d00012004014000000002800c38f0300622883 +:1030e0000c00401400000000030002242800c38fdd +:1030f0000300621000000000080000100000000043 +:10310000ff0f023cffff42342000c2af030000105b +:1031100000000000ffff02342000c2afde8080a369 +:103120004400c29324004010000000001000c0a31f +:103130001480828f1800c2af3800c28f1e004390e7 +:103140001000c2932b104300170040100000000035 +:103150001480848f00a0023c500f452421300000d1 +:10316000b05b400f000000000500401400000000ac +:103170002000c28f2400c2af100100100000000028 +:103180001000c293010042241000c2a33800c28f75 +:103190001c0043941800c28f211043001800c2afd6 +:1031a000e5ff001000000000d48080a32400c0af21 +:1031b00002010010000000003800c28f2000429081 +:1031c0002c00c2af010002242c00c38f0c0062103f +:1031d00000000000030002242c00c38f03006210d3 +:1031e0000000000013000010000000003c00c28f2f +:1031f000801002001400c2af110000100000000097 +:103200003c00c38f211060004010020021104300d9 +:103210001400c2af1400c28f010042301100c2a3db +:103220001400c28f421002001400c2af040000104c +:10323000000000003c00c28f401002001400c2af2a +:103240003800c48f1400c28f421a02000800828c1a +:10325000211043001c00c2af1400c28fff01423096 +:103260001400c2af1480838f1c00c28f3300621021 +:1032700000000000d4808293210040100000000074 +:103280001000c0a31480828f1800c2af3800c28f14 +:103290001e0043901000c2932b10430017004010f3 +:1032a000000000001480848f00a0023c500f4524d1 +:1032b00021300000b05b400f00000000050040140a +:1032c000000000002000c28f2400c2afbb0000102d +:1032d000000000001000c293010042241000c2a3ad +:1032e0003800c28f1c0043941800c28f2110430085 +:1032f0001800c2afe5ff001000000000d48080a3da +:103300001c00c48f00a0023c500f4524285b400fd6 +:10331000000000000700401400000000ffff02341e +:10332000148082af2000c28f2400c2afa30000101f +:10333000000000001c00c28f148082af3800c28fd2 +:1033400020004390030002242300621400000000c8 +:103350001400c38f00a0023c500f422421186200c9 +:103360004000c28f000062a01400c38f00a0023c86 +:10337000510f4224211862004000c28f00ff4230ea +:1033800002120200000062a01400c38f00a0023ce1 +:10339000520f4224212062004000c38fff00023cf4 +:1033a0002410620002140200000082a01400c38fe7 +:1033b00000a0023c530f4224212062004000c38f32 +:1033c000000f023c2410620002160200000082a0de +:1033d00077000010000000003800c28f20004390ea +:1033e0000200022411006214000000001400c38fc8 +:1033f00000a0023c500f4224211862004000c28ffe +:10340000000062a01400c38f00a0023c510f4224b0 +:10341000211862004000c28f00ff423002120200f9 +:10342000000062a062000010000000003800c28f9f +:1034300020004390010002245d006214000000009f +:103440001400c38f00a0023c500f422421106200e0 +:10345000000042901200c2a31100c2930a00401063 +:10346000000000004000c28f0f004230001902002f +:103470001200c2930f004230251062001200c2a356 +:1034800003000010000000004000c28f1200c2a321 +:103490001400c38f00a0023c500f42242118620088 +:1034a0001200c293000062a01400c28f01004224e7 +:1034b000ff0142301400c2af1400c28f1f0040143d +:1034c000000000003800c48f2128000021300000d7 +:1034d00001000724124c400f0000000005004010be +:1034e000000000002000c28f2400c2af3300001093 +:1034f000000000001c00c28f010042242120400077 +:1035000000a0023c500f4524285b400f0000000043 +:103510000700401400000000ffff0234148082af57 +:103520002000c28f2400c2af240000100000000061 +:103530001c00c28f01004224148082af1400c38f8c +:1035400000a0023c500f4224211062000000429073 +:103550001200c2a31100c293060040100000000038 +:103560004000c28f021102001200c2a30a00001024 +:10357000000000004000c28f021202000f00443021 +:103580001200c393f0ff022424106200211880006f +:10359000251062001200c2a31400c38f00a0023cd9 +:1035a000500f4224211862001200c293000062a052 +:1035b00001000224d48082a32400c0af2400c28f63 +:1035c00021e8c0033400bf8f3000be8f3800bd2714 +:1035d0000800e00300000000e8ffbd271400bfafb3 +:1035e0001000beaf21f0a0031800c4af21200000de +:1035f0001800c58f21300000864d400f00000000ec +:1036000021e8c0031400bf8f1000be8f1800bd2733 +:103610000800e0030000000070ffbd278800bfaf76 +:103620008400beaf8000b0af21f0a0032110800065 +:103630009400c5af9800c6af9000c2a30100022459 +:103640001200c2a79400c28f1800c2af2000c22788 +:103650007000c2af7000c48f1c80858f2c44400f57 +:10366000000000004c8280a31800c28f000042902e +:103670001000c2a31000c293070040140000000015 +:103680001f0002244c8282a3ffff02247400c2aff9 +:10369000c4010010000000001000c3937800c3af05 +:1036a0002e0002247800c38f070062100000000083 +:1036b0005c0002247800c38fc1006210000000008b +:1036c00007010010000000001800c28f0100422412 +:1036d0001800c2af1800c28f000042901000c2a3b1 +:1036e0001000c3932e0002248b006214000000001f +:1036f0001800c28f010042241800c2af1800c28f08 +:10370000000042901000c2a37000c28f3400438cae +:103710003c82828f07006214000000001f00022418 +:103720004c8282a3ffff02247400c2af9d010010ef +:10373000000000007000c38f7000c28f3400428c04 +:10374000380062ac010002241200c2a71200c22796 +:103750007000c48f2128400001000624a63b400fc2 +:10376000000000001400c2af1400c28f0700401414 +:10377000000000001b0002244c8282a3ffff0324f0 +:103780007400c3af87010010000000007000d08fec +:103790001400c48f0736400f00000000340002ae52 +:1037a0007000c38f7000c28f3400428c380062ac4e +:1037b0007000c28f3400428c1c00401400000000d6 +:1037c0007000c28f5c000324200043a0010002248b +:1037d0001100c2a31100c2930b00422c0b00401039 +:1037e000000000007000c38f1100c2932118620016 +:1037f00020000224200062a01100c2930100422494 +:103800001100c2a3f3ff0010000000007000c38f7e +:103810003c82828f380062ac7000c38f3c82828f02 +:10382000340062ac17000010000000007000c38f6d +:103830002e000224200062a07000c38f2e000224fc +:10384000210062a0020002241100c2a31100c29351 +:103850000b00422c0b004010000000007000c38fd2 +:103860001100c2932118620020000224200062a0ef +:103870001100c293010042241100c2a3f3ff001003 +:10388000000000001200c0a71200c2277000c48f01 +:103890002128400001000624a63b400f0000000044 +:1038a00007004014000000001b0002244c8282a389 +:1038b000ffff02247400c2af3a01001000000000b4 +:1038c0001000c3935c000224090062140000000091 +:1038d0001800c28f010042241800c2af1800c28f26 +:1038e000000042901000c2a3f5ff0010000000008d +:1038f0001000c29368ff4014000000001c80848ff9 +:103900007000c58f2c44400f000000007400c0af51 +:1039100024010010000000001000c29308004014b1 +:10392000000000001c80848f7000c58f2c44400f65 +:10393000000000007400c0af1a0100100000000079 +:103940001000c3935c000224170062140000000002 +:103950001000c3935c000224090062140000000000 +:103960001800c28f010042241800c2af1800c28f95 +:10397000000042901000c2a3f5ff001000000000fc +:103980001000c29344ff4014000000001c80848f8c +:103990007000c58f2c44400f000000007400c0afc1 +:1039a00000010010000000001f0002244c8282a3ce +:1039b000ffff03247400c3affa00001000000000f2 +:1039c0001800c28f010042241800c2af1800c28f35 +:1039d000000042901000c2a31000c3935c000224b8 +:1039e00007006214000000001f0002244c8282a322 +:1039f000ffff02247400c2afea00001000000000c4 +:103a00001000c2931d004014000000001c80838f32 +:103a10003c82828f340062ac1c80838f3c82828f18 +:103a2000380062ac1c80838f5c000224200062a0fe +:103a3000010002241100c2a31100c2930b00422c0a +:103a40000b004010000000001c80838f1100c29307 +:103a50002118620020000224200062a01100c293fd +:103a6000010042241100c2a3f3ff00100000000077 +:103a70007400c0afcb000010000000007000c38fc6 +:103a80003c82828f340062ac7000c38f3c82828f94 +:103a9000380062ac7000c38f5c000224200062a07a +:103aa000010002241100c2a31100c2930b00422c9a +:103ab000f9fe4010000000007000c38f1100c29397 +:103ac0002118620020000224200062a01100c2938d +:103ad000010042241100c2a3f3ff00100000000007 +:103ae0001100c0a31000c293190040100000000094 +:103af0001000c3935c000224150062100000000057 +:103b00001100c2930c00422c110040100000000074 +:103b100000a0043c1100c393010062241100c2a361 +:103b2000ff006330040f8224211862001000c2934a +:103b3000000062a01800c28f010042241800c2af2a +:103b4000000042901000c2a3e6ff00100000000039 +:103b50001100c3930c0002240f0062140000000047 +:103b60001000c2930c004010000000001000c3932e +:103b70005c00022408006210000000001800c28fe0 +:103b8000010042241800c2af000042901000c2a3fe +:103b9000f3ff00100000000000a0023c1100c393de +:103ba000040f422421106200000040a000a0023c4b +:103bb000040f442421280000a648400f0000000004 +:103bc0000500401400000000ffff03247400c3af91 +:103bd00074000010000000001100c0a31100c29387 +:103be0000b00422c17004010000000001100c3938e +:103bf0001000c227212062007000c38f1100c29301 +:103c00002110620020004290500082a07000c38ffb +:103c10001100c2932120620000a0023c1100c39356 +:103c2000040f42242110620000004290200082a074 +:103c30001100c293010042241100c2a3e7ff00104b +:103c40000000000000a0023c281244247000c58f30 +:103c50002c44400f0000000000a0023c2812442425 +:103c60007000c58f0100062421380000fc31400f90 +:103c70000000000007004010000000000c000224bb +:103c80004c8282a3ffff02247400c2af45000010e3 +:103c90000000000000a0023c28124224300043949f +:103ca0001000022407006210000000001f00022420 +:103cb0004c8282a3ffff03247400c3af39000010bd +:103cc000000000001100c0a31100c2930b00422ca1 +:103cd0000f004010000000007000c38f1100c2935d +:103ce0002120620000a0023c1100c393281242244c +:103cf0002110620020004290200082a01100c29397 +:103d0000010042241100c2a3efff001000000000d8 +:103d10007000c38f00a0023c281242240400428c91 +:103d2000340062ac7000c38f7000c28f3400428ccc +:103d3000380062ac1000c29308004014000000007c +:103d40001c80848f7000c58f2c44400f0000000041 +:103d50007400c0af13000010000000001000c393f7 +:103d60005c0002244cfe6214000000001800c28fa8 +:103d7000010042241800c2af1800c28f0000429018 +:103d80001000c2a31000c293f4ff40140000000012 +:103d90001c80848f7000c58f2c44400f00000000f1 +:103da0007400c0af7400c28f21e8c0038800bf8fc9 +:103db0008400be8f8000b08f9000bd270800e00314 +:103dc00000000000b0ffbd274c00bfaf4800beaff1 +:103dd00021f0a0035000c4af5400c5af5000c28f03 +:103de00005004010000000005400c28f4000c2a334 +:103df00003000010000000000a0002244000c2a3db +:103e00004000c2931000c2a300a0023c281242242a +:103e10001c00c2af2000c0a33000c0af4c8280a302 +:103e20005000c28f060040140000000000a0023cb9 +:103e3000641242241400c2af0b0000100000000006 +:103e40005000c28f1400c2af5400c28f060040144d +:103e5000000000001f0002244c8282a33c00c0af7f +:103e6000b3010010000000001000c3831400c28fd3 +:103e700021106200ffff42241800c2af1c00c48f53 +:103e80001c80858f2c44400f000000001c00c28f56 +:103e9000200043802e0002249600621400000000df +:103ea0001c00c28f210043802e0002249100621466 +:103eb000000000001c00c28f3400428c2400c2affe +:103ec000010002242800c2a71c00c38f1c00c28f5f +:103ed0003400428c380062ac2800c2271c00c48f1a +:103ee0002128400001000624a63b400f00000000ee +:103ef0003800c2af3800c28f060040140000000036 +:103f00001b0002244c8282a33c00c0af8801001039 +:103f1000000000003800c48f0736400f000000008a +:103f2000448282af4482828f060040140000000069 +:103f30001c00c38f3c82828f340062ac04000010ee +:103f4000000000001c00c38f4482828f340062acea +:103f50001c00c38f1c00c28f3400428c380062ac3e +:103f60002800c0a72800c2271c00c48f21284000b9 +:103f700001000624a63b400f000000003800c2af3d +:103f80003800c28f06004014000000001b0002240d +:103f90004c8282a33c00c0af65010010000000000d +:103fa0003800c48f0736400f00000000448282af03 +:103fb0004482838f2400c28f160062140000000028 +:103fc0004482838f2400c28f2a0062140000000004 +:103fd0003800c28f00004390e50002240d006210fb +:103fe000000000003800c28f0b004390080002243c +:103ff00008006210000000003800c28f0b004390e0 +:104000000f000224030062100000000019000010dd +:10401000000000002800c297010042242800c2a727 +:104020002800c2271c00c48f212840002130000036 +:10403000a63b400f000000003800c2af3800c28f1e +:1040400006004014000000001b0002244c8282a3e2 +:104050003c00c0af36010010000000003800c48fe3 +:104060000736400f00000000448282afd0ff0010ee +:10407000000000002c00c0af2c00c28f0b004228b3 +:1040800016004010000000001c00c38f2c00c28fdf +:10409000212062003800c38f2c00c28f21106200e3 +:1040a00000004290200082a01c80838f2c00c28fd1 +:1040b000212062003800c38f2c00c28f21106200c3 +:1040c00000004290200082a02c00c28f01004224f8 +:1040d0002c00c2afe8ff0010000000001c00c38fde +:1040e0002400c28f340062ac1c00c38f2400c28f36 +:1040f000380062ac1c00c28f200043805c000224a8 +:104100000a006214000000001400c38f5c00022447 +:10411000000062a01400c28f010040a01400c28ff2 +:104120003c00c2af02010010000000001c00c28f62 +:104130003400438c3c82828f8400621000000000b7 +:104140000a0002242100c2a31c00c38f2100c283e5 +:104150002110620020004380200002240600621427 +:10416000000000002100c293ffff42242100c2a3ef +:10417000f5ff0010000000002100c2830800422863 +:104180002d004014000000002100c28308004228d6 +:1041900019004014000000003000c6270000c48c45 +:1041a000211880001400c28f213862001c00c58fc6 +:1041b0002100c393ffff62242100c2a32014037ccb +:1041c0002110a200200042900000e2a001008424ff +:1041d0000000c4ac1000c3833000c28feaff621439 +:1041e000000000003000c0af010002242000c2a384 +:1041f000e5ff0010000000003000c5270000a38c80 +:10420000212060001400c28f212082002e00022491 +:10421000000082a0010063240000a3ac1000c3834f +:104220003000c28f04006214000000003000c0aff4 +:10423000010002242000c2a31c00c38f2100c283fe +:104240002110620020004380200002240600621436 +:10425000000000002100c293ffff42242100c2a3fe +:10426000f5ff0010000000002100c2831900400487 +:10427000000000003000c6270000c48c2118800018 +:104280001400c28f213862001c00c58f2100c39327 +:10429000ffff62242100c2a32014037c2110a2008e +:1042a000200042900000e2a0010084240000c4ac81 +:1042b0001000c3833000c28febff621400000000c7 +:1042c0003000c0af010002242000c2a3e6ff0010ae +:1042d000000000003000c5270000a38c21206000f2 +:1042e0001400c28f212082005c000224000082a002 +:1042f000010063240000a3ac1000c3833000c28f10 +:1043000004006214000000003000c0af010002246d +:104310002000c2a31c00c38f1c00c28f3400428c3b +:10432000380062ac1c00c48f5351400f00000000e5 +:104330007eff401000000000080002244c8282a38f +:104340003c00c0af7a000010000000003000c28fb7 +:10435000ffff42243000c2af2c00c0af2000c29348 +:104360004c004010000000003000c28f2a00c2a79d +:104370003000c28f2c00c38f231043001b00401855 +:10438000000000002c00c38f1400c28f21106200b7 +:10439000000042903400c2a32c00c38f1400c28fcf +:1043a000212062003000c38f1400c28f21106200f0 +:1043b00000004290000082a03000c38f1400c28f22 +:1043c000211862003400c293000062a03000c28f46 +:1043d000ffff42243000c2af2c00c28f01004224f4 +:1043e0002c00c2afe2ff0010000000002a00c297bc +:1043f000010042242c00c2af1800c38f1400c28fea +:10440000231062003000c2af3000c28f2c00c38f77 +:10441000231043001b004018000000002c00c38f35 +:104420001400c28f21106200000042903400c2a329 +:104430002c00c38f1400c28f212062003000c38f74 +:104440001400c28f2110620000004290000082a080 +:104450003000c38f1400c28f211862003400c29351 +:10446000000062a03000c28fffff42243000c2afc4 +:104470002c00c28f010042242c00c2afe2ff0010ca +:10448000000000001800c28f000040a026000010ad +:10449000000000003000c28f2a00c2a73000c28f87 +:1044a0002c00c38f231043001b00401800000000a5 +:1044b0002c00c38f1400c28f2110620000004290b4 +:1044c0003400c2a32c00c38f1400c28f21206200cd +:1044d0003000c38f1400c28f211062000000429090 +:1044e000000082a03000c38f1400c28f2118620028 +:1044f0003400c293000062a03000c28fffff42244c +:104500003000c2af2c00c28f010042242c00c2af89 +:10451000e2ff0010000000002a00c2971400c38fc1 +:1045200021104300010040a01400c28f3c00c2af24 +:104530003c00c28f21e8c0034c00bf8f4800be8ff3 +:104540005000bd270800e00300000000d8ffbd2791 +:104550002400bfaf2000beaf21f0a0032800c4afed +:10456000010002241200c2a71200c2272800c48f33 +:104570002128400001000624a63b400f0000000057 +:104580001800c2af1800c28f0500401400000000e0 +:10459000ff0002241c00c2afa700001000000000b2 +:1045a0001800c48f0736400f00000000448282af1d +:1045b0004482828f1b004014000000002800c38f3b +:1045c0005c000224200062a01000c0a31000c2936f +:1045d0000b00422c0b004010000000002800c38f8d +:1045e0001000c2932118620020000224200062a063 +:1045f0001000c293010042241000c2a3f3ff001078 +:10460000000000002800c38f3c82828f340062ac1f +:104610002800c38f3c82828f380062ac8500001076 +:10462000000000004482828f1400c2af2800c38fb4 +:104630004482828f340062ac2800c38f4482828f10 +:10464000380062ac1200c2272800c48f2128400025 +:1046500001000624a63b400f000000001800c2af76 +:104660001800c28f0500401400000000ff00022463 +:104670001c00c2af70000010000000001800c48fc2 +:104680000736400f00000000448282af4482828fd0 +:1046900006004014000000002800c38f3c82828f77 +:1046a000340062ac04000010000000002800c38f3a +:1046b0004482828f340062ac2800c38f2800c28fee +:1046c0003400428c380062ac1200c0a71200c2272e +:1046d0002800c48f2128400001000624a63b400f7b +:1046e000000000001800c2af1800c28f050040147f +:1046f00000000000ff0002241c00c2af4e000010aa +:10470000000000001800c48f0736400f00000000b2 +:10471000448282af4482838f1400c28f16006214d9 +:10472000000000004482838f1400c28f29006214ad +:10473000000000001800c28f00004390e500022432 +:104740000d006210000000001800c28f0b004390a3 +:104750000800022408006210000000001800c28f48 +:104760000b0043900f0002240300621000000000c1 +:1047700018000010000000001200c2272800c48f9b +:104780002128400021300000a63b400f000000001f +:104790001800c2af1800c28f0500401400000000ce +:1047a000ff0002241c00c2af230000100000000024 +:1047b0001200c297010042241200c2a71800c48f41 +:1047c0000736400f00000000448282afd1ff001086 +:1047d000000000001000c0a31000c2930b00422c88 +:1047e0000e004010000000002800c38f1000c2938c +:1047f000212062001800c38f1000c29321104300d3 +:1048000000004290200082a01000c29301004224c8 +:104810001000c2a3f0ff0010000000002800c38faa +:104820001400c28f340062ac2800c38f1400c28f02 +:10483000380062ac1c00c0af1c00c28f21e8c0036e +:104840002400bf8f2000be8f2800bd270800e00392 +:1048500000000000e8ffbd271400bfaf1000beaf8e +:1048600021f0a0031800c4af212000001800c58f5c +:10487000213000002552400f0000000021e8c00355 +:104880001400bf8f1000be8f1800bd270800e00382 +:1048900000000000c8ffbd273400bfaf3000beaf2e +:1048a00021f0a003211080003c00c5af4000c6af3e +:1048b0003800c2a33c00c28f1400c2af00a0023c6b +:1048c000140f42242800c2af4c8280a32a5c400f00 +:1048d0000000000007004010000000001800022443 +:1048e0004c8282a3ffff02242c00c2af9001001073 +:1048f000000000001000c0a31400c28f000042801e +:1049000013004010000000001400c28f000043801c +:104910002e0002240e006210000000001400c28f5e +:10492000000043805c0002240900621000000000c7 +:104930001400c28f010042241400c2af1000c293c1 +:10494000010042241000c2a3ebff00100000000091 +:104950001000c2930900422c070040140000000020 +:104960001f0002244c8282a3ffff02242c00c2af4e +:104970006f010010000000001400c28f000043808f +:104980002e00022420006214000000001400c28fd8 +:10499000010042241400c2af1000c0a31400c28f53 +:1049a000000042800e004010000000001400c28f82 +:1049b000000043805c000224090062100000000037 +:1049c0001400c28f010042241400c2af1000c29331 +:1049d000010042241000c2a3f0ff001000000000fc +:1049e0001000c2930400422c070040140000000095 +:1049f0001f0002244c8282a3ffff02242c00c2afbe +:104a00004b010010000000001400c28f0000438022 +:104a10005c00022406006214000000001400c28f33 +:104a2000010042241400c2aff7ff00100000000094 +:104a30001400c28f00004280aeff4014000000004e +:104a40003c00c28f1400c2af2800c48f1c80858f29 +:104a50002c44400f000000001400c28f0000429060 +:104a60001000c2a31000c3932e000224570062144a +:104a7000000000001400c28f010042241400c2afe5 +:104a80001400c28f000042901000c2a31000c39314 +:104a90002e0002240e006210000000001000c293dd +:104aa0000b004010000000001000c3935c000224c3 +:104ab00007006210000000001f0002244c8282a345 +:104ac000ffff02242c00c2af1901001000000000fb +:104ad0001000c3932e000224230062140000000083 +:104ae0001c80828f3400438c3c82828f07006214ca +:104af000000000001f0002244c8282a3ffff02245a +:104b00002c00c2af0a010010000000001400c28f88 +:104b1000010042241400c2af1400c28f0000429072 +:104b20001000c2a31000c3935c0002240a006210ac +:104b3000000000001000c2930700401000000000b9 +:104b40001f0002244c8282a3ffff02242c00c2af6c +:104b5000f700001000000000029d023cc003442446 +:104b6000764d400f000000001000c3935c0002244b +:104b700009006214000000001400c28f01004224ea +:104b80001400c2af1400c28f000042901000c2a3f4 +:104b9000f5ff0010000000001000c293aeff4014ab +:104ba000000000001c80848f2800c58f2c44400f1b +:104bb000000000001f0002244c8282a3ffff022499 +:104bc0002c00c2afda000010000000001000c393f8 +:104bd0005c0002243b006214000000001c80838ff4 +:104be0003c82828f340062ac1c80838f3c82828f37 +:104bf000380062ac1c80838f5c000224200062a01d +:104c0000010002241000c2a31000c2930b00422c2a +:104c10000b004010000000001c80838f1000c29326 +:104c20002118620020000224200062a01000c2931c +:104c3000010042241000c2a3f3ff00100000000096 +:104c40001400c28f010042241400c2af1400c28fae +:104c5000000042901000c2a31000c3935c00022425 +:104c60000b006214000000001c80848f2800c58f98 +:104c70002c44400f000000001f0002244c8282a33d +:104c8000ffff02242c00c2afa900001000000000aa +:104c90001000c29370ff4014000000001c80848f3d +:104ca0002800c58f2c44400f000000001f00022484 +:104cb0004c8282a3ffff02242c00c2af9c00001094 +:104cc000000000002400c0a31400c28f0000429026 +:104cd0001000c2a31100c0a31000c293190040101d +:104ce000000000001000c3935c0002241500621055 +:104cf000000000001100c2930c00422c1100401073 +:104d0000000000001100c393010062241100c2a33f +:104d1000ff0063301000c227211862001000c29308 +:104d2000080062a01400c28f010042241400c2af28 +:104d30001400c28f000042901000c2a3e6ff0010d2 +:104d4000000000001100c3931000c2272110620070 +:104d5000080040a01800c3832e0002242300621420 +:104d6000000000001900c2830f0040100000000086 +:104d70001900c3832e0002240b0062100000000003 +:104d80001c80848f2800c58f2c44400f0000000039 +:104d90001f0002244c8282a3ffff02242c00c2af1a +:104da00063000010000000001900c3832e000224dd +:104db0000e006214000000001a00c2830b004010b5 +:104dc000000000001c80848f2800c58f2c44400ff9 +:104dd000000000001f0002244c8282a3ffff022477 +:104de0002c00c2af52000010000000001800c227c3 +:104df00021204000764d400f0000000003004010cd +:104e00000000000017000010000000001000c39315 +:104e10005c00022409006214000000001400c28f2c +:104e2000010042241400c2af1400c28f000042905f +:104e30001000c2a3f5ff0010000000001000c29394 +:104e4000a1ff4014000000001c80848f2800c58f43 +:104e50002c44400f000000002c00c0af34000010b4 +:104e6000000000001800c22721204000d353400f4b +:104e70000000000009004014000000001c80848f26 +:104e80002800c58f2c44400f00000000ffff0224c3 +:104e90002c00c2af26000010000000001800c2273e +:104ea00021204000764d400f000000000b00401014 +:104eb000000000001c80848f2800c58f2c44400f08 +:104ec000000000001b0002244c8282a3ffff02248a +:104ed0002c00c2af16000010000000001400c28faa +:104ee000000043805c0002240900621400000000fe +:104ef0001400c28f010042241400c2af1400c28ffc +:104f0000000042901000c2a3f4ff00100000000057 +:104f10001000c2936cff4014000000001c80848fbe +:104f20002800c58f2c44400f000000002c00c0afab +:104f30002c00c28f21e8c0033400bf8f3000be8f29 +:104f40003800bd270800e00300000000c8ffbd27af +:104f50003400bfaf3000beaf21f0a0033800c4afb3 +:104f600000a0023c281242241000c2af1800c0a7c3 +:104f70002400c0a32400c2930c00422c0f00401058 +:104f80000000000000a0023c2400c393040f422450 +:104f9000212062002400c3933800c28f21106200d8 +:104fa00000004290000082a02400c293010042242d +:104fb0002400c2a3efff00100000000000a0023c8c +:104fc000040f442421280000a648400f00000000e0 +:104fd0000600401400000000120002244c8282a34c +:104fe0002800c0af6f000010000000002400c0a324 +:104ff0002400c2930b00422c0f0040100000000060 +:105000001000c38f2400c2932120620000a0023c44 +:105010002400c393040f4224211062000000429038 +:10502000200082a02400c293010042242400c2a3d5 +:10503000efff0010000000001000c38f1c80828f63 +:105040003400428c340062ac1000c38f1c80828f0d +:105050003800428c380062ac1000c28f040040acb3 +:105060001000c28f080040ac1000c38f1c80828fdc +:105070000000428c000062ac1800c2271000c48ff0 +:1050800021284000120006248c3c400f0000000044 +:1050900004004010000000002800c0af41000010d4 +:1050a00000000000d48082930f0040100000000038 +:1050b0001000c28f0000448c212800002130000025 +:1050c00001000724124c400f0000000006004010b1 +:1050d00000000000090002244c8282a32800c0af17 +:1050e00030000010000000001000c28f3400438c1c +:1050f0003c82828f04006214000000002000c0afd8 +:1051000004000010000000001000c28f3400428c28 +:105110002000c2af1000c38f1000c28f3400428c39 +:10512000380062ac1800c2271000c48f212840004c +:1051300001000624a63b400f000000001400c2af8f +:105140001400c28f06004014000000001b0002245f +:105150004c8282a32800c0af1200001000000000a3 +:105160001400c48f0736400f000000001c00c2afbf +:105170001000c28f0000448c1c00c58f2000c68f19 +:105180007054400f000000000500401000000000b7 +:10519000010002242800c2af02000010000000003d +:1051a0002800c0af2800c28f21e8c0033400bf8fa1 +:1051b0003000be8f3800bd270800e003000000006b +:1051c000b0ffbd274c00bfaf4800beaf21f0a00329 +:1051d0005000c4af5400c5af5800c6af1800c22776 +:1051e0003800c2afd88080af200002241200c2a7ce +:1051f0005000c28f0000448c2128000000020624c9 +:10520000d169400f000000002e0002241800c2a344 +:10521000010002241000c2a71000c2970b00422c0c +:105220000b004010000000001000c3971000c227c0 +:105230002118620020000224080062a01000c2971a +:10524000010042241000c2a7f3ff0010000000007c +:10525000100002242300c2a32400c0a35400c28f64 +:105260003200c2a75400c38fff0f023c241062001b +:10527000021402002c00c2a73400c0af3782829310 +:105280002500c2a3388282972600c2a74282829755 +:105290002800c2a72a00c0a72e00c0a73000c0a7c0 +:1052a0001000c0a71000c2971200c3972b10430034 +:1052b0000f004010000000005000c28f1000c39784 +:1052c0000000428c212062001000c3973800c28f7a +:1052d0002110620000004290000082a01000c297de +:1052e000010042241000c2a7eeff001000000000e1 +:1052f0002e0002241900c2a35800c28f3200c2a798 +:105300005800c38fff0f023c2410620002140200f9 +:105310002c00c2a71000c0a71000c2971200c397ac +:105320002b10430011004010000000005000c28ffd +:105330001000c4971200c3970000428c2110620035 +:10534000212044001000c3973800c28f2110620052 +:1053500000004290000082a01000c2970100422489 +:105360001000c2a7ecff0010000000005000c48f26 +:105370005400c58f4c45400f000000003c00c2aff8 +:105380005000c28f3c00c48f0000458c21300000cb +:10539000b05b400f00000000060040140000000059 +:1053a000090002244c8282a34000c0af0300001019 +:1053b00000000000010002244000c2af4000c28f84 +:1053c00021e8c0034c00bf8f4800be8f5000bd27ae +:1053d0000800e00300000000e8ffbd271400bfaf95 +:1053e0001000beaf21f0a0031800c4af2110a00030 +:1053f0001c00c2a31c00c293212000001800c58f0e +:1054000021300000213840000a55400f0000000004 +:1054100021e8c0031400bf8f1000be8f1800bd2705 +:105420000800e00300000000b8ffbd274400bfaf44 +:105430004000beaf21f0a003211880004c00c5af92 +:105440005000c6af2110e0004800c3a35400c2a31f +:1054500000a0023c140f42241000c2af00a0023c86 +:10546000281242241400c2af1c00c0a7029d023cb7 +:10547000c403448cc40343240400638cc403422447 +:105480000800428c2800c4af2c00c3af3000c2af6c +:105490003400c0a34c8280a31000c48f1c80858f71 +:1054a0002c44400f000000004c00c48f764d400f8c +:1054b0000000000007004010000000000c00022463 +:1054c0004c8282a3ffff02243800c2af800200108a +:1054d000000000001c80828f3400438c3c82828f4d +:1054e00009006210000000001c80828f1000c38f32 +:1054f0003400448c3400628c0300821000000000f1 +:105500000b000010000000001c80848f1000c58f6d +:105510002c44400f000000001f0002244c8282a394 +:10552000ffff02243800c2af690200100000000033 +:105530001c00c297010042241c00c2a71c00c22705 +:105540001c80848f2128400001000624a63b400fc8 +:10555000000000001800c2af1800c28f0b004014fa +:10556000000000001c80848f1000c58f2c44400f69 +:10557000000000001b0002244c8282a3ffff0224d3 +:105580003800c2af52020010000000001c00c29799 +:10559000010042241c00c2a71c00c2271c80848f6b +:1055a0002128400021300000a63b400f00000000f1 +:1055b0001800c2af1800c28f0b004014000000009a +:1055c0001c80848f1000c58f2c44400f0000000009 +:1055d0001b0002244c8282a3ffff02243800c2afca +:1055e0003b020010000000005400c2932b00401446 +:1055f000000000001800c28f00004280e801401047 +:10560000000000001800c28f00004390e500022453 +:105610000b006210000000001c80848f1000c58ffa +:105620002c44400f00000000160002244c8282a38c +:10563000ffff02243800c2af250200100000000066 +:105640001c00c297010042241c00c2a71c00c227f4 +:105650001c80848f2128400021300000a63b400f91 +:10566000000000001800c2af1800c28fe1ff401414 +:10567000000000001c80848f1000c58f2c44400f58 +:10568000000000001b0002244c8282a3ffff0224c2 +:105690003800c2af0e02001000000000488280a354 +:1056a0002000c0a748828293bd0140140000000082 +:1056b0001800c28f00004280ee0040100000000081 +:1056c0001800c28f00004390e5000224c100621060 +:1056d000000000001800c28f0b0043900800022455 +:1056e000bc006210000000001800c28f0b00439045 +:1056f0000f000224b7006210000000001800c28fe3 +:105700000b0042901000423070004010000000007a +:105710002000c297010042242000c2a72200c0a39b +:105720002200c2930800422c150040100000000027 +:105730001800c38f2200c293211043000000438051 +:10574000200002240e006210000000002200c3931b +:105750001000c227212062001800c38f2200c293cc +:105760002110430000004290180082a02200c29342 +:10577000010042242200c2a3e9ff00100000000043 +:105780001800c28f08004380200002242500621008 +:10579000000000002200c393010062242200c2a383 +:1057a000ff0063301000c227211862002e0002247f +:1057b000180062a02300c0a32300c2930300422c60 +:1057c00018004010000000001800c38f2300c2938f +:1057d00021106200080043802000022411006210a2 +:1057e000000000002200c393010062242200c2a333 +:1057f000ff0063301000c227212062001800c38f11 +:105800002300c2932110620008004290180082a079 +:105810002300c293010042242300c2a3e6ff00102c +:10582000000000002200c3931000c2272110620074 +:10583000180040a02800c22721204000764d400fcc +:10584000000000000b004010000000001c80848f4e +:105850001000c58f2c44400f000000000c000224f3 +:105860004c8282a3ffff02243800c2af98010010cf +:10587000000000001c80828f1000c38f3400448c15 +:105880003400628c0b008214000000001c80848fa6 +:105890001000c58f2c44400f000000001f000224a0 +:1058a0004c8282a3ffff02243800c2af880100109f +:1058b00000000000020002241c00c2a70100022414 +:1058c000df8082a346000010000000002800c227ed +:1058d00021204000212800000c000624d169400f3f +:1058e000000000002200c0a32200c2930b00422c43 +:1058f0000e004010000000001400c38f2200c2936d +:10590000212062001800c38f2200c293211043009f +:1059100000004290200082a02200c2930100422495 +:105920002200c2a3f0ff0010000000001400c38f8b +:1059300000a0023c04124224000062ac1400c38f99 +:105940001c00c2972c0062a41400c38f1c80828f9d +:105950003400428c340062ac1400c38f1c80828ff0 +:105960003800428c380062ac1400c28f040040ac96 +:105970001400c28f080040ac1c00c2271400c48f62 +:1059800021284000010006248940400f000000004b +:105990000b004010000000001c80848f1000c58f99 +:1059a0002c44400f00000000010002244c8282a31e +:1059b000ffff02243800c2af4501001000000000c4 +:1059c0001c00c297010042241c00c2a70400001062 +:1059d000000000001c00c297010042241c00c2a766 +:1059e000df8082930f00401000000000df8080a362 +:1059f0001c80838f1c80828f3400428c380062ac04 +:105a00001c00c2271c80848f21284000010006242e +:105a1000a63b400f000000001800c2af08000010b5 +:105a2000000000001c00c2271c80848f2128400039 +:105a300021300000a63b400f000000001800c2af5c +:105a40001800c28f17ff4014000000001c80848fd4 +:105a50001000c58f2c44400f000000001b000224e2 +:105a60004c8282a3ffff02243800c2af180100104d +:105a7000000000002000c297c50040100000000098 +:105a80001e00c0a71c80838f1c80828f3400428c34 +:105a9000380062ac1e00c2271c80848f2128400081 +:105aa00001000624a63b400f000000001800c2af12 +:105ab0001800c28f0b004014000000001c80848f6f +:105ac0001000c58f2c44400f000000001b00022472 +:105ad0004c8282a3ffff02243800c2affc000010fa +:105ae000000000001800c48f0736400f00000000bf +:105af0001e00c2a7029d023cc0034424764d400f05 +:105b0000000000000b004010000000001c80848f8b +:105b10001000c58f2c44400f000000000c00022430 +:105b20004c8282a3ffff02243800c2afe8000010bd +:105b300000000000020002241c00c2a71c80838f0a +:105b40001c80828f3400428c380062ac1c00c2275b +:105b50001c80848f2128400001000624a63b400fb2 +:105b6000000000001800c2af1800c28f0b004014e4 +:105b7000000000001c80848f1000c58f2c44400f53 +:105b8000000000001b0002244c8282a3ffff0224bd +:105b90003800c2afce000010000000001800c48f13 +:105ba0000736400f00000000448282af1e00c397fa +:105bb0004482828f11006214000000001e00c3970f +:105bc0004482828f2a006214000000001800c28ff5 +:105bd00000004390e500022408006210000000006d +:105be0001800c28f0b0043900800022403006210cb +:105bf000000000001e000010000000001c00c29702 +:105c0000010042241c00c2a71c00c2271c80848ff4 +:105c10002128400021300000a63b400f000000007a +:105c20001800c2af1800c28f0b0040140000000023 +:105c30001c80848f1000c58f2c44400f0000000092 +:105c40001b0002244c8282a3ffff02243800c2af53 +:105c50009f000010000000001800c48f0736400f9e +:105c600000000000448282afd0ff0010000000005e +:105c70002800c22721204000212800000c00062413 +:105c8000d169400f000000002200c0a32200c2938f +:105c90000b00422c0e004010000000002200c393b5 +:105ca0001000c227212062001800c38f2200c29377 +:105cb0002110430000004290180082a02200c293ed +:105cc000010042242200c2a3f0ff001000000000e7 +:105cd0002800c22721204000bb57400f00000000d1 +:105ce0000b004010000000001c80848f1000c58f46 +:105cf0002c44400f00000000010002244c8282a3cb +:105d0000ffff02243800c2af710000100000000045 +:105d10001c00c297010042241c00c2a71c80838f74 +:105d20001c80828f3400428c380062ac1c00c22779 +:105d30001c80848f2128400001000624a63b400fd0 +:105d4000000000001800c2af1800c28f0b00401402 +:105d5000000000001c80848f1000c58f2c44400f71 +:105d6000000000001b0002244c8282a3ffff0224db +:105d70003800c2af56000010000000002000c2979b +:105d8000ffff42242000c2a746fe001000000000d2 +:105d900001000224488282a342fe0010000000009d +:105da0002800c227212040000c000524714f400f1d +:105db0000000000009004014000000001c80848fd7 +:105dc0001000c58f2c44400f00000000ffff02248c +:105dd0003800c2af3e000010000000002800c227bb +:105de00021204000212800000c000624d169400f2a +:105df000000000002200c0a32200c2930b00422c2e +:105e00000e004010000000002200c3931000c227c3 +:105e1000212062001c80838f2200c2932110620027 +:105e200020004290180082a02200c2930100422468 +:105e30002200c2a3f0ff001000000000029d023cff +:105e4000c0034424764d400f000000000b004010ba +:105e5000000000001c80848f1000c58f2c44400f70 +:105e6000000000000c0002244c8282a3ffff0224e9 +:105e70003800c2af16000010000000002800c22742 +:105e800021204000bb57400f000000000b004010d5 +:105e9000000000001c80848f1000c58f2c44400f30 +:105ea00000000000010002244c8282a3ffff0224b4 +:105eb0003800c2af06000010000000001c80848f74 +:105ec0001000c58f2c44400f000000003800c0af08 +:105ed0003800c28f21e8c0034400bf8f4000be8f4e +:105ee0004800bd270800e0030000000098ffbd2720 +:105ef0006400bfaf6000beaf21f0a0036800c4af74 +:105f00002a5c400f00000000050040100000000067 +:105f1000ffff02245800c2af4b0000100000000039 +:105f20001800c227212040001c80858f2c44400f80 +:105f3000000000001400c0a31400c2930b00422c08 +:105f40000e004010000000001c80838f1400c293dc +:105f5000212062001400c3936800c28f21106200e8 +:105f600000004290200082a01400c293010042244d +:105f70001400c2a3f0ff00100000000000a0023ccb +:105f8000281244241c80858f2c44400f0000000000 +:105f90001c80848f00a0023c2812452401000624a6 +:105fa00021380000fc31400f000000001000c2af9b +:105fb0001000c28f0a004010000000001800c22725 +:105fc0001c80848f212840002c44400f00000000da +:105fd000ffff02245800c2af1b00001000000000a9 +:105fe0001c80828f2c0042241c80848f212840003a +:105ff000010006248940400f000000001000c2afdd +:106000001000c28f09004014000000001800c227d1 +:106010001c80848f212840002c44400f0000000089 +:106020005800c0af08000010000000001800c22790 +:106030001c80848f212840002c44400f0000000069 +:10604000ffff02245800c2af5800c28f21e8c003ee +:106050006400bf8f6000be8f6800bd270800e003aa +:106060000000000098ffbd276400bfaf6000beaf16 +:1060700021f0a0036800c4af6c00c5af7000c6afcc +:106080001000c2275000c2af4c8280a35000c28fc4 +:10609000200042246800c48f21284000010006240b +:1060a0000848400f000000000700401400000000f6 +:1060b000120002244c8282a3ffff02245c00c2afc4 +:1060c000f0000010000000007000c28f300040a0ff +:1060d0005b00c0a35b00c2930c00422c1400401074 +:1060e000000000005b00c3936800c28f21106200b3 +:1060f000000042800e004010000000007000c38fbe +:106100005b00c293212062005b00c3936800c28fd2 +:1061100021106200000042901c0082a05b00c2932c +:10612000010042245b00c2a3eaff0010000000004f +:106130007000c38f5b00c293211062001c0040a05e +:106140007000c38f6c00c28f290062a07000c38fe3 +:106150001c80828f3400428c2c0062ac5000c38fb4 +:1061600000a0023c04124224000062ac5000c28f26 +:10617000040040ac5000c28f080040ac5000c28ff9 +:106180002c0040a45000c38f6c00c28f300062a46a +:106190005000c38f1c80828f3400428c340062ac6c +:1061a0005000c38f1c80828f3800428c380062ac54 +:1061b00000a0023c281244245000c58f2c44400ffc +:1061c000000000005000c48f00a0023c28124524ab +:1061d0000100062401000724fc31400f00000000ec +:1061e0005400c2af5400c28f0700401000000000ee +:1061f0000b0002244c8282a3ffff02245c00c2af8a +:10620000a0000010000000005000c28f2c0042943b +:106210005800c2a75800c2275000c48f2128400050 +:10622000720006240833400f000000005400c2af83 +:106230005400c28f8f004014000000005000c28f35 +:1062400030004394080002245a006210000000004d +:106250005b00c0a35a00c0a35a00c2930800422c9e +:1062600018004010000000005000c38f5a00c29375 +:1062700021106200200043802000022411006210df +:10628000000000007000c38f5b00c2932120430018 +:106290005000c38f5a00c293211062002000429028 +:1062a000000082a05b00c293010042245b00c2a3f5 +:1062b0005a00c293010042245a00c2a3e6ff001014 +:1062c000000000005000c28f2800438020000224fc +:1062d0000d006214000000005000c28f29004380ae +:1062e0002000022408006214000000005000c28f49 +:1062f0002a004380200002240300621400000000f2 +:1063000009000010000000007000c48f5b00c39300 +:10631000010062245b00c2a3ff0062302118440028 +:106320002e000224000062a0080002245a00c2a32a +:106330005a00c2930b00422c1800401000000000cd +:106340005000c38f5a00c293211062002000438086 +:106350002000022411006210000000007000c38fb2 +:106360005b00c293212043005000c38f5a00c293a8 +:106370002110620020004290000082a05b00c293c6 +:10638000010042245b00c2a35a00c29301004224d0 +:106390005a00c2a3e6ff0010000000007000c28f88 +:1063a0005b00c39321106200000040a017000010a2 +:1063b000000000005b00c0a35b00c2930b00422cf6 +:1063c0000e004010000000007000c38f5b00c293fd +:1063d000212043005000c38f5b00c2932110620054 +:1063e00020004290000082a05b00c2930100422482 +:1063f0005b00c2a3f0ff0010000000007000c28f1d +:106400005b00c39321106200000040a07000c38fa6 +:106410005000c28f300042940d0062a07000c38f04 +:106420005000c28f1400428c100062ac7000c48f08 +:106430005000c28f1e004294001c02005000c28f08 +:106440001c00429421106200140082ac7000c38fc3 +:106450005000c28f2c004294180062ac7000c38fb1 +:1064600001000224300062a05c00c0af05000010f3 +:10647000000000001b0002244c8282a3ffff0224c4 +:106480005c00c2af5c00c28f21e8c0036400bf8f14 +:106490006000be8f6800bd270800e0030000000018 +:1064a00098ffbd276400bfaf6000beaf21f0a0031e +:1064b0006800c4af1000c2275000c2af4c8280a356 +:1064c0006800c28f300042900700401400000000b6 +:1064d000070002244c8282a3ffff02245c00c2afab +:1064e000d6000010000000006800c28f1c80838f5f +:1064f0002c00448c3400628c0700821000000000e5 +:106500001f0002244c8282a3ffff02245c00c2af62 +:10651000ca000010000000006800c28f1c00432465 +:106520005000c28f2000422421206000212840001a +:10653000010006240848400f000000000700401436 +:1065400000000000120002244c8282a3ffff0224fc +:106550005c00c2afb9000010000000005000c38f03 +:1065600000a0023c04124224000062ac5000c28f22 +:10657000040040ac5000c28f080040ac5000c38ff4 +:106580006800c28f1800428c010042242c0062a4d3 +:106590005000c38f6800c28f29004290300062a46f +:1065a0005000c38f1c80828f3400428c340062ac58 +:1065b0005000c38f1c80828f3800428c380062ac40 +:1065c00000a0023c281244245000c58f2c44400fe8 +:1065d000000000005000c48f00a0023c2812452497 +:1065e0000100062401000724fc31400f00000000d8 +:1065f0005400c2af5400c28f0700401000000000da +:106600000b0002244c8282a3ffff02245c00c2af75 +:106610008a000010000000005000c28f3000439438 +:10662000080002245a006210000000005800c0a3b5 +:106630005900c0a35900c2930800422c1800401012 +:10664000000000005000c38f5900c2932110620067 +:10665000200043802000022411006210000000008e +:106660006800c38f5800c293212043005000c38f9d +:106670005900c2932110620020004290000082a0c5 +:106680005800c293010042245800c2a35900c2938b +:10669000010042245900c2a3e6ff001000000000e0 +:1066a0005000c28f28004380200002240d00621495 +:1066b000000000005000c28f290043802000022407 +:1066c00008006214000000005000c28f2a004380be +:1066d00020000224030062140000000009000010e2 +:1066e000000000006800c48f5800c39301006224ba +:1066f0005800c2a3ff006230211844002e0002247b +:10670000000062a0080002245900c2a35900c293ed +:106710000b00422c18004010000000005000c38ff6 +:106720005900c293211062002000438020000224ff +:1067300011006210000000006800c38f5800c2936f +:10674000212043005000c38f5900c29321106200e2 +:1067500020004290000082a05800c2930100422411 +:106760005800c2a35900c293010042245900c2a399 +:10677000e6ff0010000000006800c28f5800c393bd +:1067800021106200000040a017000010000000006f +:106790005800c0a35800c2930b00422c0e004010ba +:1067a000000000006800c38f5800c29321204300fe +:1067b0005000c38f5800c293211062002000429005 +:1067c000000082a05800c293010042245800c2a3d6 +:1067d000f0ff0010000000006800c28f5800c39353 +:1067e00021106200000040a06800c38f5000c28fdb +:1067f000300042940d0062a06800c38f5000c28f29 +:106800001400428c100062ac6800c48f5000c28f2c +:106810001e004294001c02005000c28f1c004294d3 +:1068200021106200140082ac6800c38f5000c28f38 +:106830002c004294180062ac5c00c0af5c00c28fb8 +:1068400021e8c0036400bf8f6000be8f6800bd27d1 +:106850000800e00300000000f0ffbd270800beaf05 +:1068600021f0a00388bf023c1061428c0001427cf1 +:106870000000c2af0000c38f000062380100422c4c +:106880000000c2af0000c28f21e8c0030800be8f25 +:106890001000bd270800e00300000000f8ffbd273e +:1068a0000000beaf21f0a0030002022421e8c003d3 +:1068b0000000be8f0800bd270800e00300000000b4 +:1068c000f8ffbd270000beaf21f0a0035082828fe9 +:1068d00021e8c0030000be8f0800bd270800e003c8 +:1068e00000000000f8ffbd270000beaf21f0a003ac +:1068f00088bf033c0061629010004234006162a0d6 +:1069000081bf033c6090629002004234609062a0bc +:1069100088bf033c5060629002004234506062a025 +:1069200088bf043c40608390fdff02242410620075 +:10693000406082a088bf033c00616290080042343e +:10694000006162a021e8c0030000be8f0800bd27df +:106950000800e00300000000e8ffbd271400bfafff +:106960001000beaf21f0a003545c400f00000000f7 +:1069700088bf023c5060439002006334506043a0e3 +:1069800021e8c0031400bf8f1000be8f1800bd2780 +:106990000800e00300000000d0ffbd272c00bfafbf +:1069a0002800beaf21f0a0033000c4af2110a0002a +:1069b0003800c6af3400c2a3080002241000c2a7ea +:1069c00088bf043c50608390fdff022424106200c5 +:1069d000506082a0029d043c3400c39321106000eb +:1069e000401002002110430080180200d4038224ca +:1069f00021106200000042902000c2a33800c28f24 +:106a00001c00c2af029d043c3400c39321106000ff +:106a1000401002002110430080180200d403822499 +:106a200021106200010042901800c2a32000c28f12 +:106a3000400042342000c2af2000c2932120400019 +:106a4000615c400f000000001f00c2932120400045 +:106a5000615c400f000000001e00c2932120400036 +:106a6000615c400f000000001d00c2932120400027 +:106a7000615c400f000000001c00c2932120400018 +:106a8000615c400f000000001800c293212040000c +:106a9000615c400f00000000029d023c3400c39383 +:106aa000d403442421106000401002002110430050 +:106ab00080100200211044000400428c0f0040109e +:106ac00000000000029d023c3400c393d403442420 +:106ad00021106000401002002110430080100200cd +:106ae000211044000400438c0100022403006210c2 +:106af0000000000010000010000000007b5c400f50 +:106b0000000000001400c2a31000c297ffff42243f +:106b10001000c2a71400c393ff0002241a006214dd +:106b2000000000001000c297170040100000000095 +:106b3000f2ff001000000000029d023c3400c393ed +:106b4000d4034424211060004010020021104300af +:106b500080100200211044000400438c0200022433 +:106b600009006214000000007b5c400f0000000080 +:106b70007b5c400f000000001500c2a37b5c400f4f +:106b8000000000001400c2a3029d023c3400c39325 +:106b9000d40344242110600040100200211043005f +:106ba00080100200211044000400438c01000224e4 +:106bb0001f006214000000001400c0a31200c0a354 +:106bc0001200c393ff0002241900621000000000ad +:106bd0001400c2931600401400000000ffff0224be +:106be0001000c2a77b5c400f000000001400c2a38d +:106bf0001000c297ffff42241000c2a71400c293e6 +:106c000006004014000000001000c297030040106e +:106c100000000000f3ff0010000000001200c2930b +:106c2000010042241200c2a3e5ff00100000000092 +:106c3000ff000424615c400f00000000029d043c42 +:106c40003400c39321106000401002002110430063 +:106c500080180200d40382242110620008004290b0 +:106c6000050040140000000088bf023c50604390c3 +:106c700002006334506043a01400c28f3000c38f01 +:106c8000000062ac3000c28f21e8c0032c00bf8f2f +:106c90002800be8f3000bd270800e0030000000080 +:106ca000d0ffbd272c00bfaf2800beaf21f0a0034e +:106cb0003000c4af3400c5af010002241900c2a3e4 +:106cc0003000c28f401202001c00c2af1400c22765 +:106cd00021204000070005241c00c68f665a400f83 +:106ce000000000001400c2930d00401000000000de +:106cf0001400c22721204000070005241c00c68f75 +:106d0000665a400f000000001400c29304004010b7 +:106d1000000000002000c0af620000100000000072 +:106d2000ff0202241000c2a7400002241200c2a7e2 +:106d30001200c29706004010000000001200c29727 +:106d4000ffff42241200c2a7f9ff0010000000005c +:106d50007b5c400f000000001800c2a31000c29727 +:106d6000ffff42241000c2a7400002241200c2a765 +:106d70001200c29706004010000000001200c297e7 +:106d8000ffff42241200c2a7f9ff0010000000001c +:106d90001800c393ff0002240600621400000000e4 +:106da0001000c2970300401000000000e8ff001030 +:106db000000000001000c297070040100000000013 +:106dc0001800c393fe0002240300621400000000b8 +:106dd00004000010000000001900c0a328000010eb +:106de000000000001000c0a71000c2970002422c53 +:106df0001d004010000000003400c28f130040103e +:106e00000000000080bf033cff000224205a62ac57 +:106e100080bf023c105a428c0000427c03004014a8 +:106e200000000000faff0010000000001000c397ef +:106e30003400c28f2118620080bf023c205a428c6d +:106e4000000062a003000010000000007b5c400f07 +:106e5000000000001000c297010042241000c2a7e9 +:106e6000e1ff001000000000ff000424615c400fff +:106e700000000000ff000424615c400f00000000df +:106e8000ff000424615c400f0000000088bf033c49 +:106e90005060629002004234506062a01900c293b8 +:106ea0002000c2af2000c28f21e8c0032c00bf8f9a +:106eb0002800be8f3000bd270800e003000000005e +:106ec000d8ffbd272400bfaf2000beaf21f0a00334 +:106ed0002800c4af2c00c5af2110c0003000c2a3f1 +:106ee000010002241800c2a32800c28f070040142a +:106ef000000000003000c2930400401400000000b5 +:106f00001800c0a361000010000000001400c32797 +:106f10002800c28f401202002120600009000524d1 +:106f200021304000665a400f000000001400c29358 +:106f300004004010000000001800c0a34f00001023 +:106f400000000000fe000424615c400f000000000f +:106f50001000c0a71000c2970002422c160040107b +:106f60000000000080bf043c1000c3972c00c28fbb +:106f70002110620000004290205a82ac80bf023c87 +:106f8000105a428c0000427c0300401400000000b4 +:106f9000faff00100000000080bf023c205a428c23 +:106fa0001200c2a31000c297010042241000c2a721 +:106fb000e8ff001000000000ff000424615c400fa7 +:106fc00000000000ff000424615c400f000000008e +:106fd0007b5c400f000000001200c2a31200c293ad +:106fe0000f0043300500022404006210000000007e +:106ff0001800c0a31e000010000000001000c0a771 +:1070000080bf033cff000224205a62ac80bf023cd8 +:10701000105a428c0000427c030040140000000023 +:10702000faff00100000000080bf023c205a428c92 +:107030001200c2a31000c297010042241000c2a790 +:107040001200c29306004014000000001000c29716 +:107050000300401000000000e9ff001000000000e5 +:107060001000c29702004014000000001800c0a3e6 +:10707000ff000424615c400f0000000088bf023c58 +:107080005060439002006334506043a01800c293e4 +:1070900021e8c0032400bf8f2000be8f2800bd2739 +:1070a0000800e00300000000f8ffbd270000beafad +:1070b00021f0a00388bf023c1061428cc000427cda +:1070c000ff00423021e8c0030000be8f0800bd274a +:1070d0000800e00300000000f0ffbd270800beaf7d +:1070e00021f0a003211080001000c2a31000c29361 +:1070f0000000c2a30000c293ffff42240000c2a30d +:10710000ff004330ff0002240c006210000000006a +:10711000471d02240400c2af0400c28fffff4224b7 +:10712000211840000400c3afffff0224f1ff6210ea +:1071300000000000f8ff0010000000000000000048 +:1071400021e8c0030800be8f0800e0031000bd273f +:10715000f8ffbd270000beaf21f0a00380bf033cb5 +:1071600080bf023c105a428cff7f4230105a62ac02 +:1071700021e8c0030000be8f0800bd270800e0031f +:1071800000000000e0ffbd271c00bfaf1800beaf2d +:1071900021f0a003211080002000c2a380bf023c88 +:1071a000105a428cc000427c0300401400000000d2 +:1071b000faff00100000000080bf033c2000c293d3 +:1071c000205a62acb47d400f000000001000c2a342 +:1071d0002110000021e8c0031c00bf8f1800be8fe3 +:1071e0002000bd270800e00300000000e8ffbd27e5 +:1071f0001400bfaf1000beaf21f0a00380bf023c5f +:10720000105a428cc000427c030040140000000071 +:10721000faff00100000000080bf033cff000224c2 +:10722000205a62acb47d400f00000000ff004230e5 +:1072300021e8c0031400bf8f1000be8f1800bd27c7 +:107240000800e00300000000f8ffbd270000beaf0b +:1072500021f0a0030800c4af80bf023c105a40ac2c +:1072600080bf033c005a629040004234005a62a042 +:1072700080bf043c015a8390feff02242410620068 +:10728000015a82a088bf043c80618390bfff022422 +:1072900024106200806182a088bf043c81618390d9 +:1072a000feff022424106200816182a088bf043c9a +:1072b0008061839080ff022425106200806182a09b +:1072c00080bf043c015a839080ff02242510620095 +:1072d000015a82a021e8c0030000be8f0800bd272c +:1072e0000800e00300000000c0ffbd273c00bfaf66 +:1072f0003800beaf21f0a003010002241200c2a397 +:10730000030002241800c2a788bf033c50606290ab +:1073100002004234506062a080bf023c3000c2af25 +:107320009303023c008742341c00c2af0600023cbb +:10733000801a42342000c2af2000c28f40180200e1 +:107340001c00c28f1b004300f401600012100000fb +:107350002800c2af2000c28f401802001c00c28f5c +:107360001b004300f40160001010000004004010f6 +:10737000000000002800c28f010042242800c2af94 +:107380002800c28f0101422c0300401400000000bd +:10739000000102242800c2af2800c28f0400401060 +:1073a000000000002800c28fffff42242800c2af67 +:1073b0002800c28fff0042302400c2af2400c28fd9 +:1073c000ff0042303000c38f305a62ac80bf033cb4 +:1073d000005a629020004234005a62a02000042427 +:1073e000925c400f0000000001000424365c400f56 +:1073f000000000001000c0a71000c2970a00422c35 +:107400000900401000000000ff000424615c400ff0 +:10741000000000001000c297010042241000c2a723 +:10742000f5ff00100000000088bf043c506083900e +:10743000fdff022424106200506082a00100042499 +:10744000365c400f000000001400c22721204000dd +:107450002128000021300000665a400f0000000083 +:107460001400c393ff000224080062100000000013 +:107470001400c293f7004330010002240300621499 +:10748000000000000a000010000000001200c0a36d +:1074900088bf033c5060629002004234506062a09a +:1074a0001200c2932c00c2af7d000010000000004b +:1074b000ff0f02241000c2a71400c22721204000a1 +:1074c0000100052421300000665a400f0000000032 +:1074d0001000c297ffff42241000c2a71400c293fd +:1074e00006004010000000001000c297030040108a +:1074f00000000000f0ff0010000000001000c29724 +:1075000008004014000000001200c0a388bf023c25 +:107510005060439002006334506043a05e0000104e +:107520000000000002000424365c400f0000000050 +:1075300080bf023c3400c2af9303023c0087423458 +:107540002800c2af3101023c002d42342400c2affa +:107550002400c28f401802002800c28f1b00430085 +:10756000f4016000121000001c00c2af2400c28fa2 +:10757000401802002800c28f1b004300f401600085 +:107580001010000004004010000000001c00c28f1a +:10759000010042241c00c2af1c00c28f0101422c1a +:1075a0000300401400000000000102241c00c2afd0 +:1075b0001c00c28f04004010000000001c00c28f9d +:1075c000ffff42241c00c2af1c00c28fff004230ec +:1075d0002000c2af2000c28fff0042303400c38fb2 +:1075e000305a62ac80bf033c60c00234005a62acc7 +:1075f00080bf033c005a629020004234005a62a0cf +:107600001400c22721204000100005242130000072 +:10761000665a400f000000001400c22721204000dd +:107620000600052400020624665a400f00000000f0 +:10763000ff0002241000c2a71000c2970e004010e5 +:10764000000000002120000021280000285b400fde +:107650000000000021184000010002240600621012 +:10766000000000001000c297ffff42241000c2a7d4 +:10767000f1ff0010000000001000c2970600401447 +:10768000000000001200c0a388bf023c506043907d +:1076900002006334506043a01200c2932c00c2afba +:1076a0002c00c28f21e8c0033c00bf8f3800be8f82 +:1076b0004000bd270800e0030000000000e85d4135 +:1076c00000681a4000701b4090ffbd276c00bbafe4 +:1076d00000601b4082d21a006800bbaf847a5b7fd7 +:1076e00012d000006400baaf10d000006000baaf42 +:1076f00044201b7c00609b405c00bfaf5800beafc5 +:107700005400b9af5000b8af4c00afaf4800aeafb7 +:107710004400adaf4000acaf3c00abaf3800aaaf07 +:107720003400a9af3000a8af2c00a7af2800a6af47 +:107730002400a5af2000a4af1c00a3af1800a2af87 +:1077400021f0a0031081828f1000c2af010002243b +:107750001000c38f34006210000000001000c38fbf +:107760000200622806004010000000001000c28fd6 +:1077700009004010000000006f0000100000000031 +:10778000020002241000c38f2f00621000000000ce +:1077900069000010000000000b0004244560400f49 +:1077a00000000000e48082afe480828f1b0040185c +:1077b00000000000ec80838fe480828f2110620043 +:1077c000ec8082afe880828f01004224e88082afa3 +:1077d000e880828f0a004228100040140000000058 +:1077e000ec80848f6666023c676642341800820033 +:1077f0001010000083180200c31704002310620059 +:107800007c8282afe88080afec8080af01000224f0 +:10781000108182af4800001000000000108180af8e +:1078200045000010000000007c82848fd35f400f71 +:10783000000000005c8282af02000224108182af4f +:107840003d00001000000000145f400f0000000029 +:10785000108180af88bf023c5061428c0000427ca6 +:107860000600401000000000e080828f01004224ea +:10787000e08082af0200001000000000e08080afd6 +:1078800089818283150040140000000088bf023cfb +:107890005060428cc000427c060040140000000092 +:1078a00001000224898182a32080828f0a00422461 +:1078b000208082af88bf023c5060428c8000427cb6 +:1078c000060040140000000001000224898182a308 +:1078d0002080828ff6ff4224208082afac81828399 +:1078e000150040140000000088bf023c5060428c2c +:1078f000c003427c06004014000000000100022486 +:10790000ac8182a3fc80828f01004224fc8082af84 +:1079100088bf023c5060428c0001427c060040144b +:107920000000000001000224ac8182a3fc80828f51 +:10793000ffff4224fc8082af80bf023c100840acb5 +:1079400088bf033c00010224341062ac21e8c0036c +:107950005c00bf8f5800be8f5400b98f5000b88fa5 +:107960004c00af8f4800ae8f4400ad8f4000ac8f0d +:107970003c00ab8f3800aa8f3400a98f3000a88f4d +:107980002c00a78f2800a68f2400a58f2000a48f8d +:107990001c00a38f1800a28f00606041c00000008f +:1079a0006400ba8f130040036000ba8f11004003d7 +:1079b0006c00ba8f00709a406800ba8f7000bd27c3 +:1079c00000609a401800004200e85d41f4ffbd27c6 +:1079d00000601b400800bbaf04201b7c001c7b37f1 +:1079e00000609b4021f0a0030081828f0000c2afa5 +:1079f000010002240000c38f2d006210000000006f +:107a00000000c38f02006228060040100000000042 +:107a10000000c28f09004010000000003f0000106d +:107a200000000000020002240000c38f2e0062103c +:107a30000000000039000010000000006482828f06 +:107a40000f004014000000007082828f0400401874 +:107a5000000000007082828fffff4224708282af9c +:107a60008482828f04004018000000008482828f8c +:107a7000ffff4224848282af01000224648282af2d +:107a800088bf043c1061828c2880838f8410627cc4 +:107a9000106182ac80bf033c05000224200a62ac66 +:107aa00001000224008182af1c00001000000000d1 +:107ab0006482828f050040100000000088bf023cf5 +:107ac0001061439002006334106143a080bf023c08 +:107ad0000a000324200a43ac02000224008182af82 +:107ae0000e000010000000006482828f060040102b +:107af0000000000088bf043c10618390fdff022459 +:107b000024106200106182a080bf033c2480828f19 +:107b1000200a62ac008180af648280af80bf023ceb +:107b2000100a40ac88bf033c00100224341062ac41 +:107b300021e8c0030800ba8f00609a401800004294 +:107b4000e8ffbd271400bfaf1000beaf21f0a003b7 +:107b50002080828f048182af2080828f0f00422894 +:107b600003004010000000000f000224208082afbc +:107b70002080828fd10742280300401400000000bb +:107b8000d0070224208082af2080848f9878400f15 +:107b9000000000002130400021386000029d023cbe +:107ba0002005448c2405458c6b77400f00000000b5 +:107bb000029d063c21204000212860002c05c78c36 +:107bc0002805c68c9675400f00000000212040005b +:107bd000212860003079400f00000000248082af2f +:107be000f480828f100040100000000088bf043c29 +:107bf00010618390feff022424106200106182a0b5 +:107c00002080828f100042280b00401000000000ee +:107c100088bf023c1061439001006334106143a0af +:107c2000050000100000000088bf023c1061439076 +:107c300001006334106143a021e8c0031400bf8f2a +:107c40001000be8f1800bd270800e00300000000f0 +:107c5000e8ffbd271400bfaf1000beaf21f0a003a6 +:107c6000fc80828f0200410400000000fc8080af95 +:107c7000fc80828f2d014228030040140000000088 +:107c80002c010224fc8082afa08182831900401461 +:107c900000000000fc80848f767b400f0000000015 +:107ca0005c82848f21284000db7b400f00000000b5 +:107cb0000300400400000000070000100000000066 +:107cc00088bf023c5061439001006334506143a07f +:107cd0000d0000100000000088bf043c506183903c +:107ce000feff022424106200506182a006000010f2 +:107cf0000000000088bf043c50618390feff022416 +:107d000024106200506182a0888182832600401482 +:107d100000000000fc80828ff6ff422421204000fa +:107d2000767b400f000000005c82848f2128400099 +:107d3000db7b400f00000000120040040000000048 +:107d4000fc80828f0a00422421204000767b400f75 +:107d500000000000212040005c82858fdb7b400f0b +:107d6000000000000700400400000000fc80828f3b +:107d700064004228030040140000000008000010c6 +:107d800000000000f48080af88bf023c1061439087 +:107d900001006334106143a00300001000000000e4 +:107da00001000224f48082af8881838301000224d1 +:107db0002c00621400000000fc80828fffff422430 +:107dc00021204000767b400f000000005c82848f01 +:107dd00021284000db7b400f000000001800400419 +:107de00000000000fc80828f01004224212040001e +:107df000767b400f00000000212040005c82858fd0 +:107e0000db7b400f000000000d004004000000007c +:107e1000fc80828f640042280900401400000000aa +:107e20005c82848f21280000db7b400f0000000073 +:107e300003004010000000000800001000000000d7 +:107e4000f48080af88bf023c10614390010063342e +:107e5000106143a003000010000000000100022494 +:107e6000f48082af6c8183830100022419006214c4 +:107e700000000000fc80828ffbff42242120400094 +:107e8000767b400f000000005c82848f2128400038 +:107e9000db7b400f000000000300400400000000f6 +:107ea000080000100000000088bf043c10618390af +:107eb000dfff022424106200106182a00500001080 +:107ec0000000000088bf023c106143902000633432 +:107ed000106143a0029d023c5c82848f3005458c7a +:107ee000db7b400f0000000003004010000000009a +:107ef0000400001000000000212000006f60400f0f +:107f000000000000029d023c5c82848f3405458c99 +:107f1000db7b400f00000000030040100000000069 +:107f20000400001000000000212000006f60400fde +:107f30000000000021e8c0031400bf8f1000be8fb6 +:107f40001800bd270800e00300000000d0ffbd2797 +:107f50002800bfaf2400beaf2000b0af21f0a003c7 +:107f60003000c4af3000c28f1c004228080040100f +:107f700000000000029d023c3805428c1000c2af98 +:107f80001000c28f1800c2af5a000010000000009d +:107f90003000c28fff0342280c0040140000000094 +:107fa000e080828f33004228080040140000000067 +:107fb000029d023c3c05428c1000c2af1000c28ff3 +:107fc0001800c2af4b000010000000001400c0af4a +:107fd0001400c28f1f00422846004010000000001d +:107fe000029d043c1400c28f80180200a004822469 +:107ff000211062000000428c808282af3000c38f6b +:108000008082828f2a10430035004010000000005b +:108010008082828f548282af029d043c1400c28f02 +:1080200080180200a004822421106200fcff428c10 +:10803000788282af7882838f5482828f231062008d +:10804000688282af3000c38f5482828f2310620017 +:10805000748282af7482848f767b400f00000000b0 +:10806000218040006882848f767b400f00000000f2 +:108070002120000221284000eb7a400f0000000080 +:10808000588282af029d023c5882848f4005458c05 +:108090007d7a400f00000000588282af1400c38f29 +:1080a00021106000801002002110430040100200e7 +:1080b00021204000767b400f00000000212040007e +:1080c0005882858fe079400f000000001000c2af99 +:1080d0001000c28f1800c2af0600001000000000a0 +:1080e0001400c28f010042241400c2afb8ff001078 +:1080f000000000001800c28f21e8c0032800bf8fd5 +:108100002400be8f2000b08f3000bd270800e003a0 +:1081100000000000f0ffbd270800beaf21f0a00363 +:108120001000c4af81bf043c4090828c1000c38f0c +:10813000049c627c409082ac81bf033c00906290c2 +:1081400002004234009062a00000c0af0000c28f65 +:10815000c800422806004010000000000000c28f46 +:10816000010042240000c2aff8ff00100000000030 +:1081700081bf043c00908390fdff02242410620024 +:10818000009082a081bf023c0090428c0000427ca3 +:108190000300401400000000faff0010000000007f +:1081a00081bf023c7090428c21e8c0030800be8f62 +:1081b0001000bd270800e00300000000f0ffbd270d +:1081c0000800beaf21f0a0031000c4af1000c28fa2 +:1081d000010042380100422c0000c2af010002241d +:1081e0000000c38f10006210000000000000c38f69 +:1081f0000200622806004010000000000000c28f4c +:108200001d004010000000003900001000000000b8 +:10821000020002240000c38f2c0062100000000046 +:10822000330000100000000088bf043c1061839000 +:10823000feff022424106200106182a088bf033c6c +:1082400000010224641062ac88bf033c00010224d8 +:10825000681062ac88bf033c00100224641062ac5a +:1082600088bf033c00100224681062ace08080af3d +:108270001f0000100000000088bf043c5061839084 +:10828000feff022424106200506182a088bf033cdc +:108290001061629001004234106162a088bf033c0b +:1082a00000010224641062ac88bf023c681040ac3c +:1082b00088bf033c00100224641062ac88bf023cfb +:1082c000681040ac0a0000100000000088bf033caa +:1082d0001061629001004234106162a088bf033ccb +:1082e00000100224641062ac88bf023c681040aced +:1082f00021e8c0030800be8f1000bd270800e0037e +:1083000000000000d0ffbd272c00bfaf2800beaf8b +:1083100021f0a00388bf043c00618390fdff02248c +:1083200024106200006182a088bf043c0061839039 +:10833000fbff022424106200006182a088bf043c7d +:1083400000618390feff022424106200006182a07d +:10835000bd7d400f000000001000c2af88bf023c8e +:108360000030428c0003427c1c00c2af0b00401462 +:108370000000000088bf033c00100224083062acfb +:1083800088bf023c0030428c0003427c0300401452 +:1083900000000000faff0010000000001c00c28f67 +:1083a0001800c2af1800c28f1400c2af81bf023cd8 +:1083b00030f240ac81bf033c99aa023c556642347e +:1083c00030f262ac81bf033c6655023caa9942344c +:1083d00030f262ac81bf033c1800023c08f062ac92 +:1083e00081bf023c04f040ac81bf033c3333023c0c +:1083f0003333423430f262ac1400c28f1c00c2af7f +:108400001c00c28f150040100000000088bf023c15 +:108410000030428c0003427c2000c2af0b004014ad +:108420000000000088bf033c00100224083062ac4a +:1084300088bf023c0030428c0003427c03004014a1 +:1084400000000000faff0010000000002000c28fb2 +:108450001800c2af040000100000000088bf033cf9 +:1084600000100224043062ac1000c48fcc7d400f99 +:108470000000000080bf023c000840ac80bf033c0d +:1084800070000224080862ac80bf023c100840acb7 +:1084900080bf033cf4010224200862ac88bf033c87 +:1084a0001c000224b41062ac88bf033c10000224fc +:1084b000b81062ac88bf033c00010224341062ace7 +:1084c00080bf033c00800234080862ac88bf033cd4 +:1084d00000010224641062ac88bf023c681040ac0a +:1084e00080bf023c000a40ac80bf033c1000022465 +:1084f000080a62ac80bf023c100a40ac80bf033c5b +:1085000088130224200a62ac88bf033c1c000224aa +:10851000c41062ac88bf033c1c000224c81062accb +:10852000bf7d400f0000000088bf033c0010022404 +:10853000341062ac80bf033c00800234080a62ac95 +:1085400088bf033c00100224641062ac88bf023c68 +:10855000681040ac88bf033c106162900100423457 +:10856000106162a06c8180a34c8180a321e8c003cc +:108570002c00bf8f2800be8f3000bd270800e0030d +:1085800000000000e0ffbd271c00bfaf1800beaf19 +:1085900021f0a0031000c0af21200000f463400fc1 +:1085a0000000000088bf023c5060428cc000427c4a +:1085b0000300401400000000faff0010000000005b +:1085c000208080affc8080afe462400f000000009c +:1085d000010004246f60400f0000000088bf023ccf +:1085e0009061428c4002437c010002242f006214ff +:1085f00000000000d05e400f000000001000c28f9d +:10860000010042241000c2af1000c28fe9034228cb +:10861000f2ff401400000000e462400f0000000080 +:1086200088bf023c5060428cc000427c0400401471 +:10863000000000002080828f0a004224208082af48 +:1086400088bf023c5060428c8000427c0400401491 +:10865000000000002080828ff6ff4224208082af3d +:1086600088bf023c5060428cc003427c040040142e +:1086700000000000fc80828f01004224fc8082af59 +:1086800088bf023c5060428c0001427c04004014d0 +:1086900000000000fc80828fffff4224fc8082af3c +:1086a0001000c0afcdff001000000000212000002e +:1086b0006f60400f0000000021e8c0031c00bf8f66 +:1086c0001800be8f2000bd270800e0030000000056 +:1086d000f0ffbd270800beaf21f0a0031000c4af1b +:1086e0000000c0af1000c28f801802000000c28fcf +:1086f0002a1043000c0040100000000000000000a1 +:108700000000000000000000000000000000000069 +:1087100000000000000000000000c28f01004224a1 +:10872000f0ff00100000c2af21e8c0030800be8fb8 +:108730000800e0031000bd27e8ffbd271400bfaf0d +:108740001000beaf21f0a0031800c4af1800c28f04 +:10875000e80303240210437021204000b461400f5d +:108760000000000021e8c0031400bf8f1000be8f7e +:108770001800bd270800e00300000000f8ffbd2737 +:108780000000beaf21f0a0038481828f1c00401046 +:108790000000000088bf023c1061428c0000427c57 +:1087a0001700401400000000288080af7082828f84 +:1087b0000a004014000000006082828f050040140f +:1087c00000000000e8030224708282af0300001062 +:1087d000000000006082828f708282af90030224ca +:1087e000248082af7082828f030040180000000056 +:1087f000fcff00100000000001000224288082af6e +:1088000021e8c0030000be8f0800bd270800e00378 +:1088100000000000e8ffbd271400bfaf1000beaf8e +:1088200021f0a0038481828f3100401000000000fd +:1088300088bf023c1061428c0000427c2c00401436 +:108840000000000001000224288082af8482828f11 +:108850000a004014000000006c82828f0500401462 +:1088600000000000e8030224848282af03000010ad +:10887000000000006c82828f848282af9003022409 +:10888000248082af8482828f0300401800000000a1 +:10889000fcff0010000000002080848f9878400fbb +:1088a000000000002130400021386000029d023ca1 +:1088b0004805448c4c05458c6b77400f0000000048 +:1088c000029d063c21204000212860005405c78cf1 +:1088d0005005c68c9675400f000000002120400016 +:1088e000212860003079400f00000000248082af12 +:1088f00021e8c0031400bf8f1000be8f1800bd27f1 +:108900000800e00300000000e8ffbd271400bfaf2f +:108910001000beaf21f0a00321200000212800009c +:10892000029d023c3413462421380000d864400fd5 +:1089300000000000010004241c00052400a0023ceb +:10894000bc04462421380000d864400f0000000019 +:108950000200042421280000029d023c4813462402 +:1089600021380000d864400f0000000003000424f8 +:1089700021280000029d023c5813462421380000a3 +:10898000d864400f000000005480838f020002244e +:1089900008006214000000000400042421280000e4 +:1089a000029d023c6413462421380000d864400f25 +:1089b0000000000021e8c0031400bf8f1000be8f2c +:1089c0001800bd270800e00300000000d0ffbd270d +:1089d0002c00bfaf2800beaf21f0a0031000c427b9 +:1089e000029d023c701345243480868f106d400f29 +:1089f00000000000020004245a0005241000c627cd +:108a000021380000d864400f000000001c81828fd4 +:108a10003e004018000000001c81848f767b400fd0 +:108a200000000000029d033c212040008813658c5b +:108a3000eb7a400f000000002000c2af2000c48f7e +:108a4000c978400f0000000021304000213860004c +:108a50001000c427029d023c74134524106d400f82 +:108a600000000000030004244b0005241000c6276a +:108a700021380000d864400f000000002080848f5f +:108a8000767b400f0000000021204000c978400f95 +:108a900000000000029d063c2120400021286000cb +:108aa0009413c78c9013c68ca176400f0000000071 +:108ab0002120400021286000f278400f00000000d3 +:108ac000888282af8882848fc978400f00000000be +:108ad00021304000213860001000c427029d023c74 +:108ae00074134524106d400f00000000040004249e +:108af0004b0005241000c62721380000d864400f21 +:108b00000000000008000010000000000300042422 +:108b10004b000524029d023c8013462421380000ae +:108b2000d864400f00000000e122400f0000000068 +:108b30001623400f000000005480838f020002249f +:108b40000d006214000000002c63400f00000000c4 +:108b5000ac8182830300401000000000d963400f05 +:108b600000000000898182830300401000000000a3 +:108b70009063400f0000000021e8c0032c00bf8f6d +:108b80002800be8f3000bd270800e0030000000071 +:108b9000e8ffbd271400bfaf1000beaf21f0a00357 +:108ba0002120000021280000029d023c34134624ad +:108bb00021380000d864400f0000000001000424a8 +:108bc00021280000029d023c981346242138000011 +:108bd000d864400f0000000088bf023c5061428c06 +:108be0000000427c0a004010000000000500042440 +:108bf00021280000029d023cac13462421380000cd +:108c0000d864400f000000000800001000000000c1 +:108c10000500042421280000029d023cb8134624cc +:108c200021380000d864400f00000000029d023c83 +:108c30005c82848fd813458cdb7b400f00000000e2 +:108c400003004004000000000a00001000000000c3 +:108c50000300042421280000029d023cc413462482 +:108c600021380000d864400f00000000040000100c +:108c700000000000030004245964400f00000000bd +:108c8000d963400f000000002c63400f000000007b +:108c90009063400f0000000021e8c0031400bf8f64 +:108ca0001000be8f1800bd270800e0030000000080 +:108cb000d0ffbd272c00bfaf2800beaf21f0a0031e +:108cc000029d023c5c82848f1414458cdb7b400f38 +:108cd000000000000a00401000000000029d023c5d +:108ce0005c82848f1814458cdb7b400f00000000f1 +:108cf00003004010000000002600001000000000eb +:108d0000070004245964400f00000000029d023c4b +:108d10005c82848f1414458cdb7b400f00000000c4 +:108d200003004010000000000800001000000000d8 +:108d3000070004240a000524029d023cdc1346249b +:108d400021380000d864400f00000000029d023c62 +:108d50005c82848f1814458cdb7b400f0000000080 +:108d600003004010000000002f0000100000000071 +:108d7000070004240a000524029d023cf013462447 +:108d800021380000d864400f0000000026000010c9 +:108d9000000000005c82848fa07b400f0000000078 +:108da0002000c2af1000c427029d023c04144524d9 +:108db0002000c68f106d400f000000000700042443 +:108dc0002d0005241000c62721380000d864400f6c +:108dd0000000000088bf023c5061428c0000427cd1 +:108de0000a004010000000000700042423000524ae +:108df000029d023c0c14462421380000d864400f28 +:108e0000000000000800001000000000070004241b +:108e100023000524029d023c101446242138000042 +:108e2000d864400f0000000021e8c0032c00bf8f71 +:108e30002800be8f3000bd270800e00300000000be +:108e4000d0ffbd272c00bfaf2800beaf21f0a0038c +:108e50002080848f6666023c676642341800820078 +:108e60001010000083180200c317040023106200d2 +:108e70002000c2af1000c427029d023c1c144524f0 +:108e80002000c68f106d400f000000000700042472 +:108e9000550005241000c62721380000d864400f73 +:108ea000000000000400042421280000029d023c70 +:108eb0006413462421380000d864400f00000000ed +:108ec0002080848f767b400f00000000212040002e +:108ed000c978400f00000000029d063c21204000a0 +:108ee000212860002c14c78c2814c68ca176400f52 +:108ef000000000002120400021286000f278400f8f +:108f000000000000888282af8882848fc978400f79 +:108f10000000000021304000213860001000c4270c +:108f2000029d023c74134524106d400f00000000a8 +:108f3000040004244b0005241000c627213800003b +:108f4000d864400f00000000898180a321e8c0039d +:108f50002c00bf8f2800be8f3000bd270800e00323 +:108f600000000000d8ffbd272400bfaf2000beaf27 +:108f700021f0a003fc80828f020041040000000069 +:108f8000fc8080af1000c427029d023c04144524dd +:108f9000fc80868f106d400f000000000700042445 +:108fa000212800001000c62721380000d864400f97 +:108fb00000000000ac8180a321e8c0032400bf8f23 +:108fc0002000be8f2800bd270800e003000000003d +:108fd000e0ffbd271c00bfaf1800beaf21f0a0030b +:108fe000211080002000c2a31000c0a31000c29373 +:108ff0000800422c2000401000000000b0ff0324b5 +:109000001000c29321106200ff0042302120400076 +:109010005768400f00000000212000005768400ff3 +:1090200000000000100004245768400f00000000fa +:109030001100c0a31100c2830a0040040000000018 +:109040002000c293212040007968400f00000000fa +:109050001100c293010042241100c2a3f5ff0010c9 +:10906000000000001000c293010042241000c2a3bf +:10907000deff00100000000021e8c0031c00bf8fcd +:109080001800be8f2000bd270800e003000000008c +:10909000e0ffbd271c00bfaf1800beaf21f0a0034a +:1090a000211080002400c5af2000c2a3b0ff03241c +:1090b0002000c29321106200ff00423021204000b6 +:1090c0005768400f00000000212000005768400f43 +:1090d00000000000100004245768400f000000004a +:1090e0001000c0a31000c2932400c38f2a104300b5 +:1090f0000900401000000000180004247968400fa7 +:10910000000000001000c293010042241000c2a31e +:10911000f4ff0010000000002400c28f1000c2a362 +:109120001000c2830900400400000000212000005c +:109130007968400f000000001000c2930100422433 +:109140001000c2a3f6ff00100000000021e8c003d9 +:109150001c00bf8f1800be8f2000bd270800e00351 +:1091600000000000e0ffbd271c00bfaf1800beaf2d +:1091700021f0a003211080002000c2a3b0ff03242f +:109180002000c29321106200ff00423021204000e5 +:109190005768400f00000000212000005768400f72 +:1091a00000000000100004245768400f0000000079 +:1091b0001000c0a31000c28309004004000000009a +:1091c000212000007968400f000000001000c293c9 +:1091d000010042241000c2a3f6ff001000000000ae +:1091e00021e8c0031c00bf8f1800be8f2000bd27e0 +:1091f0000800e00300000000d8ffbd272400bfaf37 +:109200002000beaf21f0a003211080002800c2a3df +:109210002800c2931c00c2af010002241c00c38faf +:1092200015006210000000001c00c38f02006228bd +:1092300006004010000000001c00c28f0900401012 +:1092400000000000140000100000000002000224d2 +:109250001c00c38f0d006210000000000e00001003 +:1092600000000000029d023c580542241400c2afd9 +:109270000900001000000000029d023c5809422431 +:109280001400c2af0400001000000000029d023c68 +:10929000580d42241400c2af1000c0a31000c293a6 +:1092a0000800422c28004010000000001000c2936b +:1092b000c01102001800c2afb0ff03241000c29317 +:1092c00021106200ff004230212040005768400f0b +:1092d00000000000212000005768400f000000003f +:1092e000100004245768400f000000001100c0a3c4 +:1092f0001100c2830f004004000000001100c3935e +:109300001400c28f211862001800c28f2110620061 +:1093100000004290212040007968400f00000000ca +:109320001100c293010042241100c2a3f0ff0010fb +:10933000000000001000c293010042241000c2a3ec +:10934000d6ff00100000000021e8c0032400bf8ffa +:109350002000be8f2800bd270800e00300000000a9 +:10936000d0ffbd272c00bfaf2800beaf21f0a00367 +:109370003000c4af3400c5af3800c6af2110e000e4 +:109380003c00c2a31c00c0af3400c28f1000c2a3b7 +:109390001000c2930f0042301100c2a31000c2930c +:1093a00002110200100042341200c2a33000c28f2a +:1093b000b0ff032421106200ff0042302120400052 +:1093c0005768400f000000001100c29321204000a8 +:1093d0005768400f000000001200c2932120400097 +:1093e0005768400f000000001400c0af1400c38f86 +:1093f0003800c28f21106200000042909700401098 +:10940000000000001400c38f3800c28f21106200da +:10941000000042905300422c140040100000000055 +:109420002000c5271400c38f3800c28f21106200ae +:109430000000449021108000801802002118640070 +:10944000029d023c5811422460ff42242110620018 +:109450002120a00021284000050006247769400f44 +:10946000000000003c000010000000001400c38f4a +:109470003800c28f21106200000042907f00422c11 +:109480002e004010000000001400c38f3800c28f6f +:1094900021106200000042905c00422c1400401435 +:1094a000000000002000c5271400c38f3800c28fc1 +:1094b00021106200000044902110800080180200fa +:1094c00021186400029d023c581242245cfe422492 +:1094d000211062002120a000212840000500062460 +:1094e0007769400f000000001b0000100000000022 +:1094f0002000c5271400c38f3800c28f21106200de +:10950000000044902110800080180200211864009f +:10951000029d023c5812422461fe42242110620046 +:109520002120a00021284000050006247769400f73 +:109530000000000008000010000000002000c2270a +:1095400021204000029d023c5811452405000624bc +:109550007769400f000000001800c0af1800c28fec +:109560000500422832004010000000001c00c28f9d +:10957000800042281b004010000000003c00c29305 +:109580000a004014000000001800c38f1000c2271a +:109590002110430010004290212040007968400fc4 +:1095a000000000000a000010000000001800c38f37 +:1095b0001000c22721104300100042902710020023 +:1095c000ff004230212040007968400f0000000079 +:1095d0001c00c28f010042241c00c2af0f0000100b +:1095e000000000003000c28fb1ff03242110620090 +:1095f000ff004230212040005768400f000000006b +:109600001800c38f1000c2272110430010004290a1 +:10961000212040007968400f000000001800c28f30 +:10962000010042241800c2afccff0010000000006f +:10963000212000007968400f000000001c00c28f4c +:10964000010042241c00c2af1400c28f010042245a +:109650001400c2af65ff00100000000021e8c00345 +:109660002c00bf8f2800be8f3000bd270800e0030c +:1096700000000000e8ffbd271400bfaf1000beaf20 +:1096800021f0a00321200000f463400f000000003f +:10969000212000000a000524029d023c34134624c8 +:1096a00021380000d864400f0000000001000424ad +:1096b00014000524029d023c301446242138000089 +:1096c000d864400f000000000200042414000524a8 +:1096d000029d023c3814462421380000d864400f13 +:1096e000000000000300042414000524029d023c35 +:1096f0004414462421380000d864400f00000000c4 +:109700000400042414000524029d023c5014462445 +:1097100021380000d864400f000000000500042438 +:1097200014000524029d023c5c14462421380000ec +:10973000d864400f0000000021e8c0031400bf8f70 +:109740001000be8f1800bd270800e00300000000d5 +:10975000e8ffbd271400bfaf1000beaf21f0a0038b +:1097600021200000f463400f0000000021200000d1 +:109770000a000524029d023c3413462421380000cf +:10978000d864400f000000000100042421280000dc +:10979000029d023c6c14462421380000d864400f1e +:1097a000000000000400042421280000029d023c67 +:1097b0007414462421380000d864400f00000000d3 +:1097c0000500042421280000029d023c7c1446244c +:1097d00021380000d864400f000000000600042477 +:1097e00021280000029d023c8414462421380000f8 +:1097f000d864400f0000000021e8c0031400bf8fb0 +:109800001000be8f1800bd270800e0030000000014 +:10981000e8ffbd271400bfaf1000beaf21f0a003ca +:1098200021200000f463400f000000002120000010 +:109830000a000524029d023c34134624213800000e +:10984000d864400f00000000010004241400052427 +:10985000029d023c8c14462421380000d864400f3d +:109860000000000021e8c0031400bf8f1000be8f6d +:109870001800bd270800e00300000000e8ffbd2736 +:109880001400bfaf1000beaf21f0a00301000424fc +:109890005964400f00000000010004241400052456 +:1098a000029d023c5014462421380000d864400f29 +:1098b0000000000021e8c0031400bf8f1000be8f1d +:1098c0001800bd270800e00300000000e8ffbd27e6 +:1098d0001400bfaf1000beaf21f0a0032120000094 +:1098e000f463400f00000000010004242128000060 +:1098f000029d023c9c14462421380000d864400f8d +:109900000000000021e8c0031400bf8f1000be8fcc +:109910001800bd270800e00300000000d8ffbd27a5 +:109920002400bfaf2000beaf21f0a0032800c4afc9 +:109930002c00c5af3000c6af2110e0003400c2a338 +:1099400021200000f463400f000000000100042407 +:1099500021280000029d023cb0144624213800005a +:10996000d864400f000000002800c48fc978400f61 +:109970000000000021304000213860001000c427a2 +:10998000029d023cbc144524106d400f00000000f5 +:1099900003000424212800001000c62721380000fd +:1099a000d864400f000000002c00c48fc978400f1d +:1099b0000000000021304000213860001000c42762 +:1099c000029d023cc4144524106d400f00000000ad +:1099d00004000424212800001000c62721380000bc +:1099e000d864400f000000003400c2831300401010 +:1099f000000000003000c48fc978400f0000000054 +:109a000021304000213860001000c427029d023c34 +:109a1000cc144524106d400f000000000500042404 +:109a2000212800001000c62721380000d864400f0c +:109a300000000000080000100000000005000424e1 +:109a400021280000029d023cd41446242138000045 +:109a5000d864400f0000000021e8c0032400bf8f3d +:109a60002000be8f2800bd270800e0030000000092 +:109a7000e8ffbd271400bfaf1000beaf21f0a00368 +:109a800021200000f463400f0000000021200000ae +:109a900021280000029d023ce014462421380000e9 +:109aa000d864400f000000000200042421280000b8 +:109ab000029d023cec14462421380000d864400f7b +:109ac000000000000400042421280000029d023c44 +:109ad000fc14462421380000d864400f0000000028 +:109ae00021e8c0031400bf8f1000be8f1800bd27ef +:109af0000800e00300000000e8ffbd271400bfaf2e +:109b00001000beaf21f0a0031800c4af1c00c5af09 +:109b10002110c0002000c2a31800c28f0800422cf0 +:109b200073014010000000001800c28f801802006e +:109b3000029d023c14154224211062000000428c58 +:109b400008004000000000002000c393010004242e +:109b50001c00c58f029d023c0c1546242138600074 +:109b6000d864400f00000000020004241c00c58fd0 +:109b7000029d023c1015462421380000d864400f95 +:109b800000000000030004241c00c58f029d023c5d +:109b90001015462421380000d864400f0000000052 +:109ba000040004241c00c58f029d023c10154624ad +:109bb00021380000d864400f000000000500042494 +:109bc0001c00c58f029d023c101546242138000060 +:109bd000d864400f00000000060004241c00c58f5c +:109be000029d023c1015462421380000d864400f25 +:109bf00000000000070004241c00c58f029d023ce9 +:109c00001015462421380000d864400f00000000e1 +:109c10003701001000000000010004241c00c58f63 +:109c2000029d023c1015462421380000d864400fe4 +:109c3000000000002000c393020004241c00c58f14 +:109c4000029d023c0c15462421386000d864400f68 +:109c500000000000030004241c00c58f029d023c8c +:109c60001015462421380000d864400f0000000081 +:109c7000040004241c00c58f029d023c10154624dc +:109c800021380000d864400f0000000005000424c3 +:109c90001c00c58f029d023c10154624213800008f +:109ca000d864400f00000000060004241c00c58f8b +:109cb000029d023c1015462421380000d864400f54 +:109cc00000000000070004241c00c58f029d023c18 +:109cd0001015462421380000d864400f0000000011 +:109ce0000301001000000000010004241c00c58fc7 +:109cf000029d023c1015462421380000d864400f14 +:109d000000000000020004241c00c58f029d023cdc +:109d10001015462421380000d864400f00000000d0 +:109d20002000c393030004241c00c58f029d023c45 +:109d30000c15462421386000d864400f0000000054 +:109d4000040004241c00c58f029d023c101546240b +:109d500021380000d864400f0000000005000424f2 +:109d60001c00c58f029d023c1015462421380000be +:109d7000d864400f00000000060004241c00c58fba +:109d8000029d023c1015462421380000d864400f83 +:109d900000000000070004241c00c58f029d023c47 +:109da0001015462421380000d864400f0000000040 +:109db000cf00001000000000010004241c00c58f2b +:109dc000029d023c1015462421380000d864400f43 +:109dd00000000000020004241c00c58f029d023c0c +:109de0001015462421380000d864400f0000000000 +:109df000030004241c00c58f029d023c101546245c +:109e000021380000d864400f000000002000c393f8 +:109e1000040004241c00c58f029d023c0c1546243e +:109e200021386000d864400f0000000005000424c1 +:109e30001c00c58f029d023c1015462421380000ed +:109e4000d864400f00000000060004241c00c58fe9 +:109e5000029d023c1015462421380000d864400fb2 +:109e600000000000070004241c00c58f029d023c76 +:109e70001015462421380000d864400f000000006f +:109e80009b00001000000000010004241c00c58f8e +:109e9000029d023c1015462421380000d864400f72 +:109ea00000000000020004241c00c58f029d023c3b +:109eb0001015462421380000d864400f000000002f +:109ec000030004241c00c58f029d023c101546248b +:109ed00021380000d864400f000000000400042472 +:109ee0001c00c58f029d023c10154624213800003d +:109ef000d864400f000000002000c3930500042434 +:109f00001c00c58f029d023c0c15462421386000c0 +:109f1000d864400f00000000060004241c00c58f18 +:109f2000029d023c1015462421380000d864400fe1 +:109f300000000000070004241c00c58f029d023ca5 +:109f40001015462421380000d864400f000000009e +:109f50006700001000000000010004241c00c58ff1 +:109f6000029d023c1015462421380000d864400fa1 +:109f700000000000020004241c00c58f029d023c6a +:109f80001015462421380000d864400f000000005e +:109f9000030004241c00c58f029d023c10154624ba +:109fa00021380000d864400f0000000004000424a1 +:109fb0001c00c58f029d023c10154624213800006c +:109fc000d864400f00000000050004241c00c58f69 +:109fd000029d023c1015462421380000d864400f31 +:109fe000000000002000c393060004241c00c58f5d +:109ff000029d023c0c15462421386000d864400fb5 +:10a0000000000000070004241c00c58f029d023cd4 +:10a010001015462421380000d864400f00000000cd +:10a020003300001000000000010004241c00c58f54 +:10a03000029d023c1015462421380000d864400fd0 +:10a0400000000000020004241c00c58f029d023c99 +:10a050001015462421380000d864400f000000008d +:10a06000030004241c00c58f029d023c10154624e9 +:10a0700021380000d864400f0000000004000424d0 +:10a080001c00c58f029d023c10154624213800009b +:10a09000d864400f00000000050004241c00c58f98 +:10a0a000029d023c1015462421380000d864400f60 +:10a0b00000000000060004241c00c58f029d023c25 +:10a0c0001015462421380000d864400f000000001d +:10a0d0002000c393070004241c00c58f029d023c8e +:10a0e0000c15462421386000d864400f00000000a1 +:10a0f00021e8c0031400bf8f1000be8f1800bd27d9 +:10a100000800e00300000000f8ffbd270000beaf1c +:10a1100021f0a0030800c4af80bf033c0800c28f39 +:10a12000205a62ac80bf023c105a428c0000427c34 +:10a130000300401400000000faff001000000000bf +:10a1400080bf023c205a428c21e8c0030000be8f31 +:10a150000800bd270800e00300000000e8ffbd275d +:10a160001400bfaf1000beaf21f0a003211080008b +:10a170001800c2a388bf043c10618390bfff022473 +:10a1800024106200106182a088bf043c506083905c +:10a19000dfff022424106200506082a01800c293e6 +:10a1a000212040004268400f0000000088bf033caf +:10a1b0005060629020004234506062a088bf033c2f +:10a1c0001061629040004234106162a021e8c00337 +:10a1d0001400bf8f1000be8f1800bd270800e003d9 +:10a1e00000000000e8ffbd271400bfaf1000beafa5 +:10a1f00021f0a003211080001800c2a388bf033cf7 +:10a200001061629040004234106162a088bf043c3b +:10a2100050608390dfff022424106200506082a00f +:10a220001800c293212040004268400f0000000047 +:10a2300088bf033c5060629020004234506062a0ae +:10a2400088bf033c1061629040004234106162a0fc +:10a2500021e8c0031400bf8f1000be8f1800bd2777 +:10a260000800e00300000000e0ffbd271c00bfafb6 +:10a270001800beaf21f0a003211080002000c2a36f +:10a280001000c0a31000c2930800422c2000401010 +:10a2900000000000b0ff03241000c29321106200f0 +:10a2a000ff004230212040005768400f00000000ae +:10a2b000212000005768400f000000001000042417 +:10a2c0005768400f000000001100c0a31100c283b6 +:10a2d0000a004004000000002000c293212040003a +:10a2e0007968400f000000001100c2930100422471 +:10a2f0001100c2a3f5ff0010000000001000c2937f +:10a30000010042241000c2a3deff00100000000084 +:10a3100021e8c0031c00bf8f1800be8f2000bd279e +:10a320000800e00300000000e0ffbd271c00bfaff5 +:10a330001800beaf21f0a0031000c0af80bf033ce7 +:10a3400020810234005a62ac88bf043c10618390c3 +:10a35000bfff022424106200106182a088bf043c69 +:10a3600050608390dfff022424106200506082a0be +:10a3700088bf033c106162907f004230106162a090 +:10a380001000c0af1000c28fd007422c0600401052 +:10a39000000000001000c28f010042241000c2af74 +:10a3a000f8ff00100000000088bf043c106183909b +:10a3b00080ff022425106200106182a01000c0af4f +:10a3c0001000c28fd007422c060040100000000091 +:10a3d0001000c28f010042241000c2aff8ff00102d +:10a3e0000000000088bf023c5060439020006334ae +:10a3f000506043a0d50004245768400f00000000bf +:10a40000100004245768400f00000000d30004240b +:10a410005768400f00000000212000005768400fdf +:10a4200000000000a80004245768400f000000004e +:10a430003f0004245768400f00000000d8000424a7 +:10a440005768400f00000000212000005768400faf +:10a4500000000000400004245768400f0000000086 +:10a46000a00004245768400f00000000c800042426 +:10a470005768400f00000000da0004245768400fbe +:10a4800000000000120004245768400f0000000084 +:10a49000810004245768400f00000000f0000424ed +:10a4a0005768400f00000000a40004245768400fc4 +:10a4b00000000000d90004245768400f000000008d +:10a4c000f20004245768400f00000000a600042496 +:10a4d0005768400f00000000260004245768400f12 +:10a4e00000000000010004245768400f0000000035 +:10a4f000212000005768400f0000000021200000cc +:10a500005768400f00000000010004245768400f06 +:10a5100000000000212000009a68400f00000000a9 +:10a520001000c0af1000c28fd007422c06004010b0 +:10a53000000000001000c28f010042241000c2afd2 +:10a54000f8ff001000000000af0004245768400f1f +:10a550000000000021e8c0031c00bf8f1800be8f60 +:10a560002000bd270800e00300000000e8ffbd2731 +:10a570001400bfaf1000beaf21f0a00321200000e7 +:10a58000f463400f00000000010004247e64400fcb +:10a5900000000000c8000424365c400f00000000ea +:10a5a00021200000f463400f000000002120000083 +:10a5b0007e64400f00000000c8000424365c400f99 +:10a5c0000000000021e8c0031400bf8f1000be8f00 +:10a5d0001800bd270800e0030000000021108000e3 +:10a5e0005600c0100c00ca2c4d0040152618a400bf +:10a5f0000300633023380400290060100300e730b3 +:10a600000600e0102330c7000000a3980300a388d1 +:10a610002128a700000083b8212087000f00c33045 +:10a620002338c3001100e010213060002138e5001c +:10a630000000a3980300a3880400a8980700a88836 +:10a640000800a9980b00a9880c00aa980f00aa88f6 +:10a65000000083ac040088ac080089ac1000a5247d +:10a6600010008424f2ffa714fcff8aac0300c3305f +:10a670002338c3002a00e010213060002138e500b3 +:10a680000000a3980300a3880400a52404008424e8 +:10a69000fbffa714fcff83ac2100001000000000aa +:10a6a0000500e0102330c7000000a3982128a70070 +:10a6b000000083b8212087000f00c3302338c30077 +:10a6c0000d00e010213060002138e5000000a38c6f +:10a6d0000400a88c0800a98c0c00aa8c000083ac94 +:10a6e000040088ac080089ac1000a5241000842464 +:10a6f000f6ffa714fcff8aac0300c3302338c30065 +:10a700000700e010213060002138e5000000a38c34 +:10a710000400a52404008424fcffa714fcff83ace0 +:10a720000600c0102138c5000000a3900100a52438 +:10a7300001008424fcffa714ffff83a00800e003ae +:10a7400000000000211080002600c0101000ca2c5c +:10a750001f004015ff00a530005205002528aa0063 +:10a76000005405002528aa0003008330050060106e +:10a77000040007242338e3002330c700000085b815 +:10a78000212087000f00c3302338c3000800e010e9 +:10a79000213060002138e400000085ac040085ac65 +:10a7a000080085ac10008424fbff8714fcff85acf7 +:10a7b0000300c3302338c3000500e01021306000df +:10a7c0002138e40004008424feff8714fcff85acdc +:10a7d0000400c0102138c40001008424feff871447 +:10a7e000ffff85a00800e003000000002540850071 +:10a7f0000300083103000011211080003800001010 +:10a800000000aa900000aa8c0101093c0101293531 +:10a81000c07909002340490124400f0107000011bd +:10a8200024600a0105008811000000000000a52432 +:10a830000000aa902a000010000084240400ab8cc1 +:10a8400000008aac2340690124400f010700001179 +:10a8500024600b0105008811000000000400a524fd +:10a860000000aa901e000010040084240800aa8c96 +:10a8700004008bac2340490124400f010700001164 +:10a8800024600a0105008811000000000800a524ca +:10a890000000aa9012000010080084240c00ab8c69 +:10a8a00008008aac2340690124400f010700001111 +:10a8b00024600b0105008811000000000c00a52495 +:10a8c0000000aa90060000100c0084241000aa8c3e +:10a8d0000c008bac10008424ceff00101000a524c7 +:10a8e0000300401500008aa00800e00300000000fb +:10a8f0000100ab900300601501008ba00800e0038d +:10a90000000000000200aa900300401502008aa087 +:10a910000800e003000000000300ab900300601596 +:10a9200003008ba00800e003000000000400aa90d0 +:10a930000300401504008aa00800e00300000000a6 +:10a940000500ab900300601505008ba00800e00334 +:10a95000000000000600aa900300401506008aa02f +:10a960000800e003000000000700ab900300601542 +:10a9700007008ba00800e003000000000800aa9078 +:10a9800008008424d6ff00100800a52400008a9047 +:10a990002110800003004015000000000800e003c3 +:10a9a0000000022401008a9003004015000000000e +:10a9b0000800e0030100022402008a900300401511 +:10a9c000000000000800e0030200022403008a9057 +:10a9d00003004015822004000800e0030300022465 +:10a9e000010084248020040000008a8c0101093cbd +:10a9f00001012935c07909002340490124400f0194 +:10aa00000600001124600a01040088110000000003 +:10aa100000008a90220000100000842404008b8c27 +:10aa20002340690124400f010600001124600b013e +:10aa3000040088110000000004008a901800001033 +:10aa40000400842408008a8c2340490124400f011b +:10aa50000600001124600a010400881100000000b3 +:10aa600008008a900e000010080084240c008b8cd3 +:10aa70002340690124400f010600001124600b01ee +:10aa800004008811000000000c008a9004000010ef +:10aa90000c00842410008a8cd7ff0010100084243e +:10aaa0000400401500000000000084240800e003ba +:10aab0002310820001008a9004004015000000006d +:10aac000010084240800e0032310820002008a9021 +:10aad0000400401500000000020084240800e00388 +:10aae0002310820003008a90030084240800e003fe +:10aaf00023108200b0ffbd270000a1af0400a2af69 +:10ab00000800a3af0c00a4af1000a5af1400a6afbf +:10ab10001800a7af1c00a8af2000a9af2400aaaf5f +:10ab20002800abaf2c00acaf3000adaf3400aeafff +:10ab30003800afaf3c00b8af4000b9af4400bfaf82 +:10ab4000124000004800a8af104000005000a8af1d +:10ab50000068044000600540526d400f0000000096 +:10ab60005000a88f110000014800a88f13000001b9 +:10ab70000000a18f0400a28f0800a38f0c00a48ff7 +:10ab80001000a58f1400a68f1800a78f1c00a88f97 +:10ab90002000a98f2400aa8f2800ab8f2c00ac8f37 +:10aba0003000ad8f3400ae8f3800af8f3c00b88fcf +:10abb0004000b98f4400bf8f5000bd27c000000087 +:10abc000180000422518a400030062302000401441 +:10abd000214080000400c92c1c0020152138a00051 +:10abe0000000af8cfefe183cfffe053727700f00fb +:10abf0002168e50180800c3c2458ae0180808335bb +:10ac000024506301120040552128e0002148a00093 +:10ac1000212860000000e28cfcffc6240400d92c2f +:10ac2000000082ac0400e7240800201704008424fc +:10ac30000000ed8c27600d002158a90124506c0103 +:10ac400024184501f4ff60500000e28c2128e00048 +:10ac50000e00c010ffffc2240000a790ffffc62413 +:10ac6000000087a00100a524f9ffe014010084245e +:10ac70000600c010ffffc224ffff0324ffff422491 +:10ac8000000080a0fdff4314010084240800e003bd +:10ac9000211000010300823018004014ff00a5308d +:10aca000003a05002540a7000034080025380601b9 +:10acb0008080033c21308000fefe043cfffe89348e +:10acc000808068340000cf8c2610e7012168e901fc +:10acd00027700f0027c8020021c049002458ae0188 +:10ace00024601903245068010300401524188801ca +:10acf000f4ff60500400c6242120c00000008390af +:10ad0000ff00693003002515211080000800e003d2 +:10ad100000000000f9ff6014010084240800e00333 +:10ad200021100000e0ffbd2700a0053c1000b0afdf +:10ad30000000b0241800b2af1400b1af2190800021 +:10ad400000a0113c1c00bfaf216d400f212000026c +:10ad50001c01238e01000424380064ac256d400fd3 +:10ad6000212000021c01228e1000508c0d000012c8 +:10ad70001c012a8e0400028e08004018ffff4724a1 +:10ad800080480700214030010800068d09f8c00006 +:10ad9000040007aef8ff00100400028ef3ff00105d +:10ada0000000108e3400428d0300401000000000af +:10adb00009f8400000000000756d400f212040029e +:10adc000029d073c4d15e6242110860000004590a9 +:10add000200082240100a3300800e0030a10830051 +:10ade000029d073c4d15e624211086000000459089 +:10adf000e0ff82240200a3300800e0030a10830071 +:10ae0000029d053c4d15a324212083000000829063 +:10ae10000800e00307004230029d053c4d15a324c5 +:10ae200021208300000082900800e00303004230ec +:10ae30000800e0038000822c029d053c4d15a324f0 +:10ae400021208300000082900800e00320004230af +:10ae5000029d053c4d15a324212083000000829013 +:10ae60000800e00304004230029d053c4d15a32478 +:10ae700021208300000082900800e0031700423088 +:10ae8000029d053c4d15a3242120830000008290e3 +:10ae90000800e00302004230029d053c4d15a3244a +:10aea00021208300000082800800e00397004230e8 +:10aeb000029d053c4d15a3242120830000008290b3 +:10aec0000800e00310004230029d053c4d15a3240c +:10aed00021208300000082800800e00388004230c7 +:10aee000029d053c4d15a324212083000000829083 +:10aef0000800e00301004230029d053c4d15a324eb +:10af000021208300000082900800e00344004230ca +:10af10000800e0037f0082300800e0032000822464 +:10af20000800e003e0ff8224e8ffbd271000bfaf68 +:10af3000546c400f212800001000bf8f0800e00370 +:10af40001800bd27e8ffbd27212800001000bfaf73 +:10af5000d96b400f0a0006241000bf8f0800e003e1 +:10af60001800bd2700008380213880002150000098 +:10af700021700000215800000e00601021680000c0 +:10af8000029d093c4d1528252110680000004280d3 +:10af900088004330080060500000e3800100e7248f +:10afa0000000ec800300801121188801f8ff0010d8 +:10afb000000062800000e3802b000824030068107a +:10afc0002d000f2404006f14000000002d007838bd +:10afd00001000e2f0100e7241100c014100003240b +:10afe0000000e280300019241c0059140a000624d5 +:10aff0000100e7240000e38078000924080006240b +:10b000000400691001000d2458000c2414006c1475 +:10b01000ff7f023c0100e72410000010100006240e +:10b020000f00c314ff7f023c0000ef8030000824b3 +:10b030000c00e815ffff43340100e7240000e38023 +:10b04000780018240400781001000d2458001924f9 +:10b0500004007914ffff43340100e724ff7f023c22 +:10b06000ffff43341a006600f401c0002148e000ed +:10b070000000e7802400e01012600000029d083c00 +:10b080004d151825217860002110f800000043902c +:10b090000400793007002017d0ffe824030068304f +:10b0a0001900001101006330a9fff924c9ffe82449 +:10b0b0000a4023032a18060101007938c217080044 +:10b0c000253859001100e05401006f2d2a388a01fb +:10b0d0000800e01401000d24080060550100292536 +:10b0e0000250467123c8ea012a102803020040508a +:10b0f0002150480101000b2401002925000027816f +:10b10000e2ffe0542110f80001006f2d2460cf0110 +:10b1100023300a000b50cc000800601121104001c0 +:10b1200022000b2400a00a3c04024bad0300c01512 +:10b130000080023cff7f0e3cffffc2350200a010e2 +:10b140000a488d000000a9ac0800e00300000000e0 +:10b15000e8ffbd271000bfaf1b7c400f00000000c0 +:10b160001000bf8f0800e0031800bd27e8ffbd27cf +:10b170001000bfaf0400828c21188000ffff06245e +:10b18000010004242128400003004610000060aca8 +:10b1900004000010040066ac606d400f0000000069 +:10b1a000212840001000bf8f2110a0000800e003fc +:10b1b0001800bd27e8ffbd271000b0af1400bfafd7 +:10b1c00010008394020062300e0040102180800045 +:10b1d0000000838c0e0060041400bf8f0c00848c70 +:10b1e0000300641023288300626d400f0800048e62 +:10b1f0000800058e0c00068e040005ae030000104a +:10b20000000006aeffff0724040087ac1400bf8fc8 +:10b210001000b08f211000000800e0031800bd27c7 +:10b22000d8ffbd271c00b1af1800b0af2000bfafe2 +:10b230000c00a28c2180a000218880000100052440 +:10b2400006004014212000021000a427626d400f68 +:10b250001000b1a323000010000000ae0000068e15 +:10b26000ffff03240100c5240d00a314000005ae58 +:10b270000800078e00a0083c040405250800e0141f +:10b280008000062410000a96040005ae100049351f +:10b29000000006ae080005ae0c0006ae100009a6c0 +:10b2a0006d6c400f0000000000000e8e04000c8e3c +:10b2b000ffffcd2501008b250a00042400000dae00 +:10b2c000000091a10700241604000bae1000189690 +:10b2d00008000f330300e011212000026d6c400fc5 +:10b2e00000000000211020022000bf8f1c00b18f41 +:10b2f0001800b08f0800e0032800bd27e0ffbd273d +:10b300001000b0af0280c5701800b2af1400b1af2a +:10b310001c00bfaf2188c0002190800011000012e6 +:10b32000212800001000e6942120e0000100c23036 +:10b33000060040104000c3341000e3a400a0043c09 +:10b340000900032407000010040283ac6d6c400f59 +:10b350000000000021280002626d400f2120400201 +:10b36000212820021c00bf8f1800b28f1400b18f5b +:10b370001000b08f2110a0000800e0032000bd27be +:10b3800010008794ffffe330241065004000e6348e +:10b390000600401001000324100086a409000524c3 +:10b3a00000a0043c040285ac211800000800e00362 +:10b3b00021106000c8ffbd27ffffa9242128c0007d +:10b3c0002130e000029d073c21408000ffff0b245c +:10b3d0001000a42782000a24ac17e2243000bfaf7b +:10b3e0002200aba72000aaa71c00a9af1400a8af99 +:10b3f0002800a2af1000a9af356e400f1800a8af0b +:10b400001400a38f3000bf8f3800bd270800e00371 +:10b41000000060a02110a000ff7f053ce8ffbd27d1 +:10b420002138c000ffffa5341000bfafed6c400f06 +:10b43000213040001000bf8f0800e0031800bd2736 +:10b44000e8ffbd272110a000ff7f053c2000a6af2c +:10b450002400a7afffffa5342000a7271000bfaf2f +:10b46000ed6c400f213040001000bf8f0800e0035a +:10b470001800bd270800e003211000000800e003c9 +:10b48000211000000800e003211000000800e00384 +:10b49000211000000800e003211000000800e00374 +:10b4a000211000000800e003211000000800e00364 +:10b4b000211000000800e003211000000800e00354 +:10b4c000211000000800e003ffff02240800e00351 +:10b4d000000000000800e003000000000800e00396 +:10b4e000000000000800e003000000000800e00386 +:10b4f000000000000800e003000000000000828c53 +:10b50000e8ffbd27040040141000bfaf0200032471 +:10b5100009f8a000000083ac1000bf8f21100000cc +:10b520000800e0031800bd270800e003ffff022425 +:10b530000800e003ffff02240800e00321100000e0 +:10b540000800e0032110a000ffff00100000000031 +:10b55000ffff0010000000000800e00300000000f2 +:10b560000800e0030000000000601a40bfff1b3c21 +:10b57000ffff7b3724d05b0300609a401800004235 +:10b580000800e003ffff0224e0ffbd271400b1af75 +:10b590001000b0af1800bfaf2188800008008010f5 +:10b5a0002180a000070000121800bf8f0000248235 +:10b5b000db73400fffff1026faff00100100312659 +:10b5c0001800bf8f1400b18f1000b08f0800e00387 +:10b5d0002000bd27ffff001000000000e0ffbd2796 +:10b5e0001800b2af1400b1af1000b0af1c00bfaf75 +:10b5f000218880002190c0000c00a010ffffb02423 +:10b6000000002482a073400f21284002ffff032482 +:10b61000ffff102603004314010031260400001030 +:10b62000ffff0224f7ff03560000248221100000d0 +:10b630001c00bf8f1800b28f1400b18f1000b08fa4 +:10b640000800e0032000bd27e0ffbd271800b2afcf +:10b650001400b1af1000b0af1c00bfaf2180a0003c +:10b66000219080002188c0000d0000122100022ed0 +:10b67000200007240b3802022128e00021202002ac +:10b6800021304002776d400f23800702ffff032423 +:10b69000f5ff4314ffff0224030000101c00bf8fbe +:10b6a000211000001c00bf8f1800b28f1400b18f52 +:10b6b0001000b08f0800e0032000bd27d0ffbd2799 +:10b6c0001400b1af2188e0004000a78f1800b2af8e +:10b6d0001000b0af0100f2302180c0000100432e05 +:10b6e0001c00b3af2a981102029d063c241073007f +:10b6f0002800b6af2400b5af2000b4af2c00bfaf18 +:10b7000021a0a0007016c624ffff162423283002b3 +:10b7100021a880000400401021180000926d400f05 +:10b720000000000021184000212080022128000292 +:10b730000e0076102130a002776d400f000000004f +:10b740000b0056102a2030020a0040520a802402c0 +:10b75000029d053c7016a6242120a0020300601261 +:10b7600023283002926d400f000000002a20300292 +:10b770000a802402211000022c00bf8f2800b68fff +:10b780002400b58f2000b48f1c00b38f1800b28f37 +:10b790001400b18f1000b08f0800e0033000bd2707 +:10b7a000c8ffbd272c00b5af1c00b1af21a8c00059 +:10b7b0002188e00021300000213800002800b4afcb +:10b7c0002400b3af2000b2af1800b0af3000bfaf5d +:10b7d000219080002198a0004800b48f7379400f19 +:10b7e0004c00b08311004010029d023c6817468c4b +:10b7f0006c17478c21204002a176400f212860025f +:10b8000021204000212860001075400f1000a6275d +:10b810000b000010029d063c000025a20000a48e33 +:10b8200001008324210000100000a3ae9878400f8f +:10b83000d0ff04261000a2af1400a3af029d063c67 +:10b840007017c48c7417c58c1400a78f7379400fc0 +:10b850001000a68f16004104211020022e0006249d +:10b860003000052400008d822660a60101008b2d8a +:10b8700023208b0200008a90ffff942401004825ba +:10b88000204c087c3a0027290800e014000088a01a +:10b89000f4ff9114000085a0dfffa05631000524bd +:10b8a00031000e24ffff2ea2ffff312621102002bf +:10b8b0003000bf8f2c00b58f2800b48f2400b38fc9 +:10b8c0002000b28f1c00b18f1800b08f0800e00379 +:10b8d0003800bd2718fbbd27e404bfafe004beafae +:10b8e000dc04b7afd804b6afd404b5afd004b4af5e +:10b8f000cc04b3afc804b2afc404b1afc004b0af9e +:10b900001800838cec04a5af1000628ce804a4af8f +:10b910000100052409f84000f004a6af9404a0af8c +:10b9200034054010ffff0324ec04a68f0000c48000 +:10b930000100c52429058010ec04a5af25000724cb +:10b9400006008710ec04a88fa073400fe804a58fb1 +:10b950009404a48f1f0500100100832400001281ad +:10b960000b004416ffff0624e804a58fa073400fc8 +:10b9700025000424ec04ac8f9404aa8f01008b25cd +:10b9800001004925ec04abafe7ff00109404a9af18 +:10b990009c04a0af2d0007242b00052420000424c4 +:10b9a0002300032430000224030047169c04ad8fbb +:10b9b000100000100100a835030045169c04ae8f4e +:10b9c0000c0000100200c835030044169c04af8f21 +:10b9d000080000100400e835030043169c04b08ff3 +:10b9e0000400001008000836080042169c04b18fbd +:10b9f00010002836ec04b28f9c04a8af0100532637 +:10ba0000ec04b3afe8ff0010000072822a00142497 +:10ba10000e005416d0ff4526f004a28ffcff1f2411 +:10ba200003005e2424b0df03ec04b98f0000d88e3d +:10ba300001003727ec04b7af9804b8af0000f282da +:10ba40000400d52611000010f004b5af0a00a32ca5 +:10ba5000160060109804a0af0a0003249804ac8f6d +:10ba6000ec04ad8f025883710100aa25ec04aaaf43 +:10ba70002148720100005281d0ff2825d0ff4426c2 +:10ba80000a00872cf5ffe0149804a8af9804a88f4b +:10ba9000070001052e0011249c04b08f23700800bc +:10baa00001000f369c04afaf9804aeaf2e001124f6 +:10bab0002600511668000c24ec04b28f2a000624dc +:10bac00001005326ec04b3af000072820d0046164d +:10bad000d0ff4226f004be8fec04b78f0300d827b6 +:10bae0000100f626fcff192424a81903ec04b6afc4 +:10baf0000000d2820000a68e0400b4260f000010c1 +:10bb0000f004b4af0a005f2c0f00e01321300000f6 +:10bb10000a000324ec04aa8f0220c3700100482508 +:10bb2000ec04a8af2148920000001281d0ff472604 +:10bb30000a00e52cf7ffa014d0ff26250000c3283b +:10bb4000ffff0b240b30630168000c2412004c161d +:10bb50006c001524ec04a58f0100ad800700b21520 +:10bb60009c04b38f9c04b08f0100ae2480000f367c +:10bb70009c04afaf03000010ec04aeaf00017136bf +:10bb80009c04b1afec04b28f01005426ec04b4afb6 +:10bb90002700001000009282120055167100072441 +:10bba000ec04a48f010096800700d2169c04bf8f7e +:10bbb0009c04b98f01009724000838379c04b8af63 +:10bbc00003000010ec04b7af0002fe379c04beafc8 +:10bbd000ec04a58f0100a224ec04a2af1400001015 +:10bbe00000005280090047164c000b24ec04aa8f79 +:10bbf0009c04a88f01004425ec04a4af00009280af +:10bc0000000809350a0000109c04a9af09004b1672 +:10bc1000ec04b18fec04ae8f9c04ac8f0100cd25f9 +:10bc2000ec04adaf000483350000b2819c04a3afe7 +:10bc3000ec04b18f9c04a38f0100302602006f300a +:10bc40000400e011ec04b0affbff1424249874004e +:10bc50009c04b3af9c04a58f0100b5300400a01272 +:10bc6000bcff4326efff172424b0b7009c04b6aff7 +:10bc70003500782c5504001321100000029d053c6e +:10bc800080f803009016a22421f0e2030000d98f6f +:10bc900008002003000000009c04a78f0002f2347b +:10bca0009c04b2af9c04aa8ff7ff0424001048350f +:10bcb000244804010d0000109c04a9af9c04a38f2c +:10bcc00000026b349c04abaf150000100800142474 +:10bcd0009c04ad8f0002ac359c04acaf9c04af8fcc +:10bce000f7ff10242470f0019c04aeaf0c0000108c +:10bcf0000a0014249c04b38f004071360700001022 +:10bd00009c04b1af9c04b58f0040b4369c04b4af22 +:10bd10009c04b78f0802f6369c04b6af10001424ba +:10bd2000ffff18240300d8149c04be8f04000010e9 +:10bd300001000624efff1f2424c8df039c04b9afd1 +:10bd40009c04a58f0010b6300b00c0120008a23072 +:10bd50000c004014f004ab8ff004a98ffcff022408 +:10bd6000030027252410e2000000528c212040020d +:10bd700010000010c32f120009004010f004ad8f16 +:10bd8000f004ab8ff8ff0a240700642524408a00e2 +:10bd90000000048d0400058d070000100800022536 +:10bda000fcff0c240300a32524106c000000448c2d +:10bdb0002128000004004224f004a2af218080006a +:10bdc0002188a0002198c0005f00b2270800c0129f +:10bdd00021b800000700a1042118000023801000f2 +:10bde000238811002b101000238822020100172441 +:10bdf000211800001b001016212800021a007114df +:10be000025101102330000129c04ae8f0040c63191 +:10be10001b00b400f4018002102000000a008f28eb +:10be20000300e05137009124040000103000842406 +:10be300057009024212020020a2006021b00b40093 +:10be4000f4018002000044a2ffff7326ffff522688 +:10be500012a80000eeffa016122800001e0000101d +:10be6000ffff6226251011021a004010c3af140014 +:10be700021282002213080022138a002f47e400fc8 +:10be8000212000020a00582806000017300045242f +:10be90009c04bf8f570059240040fe3337004524cf +:10bea0000a283e03000045a221200002212820028a +:10beb00021308002d57d400f2138a0022180400032 +:10bec0002188600025104300ffff5226e6ff001086 +:10bed000ffff7326ffff6226070040049c04a88f23 +:10bee00030000324ffff4224000043a2fdff410471 +:10bef000ffff52269c04a88f10001331250060120a +:10bf00009c04ae8f2000a5279804a98f23384502f2 +:10bf100021282701080002310c004010c1ffa42491 +:10bf20000800082407008816feff8c2401004b82bd +:10bf300030000a2404006a511000833a0300001004 +:10bf4000c0ffa4241000833a0a2083010900c052d4 +:10bf5000ffff83240600e056ffff84249c04a68f85 +:10bf60000600cd300300a011ffff8324ffff8424cf +:10bf7000ffff8324070062049c04ae8f300002247c +:10bf8000ffff6324000042a2fdff6104ffff522671 +:10bf90009c04ae8f0800c4311600801008000f24e6 +:10bfa00008008f5610001124010050823000032435 +:10bfb0000400035210001124000043a20d000010e1 +:10bfc000ffff52260b009116212840029c04b28fdd +:10bfd000ffffa324004054320200801658000424be +:10bfe00078000424300015240000a4a0ffff722470 +:10bff000000075a01000c012010045260b00e016dd +:10c000002d0002249c04b78f0200f6320300c012f8 +:10c010009c04b98f050000102b0002240400383363 +:10c02000050000530100452620000224000042a222 +:10c03000ffff52260100452623f0a5031f03001031 +:10c040006000c627f004ac8ff8ff0a2407008b2598 +:10c0500024406a010000098d0400078d6000a9af2b +:10c060006400a7af6000b08f6400b18f08000525a1 +:10c070000055337eff077f3af004a5af2300e01799 +:10c08000a004a6af212000022128200221300002b6 +:10c090007379400f21382002070040502120000210 +:10c0a000029d033c9804a78fe804a48f9017652491 +:10c0b0000403001003000624212820022130000080 +:10c0c0007379400f2138000009004304029d043cad +:10c0d000029d063c9c04ad8f9804a78fe804a48fb2 +:10c0e0009c17c52404000624f80200101000adaf10 +:10c0f000941785249c04ae8f9804a78fe804a48f1e +:10c1000004000624f10200101000aeafffff0f2460 +:10c110000400cf14a404a0af0600142413000010e0 +:10c12000a004b4af2800d5281100a01621400002b9 +:10c1300067005e3a4700593a2bb81e002bc0190021 +:10c1400024b0f8020600c016d9ffc2249c04b38fa5 +:10c1500008007f320400e01327000724d9ffc2241f +:10c16000a404a2af27000724a004a7af2140000227 +:10c17000214820026900a0a39004a0afa004be8fb4 +:10c18000a804b2af0a002106b404a0af21500001f8 +:10c19000029d083c7c17058d2d0009242688250268 +:10c1a0007002a9a321404001020000102148200292 +:10c1b0007002a0a38004a627212000011075400f63 +:10c1c000212820016900ad276902ac2721a8600061 +:10c1d000ffff8b250100a32521a04000b804a3afd9 +:10c1e000ac04a3af2198600024000010b004abaff2 +:10c1f0006817108f6c17118f2120c0022128e002d0 +:10c20000213820026b77400f2130000221204000ae +:10c21000212860008004a6271075400f029d173c5e +:10c220008017e68e8417e78e2120400021286000c9 +:10c230008804a2af9875400f8c04a3af2120400062 +:10c240002130000221286000a176400f2138200211 +:10c25000212040003079400f21286000b004af8fca +:10c26000300056240000f6a19004ae8fffffe425b5 +:10c270000100c625b004a4af9004a6af8004b68f19 +:10c280008404b78f21300000213800002120c00233 +:10c290007379400f2128e002d5ff4014029d183c1d +:10c2a000650019246c00591266005f2a0600e0132d +:10c2b000660007244500022467004212470002245a +:10c2c0000300001000000000050047126700022470 +:10c2d000580142126900a68300020010b804b08f12 +:10c2e0009004b28f10004012b804a38fb004a58f41 +:10c2f0006902a9270100a4242b5089000e004011d7 +:10c30000a004ad8f00008b906902ac27010084244b +:10c310002b408c0000006ba2faff00150100732671 +:10c3200005000010a004ad8f30001324000073a09e +:10c3300001007324a004ad8f0600a0152e00042474 +:10c340009c04ae8f0800c6310500c0102120800279 +:10c350002e000424000064a2010073262120800224 +:10c360002128a002213000007379400f21380000fd +:10c370002f004010a004af8f1d00e011212080028b +:10c38000029d113c6817268e6c17278e2120800293 +:10c39000a176400f2128a002212040002128600022 +:10c3a0001075400f8804a6278804a48f8c04a58fdd +:10c3b00021a040003079400f21a8600030005624b1 +:10c3c000ffffde27000076a20800c01301007326dd +:10c3d000212080022128a002213000007379400f23 +:10c3e00021380000e7ff4014029d113c212080020b +:10c3f0002128a002213000007379400f213800006d +:10c400000b004010b804a78fffff772621300000f3 +:10c410007002b027212080022128a0021000b7afaf +:10c420001800b0afe86d400f1400a0afac04a2af8d +:10c43000a801c013ffffc22730000424ffff03241c +:10c44000ffff4224000064a2fdff43140100732695 +:10c45000a10100106900a6839004b88f3900001371 +:10c4600021208002b004a28fb804b98f01005f9030 +:10c470000100432400003fa30500c017010030273e +:10c480009c04b28f080047321800e01001006d24b0 +:10c49000b804aa8f2e000924010049a11200c0137c +:10c4a00002005025b004a88f6902a52702000325c9 +:10c4b0002b1065000a0040100000000000006b9087 +:10c4c000ffffde2700000ba20700c01301001026ab +:10c4d000010063246902ac27f6ff00102b106c00ea +:10c4e0001500c0179004a48f01006d246902a627cf +:10c4f0002b98a601100060129004a48fffff0e2657 +:10c500001000aeaf010075807002b4271400b5af03 +:10c510001800b4afb804a78f21a0000021a8000024 +:10c520009004a62721208002e86d400f2128a00258 +:10c53000ac04a2af9004a48fffff83243d00001041 +:10c540009004a3af2128a002213000007379400f8e +:10c55000213800002b004010b804a78fffff0224f1 +:10c560009004a2af029d0f3c6817e68d6c17e78d13 +:10c5700021208002a176400f2128a0022120400026 +:10c58000212860001075400f8804a6278804b08f0a +:10c590008c04b18f213000002138000021200002de +:10c5a0002128200221a040007379400f21a86000bb +:10c5b000030040149004b68fe9ff0010ffffc2266d +:10c5c000212000023079400f21282002b804b18fc9 +:10c5d00030005024000030a20500c01701003026b2 +:10c5e0009c04b88f080017331300e012212080024a +:10c5f000b804b98f2e001f24020030270d00001050 +:10c6000001003fa3300002240000e2a00500c01793 +:10c610000100f0249c04aa8f080052310600401249 +:10c6200021208002b804a98f2e000524010025a135 +:10c6300002003025212080022128a00221300000a4 +:10c640007379400f213800002f00401000000000d7 +:10c650001d00c01321208002029d0b3c6817668dcf +:10c660006c17678d21208002a176400f2128a0023f +:10c6700021204000212860001075400f8804a62763 +:10c680008804a48f8c04a58f21a040003079400f2e +:10c6900021a8600030004824ffffde27000008a228 +:10c6a0000800c01301001026212080022128a002ca +:10c6b000213000007379400f21380000e7ff40145b +:10c6c000029d0b3c212080022128a0022130000085 +:10c6d0007379400f213800000b004010ac04a78f85 +:10c6e0007002ac27ffff13269004a62721208002aa +:10c6f0002128a0021000b3af1800acafe86d400fc6 +:10c700001400a0afac04a2af0700c013ffffc22704 +:10c7100030000424ffff0324ffff4224000004a292 +:10c72000fdff431401001026b404be8f1400c05353 +:10c730009004a48f9c04a68f0800cd301000a05553 +:10c740009004a48f30000324ac04b58f2ba0b0025a +:10c750000600805200001682ffff102600000e82a5 +:10c76000fbffc3112ba0b002000016822e00cf3aaf +:10c770000100e42d23180402010070249004a48f0a +:10c78000a804b18f02000526000011a20600810452 +:10c790007804a8272d001724232004002130a000ae +:10c7a00004000010010017a22b001824010018a299 +:10c7b0002130a0000a00902817000016213800013f +:10c7c0000a0005241a008500f401a000ffffe724f9 +:10c7d000101000001220000030005f240a00992889 +:10c7e000f8ff20130000ffa0ffffe52430008a249b +:10c7f0002b18a800ffffeaa0b60060102198c00027 +:10c800000000a7900100a5240000c7a02b18a800d5 +:10c81000f9ff00100100c6243000892430000824ec +:10c820000000a8a00100a9a00200a624a9000010f1 +:10c830002198c000a004ab8f010010249004a38fa6 +:10c840000b80cb032a2803021300a014feff4d2601 +:10c8500016006014b004ae8f212080022128a002af +:10c86000213000007379400f213800001e00401075 +:10c87000b804a48f029d0c3c8817868d8c17878d79 +:10c88000212080027379400f2128a0021600410464 +:10c89000b804a48ffeff4d2601001324ffff1e26bf +:10c8a000a804adafecfe0010b404b3af6902a62734 +:10c8b0000100c4252bf086000e00c013000000000c +:10c8c00000008f906902b627010084242b1896007f +:10c8d00000006fa2ffff1026f9ff6014010073260d +:10c8e000040000100000000030001124000091a09e +:10c8f00001009324060000162e0019249c04b88f12 +:10c90000080017330500e012219000002e001924c2 +:10c91000000079a201001224010073262120800268 +:10c920002128a002213000007379400f2138000037 +:10c930004c0040509c04b58f38000012212080022a +:10c94000029d113c6c17278e6817268e21208002cd +:10c95000a176400f2128a002212040008804a627ac +:10c960001075400f212860008804a48f8c04a58fc7 +:10c9700021a040003079400f21a8600030005f24e2 +:10c9800000007fa28804a48f8c04a58f21300000b2 +:10c99000213800007379400f010073261500401400 +:10c9a0009004a28fe7ff4050029d113c120000103e +:10c9b000ffff10266c17278e21208002a176400fe2 +:10c9c0002128a00221204000212860001075400f7e +:10c9d0008804a6278804a48f8c04a58f21a040007a +:10c9e0003079400f21a8600030004a2400006aa27c +:10c9f00001007326ffff102607000012212080028d +:10ca00002128a002213000007379400f2138000056 +:10ca1000e8ff40146817268e212080022128a002fa +:10ca2000213000007379400f213800000d00405084 +:10ca30009c04b58fb804a78fffff68267002a92752 +:10ca400021300000212080022128a0021000a8af80 +:10ca50001800a9afe86d400f1400a0afac04a2af5e +:10ca60009c04b58f0800b4320b0080120000000057 +:10ca700018000012ffff022630000424ffff0324e9 +:10ca8000ffff4224000064a2fdff4314010073264f +:10ca9000110000106900a6830f0040126900a683f0 +:10caa00030000324ac04b28f2b80530206000052e6 +:10cab00000006c82ffff732600006782fbffe3101b +:10cac0002b80530200006c822e008b392b280b0028 +:10cad000219865026900a683b804b08fac04ad8fbd +:10cae0007002a3936900be270b80c6030500601087 +:10caf00023886d02ffff102601003126110000106f +:10cb0000000003a29c04ae8f0200d3310600601225 +:10cb10009c04b68fffff10262b0003240100312652 +:10cb200008000010000003a20400cf320600e0114c +:10cb30009c04bf8fffff102620000424000004a2e5 +:10cb4000010031269c04bf8fa404b98f9804a88fdc +:10cb50000100f433219039020100982e2a984802ee +:10cb600024b813030700e01221200000029d023cbc +:10cb7000e804a48f70164624926d400f23281201fa +:10cb800021204000ffff152405009510e804a68f22 +:10cb900021200002776d400f212820022120400033 +:10cba000a404a58f274004002b5008002b48050043 +:10cbb000248849010600201200000000e804a48f28 +:10cbc000029d103c926d400f501606262120400019 +:10cbd0000c0095109804a78f0b0080122a28f200f1 +:10cbe0000a0060120b3845029804b48f029d153c70 +:10cbf000e804a48f7016a626926d400f2328920297 +:10cc00009804a78f2a28f2000b3845026f00001005 +:10cc10002110e000f004b38ffcff062403007e2601 +:10cc20002458c60300006d8d9c04ac8f9804a78f18 +:10cc3000e804a48f040072257804a52701000624c7 +:10cc40007804ada31000acaf20000010f004b2af28 +:10cc5000f004a48ffcff0324030096242478c3026d +:10cc60000000f18d0400ee25f004aeaf04002016a4 +:10cc700021802002029d173ca417f126218020026a +:10cc8000ffff18240900d814ffffc324636a400f74 +:10cc9000212020020700001021800202060020133c +:10cca00021282002ffff632401001026fbff6304fc +:10ccb0000000198221282002233011029804a78f36 +:10ccc000e804a48f9c04bf8f1000bfafaf6d400f6e +:10ccd000000000003e0000109404ad8f9c04b18f52 +:10cce000000822320d0040109c04ab8ff004a58f89 +:10ccf000fcff07240300b52424a0a7029404a88ff6 +:10cd000000008a8ec34f080004009026f004b0afe4 +:10cd1000000048ad2c000010040049ad0002723143 +:10cd20000b0040529c04a38ff004af8ffcff0e2435 +:10cd30000300f32524306e020000cc8c9404ad8fe8 +:10cd40000400de24f004beaf1f00001000008dad13 +:10cd5000f004a48f000176300900c0120300832480 +:10cd6000fcff022424f862000000f78f9404b88fbf +:10cd70000400f927f004b9af130000100000f8a672 +:10cd80009c04aa8f8000513109002012fcff0c2462 +:10cd9000fcff152424a075000000898e9404a88f40 +:10cda00004009026f004b0af07000010000028a196 +:10cdb00024586c000000678d9404a58f0400722530 +:10cdc000f004b2af0000e5ac211000009404ad8f78 +:10cdd0002118a201d4fa00109404a3afe804ae8f86 +:10cde0009404be8f1000d395ffff032440006632e9 +:10cdf0000a18c603e404bf8fe004be8fdc04b78fbb +:10ce0000d804b68fd404b58fd004b48fcc04b38fbc +:10ce1000c804b28fc404b18fc004b08f2110600069 +:10ce20000800e003e804bd2700a0063ce8ffbd279a +:10ce30001c01c28c1000bfaf211880000400448c7c +:10ce40002130a000356e400f212860001000bf8ff8 +:10ce50000800e0031800bd270800e003ffff0224dc +:10ce60000800e003211080000800e003211000000a +:10ce70000800e003211000000800e0030100022484 +:10ce8000e0ffbd271400b1af1000b0af1800bfaf76 +:10ce90001800a38c2180a0001000628c21888000e3 +:10cea0002120a00009f840000100052419004010cd +:10ceb000ffff03240000078e0a00283affffe62444 +:10cec00021202002212800020100032d0600c004b9 +:10ced000000006ae10000b96c0006a7d2448430196 +:10cee000070020112130200218000c8e0400908dc4 +:10cef00009f8000200000000050000102130400089 +:10cf00000400058e0100a4240000b1a0040004aeba +:10cf10002118c0001800bf8f1400b18f1000b08f0f +:10cf2000211060000800e0032000bd27e8ffbd27b6 +:10cf30001000bfafa073400f000000001000bf8fb3 +:10cf40000800e0031800bd2700a0033ce8ffbd2750 +:10cf50001c01628c1000bfafa073400f0400458c11 +:10cf60001000bf8f0800e0031800bd272024047cb8 +:10cf700080bf033c1062658c0002a27cfdff401064 +:10cf80000000000080bf033c206264ac0800e003a6 +:10cf9000000000004050050042550a00c04a05004c +:10cfa000427d040025482f01c042040000800e3c51 +:10cfb00025482e0140680700426d0d00c062070041 +:10cfc000427d060025608f01c05a060025608e0153 +:10cfd0002470c501ffff4f25fe07e12d56002010ec +:10cfe00000000000ffffaf25fe07e12d6e002010be +:10cff0000000000023384d014b00e0040000000059 +:10d0000042400800c07f090025400f014248090046 +:10d0100042580b00c07f0c0025586f0142600c0085 +:10d020002b780b0123400b012b102f0123482f01dc +:10d030002b782c012578e2010500e01123482c0112 +:10d0400021400b012b780b0121482c0121482f0195 +:10d050002a780001214008012148290121482f0197 +:10d06000ffffe724eeffe1040000000008002015a8 +:10d0700025500d0003000015000000000d000010f9 +:10d0800000000a242548000100000824e0ff4a258a +:10d09000203827710700e0100000000023504701ee +:10d0a000223007000630c8000440e8000448e900c8 +:10d0b000254826011400401d00000000010007243f +:10d0c0002338ea002000e12c0500201400000000b5 +:10d0d0002540090000000924faff0015e0ffe724bd +:10d0e0000800e01000000000253009000640e800bc +:10d0f0000648e90020000f242338e7010430e60049 +:10d100002540060100000a24c2220800407d0900d3 +:10d1100025208f0040280900022b0500007d0a0011 +:10d120002528af002528ae0025100400251805008d +:10d130000800e003000000003b0040150000000074 +:10d140002a780001214008012148290121482f01a6 +:10d1500025782801a3ffe011000000000800201539 +:10d160000000000003000015000000009dff0010fb +:10d1700000000a242548000100000824e0ff4a2599 +:10d180002038277197ffe01000000000235047016e +:10d19000223007000630c8000440e8000448e900d7 +:10d1a00090ff0010254826011b00a015000000007c +:10d1b0002a78600121586b0121608c0121608f0168 +:10d1c00025788b011800e011000000000800801590 +:10d1d00000000000030060150000000085ff001043 +:10d1e00000000d242560600100000b24e0ffad2548 +:10d1f000203887717fffe010000000002368a7013e +:10d20000223007000630cb000458eb000460ec002d +:10d2100078ff00102560860140780c002578eb012e +:10d22000c1ffe01100000000f8ff053cbeff001048 +:10d230000000042440380500423d0700ffffe924b8 +:10d24000fe07212d0c0020100000000002fce72446 +:10d250000f80013cffff21342428a100e03f013c66 +:10d260002528a1000000c7ac2510040025180500e2 +:10d270000800e003000000001300e01400000000bc +:10d280004048050025482401f6ff20110000000059 +:10d290000080013c2440a1000100e724ffffe724b7 +:10d2a0002a488000212084002128a5002128a900e7 +:10d2b0001000013c2b08a100f8ff20140000000022 +:10d2c000e2ff00102528a800f8ff053c0000072415 +:10d2d000e4ff00102520070040480500424d0900ea +:10d2e000ffff2c25fe07812d0f00201000000000fd +:10d2f00021482601ffff2c25fe07812d210020104b +:10d30000000000000f80013cffff21342428a10011 +:10d31000006509002528ac0025100400251805002b +:10d320000800e003000000000063050025608401a0 +:10d33000f9ff80110000000004002011000000002f +:10d34000f8ff053cf4ff001000000424010029252b +:10d350000080013c2450a100ffff29252a608000a5 +:10d36000212084002128a5002128ac001000013cc8 +:10d370002b08a100f8ff201400000000dcff0010c3 +:10d380002528aa00c04205004265040025400c0182 +:10d39000c03a04000080013c254001010080013cae +:10d3a000050020192428a100f07f013c2528a100b8 +:10d3b000d9ff00100000042401000a242350490171 +:10d3c0002000412d0700201400000000e0ff4a214a +:10d3d0002b2007000d00081025380401f8ff00106d +:10d3e00000000834090040110000000022580a0023 +:10d3f00004206701045868010638470106404801c7 +:10d4000002008010253867010200e7340004e72499 +:10d410000004ec2c21400c01c262070001008c3199 +:10d420002338ec00c22207004065080025208c004c +:10d430004060080002630c00b7ff00102528ac0014 +:10d4400025380400254005000080013c2458a10037 +:10d4500040480500424d0900ffff2c25fe07812da5 +:10d46000370020100000000033040a242350490133 +:10d47000350041292f002010000000002000412924 +:10d480000600201400000000e0ff4a2500000424ec +:10d490000628450105000010042845010300401935 +:10d4a000000000000620440104204401234005013f +:10d4b0002338e4000000c4ac0400c5ac080000152b +:10d4c0000b0029250300e014000000000d000010ef +:10d4d000000009242540e00000000724e0ff292582 +:10d4e0002020047107008010000000002348240160 +:10d4f0002250040006504701043887000440880089 +:10d5000025400a01c22207004065080025208c0042 +:10d5100040280800022b0500006509002528ac0002 +:10d520002528ab0025100400251805000800e0039d +:10d53000000000000400cbacfaff00100000c0acfb +:10d54000fcff201100000000f8ff053c000004244f +:10d550000000c4acf3ff00100400c5ac0080013c27 +:10d560002440a10040380500423d0700ff07012488 +:10d570002a00e1100000000033040a242338470188 +:10d580002200e018000000003500e1280800201407 +:10d59000000000002a000015000000002550a40033 +:10d5a00024004015000000002500001000000000cd +:10d5b00005000015000000002b500400232004008b +:10d5c000232805002328aa001f00ea3001000924af +:10d5d00004484901234809002000e12804002014e0 +:10d5e0000000000000000424020000102428a9000c +:10d5f0002420890005000015000000002b500400c5 +:10d6000023200400232805002328aa002510040055 +:10d61000251805000800e003000000000053050085 +:10d62000255044010900401500000000f7ff0010dc +:10d6300000000000f03f053cf4ff0010000004244f +:10d6400025280800f1ff001000000424f8ff053c25 +:10d65000eeff0010000004240080013c2638e100a9 +:10d6600040580500425d0b00c0520500427d040099 +:10d6700025504f01c04a04000080083c2550480155 +:10d680004070070042750e00c06a0700427d060028 +:10d690002568af01c06206002568a801ffff6f255d +:10d6a000fe07e12d8d00201000000000ffffcf25b8 +:10d6b000fe07e12dbb002010000000000080013caf +:10d6c0002428a10023406e012c000011000000005e +:10d6d00015000019000000002000012d0700201493 +:10d6e00000000000e0ff08212b300c0023000d108b +:10d6f0002560a601f8ff001000000d341f00001186 +:10d70000000000002220080004308c0004208d005e +:10d7100006600c0106680d011800c01025608c0021 +:10d720001600001002008c3525580e00234008001a +:10d730002000012d0700201400000000e0ff082158 +:10d740002b3009000d000a1025484601f8ff001093 +:10d7500000000a3409000011000000002220080027 +:10d760000430890004208a000648090106500a0195 +:10d770000200c01025488900020029352678a7003c +:10d780001c00e0050000000021482c012b782c0132 +:10d7900021504d0121504f0102004d1100000000a9 +:10d7a0002b784d013700e0110000000001002f31ff +:10d7b0000200e01100000000020029354248090083 +:10d7c000c07f0a0025482f0142500a000080013c1a +:10d7d0002550410101006b25ff0701242900611537 +:10d7e00000000000f07f013c2528a1003700001058 +:10d7f000000004242b782c0123482c012b104f010e +:10d8000023504f012b784d012578e2010700e011ec +:10d8100023504d010080013c2628a1002b780900ef +:10d820002348090023500a0023504f0108004015e7 +:10d830000000000003002015000000000d00001093 +:10d8400000000b242550200100000924e0ff6b2577 +:10d8500020404871070000110000000023586801b3 +:10d8600022200800062089000448090104500a010a +:10d8700025504401257849010200e0150000000010 +:10d88000000005246800601900000000000429253c +:10d8900000042f2d21504f012b784f0121586f018b +:10d8a000c27a09000100ef3123482f01c22209008a +:10d8b000407d0a0025208f0040780a00027b0f007f +:10d8c0002528af00007d0b002528af00251004009f +:10d8d000251805000800e003000000002a78200158 +:10d8e0002148290121504a012300601521504f0190 +:10d8f000257849011400e0110000000008004015df +:10d9000000000000030020150000000067ff001069 +:10d9100000000b242550200100000924e0ff6b25a6 +:10d920002040487161ff0011000000002358680189 +:10d9300022200800062089000448090104500a0139 +:10d940005aff001025504401ff0701241500c111a2 +:10d95000000000002140e700257806010300e015e3 +:10d9600000000000d9ffe0040000000025100600c0 +:10d97000d8ff001025180700257849012700e01579 +:10d9800000000000ff070124d0ffc11500000000c7 +:10d990002678a7002100e00500000000f3ff00103a +:10d9a000000000002a78800121608c012168ad010f +:10d9b0001700c0152168af012578ac01c3ffe01145 +:10d9c000000000000800a015000000000300801502 +:10d9d0000000000039ff001000000e2425688001bf +:10d9e00000000c24e0ffce252040a87133ff001179 +:10d9f000000000002370c8012220080006208c00cf +:10da000004600c0104680d012cff00102568a401be +:10da10002578ac01d5ffe01100000000f8ff053cbf +:10da2000aaff0010000004240100082423400b0179 +:10da30002000012d0700201400000000e0ff082155 +:10da40002b3009000d000a1025484601f8ff001090 +:10da500000000a3409000011000000002220080024 +:10da60000430890004208a000648090106500a0192 +:10da70000200c010254889000200293583ff0010ec +:10da800000000b244050050042550a00c04a050022 +:10da9000427d040025482f01c042040000800e3c56 +:10daa00025482e0140680700426d0d00c062070046 +:10dab000427d060025608f01c05a060025608e0158 +:10dac0002628a7002428ae00ffff4f25fe07e12de2 +:10dad0004700201000000000ffffaf25fe07e12dea +:10dae0006f0020100000000002fcaf2521504f0104 +:10daf00019002c01123800001070000019000b01f1 +:10db0000122000001030000019002b0112580000f4 +:10db1000106800002130cb002b78cb002138ed00bd +:10db20002138ef000200ed10000000002b78ed001e +:10db30002170cf0119000c011240000010480000b4 +:10db40002130c8002b78c8002138e9002138ef00c7 +:10db50000200e910000000002b78e9002170cf01dd +:10db6000257886000200e011000000000100e73483 +:10db700025480e0006002005254007002a780001f0 +:10db8000214008012148290121482f01ffff4a2592 +:10db9000ffff4f25fe07e12d680020100000000068 +:10dba0000004082500040f2d21482f012b782f0198 +:10dbb00021504f01c27a08000100ef3123400f01cc +:10dbc000c2220800407d090025208f00407809000e +:10dbd000027b0f002528af00007d0a002528af003a +:10dbe00025100400251805000800e00300000000cf +:10dbf0002a78000121400801214829011c00401514 +:10dc000021482f01257828011400e01100000000b0 +:10dc100008002015000000000300001500000000af +:10dc2000adff001000000a24254800010000082470 +:10dc3000e0ff4a2520702e71a7ffc01100000000f0 +:10dc400023504e0122380e000638e8000440c80177 +:10dc50000448c901a0ff001025482701ff0701243f +:10dc60003300a11100000000ddff001000000000e3 +:10dc7000257828012e00e015000000000500a01501 +:10dc80000000000040780c002578eb012800e0112e +:10dc900000000000ff0701242100a1150000000082 +:10dca0002a78600121586b0121608c011900a015b0 +:10dcb00021608f0125788b011400e0110000000025 +:10dcc000080080150000000003006015000000003f +:10dcd00085ff001000000d242560600100000b246a +:10dce000e0ffad25203086717fffc01000000000ee +:10dcf0002368a601227006000670cb010458cb00f1 +:10dd00000460cc0078ff001025608e01b4ff001085 +:10dd10000000042425788b010500e01500000000b8 +:10dd2000f07f013c2528a100adff00100000042475 +:10dd3000f8ff053caaff001000000424f8ff401d76 +:10dd40000000000001000e242370ca012000c12d34 +:10dd50000700201400000000e0ffce212b30080057 +:10dd60000d00091025402601f8ff001000000934bd +:10dd70000900c0110000000022380e000430e80045 +:10dd80000438e9000640c8010648c9010200c01075 +:10dd90002540e800020008350004082500040f2d86 +:10dda00021482f0183ff0010c25709004050050091 +:10ddb00042550a00c04a0500427d040025482f0153 +:10ddc000c042040000800e3c25482e014068070038 +:10ddd000426d0d00c0620700427d060025608f0184 +:10dde000c05a060025608e012628a7002428ae0010 +:10ddf000ffff4f25fe07e12dcb00201000000000a3 +:10de0000ffffaf25fe07e12df40020100000000009 +:10de100023504d01ff034a2542400800c07f0900fe +:10de200025400f0142480900023c0c00f401e000cb +:10de30001b0027011270000010480000ffff863110 +:10de40001900ce0012200000004c0900027c0800de +:10de500025482f012b7824010600e01123482401d6 +:10de6000ffffce2521482c012b082c01fcff2010a0 +:10de700000000000f401e0001b0027011238000040 +:10de8000104800001900c70012200000004c0900d3 +:10de9000ffff0f3125482f012b7824010600e011e8 +:10dea00023482401ffffe72421482c012b082c01e3 +:10deb000fcff20100000000000740e002170c7015c +:10dec0001900cb01123800001020000000000824c7 +:10ded0002b780701234007012b102f0123482f0126 +:10dee0002b7824012578e2010b00e011234824015e +:10def000ffffce2521400b012b780b0121482c017f +:10df000021482f0102002c11000000002b782c0169 +:10df1000f7ffe0110000000006002c1500000000d3 +:10df200025200b002548080000000d242a000010c1 +:10df300025380d00023c0c00f401e0001b00270115 +:10df40001268000010480000ffff86311900cd0064 +:10df500012200000004c0900027c080025482f0117 +:10df60002b7824010600e01123482401ffffad2592 +:10df700021482c012b082c01fcff20100000000080 +:10df8000f401e0001b0027011238000010480000d7 +:10df90001900c70012200000004c0900ffff0f31dc +:10dfa00025482f012b7824010600e0112348240185 +:10dfb000ffffe72421482c012b082c01fcff201037 +:10dfc00000000000006c0d002168a7011900ab01e2 +:10dfd0001238000010200000000008242b780701f0 +:10dfe000234007012b102f0123482f012b782401f8 +:10dff0002578e2010b00e01123482401ffffad2545 +:10e0000021400b012b780b0121482c0121482f01c5 +:10e0100002002c11000000002b782c01f7ffe0110a +:10e02000000000000600c005000000002a78a001e2 +:10e030002168ad012170ce012170cf01ffff4a257b +:10e04000257828010200e011000000000100ad3534 +:10e0500025480e0025400d00ffff4f25fe07e12d4e +:10e0600015002010000000000004082500040f2dfa +:10e0700021482f012b782f0121504f01c27a08002f +:10e080000100ef3123400f01c2220800407d09004a +:10e0900025208f0040780900027b0f002528af0063 +:10e0a000007d0a002528af00251004002518050072 +:10e0b0000800e003000000004400401d00000000d4 +:10e0c00001000e242370ca012000c12d0700201476 +:10e0d00000000000e0ffce212b2008000d000910f9 +:10e0e00025402401f8ff0010000009340900c01188 +:10e0f0000000000022300e000420c8000430c900d7 +:10e100000640c8010648c901020080102540c80029 +:10e11000020008350004082500040f2d21482f01b6 +:10e12000d6ff0010c25709002a78000121400801db +:10e13000214829011700401521482f012578280181 +:10e140001400e0110000000008002015000000008d +:10e15000030000150000000029ff001000000a2441 +:10e160002548000100000824e0ff4a2520702e7198 +:10e1700023ffc0110000000023504e0122300e008a +:10e180000630c8000440c8010448c9011cff001043 +:10e190002548260105004d150000000040780c00c0 +:10e1a0002578eb012b00e01100000000ff0701249f +:10e1b0000a00a11100000000bbff40110000000098 +:10e1c000257828012300e01500000000f07f013cc5 +:10e1d0002528a100b4ff0010000004242a78600163 +:10e1e00021586b0121608c011700a01521608f015f +:10e1f00025788b01f5ffe011000000000800801574 +:10e2000000000000030060150000000000ff001087 +:10e2100000000d242560600100000b24e0ffad2507 +:10e2200020708e71fafec011000000002368ae015c +:10e2300022300e000630cb000458cb010460cc0124 +:10e24000f3fe00102560860125788b010200e011a5 +:10e2500000000000f8ff053c93ff001000000424bc +:10e260000000052425480500253805002530040058 +:10e270000c00c010000000000600c10400000000f7 +:10e280000080093c2b5005002328050023300600a0 +:10e290002330ca001e0407242040c8702338e80039 +:10e2a00004300601c24205004055060025400a011f +:10e2b0004050060002530a0025482a010055070075 +:10e2c00025482a0125100800251809000800e00348 +:10e2d000000000000000052425380500253004005a +:10e2e0000500c010000000001e0407242048c9706b +:10e2f0002338e90004302601c242050040550600db +:10e3000025400a0140480600024b0900005507005d +:10e3100025482a0125100800251809000800e003f7 +:10e3200000000000c23d0400ff00e7300080013c17 +:10e3300024308100ffffe924fe00212d0c00201075 +:10e34000000000008003e724404a0400024b09005b +:10e350002530c900402f0400004d07002530c900ba +:10e3600025100500251806000800e0030000000045 +:10e370000000052421208400f7ff80100000000029 +:10e380000900e01400000000ffffe72421208400c2 +:10e390008000013c2b088100fbff201400000000de +:10e3a000e8ff001000000000ff07072400ff013c09 +:10e3b000010021342b088100e7ff20140000000039 +:10e3c000e5ff0010f8ff063cc03a0500425d04007e +:10e3d0002538eb00c03204000080013c2538e10004 +:10e3e0000080013c2448a10040400500424508004f +:10e3f00080fc0825ffff0b25fe00612d1100201079 +:10e40000000000000200c010000000000100e7341e +:10e410008000e7248000eb2c21400b01025a07000a +:10e4200001006b312338eb0040380700423a070007 +:10e43000c05d08002538eb002510e9000800e00366 +:10e44000000000007f040124070001150000000007 +:10e4500040580700255866010300601100000000c5 +:10e46000f6ff0010c0ff023cff0001290400201449 +:10e4700000000000807f013cf0ff0010251021010a +:10e4800001000a24235048012000412d03002014dc +:10e4900000000000e9ff00102510090020000c24f6 +:10e4a00023608a01045887012530cb0006384701d4 +:10e4b000000008240080013cd2ff00102538e10054 +:10e4c000c03a0500425504002538ea000080013cae +:10e4d0002538e1004050050042550a001e0406247c +:10e4e0002330ca000b00c018000000002000c12c1f +:10e4f0000200201400000000000007340200a10404 +:10e500000638c70023380700251007000800e0037d +:10e510000000000002008010000000000100a5348f +:10e52000f07f013c010021342b08a10003002014de +:10e5300000000000f5ff00100080023cff7f023c5d +:10e54000f2ff0010ffff4234c03a050042550400bc +:10e550002538ea000080013c2538e10040500500e4 +:10e5600042550a001e0406242330ca000b00c004d2 +:10e57000000000002000c12c020020140000000058 +:10e58000000007340200a1040638c7002338070042 +:10e59000251007000800e0030000000002008010c2 +:10e5a000000000000100a534f07f013c010021348f +:10e5b0002b08a1000300201400000000f5ff00104c +:10e5c0000080023cf3ff0010ffff0224feff09243d +:10e5d0004050050040580700255864012558660141 +:10e5e00025504b0103004015000000003c000010c6 +:10e5f00000000224020080104040050001000825b0 +:10e60000e0ff013c010021342b08010136002010fd +:10e61000000000000200c010404007000100082573 +:10e62000e0ff013c010021342b0801012e002010e5 +:10e63000000000001600a104000000000300e00438 +:10e640000000000026000010ffff02242b5086006f +:10e65000232086002b58aa002328aa002b50a700ad +:10e6600025504b01030040112328a7001c00001077 +:10e67000010002242550a400030040110000000006 +:10e6800017000010ffff02241500001000000224f4 +:10e690000300e1040000000011000010010002244a +:10e6a0002b508600232086002b58aa002328aa007e +:10e6b0002b50a70025504b01030040112328a70031 +:10e6c00007000010ffff02242550a40003004011a2 +:10e6d00000000000020000100100022400000224db +:10e6e0000800e00300000000fdff001025100900f5 +:10e6f0000080013c2628a1002510040025180500f3 +:10e700000800e00300000000ff7f013cffff213410 +:10e710002428a10025100400251805000800e003a6 +:10e7200000000000020080104040050001000825a4 +:10e73000e0ff013c010021342b08010103002014fb +:10e74000000000000c000010010002240200c010b4 +:10e750004040070001000825e0ff013c0100213492 +:10e760002b0801010300201400000000020000102b +:10e7700001000224000002240800e0030000000061 +:10e780000080013c2628a100c24d0400ff00293171 +:10e79000c25d0500ff006b310080073c00420400b1 +:10e7a000254007010052050025504701ffff2d2598 +:10e7b000fe00a12d6100201000000000ffff6d256c +:10e7c000fe00a12d770020100000000023602b0127 +:10e7d0000d008005000000002000812903002014a6 +:10e7e000000000001500001002000a2425300a0075 +:10e7f00006508a0104688a011000a611000000007a +:10e800000e00001002004a3525480b0023600c0062 +:10e8100020008129030020140000000007000010e0 +:10e820000200082425300800064088010468880199 +:10e830000200a611000000000200083524608700d5 +:10e84000266885011000a0050000000021400a0193 +:10e850002b680a011700a0110000000001000d3113 +:10e860000200a0110000000002000835424008002c +:10e8700001002925ff0001240e00211500000000e1 +:10e880000c000010000008242b680a010400a011ed +:10e8900023400a012340080003000010266087017e +:10e8a00050000011000000002030067123482601ae +:10e8b0000440c8000e002019000000008000082558 +:10e8c00080000d2d21482d01026a08000100ad31a4 +:10e8d00023400d014040080042420800c06d09007d +:10e8e00025400d0125100c010800e0030000000088 +:10e8f000010006242330c9002000c12c390020105b +:10e90000000000000080013c2540010120000d2492 +:10e910002368a6010448a801020020110640c8008f +:10e92000010008350000092480000d25e3ffa10542 +:10e9300000000000e1ff0010010009240e00201576 +:10e940000000000021400801050000110000000047 +:10e9500020600c7123482c0198ff001004408801ae +:10e96000ff0001240f006111000000000080013c45 +:10e970001800a11400000000216808011b00a01568 +:10e9800000000000ff0001241400611500000000d9 +:10e99000266885001500a005000000000d0000108d +:10e9a00000000000080060150000000021504a012e +:10e9b0000a0040110000000020604c7123586c01d7 +:10e9c00082ff001004508a0121684a010700a01547 +:10e9d00000000000c4ff001025100500c2ff001059 +:10e9e00025100400c0ff001000000224beff00102c +:10e9f000c0ff023cc23d0400ff00e730c24d0500ed +:10ea0000ff00293100800a3c003204002530ca0092 +:10ea10000042050025400a012660850024504c0173 +:10ea2000ffffec24fe00812d2100201000000000db +:10ea3000ffff2c25fe00812d360020100000000075 +:10ea40001900c800125800000200601110300000c8 +:10ea50000100c6340300c00400000000403006007e +:10ea6000ffffe72482ff2c252138ec00ffffec2478 +:10ea7000fe00812d3a002010000000008000c62416 +:10ea80008000cc2c2138ec000262060001008c31a1 +:10ea90002330cc004030060042320600c06507003b +:10eaa0002530cc002510ca000800e003000000005b +:10eab0000d00e014000000002130c6000500c01069 +:10eac000000000002058cb702338eb00d8ff001066 +:10ead00004306601ff0001241f0021110000000026 +:10eae00015000010000000002160c6001a0080150b +:10eaf0000000000004002015000000002160080153 +:10eb00001500801100000000ff0001240f002115f6 +:10eb1000000000000a00201500000000214008014c +:10eb2000050000110000000020580b7123482b0144 +:10eb3000c3ff001004406801dbff001025100a002d +:10eb4000216008010400801500000000807f013c66 +:10eb5000d5ff001025104101d3ff0010c0ff023c7b +:10eb6000faffe01c0000000001000b24235867019d +:10eb70002000612df0ff20100000000020000c2478 +:10eb800023608b01043886010200e0100630660124 +:10eb90000200c634000007248000cc24b7ff8105a2 +:10eba00000000000b5ff00100100072400800b3cae +:10ebb000c2450400ff000831c2550500ff004a317c +:10ebc000003a04002538eb00004a050025482b01d7 +:10ebd0002670850024586e01ffff0e25fe00c12d12 +:10ebe0003f00201000000000ffff4e25fe00c12d59 +:10ebf00053002010000000002b08e900030020143f +:10ec00000000000042380700010008258263090067 +:10ec1000f40180011b00ec00122000001030000005 +:10ec2000ff3f2d311900a401122800008033060097 +:10ec30002b70c5000400c0112330c500ffff8424e1 +:10ec40002130c9002b70c900f40180011b00cc00e9 +:10ec500012380000103000001900a701122800002f +:10ec6000803306002b70c5000400c0112330c5009e +:10ec7000ffffe7242130c9002b70c9008073040016 +:10ec80002138ee000200c010003907000100e7340f +:10ec90007e000e242370ca0121400e01ffff0e25c5 +:10eca000fe00c12d34002010000000008000e72489 +:10ecb0008000ee2c21400e01027207000100ce31cf +:10ecc0002338ee0040380700423a0700c0750800bc +:10ecd0002538ee002510eb000800e00300000000de +:10ece00008000015000000002138e7000500e010d2 +:10ecf000000000002060ec7023400c01baff0010ff +:10ed00000438870104004815000000002170290123 +:10ed10002f00c01100000000ff0001240800411175 +:10ed20000000000012000011000000002170e70048 +:10ed30002700c015000000002200001000000000a5 +:10ed40000800401500000000214829011d00201185 +:10ed50000000000020602c7123504c01a6ff001021 +:10ed600004488901217029011900c0150000000024 +:10ed7000d9ff001025100b001200001d000000003c +:10ed800001000c24236088012000812df8ff201051 +:10ed90000000000020000e242370cc010440c701b5 +:10eda00002000011063887010200e7340000082441 +:10edb0008000ee24bdffc10500000000bbff001075 +:10edc00001000824807f013cc3ff00102510610171 +:10edd000c1ff0010c0ff023c0080013c1200801007 +:10ede0002430810002008104000000002320040080 +:10edf0009e000524203887702328a7000420e40003 +:10ee0000800084248000882c2128a800034204006c +:10ee10000100083123208800402004004222040021 +:10ee2000c045050025208800251086000800e00365 +:10ee3000000000000f008010000000009e0006246b +:10ee4000202885702330c5000420a400800084247d +:10ee50008000872c2130c700023a04000100e7300f +:10ee6000232087004020040042220400c03d060009 +:10ee700025208700251004000800e00300000000a2 +:10ee8000002a04000080013c2528a100c23d0400a6 +:10ee9000ff00e7309e0006242330c7000c00c01896 +:10eea000000000002000c128030020140000000022 +:10eeb0000500001000000224020081040628c5009d +:10eec00023280500251005000800e00300000000cd +:10eed000807f013c010021342b08810003002014b5 +:10eee00000000000f8ff00100080023cff7f023ca1 +:10eef000f5ff0010ffff4234002a04000080013caf +:10ef00002528a100c23d0400ff00e7309e00062432 +:10ef10002330c7000c00c004000000002000c128fe +:10ef2000030020140000000005000010000002246f +:10ef3000020081040628c5002328050025100500cd +:10ef40000800e00300000000807f013c0100213444 +:10ef50002b0881000300201400000000f8ff0010bf +:10ef60000080023cf6ff0010ffff0224feff082491 +:10ef700040300400403805002548c7001b00201120 +:10ef80000000000000ff013c010021342b08c100fb +:10ef9000190020100000000000ff013c0100213496 +:10efa0002b08e10014002010000000000200810482 +:10efb00042300600233006000200a1044238070058 +:10efc000233807002a08c7000300201000000000b3 +:10efd00007000010ffff02242a08e60003002010ab +:10efe00000000000020000100100022400000224c2 +:10eff0000800e00300000000fdff001025100800dd +:10f0000040100400421002000800e003000000006d +:10f010000080013c261081000800e0030000000091 +:10f020004030040000ff013c010021342b08c100e6 +:10f0300003002014000000000a0000100100022458 +:10f040004030050000ff013c010021342b08c100c5 +:10f050000300201400000000020000100100022440 +:10f06000000002240800e00300000000b8ffbd27f4 +:10f070004800a4af4000beaf3400b5af3000b4af1d +:10f080002c00b3af4400bfaf3c00b7af3800b6af01 +:10f090002800b2af2400b1af2000b0af00008880dc +:10f0a000029d063c4d15c424211004010000478038 +:10f0b0004800b38f8800e3304c00a5af1000a0af2c +:10f0c0001400a0af21f000001800a0af21a00000a4 +:10f0d0000800601021a8000001007326000068826b +:10f0e000215004010000498188002531fbffa05414 +:10f0f000010073262d000424d40004112b000c24dd +:10f10000d7000c51010073264d15d724217017012b +:10f110000000cd910400a6311b00c01001000f2497 +:10f12000029d163c1800afaf6817c68e6c17c78ecd +:10f13000d0ff12252128a002a176400f21208002b5 +:10f140002120400221a840009878400f21a06000b3 +:10f15000213040002120a0022128800221386000b7 +:10f160009875400f010073260000688225f0d203d5 +:10f17000219017010000519221a04000040030327c +:10f18000e9ff001621a860002e0016248a001651ff +:10f19000010073261800a48f280080104c00a48f53 +:10f1a0004500063965000d390100ab2d0100cc2c5e +:10f1b00025406c01210000114c00a48f0100732632 +:10f1c000000064822d000e2421280000af008e1064 +:10f1d000213800002b000f24a3008f50010073265c +:10f1e00021c09700000016930400d7320d00e012f2 +:10f1f000029d193c4d15262780900500215045029f +:10f2000040280a00010073262148a40000006482ff +:10f21000211886000000629004005f30f6ffe017be +:10f22000d0ff25251400b18f238005000b2807028d +:10f23000213825021400a7af4c00a48f05008010d0 +:10f240004800ab8f1800ac8f4c00a88f0a986c0157 +:10f25000000013ad1400a28f28004010029d1f3c37 +:10f26000c39f0200029d0f3c26705300029d0d3c7f +:10f270000818e68d0c18e78d2390d30121b04000cb +:10f28000b817b32503000010090003241000001272 +:10f2900021180002ffff702407c01202c0c803003b +:10f2a00001001733214033032120c000f7ffe01293 +:10f2b0002128e0000000068da176400f0400078d94 +:10f2c0002138600021304000f2ff001621180002b2 +:10f2d0006a00c00621208002a176400f2128a002ea +:10f2e00021204000212860002c7d400f2130c002e9 +:10f2f00021a0400021a86000029d1f3c1418f68f39 +:10f30000040080162438b602f07f023c5800e21058 +:10f3100022000324259095020100452e2b501e004b +:10f320002448aa005d002055220015241000a78f54 +:10f330000e00e014211080022118a0024400bf8fab +:10f340004000be8f3c00b78f3800b68f3400b58fb9 +:10f350003000b48f2c00b38f2800b28f2400b18fff +:10f360002000b08f0800e0034800bd272120800264 +:10f37000bc79400f2128a00221a0400021a86000f4 +:10f38000211080022118a0024400bf8f4000be8fd0 +:10f390003c00b78f3800b68f3400b58f3000b48f83 +:10f3a0002c00b38f2800b28f2400b18f2000b08fc3 +:10f3b0000800e0034800bd270000688221f817011b +:10f3c0000000f9930400383372ff0013029d163ccd +:10f3d000010003241800a3af6817c68e6c17c78ef0 +:10f3e000d0ff12252128a002a176400f2120800203 +:10f3f00021204002218040009878400f2188600041 +:10f400002138600021282002212000022130400004 +:10f410009875400f01007326000068821400a98fc0 +:10f420002150170121a0400000004291ffff252537 +:10f430000400473021a8600025f0d203e6ffe01465 +:10f440001400a5af57ff00104500063901007326d0 +:10f450000000688201000b242bff00101000abafee +:10f4600029ff0010000068825dff00100000648228 +:10f4700000a01e3cadff00100402c3af6b77400f2d +:10f480002128a00297ff00102120400001007326d0 +:10f490000000648252ff00100100072400a0143c09 +:10f4a000040295ae21a00000a0ff001021a80000da +:10f4b0000055a77cffffe324fe07622c214080005b +:10f4c0002150c000c007ab7c3f0040100098a97cd1 +:10f4d000029d043c1c18858c01fce4242530250188 +:10f4e0002148c00021788a00c0480900425708001e +:10f4f000ff03e72525482a014100e018c040080025 +:10f50000070006311d00c014c000057d40670900da +:10f51000c2300800ff07e4282540cc0031008010ed +:10f52000c2480900029d033c1c18798c2178000018 +:10f5300024c039012550f80107004051213800004e +:10f5400021100001029d083c2c18058d214040002f +:10f55000247025012148c001c06a0b002520a701a5 +:10f560000035040021600000252088012528c900fd +:10f57000211080000800e0032118a0000300a2244d +:10f580002118000021400201029d183c2bc80201f5 +:10f590002148230124180f8f2148390121680000d8 +:10f5a00024502f012560aa01d9ff8011406709006e +:10f5b000c07709004240080025400e01424809007a +:10f5c000d2ff00100100e7240400e01421108000a5 +:10f5d000253889002900e014026809000800e003ca +:10f5e0002118a000c06a0b00ff07a735002d0700f7 +:10f5f00021200000211080000800e0032118a00055 +:10f6000001001924233027033800d828180000539c +:10f6100001000824232806002000a2302718c0007b +:10f620000660c800041869000668c9004018030095 +:10f63000256083012000c3300b60a3010b68030029 +:10f6400021500001040040140418a8000218090009 +:10f650000440a300251848012b20030021280000a6 +:10f66000254084012548a501a5ff00102138e600aa +:10f6700021480000a2ff00102138e60002fc04240b +:10f680000300a0152018a37120700e712000c3255f +:10f69000f5ff632494ff601021788a002710600032 +:10f6a0000438690006104800043068004210020067 +:10f6b0002538e200200062300b38c2000b30020017 +:10f6c000232083002140c00086ff00102148e00075 +:10f6d00080bf033c105a648c0000827cfdff401008 +:10f6e0000000000080bf033c205a628c0800e00349 +:10f6f000000000000800e00300606241e8ffbd2751 +:10f700001000bfaf006805408000063c2520a60021 +:10f71000006884400010032488bf023cd37d400f62 +:10f72000081043ac1000bf8f0800e0031800bd278d +:10f730000100843003008010000000000800e00396 +:10f74000206060410800e003006060410800e003c1 +:10f75000206062412118e0002140a0002138c00053 +:10f760003a006014216080002b10a6008c0040102d +:10f77000000000002030c670c200c014232806001c +:10f78000023407001b000601f401c000ffffeb304c +:10f7900002740c001248000010c00000125000005b +:10f7a00002482b71007c18002528ee012b68a90067 +:10f7b0001b000601f401c0000900a0512320a9008c +:10f7c0002128a7002b40a70004000015ffff4a25b1 +:10f7d0002bc8a900fc002057ffff4a252320a900c1 +:10f7e0001b008600f401c000ffff83311268000097 +:10f7f00010280000124800000258ab7100140500e8 +:10f80000254043002b600b011b008600f401c00063 +:10f8100009008051005c0a00214007012b300701dc +:10f820000400c014ffffa9252b700b012b380e001c +:10f8300023482701005c0a002520690121300000cf +:10f84000211080000800e0032118c0002b58a300fd +:10f8500021200000faff6015213000002048697067 +:10f860008e0020112b10870120000d242370a90188 +:10f87000045023010678c70125684f0106c8c50159 +:10f8800002540d001b002a03f401400106c0cc0104 +:10f8900004282501ffffaf312570b80004c02c01fa +:10f8a000021c0e000438270112200000105800002e +:10f8b0001260000002408f70004c0b00255823019d +:10f8c0002b3068011b002a03f40140010b00c050db +:10f8d0002318680121586d012b106d01060040149a +:10f8e000ffff8c242b3068010400c010231868012e +:10f8f000ffff8c2521586d01231868011b006a0049 +:10f90000f4014001ffffcb3112480000104000001d +:10f910001230000002482f710024080025408b009f +:10f920002bc809011b006a00f40140010b002053a1 +:10f93000007c0c0021400d012b280d010600a014b5 +:10f94000ffffc6242b7009010400c011007c0c00cd +:10f9500021400d01ffffc624007c0c002520e6019c +:10f960001900870010280000231809012b6065008a +:10f9700009008055ffff8424121000002668a300b0 +:10f980002b5002030100b82d24380a03acffe050cd +:10f9900021300000ffff8424a9ff00102130000067 +:10f9a0004500c01001000a242050ea7049004015ab +:10f9b000200009242328070101000624024c070027 +:10f9c000ffffed301b00a900f401200102cc0c0068 +:10f9d00012500000101800001258000002504d7123 +:10f9e00000240300254099002b700a011b00a90088 +:10f9f000f40120010900c01123780a012140070108 +:10fa00002b2807010400a014ffff6b252b100a010f +:10fa10006b004054ffff6b2523780a011b00e901ae +:10fa2000f4012001ffff983112c8000010400000cf +:10fa30001250000002602d73007408002540d801a8 +:10fa40002b680c011b00e901f40120010900a01141 +:10fa5000001c0b00214007012b4807010500201561 +:10fa6000ffff2a272b380c012b60070023504c0185 +:10fa7000001c0b0025206a00211080000800e00314 +:10fa80002118c0000620a4000418c8002540640006 +:10fa90000460cc003aff00100438c7002b2065003a +:10faa00001004538255085002b200a0021108000d8 +:10fab0000800e0032118c0001b004601f401c0004b +:10fac000123800002050ea70bbff401123280701c4 +:10fad0002000092423782a010438470106c8e801d8 +:10fae000024c07001b002903f40120010670ec0101 +:10faf00004104801ffffed3025784e0002240f006e +:10fb00001230000010280000127000000240cd707a +:10fb1000001c0500255864002bc068011b00290348 +:10fb2000f40120010a00001304604c012158670110 +:10fb30002b50670106004015ffffce242bc0680143 +:10fb40000400001323c86801ffffce252158670178 +:10fb500023c868011b002903f4012001ffffe431e1 +:10fb60001228000010400000123000000250ad705a +:10fb7000001c0800254064002b580a011b002903c3 +:10fb8000f40120010b00601100c40e0021400701a8 +:10fb90002b10070107004014ffffa6242b780a0151 +:10fba0000500e05125300603ffffc6242140070170 +:10fbb00000c40e002530060382ff001023280a012e +:10fbc00095ff00102140070104ff00102128a70025 +:10fbd000e8ffbd272140e0001000b2af0c00b1af3c +:10fbe0000800b0af2190a0032150c0002158800030 +:10fbf000400000152138a0002b10a6005c0040102a +:10fc00002070ce707900c01523280e00024c0a0027 +:10fc10001b00e900f4012001ffff4f3102640b00db +:10fc2000128000001030000002280f72006c0600e5 +:10fc30002530ac012b40c5001b00e900f401200178 +:10fc40000a0000112318c5002130ca002b38ca0051 +:10fc50000600e0142318c5002bc8c5000000383b7f +:10fc60002188ca000b3038022318c5001b00690028 +:10fc7000f4012001ffff713112c8000010c0000024 +:10fc800002582f73007c18002540f1012b380b011e +:10fc90001b006900f40120010a00e01023180b0189 +:10fca00021400a012b480a010600201523180b01e8 +:10fcb0002b100b0121200a0100004a380b408a005a +:10fcc00023180b010660c3010300401221680000e5 +:10fcd00000004cae04004dae0000a28f0400a38fc4 +:10fce0001000b28f0c00b18f0800b08f0800e00345 +:10fcf0001800bd272b70a8000a00c05120700e719b +:10fd00001000b28f0c00b18f0800b08f211080005e +:10fd10002118a0000000a4af0400a5af0800e00374 +:10fd20001800bd273700c01520000f242b6886005f +:10fd30000100ac392b3005012528cc000700a010ac +:10fd40002160600123808a002388e8002b40900016 +:10fd5000233828022158000221606001deff401292 +:10fd60002168e00000004caedbff001004004dae47 +:10fd70007e00c0100100092420704e718200c01561 +:10fd800020000f242330ea00024c0a00ffff4f310d +:10fd90001b00c900f401200102240b0012400000e6 +:10fda0001028000002380f71001c0500252864008f +:10fdb0002b10a7001b00c900f4012001abff40106d +:10fdc0002318a7002128aa002b30aa00a7ffc0549f +:10fdd0002318a7002b80a70000000d3a2160aa007d +:10fde0000b288d01a1ff00102318a7000620a400f6 +:10fdf0000418c701253864000450c60183ff0010b1 +:10fe00000458cb0123c0ee010448c80106c806030c +:10fe10002578390106200503024c0f001b008900dc +:10fe2000f401200106380b030468c501fffff1311e +:10fe300025c8a7010480cb010438ca01021c19009f +:10fe40001230000010600000125800000250d17003 +:10fe5000002c0c002540a3002b100a011b00890078 +:10fe6000f40120010b00405023180a0121400f012a +:10fe70002b100f0106004014ffffcb242b200a019a +:10fe80000400801023180a01ffff6b2521400f0199 +:10fe900023180a011b006900f4012001ffff25332c +:10fea000125000001040000012300000025051714a +:10feb00000640800254085012b880a011b006900a9 +:10fec000f40120010b00201200140b0021400f014f +:10fed0002b680f010700a015ffffc6242bc80a01dd +:10fee0000500201325484600ffffc62421400f01ce +:10fef00000140b00254846001900270110300000af +:10ff000023400a012b580601070060151228000043 +:10ff10002660c8000100912d2b1805022420230221 +:10ff200006008010000000002350a7002b38aa0014 +:10ff30002368cf002330a7012128400166ff40122b +:10ff400023780502232806012b400f022380a800f6 +:10ff50000430100306c0cf012560d8000668d00128 +:10ff600000004cae5cff001004004dae1b002601eb +:10ff7000f401c0001250000020704e7182ffc011c9 +:10ff80002330ea0020000f242380ee010450ca0130 +:10ff900006200702024c0a001b008900f401200120 +:10ffa00006680b020430c701ffff4f312538cd0032 +:10ffb000021c0700126000001040000002308f7128 +:10ffc000002c08002540a3002b1006011b0089000f +:10ffd000f4012001050040100458cb0121400a0122 +:10ffe0002b880a01190020122b1006012318060184 +:10fff0001b006900f4012001ffffe53012680000da +:020000041d02db +:10000000106000000238af7100440c00253005017b +:100010002b20c7001b006900f40120015cff805009 +:100020002330c7002130ca002b80ca0058ff005679 +:100030002330c7002bc8c7000000383b2188ca0006 +:100040000b30380252ff00102330c700000059382f +:0c00500021c00a01e5ff00100b4019035d +:020000040000fa +:020000041d02db +:100060005261704d616e205665723a312e302e38d5 +:1000700000000000496e736572742053442d436183 +:100080007264206f720000003c3c45534320544f83 +:1000900020524553554d4500496e76616c69642088 +:1000a00046696c652054797065000000506c65618c +:1000b0007365206f6e6c7920757365002a2e424639 +:1000c00042206f72202a2e47434f2046696c657389 +:1000d0000000000050415553450000004572726f0a +:1000e00072205445535400004578747275646572eb +:1000f000204f46460000000046696c65204572723c +:100100006f72203a7365656b20707400556e6b6e6c +:100110006f776e204572726f72000000203c45536d +:100120004320544f20524553554d45003c0000009c +:10013000000002430000c8c2546f6f6c3a20506543 +:100140006e000000546f6f6c3a20457874727564cd +:1001500065720000546f6f6c3a2045787472756454 +:1001600065723200546f6f6c3a204e6f7420446594 +:1001700066696e6564000000546f6f6c3a20526fc0 +:100180007574657200000000546f6f6c3a204e6ffa +:100190006e6500007200000046696c652045727251 +:1001a0006f7220202020000046696c65204e6f741d +:1001b00020466f756e6400004f70656e0000000091 +:1001c0002a2e2a0046696e6420466972737420459f +:1001d00072726f72000000004e6f2066696c65736a +:1001e000206f6e20636172640000000046696c65d8 +:1001f00000000000253375006f6600000000004419 +:100200000000fe420000fe4225362e32660000004d +:10021000cdcccccccce45540000020455a20444ff6 +:10022000574e2020202020005920464f525741523f +:1002300044202000484f4d45205820202020000019 +:10024000484f4d452059202020200000484f4d4563 +:10025000205a202020200000484f4d452041424f89 +:100260005254454400000000484f4d4520434f4d37 +:10027000504c455445000000cdcccccccce455408e +:1002800039b4c876be9ff63f0000c84200000000a7 +:10029000cdcccccccce45540000020450000000083 +:1002a000cdcccccccce4554000808443000048c386 +:1002b000000002430000c8c2000000000000e03f50 +:1002c000000000000000e03f000000000000e0bf70 +:1002d00054454d5045524154555245204348414e96 +:1002e00047450000400a019d680c019d680c019d76 +:1002f000680c019d680c019d680c019d680c019db6 +:10030000680c019d680c019d680c019d680c019da5 +:10031000680c019d680c019d680c019d680c019d95 +:10032000680c019d680c019d000c019d680c019ded +:10033000680c019d680c019d680c019d5409019d8c +:10034000680c019d680c019d680c019d680c019d65 +:10035000680c019d680c019d680c019d680c019d55 +:10036000680c019d400a019d680c019d680c019d6f +:10037000680c019d680c019d680c019d680c019d35 +:10038000680c019d680c019d680c019d680c019d25 +:10039000680c019d680c019d680c019d680c019d15 +:1003a000680c019d680c019d000c019d680c019d6d +:1003b000680c019d680c019d680c019d5409019d0c +:1003c0002e2e000020202020202020202020200071 +:1003d0000000000000950000000000000000000088 +:1003e00001f90000000000000000000009af00005b +:1003f00000000000010000000a1b000000000000d7 +:10040000010000000cc3000000000000000000001c +:100410000daf0000020000000000000010ff00000f +:10042000000000000000000011ff000000000000bc +:100430000100000012ff00000000000001000000a9 +:1004400018ff0000000000000100000019ff00007c +:10045000000000000100000020ff0000000000007c +:100460000000000021ff000000000000000000006c +:1004700026df0000010000000000000037730000cc +:1004800000000000000000003a250000030000000a +:10049000000000003b2500000000000000000000fc +:1004a00000040000ff030000fe030000fc03000046 +:1004b000fa030000f7030000f2030000ec03000061 +:1004c000e3030000d8030000c9030000b6030000e6 +:1004d0009f03000083030000610300003b03000052 +:1004e00010030000e1020000af0200007b020000e8 +:1004f0004702000013020000e0010000b10100000b +:10050000840100005a0100003501000013010000c1 +:10051000f4000000d9000000c1000000000000004d +:1005200000000000389c2c41000000000000394011 +:10053000000080bf00c0794400c07944000080bf43 +:10054000000020410000000000000000389c2c4109 +:100550000000000000003940000000000000000022 +:10056000000000000000000000000000000000008b +:10057000000000000000000000000000000000007b +:10058000000000000000000000000000000000006b +:10059000e0e0606060ffff6363e3e3030303ffffea +:1005a000000000000000000000000000000000004b +:1005b000000000000000000000000000000000003b +:1005c000000000000000000000000000000000002b +:1005d000000000000000000000000000000000001b +:1005e000000000000000000000000000000000000b +:1005f00000000000000000000000000000000000fb +:1006000000000000000000000000000000000000ea +:10061000ffffc0c0c0c7c7c6c6ffff060606070764 +:1006200000000000000000000000000000000000ca +:1006300000000000000000000000000000000000ba +:1006400000000000000000000000000000000000aa +:10065000000000000000000000000000000000009a +:10066000000000000000000000000000000000008a +:10067000000000000000000000000000000000007a +:10068000000000000000000000000000000000006a +:10069000000000000000000000000000000000005a +:1006a000000000000000000000000000000000004a +:1006b000000000000000000000000000000000003a +:1006c000000000000000000000000000000000002a +:1006d000000000000000000000000040c0c0c0c0da +:1006e000c0c0c0c0c0c0c0c0c0c0c0c0808000000a +:1006f00000000000000000000000000000000000fa +:1007000000000000000000000000000000000000e9 +:1007100000000000000040c0c0c0c0c0c0c0c08019 +:10072000000000000080c0c0c0c0c0c0c0c0400009 +:1007300000000000000000000000000000000000b9 +:1007400000000000000000000000000000000000a9 +:10075000000000000000000000000000ffffffff9d +:10076000ffffff7171f1f1ffffffffff7f3f00000f +:10077000009c9c9c9c9c9c9c9c9cfcfcfcfcfcf819 +:10078000f0000004fcfcfcfcfcfcf81c1c1cfcfc49 +:10079000fcfcfcf8f00000ffffff0f7ffffffffff6 +:1007a000fce000e0fc3f07ffffffffffffff000052 +:1007b00000009c9c9c9c9c9c9c9c9cfcfcfcfcfcd1 +:1007c000f8f0000000fcfcfcfcfcfcf81c1c1cfc11 +:1007d000fcfcfcfcf8f00000000000407f7f7f7f05 +:1007e0007f7f7f400000073f7f7f7f7f7c704000de +:1007f0003f7f7f7f7f7f7f7171717f7f7f7f7f7f73 +:100800007f400000ffffffffffffff7070707f7fe2 +:100810007f7f7f7f3f00407f7f7f0000031f7f7fc0 +:100820007f7f7f0f0100407f7f7f7f7f7f7f400042 +:10083000003f7f7f7f7f7f7f7171717f7f7f7f7fb1 +:100840007f7f4000407f7f7f7f7f7f7f4000407fb2 +:100850007f7f7f7f7f7f400000000000000000005e +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000007070707070707040000000033 +:100890000000000000000000000000000000000058 +:1008a0000000000000000000000000000000000048 +:1008b0000000000000000000000000000000000038 +:1008c0000000000000000000000000000000000028 +:1008d0000000000000000000000000000000000018 +:1008e0000000000000000000000000000000000008 +:1008f00000000000000000000000000000000000f8 +:1009000000000000000000000000000000000000e7 +:1009100000000000000000000000000000000000d7 +:1009200000000000000000000000000000000000c7 +:1009300000000000000000000000000000000000b7 +:1009400000000000000000000000000000000000a7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:10098000000000000000000000c060301088e45447 +:100990006e6e26f32f272323272ff3266e5664cc63 +:1009a000983020e0800000000000000000000000ff +:1009b0000000000000000000000000000000000037 +:1009c0000000000000000000000000000000000027 +:1009d0000000000000000000000000000000000017 +:1009e0000000000000000000000000000000000007 +:1009f00000000000000000000000000000000000f7 +:100a0000000000000000c0fc472632f93f10080833 +:100a100008f80f0908080808080809ff080808105e +:100a2000173df326655ffcc00000000000000000d9 +:100a300000000000000000000000000000000000b6 +:100a400000000000000000000000000000000000a6 +:100a50000000000000000000000000000000000096 +:100a60000000000000000000000000000000000086 +:100a70000000000000000000000000000000000076 +:100a80000000000000000f74c888107fd030206084 +:100a9000607fc04040404040404040ff60602030a8 +:100aa00010f01f90d8e87c0f00000000000000004c +:100ab0000000000000000000000000000000000036 +:100ac0000000000000000000000000000000000026 +:100ad0000000000000000000000000000000000016 +:100ae0000000000000000000000000000000000006 +:100af00000000000000000000000000000000000f6 +:100b0000000000000000000003070d3b276e5ca8fa +:100b1000c888977cd090101090d03c97d8e8b8cc7b +:100b200067371b0d070100000000000000000000f7 +:100b300000000000000000000000000000000000b5 +:100b400000000000000000000000000000000000a5 +:100b500000000000000000000000000000c0c040d5 +:100b60004040c0c08000c000c0c0c0c08080c00085 +:100b700080c0c0c0c0000000000000c0c0c0c0c035 +:100b800000000000c0c0c0c0c0c0c080000080c065 +:100b9000c0c1c1c1810303c38303010101000080ff +:100ba000c00000000000c0c0404040c0c080000045 +:100bb000c0c000000080c00000c0c0c0c08080c0b5 +:100bc0000080c0c0c0c00000000080c0c0c0c00025 +:100bd000000000000000000000000000003f3f2671 +:100be0002226361f0f003f0000003f3f000000009c +:100bf00033333434343c18000000003f3d04040417 +:100c0000040404003f3f060e1e1e362700061f3058 +:100c1000303030301f06003f030f1c38381c0f03e4 +:100c20003f00000000003f3f262226361f0f000035 +:100c30000001033e03010000000000003f0000002f +:100c4000001f1f3434343434340033333434343cf0 +:100c5000180000000000000000000000000000007c +:100c60000000000000000000000000000000000084 +:100c70000000000000000000000000000000000074 +:100c80000000000080808000e0f0f81818b0a0009c +:100c9000e0f0f818f8f0e000f8f8f810f8f8f018bc +:100ca000f8f8f00000000000000000000000000064 +:100cb0000000000000000000000000000000000034 +:100cc0000000000000000000000000000000000024 +:100cd0000000000000000000000000000000000014 +:100ce0000000000000000000000000000000000004 +:100cf00000000000000000000000000000000000f4 +:100d000000000000030303000001030303010000cf +:100d100000010303030100000303030003030300b6 +:100d200003030300000000000000000000000000ba +:100d300000000000000000000000000000000000b3 +:100d400000000000000000000000000000000000a3 +:100d50000000000000000000000000000000000093 +:100d60000000000000000000000000000000000083 +:100d70000000000000000000000000000000000073 +:100d80000000000000000000000000000000000063 +:100d90000000000000000000000000000000000053 +:100da0000000000000000000000000000000000043 +:100db0000000000000000000000000000000000033 +:100dc0000000000000000000000000000000000023 +:100dd0000000000000000000000000000000000013 +:100de0000000000000000000000000000000000003 +:100df00000000000000000000000000000000000f3 +:100e000000000000000000000000000000000000e2 +:100e100000000000000000000000000000000000d2 +:100e200000000000000000000000000000000000c2 +:100e300000000000000000000000000000000000b2 +:100e400000000000000000000000000000000000a2 +:100e50000000000000000000000000008040202092 +:100e600040800000000000000000000000000000c2 +:100e70000000000000000000000000000000000072 +:100e80000000000000000000000000000000000062 +:100e90000000000000000000000000000000000052 +:100ea0000000000000000000000000000000000042 +:100eb0000000000000000000000000000000000032 +:100ec0000000000000000000000000000000000022 +:100ed00000000000000000000000fc0300c0c0c0d3 +:100ee000c00003fc00000000000000000000000043 +:100ef00000000000000000000000020502003c426b +:100f000081818166000000000000000000000000f8 +:100f100000000000000000000000000000000000d1 +:100f200000000000000000000000000000000000c1 +:100f3000000080402010100808080404040404087d +:100f40000808101020408000000000000000000091 +:100f500000000000000000000000ff0000ffffff95 +:100f6000ff0000ff00000000000000000000000083 +:100f70000000000000000000000000000000808071 +:100f80008080000000000000000000000000000061 +:100f90000000000000000000000000000000000051 +:100fa0008000000080000000000000000000000041 +:100fb000f00e010000000000000080e0e0e0000012 +:100fc000000000000000010ef00000000000000022 +:100fd00000000000000000000000ff0000ffffff15 +:100fe000ff0000ff00000000000000000000000003 +:100ff00000000000000000000000000000007f046e +:10100000040000324a4a7c007e04027c000000009a +:1010100000000000000000000000000000000003cd +:1010200004631c3348300000000000f00808f000a2 +:10103000010e30408804040201010000000000009d +:10104000000000008040300e01e010902000e01011 +:1010500010e000000000000080c0fff0f8ffffff7c +:10106000fff8f0ffc080000000000000000000005a +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010a0000000000000000000000000030404030032 +:1010b0000000000000010102020204040404040212 +:1010c00002020101000000000007090807000708ec +:1010d0000807000000000000ffffffffffffffff09 +:1010e000ffff7f3f1f0f0000000000000000000016 +:1010f000000000000000000000020502003c4281e8 +:101100008181660000000000000000000000000077 +:1011100000000000000000000000000000000000cf +:1011200000000000000000000000000000ff09199e +:10113000294680ff1111110e00ff0678807806ff06 +:10114000000000000000000000000000000000009f +:101150000000000000000000000000000000005f30 +:1011600000000003000300143e143e14242a7f2aca +:1011700012433308666136495522500005030000ca +:10118000001c2241000041221c0014083e081408e3 +:10119000083e0808005030000008080808080060f1 +:1011a00060000020100804023e5149453e04027fc1 +:1011b0000000426151494622414949361814127fc4 +:1011c0001027454545393e49494932010171090712 +:1011d0003649494936264949493e0036360000001d +:1011e000563600000814224100141414141400414f +:1011f00022140802015109063e4159555e7e090933 +:10120000097e7f494949363e414141227f41414162 +:101210003e7f494949417f090909013e4141493a17 +:101220007f0808087f00417f4100304040403f7ff9 +:10123000081422417f404040407f020c027f7f0221 +:1012400004087f3e4141413e7f090909061e2121d4 +:10125000215e7f0909097600264949493201017f4b +:1012600001013f4040403f1f2040201f7f201020b1 +:101270007f41221c224107087008076151494543fc +:10128000007f410000020408102004020102044013 +:1012900040404040000102040020545454787f44f0 +:1012a0004444383844444444384444447f385454d3 +:1012b000541804047e0505085454543c7f08040463 +:1012c0007800447d40002040443d007f10284400c9 +:1012d00000417f40007c047804787c08040478385e +:1012e000444444387c14141408081414147c007cfe +:1012f000080404485454542004043f44443c4040ef +:10130000207c1c2040201c3c4030403c44281028bd +:10131000440c5050503c4464544c44000836414105 +:1013200000007f0000414136080002010204020073 +:10133000000000005261704d616e205665723a31b6 +:101340002e302e3800000000472d436f6465204c7e +:10135000696e653a0000000048656164205370655d +:1013600065643a004578742e20526174653a000035 +:101370002531750025352e31666d6d2f7300000007 +:101380004e6f74205365740000007042000000002e +:1013900079e9263108acac3f4578747275646572a2 +:1013a00020436f6e74726f6c0000000048656174ba +:1013b0006572204f6e200000486561746572204f91 +:1013c00066660000203c31303043204d6f746f72f0 +:1013d000204f4646000000000000c84254454d50d2 +:1013e00045524154555245204552524f520000003b +:1013f000544845524d4953544f52204552524f5232 +:101400000000000025337543000000002a000000a2 +:101410002000000000c07944000080bf25337552d1 +:10142000504d00000000000084471b47acc5a73f9b +:101430004d454e550000000052554e2046494c4542 +:10144000000000004d414e55414c204d4f56450087 +:10145000544f4f4c2053455455500000484f4d4574 +:1014600020544f4f4c204845414400004d414e55bb +:10147000414c0000585f537465703a00595f5374d3 +:1014800065703a005a5f537465703a004155544f85 +:101490003a204c6f6164696e672e2e00484f4d49ab +:1014a0004e4720504c454153452057414954000078 +:1014b0004d4f564520544f3a00000000583d253608 +:1014c0002e326600593d25362e3266005a3d2536ad +:1014d0002e3266004e4f205a204d4f5645000000d8 +:1014e00050726f672e456e6400000000526574757f +:1014f000726e20746f204d656e7500003c3c3c2080 +:101500005072657373204573632e00003e00000027 +:1015100020200000f0a0019d489b019d189c019d8a +:10152000e89c019db89d019d889e019d589f019d4d +:1015300028a0019d000000006cb1019d20b2019d1a +:10154000b4b1019dfcb2019d80b3019d002020201b +:101550002020202020202828282828202020202063 +:10156000202020202020202020202020208010103b +:10157000101010101010101010101010100404048f +:10158000040404040404041010101010101041414d +:10159000414141410101010101010101010101013b +:1015a000010101010101010110101010101042424f +:1015b000424242420202020202020202020202020b +:1015c00002020202020202021010101020000000ab +:1015d000000000000000000000000000000000000b +:1015e00000000000000000000000000000000000fb +:1015f00000000000000000000000000000000000eb +:1016000000000000000000000000000000000000da +:1016100000000000000000000000000000000000ca +:1016200000000000000000000000000000000000ba +:1016300000000000000000000000000000000000aa +:10164000000000000000000000000000000000009a +:10165000303030303030303030303030303030308a +:10166000303030303030303030303030303030307a +:10167000202020202020202020202020202020206a +:10168000202020202020202020202020202020205a +:1016900098bc019d44c0019dc8cd019d44c0019de1 +:1016a000c8cd019dc8cd019dc8cd019dc8cd019d6e +:1016b000c8cd019dc8cd019dc8cd019dbcbc019d7b +:1016c00004bd019dc8cd019dc8cd019dc8cd019d22 +:1016d000c8cd019dd0bc019dc8cd019dc8cd019d47 +:1016e000f4bc019dc8cd019dc8cd019dc8cd019d13 +:1016f000c8cd019dc8cd019dc8cd019dc8cd019d1e +:10170000c8cd019dc8cd019dc8cd019d14cc019dc2 +:10171000a4bc019d44c0019d44c0019d44c0019de5 +:10172000c8cd019da4bc019dc8cd019dc8cd019d22 +:10173000c8cd019dc8cd019ddccc019dc8bc019ddb +:1017400010bd019dc8cd019dc8cd019d50cc019d0e +:10175000c8cd019ddcbc019dc8cd019dc8cd019dba +:101760001cbd019d0000000000000000000024409e +:101770000000000000001040000000000000008099 +:101780007b14ae47e17a843f2d431cebe2361a3fcf +:101790004e614e002b496e66000000002d496e66ba +:1017a00000000000286e756c6c29000058ce019d69 +:1017b00060ce019d68ce019d70ce019d78ce019dc9 +:1017c000000000000000144000000000000039404c +:1017d00000000000008883400000000084d717410b +:1017e0000080e03779c34142176e05b5b5b8934420 +:1017f000f5f93fe9034f3849321d30f948778252f5 +:101800003cbf737fdd4f1565000000000000f03f16 +:10181000ffffffffffffff7f000000000000100040 +:101820000000000000000001ffffffffffff0f00ae +:020000040000fa +:020000041d02db +:101830000c00000000000000010001041f0c1d004e +:101840000c0000001400000054f7019d7c0400000f +:101850000c00000000000000010001041f0c1d002e +:101860001c00000014000000d0fb019d8c0400004f +:10187000440e185011107c11117d11127e000000d1 +:020000040000fa +:020000041d02db +:1018800000000000ffffffff00000000000000005c +:101890000000000000000000000000000000000048 +:1018a000840000a0a00000a0bc0000a0800000a058 +:1018b0007c0300a001000000000000000000000008 +:1018c0000000000000000000000000000000000018 +:1018d0000000000000000000000000000000000008 +:1018e00000000000000000000000000000000000f8 +:1018f00000000000000000000000000000000000e8 +:1019000000000000ffffffffffffffff00000000df +:101910000004000009100000000000003815029dbe +:10192000ffffffff000000000000000000040000b7 +:101930000a100100000000003815029dffffffffa4 +:101940000000000000000000000000000200020093 +:10195000000000003815029dfdffffff00000000a1 +:101960000000000000000000000000000000000077 +:041970000000000073 +:020000040000fa +:020000041d02db +:10197400010000001e000000ffff00000100000045 +:10198400ffff0000ffffffffc80e00a09001000052 +:0c199400f5ff000001000000200000a092 +:00000001FF diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan1_0_9-factory.hex b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan1_0_9-factory.hex new file mode 100644 index 00000000..263668a1 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/RapMan1_0_9-factory.hex @@ -0,0 +1,15109 @@ +:020000041D00DD
+:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10501000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10502000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10503000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10504000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10505000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10506000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10507000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10508000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10509000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1050A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1050B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1050C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1050D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1050E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1050F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10510000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10511000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10512000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10513000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10514000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10515000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10516000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10517000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10518000029D1A3C4CAC5A27080040030000000066
+:10519000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1051A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1051B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1051C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1051D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1051E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1051F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10520000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10521000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10522000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10523000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10524000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10525000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10526000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10527000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10528000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10529000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1052A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1052B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1052C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1052D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1052E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1052F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10530000F05D400B00000000FFFFFFFFFFFFFFFF0D
+:10531000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10532000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10533000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10534000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10535000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10536000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10537000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10538000B35E400B00000000FFFFFFFFFFFFFFFFC9
+:10539000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1053A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1053B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1053C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1053D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10540000C826400B00000000FFFFFFFFFFFFFFFF6B
+:10541000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10542000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10543000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10544000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10545000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10546000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10547000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10548000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10549000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1054A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1054B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1054C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1054D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1054E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1054F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10550000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10551000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10552000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10553000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10554000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10555000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10556000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10557000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10558000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10559000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1055A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1055B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1055C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1055D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1055E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1055F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10560000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10561000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10562000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10563000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10564000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10565000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10566000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10567000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10568000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10569000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1056A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1056B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1056C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1056D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1056E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1056F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10570000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10571000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10572000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10573000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10574000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10575000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10576000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10577000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10578000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10579000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1057A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1057B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1057C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1057D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1057E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1057F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10580000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10581000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10582000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10583000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10584000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10585000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10586000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10587000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10588000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10589000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1058A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1058B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1058C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1058D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1058E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1058F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10590000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10591000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10592000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10593000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10594000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10595000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10596000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10597000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10598000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10599000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1059A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1059B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1059C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1059D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1059E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1059F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:105A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:105A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:105A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:105A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:105A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:105A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:105A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:105A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:105A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:105A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:105AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:105AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:105AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:105AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:105AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:105AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:105B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:105B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:105B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:105B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:105B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:105B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:105B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:105B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:105B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:105B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:105BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:105BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:105BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:105BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:105BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:105BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:105C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:105C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:105C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:105C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:105C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:105C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:105C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:105C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:105C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:105C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:105CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:105CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:105CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:105CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:105CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:105CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:105D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:105D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:105D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:105D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:105D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:105D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:105D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:105D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:105D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:105D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:105DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:105DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:105DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:105DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:105DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:105DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:105E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:105E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:105E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:105E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:105E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:105E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:105E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:105E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:105E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:105E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:105EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:105EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:105EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:105ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:105EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:105EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:105F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:105F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:105F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:105F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:105F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:105F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:105F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:105F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:105F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:105F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:105FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:105FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:105FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:105FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:105FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:105FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10600000009D1A3C90645A270800400300000000DD
+:10601000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10602000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10603000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10604000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10605000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10606000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10607000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10608000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10609000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1060A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1060B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1060C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1060D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1060E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1060F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10610000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10611000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10612000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10613000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10614000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10615000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10616000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10617000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10618000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10619000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1061A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1061B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1061C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1061D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1061E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10620000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10621000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10622000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10624000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10625000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10626000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10627000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10628000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10629000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1062A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1062B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1062C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1062D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1062E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1062F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10630000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10631000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10632000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10633000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10634000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10635000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10636000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10637000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10638000029D1A3CA8B65A270800400300000000EE
+:10639000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1063A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1063B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1063C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10644000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10645000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10646000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10647000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10648000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1064900000601A40C0045A7F05004013000000004D
+:1064A000029D1A3CC0B65A270800400300000000B5
+:1064B00001A01D3C0080BD2701A01C3CF0809C2752
+:1064C0000260094020582001801E2A7D8449497DB0
+:1064D0000260894000E0DC4102608B40029D083C84
+:1064E000B0B6082509F800010000000000A0083C33
+:1064F0002001082500A0093C84122925060000106F
+:1065000000000000000000AD040000AD080000AD78
+:106510000C0000AD100008252B080901F9FF20141C
+:1065200000000000029D083C801A082500A0093CDC
+:106530000000292500A00A3C20014A250500001082
+:106540000000000000000B8D00002BAD04000825AA
+:10655000040029252B082A01FAFF2014000000005E
+:106560000000093C000029251D002011000000004A
+:10657000029D083CA01B082500A0093C00202925FD
+:1065800000A00A3C00204A2500000B8D00002BAD26
+:1065900004000825040029252B082A01FAFF2014ED
+:1065A000000000000000093C0020292588BF0A3CAB
+:1065B00010204A25000049AD0100093C0080292532
+:1065C00088BF0A3C20204A25000049AD0100093C53
+:1065D0000080292588BF0A3C30204A25000049ADAB
+:1065E00000488040FFFF0A2400588A40009D093C73
+:1065F00000502925017889400000093C0100292527
+:1066000000000A2444492A7D01608A408000093C38
+:1066100000688940008008408005097D404C0900E1
+:10662000006008405800013C244001012540280139
+:1066300000608840029D083CB8B6082509F80001B2
+:106640000000000000600840BFFF013CFFFF213454
+:106650002440010100608840000084300000A53023
+:10666000009D083C006A08250800000100000000A9
+:10667000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10668000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10669000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1066A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1066B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1066C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1066D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1066E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1066F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10670000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10671000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10672000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10673000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10674000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10675000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10676000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10677000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10678000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10679000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1067A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1067B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1067C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1067D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1067E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1067F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10680000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10681000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10682000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10683000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10684000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10685000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10686000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10687000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10688000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10689000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1068A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1068B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1068C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1068D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1068E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10697000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:106A0000861A400F000000009F6B400F000000003E
+:106A1000FFFF001000000000E0FFBD271C00BFAF1B
+:106A20001800BEAF21F0A003AD1C400F0000000015
+:106A3000B169400F0000000088BF023C5060428CEA
+:106A4000C000427C0300401400000000FAFF001068
+:106A500000000000131E400F000000001000C2AF35
+:106A60001000C28F1400C2AF010002241400C38FB3
+:106A700018006210000000001400C38F020062289A
+:106A800006004010000000001400C28F0D004010EE
+:106A900000000000E8FF00100000000002000224D7
+:106AA0001400C38F100062100000000003000224D5
+:106AB0001400C38F1400621000000000DEFF0010FD
+:106AC00000000000C61A400F00000000DAFF0010AE
+:106AD00000000000010004244B23400F00000000D0
+:106AE000D5FF0010000000005480838302000224C0
+:106AF000D1FF621400000000A261400F00000000FE
+:106B0000CDFF001000000000D024400F0000000066
+:106B1000C9FF001000000000D0FFBD272C00BFAF50
+:106B20002800BEAF21F0A003448180A3851D400F43
+:106B300000000000010140100000000021200000C2
+:106B40003564400F00000000212000000A000524E9
+:106B5000029D023C30024624213800001965400F96
+:106B60000000000088BF023C5060428CC000427CA4
+:106B70000300401400000000FAFF001000000000B5
+:106B8000575A400F00000000190040140000000098
+:106B90000200042421280000029D023C44024624F5
+:106BA000213800001965400F000000000400042493
+:106BB00021280000029D023C580246242138000092
+:106BC0001965400F00000000FA000424775C400FB4
+:106BD0000000000088BF023C9061428C4002427C71
+:106BE000E7FF401400000000D40000100000000087
+:106BF000020004249A64400F0000000004000424F2
+:106C00009A64400F00000000F61E400F00000000D4
+:106C100088BF023C5060428CC000427C030040149C
+:106C200000000000FAFF00100000000088BF023CD6
+:106C30009061428C4002427C03004014000000003E
+:106C4000BE000010000000006480838F0300022457
+:106C500007006210000000006480838F010002249E
+:106C600003006210000000007F0000100000000020
+:106C7000D024400F0000000003004014000000007A
+:106C8000AE0000100000000003000224508082AF1C
+:106C9000212000003564400F000000008362400F97
+:106CA00000000000C728400F00000000010004247D
+:106CB0009B24400F0000000088BF023C9061428C82
+:106CC0004002427C2100401400000000D51B400F10
+:106CD0000000000088BF023C9061428C4002427C70
+:106CE0000300401400000000FAFF00100000000044
+:106CF000CC81838FF081828F0E0062100000000033
+:106D00003C80838301000224F9FF6214000000002C
+:106D1000F081828F01004324CC81828FF4FF6214C2
+:106D200000000000CC81828FF08182AFF0FF001064
+:106D3000000000009080848F9480858F21300000B7
+:106D4000213800009F1E400F00000000B462400F79
+:106D500000000000EF20400F0000000000A0023CF7
+:106D60008804422401004390280002240300621496
+:106D700000000000F7FF0010000000005221400F4B
+:106D8000000000005481838399818683648182831B
+:106D90001000A2AF4081828F1400A2AF7C81828359
+:106DA0001800A2AF9C81828F1C00A2AF5581828304
+:106DB0002000A2AF3C81828F2400A2AF212060007E
+:106DC0002C81858F1881878F8D2D400F000000004A
+:106DD0006822400F000000005480838302000224D8
+:106DE0000300621400000000115F400F000000006B
+:106DF00088BF023C5061428C4001427C0600401436
+:106E00000000000001000224448182A36881828F77
+:106E10000A004224688182AF88BF023C5061428CE4
+:106E20000001427C06004014000000000100022422
+:106E3000448182A36881828FF6FF4224688182AFF9
+:106E40003C808283010042382B1802004080828FF0
+:106E50002B100200251062002200401000000000EC
+:106E600095FF001000000000212000003564400F55
+:106E7000000000000200042421280000029D023CC2
+:106E800068024624213800001965400F0000000008
+:106E90000300042421280000029D023C7C024624B9
+:106EA000213800001965400F000000000400042490
+:106EB00021280000029D023C8C024624213800005B
+:106EC0001965400F0000000088BF023C9061428CB1
+:106ED0004002427C0300401000000000FAFF001056
+:106EE0000000000021200000B060400F0000000002
+:106EF000212000009B24400F000000003081828F81
+:106F00005C8182AF5C81848F4F3F400F00000000A6
+:106F1000AD1C400F00000000F266400F00000000B2
+:106F200088BF023C9061428C4002427C03004010CA
+:106F300000000000FAFF00100000000021E8C0037C
+:106F40002C00BF8F2800BE8F3000BD270800E00353
+:106F500000000000E8FFBD271400BFAF1000BEAF67
+:106F600021F0A00388BF023C9061428C4002427C29
+:106F70000300401400000000FAFF001000000000B1
+:106F8000040004249A64400F00000000050004245B
+:106F90009A64400F00000000060004249A64400F29
+:106FA000000000000500042421280000029D023C8E
+:106FB000A4024624213800001965400F000000009B
+:106FC00001000224A08182A32881848F6081858FA3
+:106FD0008081868F213800009F1E400F0000000036
+:106FE0000500042421280000029D023C580246248A
+:106FF000213800001965400F000000001A64400F9E
+:10700000000000006D63400F00000000F401042444
+:10701000775C400F0000000088BF023C9061428C0A
+:107020004002427C0300401000000000F3FF00100B
+:1070300000000000A08180A3050004249A64400F92
+:107040000000000001000424B060400F00000000B8
+:107050008F30400F0000000021E8C0031400BF8FF4
+:107060001000BE8F1800BD270800E00300000000DC
+:10707000E0FFBD271C00BFAF1800BEAF21F0A0038A
+:107080002000C4AF020004249A64400F00000000F6
+:10709000030004249A64400F00000000040004244C
+:1070A0009A64400F00000000050004249A64400F19
+:1070B00000000000060004249A64400F0000000055
+:1070C000070004249A64400F000000002000C28FD3
+:1070D0001000C2AF1000C38F070060100000000056
+:1070E000010002241000C38F220062100000000083
+:1070F0003F000010000000000300042421280000CD
+:10710000029D023CAC024624213800001965400F64
+:107110000000000054808383020002240B006214EC
+:107120000000000021200000B060400F00000000BF
+:107130000400042421280000029D023CB8024624D9
+:10714000213800001965400F000000002881848F5D
+:107150006081858F8081868F213800009F1E400FBF
+:1071600000000000010002243C8082A327000010E0
+:10717000000000000300042421280000029D023CBE
+:10718000C8024624213800001965400F00000000A5
+:1071900054808383020002240B006214000000006C
+:1071A00021200000B060400F000000000400042413
+:1071B00021280000029D023CB8024624213800002C
+:1071C0001965400F000000002881848F6081858F41
+:1071D0008081868F213800009F1E400F0000000034
+:1071E000010002243C8082A308000010000000007F
+:1071F0000300042421280000029D023CDC024624F6
+:10720000213800001965400F00000000050004242B
+:1072100021280000029D023CEC0246242138000097
+:107220001965400F0000000096000424775C400FB1
+:10723000000000000500042421280000029D023CFB
+:10724000FC024624213800001965400F00000000B0
+:1072500096000424775C400F0000000088BF023CC9
+:107260009061428C4002427C03004010000000000C
+:10727000E6FF00100000000088BF023C9061428CD5
+:107280004002427C0300401400000000FAFF00109E
+:1072900000000000297E400F0000000021E8C0032C
+:1072A0001C00BF8F1800BE8F2000BD270800E00320
+:1072B00000000000E8FFBD271400BFAF1000BEAF04
+:1072C00021F0A00381BF033C609062902000423413
+:1072D000609062A088BF043C40608390DFFF02247E
+:1072E00024106200406082A088BF043C006183904B
+:1072F000BFFF022424106200006182A088BF033C0B
+:10730000006162907F004230006162A081BF043C56
+:1073100061908390F7FF022424106200619082A0A4
+:1073200088BF033C4160629008004234416062A023
+:1073300081BF043C61908390EFFF0224241062001F
+:10734000619082A088BF033C41606290100042348B
+:10735000416062A081BF033C6090629001004234B2
+:10736000609062A088BF033C40606290010042349C
+:10737000406062A081BF033C609062900400423490
+:10738000609062A081BF033C60906290080042342C
+:10739000609062A081BF033C609062901000423414
+:1073A000609062A081BF043C6190839080FF0224C2
+:1073B00025106200619082A088BF033C406062900B
+:1073C00004004234406062A088BF033C4060629089
+:1073D00008004234406062A088BF033C4060629075
+:1073E00010004234406062A088BF043C416083903A
+:1073F00080FF022425106200416082A088BF033C08
+:107400004061629010004234406162A088BF033C3A
+:107410004061629020004234406162A088BF033C1A
+:107420008161629002004234816162A088BF033CA6
+:10743000E061629010004234E06162A088BF033CCA
+:10744000E061629020004234E06162A088BF033CAA
+:10745000E061629040004234E06162A088BF033C7A
+:10746000E161629010004234E16162A088BF033C98
+:10747000E261629002004234E26162A088BF033C94
+:10748000E261629004004234E26162A088BF033C82
+:10749000E161629008004234E16162A088BF033C70
+:1074A000C060629010004234C06062A088BF033C9C
+:1074B0008160629020004234816062A088BF033CFA
+:1074C0008160629040004234816062A088BF033CCA
+:1074D000E161629020004234E16162A088BF033C18
+:1074E000E061629002004234E06162A088BF033C28
+:1074F000E061629001004234E06162A081BF023C21
+:10750000009040AC81BF023C109040AC81BF033C76
+:10751000021F0224209062AC81BF023C509040AC1C
+:1075200081BF043C0190839080FF022425106200FB
+:10753000019082A088BF043C40618390FEFF02243A
+:1075400024106200406182A088BF043C5061839097
+:10755000FEFF022424106200506182A088BF043C18
+:1075600000618390DFFF022424106200006182A08A
+:1075700088BF043C10618390DFFF02242410620066
+:10758000106182A088BF043CC1608390F7FF022491
+:1075900024106200C16082A088BF043CD160839047
+:1075A000F7FF022424106200D16082A080BF023C59
+:1075B000007040ACC728400F000000000261400F7F
+:1075C000000000002069400F00000000157E400F01
+:1075D00000000000448180A3688180AF029D023CCE
+:1075E0000003428C288182AF029D023C0403428C3E
+:1075F000608182AF21100000808182AF21E8C0034A
+:107600001400BF8F1000BE8F1800BD270800E003D4
+:1076100000000000D8FFBD272400BFAF2000BEAF90
+:1076200021F0A0031000C0AF1400C0A31000C28F4F
+:107630001F004014000000000C0004248660400F6E
+:1076400000000000448082AF4C80838F4480828F92
+:10765000211062004C8082AF4880828F010042245A
+:10766000488082AF4880828F04004228EFFF401498
+:10767000000000004C80828F1800C2AF1800C28F3B
+:1076800004004104000000001800C38F03006324BD
+:107690001800C3AF1800C38F831003001000C2AFDF
+:1076A000488080AF4C8080AFE0FF001000000000F9
+:1076B0001000C28F0E004004000000001000C28FB6
+:1076C000C90042280A004010000000000100022406
+:1076D0001400C2A30100042414000524029D023CEE
+:1076E00008034624213800001965400F00000000FF
+:1076F0001000C28FC80042280E0040140000000095
+:107700001000C28F910142280A00401000000000C2
+:10771000020002241400C2A3010004241400052462
+:10772000029D023C14034624213800001965400FD5
+:10773000000000001000C28F900142280E0040148B
+:10774000000000001000C28F590242280A004010B9
+:1077500000000000030002241400C2A3010004245E
+:1077600014000524029D023C240346242138000015
+:107770001965400F000000001000C28F5802422817
+:107780000E004014000000001000C28F21034228A8
+:107790000A00401000000000040002241400C2A3EC
+:1077A0000100042414000524029D023C34034624F5
+:1077B000213800001965400F000000001000C28F42
+:1077C000200342280E004014000000001000C28F69
+:1077D000E90342280A0040100000000005000224CE
+:1077E0001400C2A30100042414000524029D023CDD
+:1077F00048034624213800001965400F00000000AE
+:107800001000C28FFC034228090040140000000051
+:107810001400C0A30100042414000524029D023CAE
+:1078200058034624213800001965400F000000006D
+:107830001400C28321E8C0032400BF8F2000BE8F44
+:107840002800BD270800E00300000000E0FFBD277E
+:107850001C00BFAF1800BEAF21F0A0031000C0AFE6
+:10786000851D400F00000000548082A3DE65400F9C
+:1078700000000000271E400F000000001000C2AFF3
+:107880001000C28F21E8C0031C00BF8F1800BE8FFC
+:107890002000BD270800E00300000000E0FFBD2736
+:1078A0001C00BFAF1800BEAF21F0A0031000C0AF96
+:1078B00088BF023C5060428CC000437C010002241F
+:1078C0006700621400000000050004240F62400FEE
+:1078D0000000000088BF023C5060428C0001427CE6
+:1078E0001300401400000000050004240F62400F44
+:1078F0000000000088BF023C5060428C0001427CC6
+:107900000300401400000000FAFF00100000000017
+:107910001000C28F010042241000C2AF1000C28FBD
+:107920000400422802004014000000001000C0AF14
+:1079300088BF023C5060428CC003427C130040145C
+:1079400000000000050004240F62400F000000004A
+:1079500088BF023C5060428CC003427C030040144C
+:1079600000000000FAFF0010000000001000C28FAD
+:10797000FFFF42241000C2AF1000C28F0300410479
+:1079800000000000030002241000C2AF1000C28FEC
+:107990001400C2AF010002241400C38F1B00621048
+:1079A000000000001400C38F02006228060040108F
+:1079B000000000001400C28F0D0040100000000005
+:1079C000BBFF001000000000020002241400C38F5F
+:1079D0001500621000000000030002241400C38F91
+:1079E0001800621000000000B1FF0010000000004D
+:1079F0000200042421280000010006241467400F1F
+:107A000000000000AAFF0010000000000300042492
+:107A100021280000010006241467400F0000000028
+:107A2000A3FF00100000000004000424212800002F
+:107A3000010006241467400F000000009CFF0010A6
+:107A40000000000005000424212800000100062495
+:107A50001467400F0000000095FF001000000000B8
+:107A60001000C28F21E8C0031C00BF8F1800BE8F1A
+:107A70002000BD270800E00300000000D0FFBD2764
+:107A80002C00BFAF2800BEAF21F0A0033000C4AF70
+:107A90003400C5AF3800C6AF2110E0003C00C2A3DF
+:107AA00088BF033C0100023C641062AC88BF033C09
+:107AB0000100023C681062AC01000224608082AFC9
+:107AC00047000224548182A32C8180AF58000224F5
+:107AD000998182A33000C28F188182AF590002249D
+:107AE000648182A33400C28F408182AF3C00C28394
+:107AF00007004010000000005A0002247C8182A38D
+:107B00003800C28F9C8182AF04000010000000008A
+:107B10007C8180A3211000009C8182AF460002245A
+:107B2000558182A3211000003C8182AF5481838360
+:107B300099818683648182831000A2AF4081828F05
+:107B40001400A2AF7C8182831800A2AF9C81828F37
+:107B50001C00A2AF558182832000A2AF3C81828F9E
+:107B60002400A2AF212060002C81858F1881878F8F
+:107B70008D2D400F00000000548180A32C8180AF28
+:107B8000998180A321100000188182AF648180A3B5
+:107B900021100000408182AF7C8180A32110000071
+:107BA0009C8182AF558180A3211000003C8182AF6F
+:107BB000608080AFFA000424775C400F0000000072
+:107BC00021E8C0032C00BF8F2800BE8F3000BD27E6
+:107BD0000800E00300000000E8FFBD271400BFAF6D
+:107BE0001000BEAF21F0A0033C808383010002247B
+:107BF00006006214000000003C8080A3308180AF4A
+:107C0000408080AF308080AF348080AFEA31400F59
+:107C1000000000000300401400000000FBFF001003
+:107C200000000000501F400F0000000088BF023C11
+:107C30009061428C4002427C03004014000000002E
+:107C400039000010000000009220400F00000000EA
+:107C5000648082AF00A0023CBC044424029D023C2C
+:107C6000640345242042400F000000005C8182AF85
+:107C70005C81828F308182AF5C81828F00004238CC
+:107C80000100422C2510420020004010000000009E
+:107C90000200042421280000029D023C68034624BF
+:107CA000213800001965400F000000000300042483
+:107CB00028000524029D023C780346242138000058
+:107CC0001965400F00000000040004242128000072
+:107CD000029D023C58024624213800001965400FDD
+:107CE00000000000FA000424775C400F0000000050
+:107CF00088BF023C9061428C4002427CE4FF401409
+:107D00000000000008000010000000000200042431
+:107D10005A000524029D023C8803462421380000B5
+:107D20001965400F0000000021E8C0031400BF8F58
+:107D30001000BE8F1800BD270800E00300000000FF
+:107D400080FFBD277C00BFAF7800BEAF21F0A0034D
+:107D5000200002244800C2A3029D023C9003428CF2
+:107D60005000C2AF010002245800C2AF5C00C0AF97
+:107D70006000C0AF5000C2274800C39321204000DC
+:107D8000212860001000C6275A58400F000000004C
+:107D90005800C2AF5800C28F3700401400000000E6
+:107DA000010002246C8082AF1000C4276959400F83
+:107DB000000000005800C2AF5800C28F04004014F9
+:107DC000000000006C80828F010042246C8082AF32
+:107DD0005800C28F0300401400000000F2FF0010A2
+:107DE000000000006000C28F23004014000000006B
+:107DF0005000C2274800C393212040002128600082
+:107E00001000C6275A58400F000000005800C2AFAB
+:107E100001000224688082AF010002245C00C2AF2E
+:107E20005C00C28F6C80838F2A1043000A004010D0
+:107E3000000000001000C4276959400F0000000036
+:107E40005800C2AF5C00C28F010042245C00C2AF88
+:107E5000F3FF0010000000006C80828F688082AF0A
+:107E600002000424212800001000C6272138000049
+:107E70001965400F000000005800C28F220040101A
+:107E8000000000006C8080AF688080AF0200042496
+:107E900021280000029D023C940346242138000062
+:107EA0001965400F00000000030004242128000091
+:107EB000029D023CA8034624213800001965400FAA
+:107EC000000000000500042421280000029D023C5F
+:107ED00058024624213800001965400F00000000B8
+:107EE000FA000424775C400F0000000088BF023CC9
+:107EF0009061428C4002427CE4FF4014000000008C
+:107F0000CB000010000000005800C28FA5004014F4
+:107F10000000000088BF023C5060428C0001427C9F
+:107F2000330040140000000088BF023C5060428CC7
+:107F30000001427C0300401400000000FAFF001022
+:107F4000000000001E000424775C400F00000000C9
+:107F50001000C4276959400F000000005800C2AF4C
+:107F60005800C28F0F004014000000006880828F0C
+:107F70006C80838F2A106200050040100000000012
+:107F80006C80828F688082AF1000001000000000BB
+:107F90006880828F01004224688082AF0B0000104D
+:107FA000000000005000C2274800C3932120400079
+:107FB000212860001000C6275A58400F000000001A
+:107FC0005800C2AF01000224688082AF020004247E
+:107FD0009A64400F000000000200042421280000E1
+:107FE0001000C627213800001965400F000000006E
+:107FF00088BF023C5060428CC003427C3F0040146A
+:108000000000000088BF023C5060428CC003427CEC
+:108010000300401400000000FAFF00100000000000
+:108020001E000424775C400F000000001000C427ED
+:108030006959400F000000005800C2AF5800C28FBD
+:108040000300401400000000F8FF001000000000D2
+:108050005000C2274800C39321204000212860001F
+:108060001000C6275A58400F000000005800C2AF49
+:108070006880828FFFFF4224688082AF6880828F91
+:1080800005004014000000006C80828F688082AF81
+:10809000010002246000C2AF010002245C00C2AFF4
+:1080A0005C00C28F6880838F2A1043000A00401052
+:1080B000000000001000C4276959400F00000000B4
+:1080C0005800C2AF5C00C28F010042245C00C2AF06
+:1080D000F3FF001000000000020004249A64400F27
+:1080E0000000000002000424212800001000C62720
+:1080F000213800001965400F00000000060004242C
+:1081000021280000029D023CBC03462421380000C7
+:108110001965400F000000006800C22721204000C0
+:10812000029D023CC40345246880868F666D400F23
+:10813000000000006800C22706000424190005247E
+:1081400021304000213800001965400F0000000078
+:108150000600042441000524029D023CC803462475
+:10816000213800001965400F000000006800C22798
+:1081700021204000029D023CC40345246C80868F70
+:10818000666D400F000000006800C227060004244E
+:108190005A00052421304000213800001965400FA5
+:1081A0000000000088BF023C9061428C4002427C8B
+:1081B00003004014000000001D000010000000003B
+:1081C00088BF023C5060428CC000427C01004238B3
+:1081D0000100432C5800C28F000042380100422C9D
+:1081E00024106200030040100000000046FF001051
+:1081F0000000000088BF023C5060428CC000437CFD
+:10820000010002240300621400000000D9FE0010E7
+:108210000000000000A0023CBC0444241000C5275C
+:10822000516A400F000000002000C28F488182AFD9
+:1082300021E8C0037C00BF8F7800BE8F8000BD277F
+:108240000800E00300000000F0FFBD270800BEAFFB
+:1082500021F0A003080002240100C2A30100C29380
+:10826000500040100000000000A0023C0100C39339
+:10827000BC04422421106200000043802E0002242E
+:10828000430062140000000000A0023C0100C39300
+:10829000BC044224211062000100428047004238A1
+:1082A0000100442C00A0023C0100C393BC04422402
+:1082B0002110620002004280430042380100422C3B
+:1082C0002420820000A0023C0100C393BC0442248D
+:1082D00021106200030042804F0042380100422C0E
+:1082E000241082000700401000000000010002245A
+:1082F0000000C2A3010002240400C2AF2900001044
+:108300000000000000A0023C0100C393BC04422412
+:108310002110620001004280420042380100442CDA
+:1083200000A0023C0100C393BC044224211062005F
+:1083300002004280460042380100422C2420820084
+:1083400000A0023C0100C393BC044224211062003F
+:1083500003004280420042380100422C2410820077
+:108360000700401000000000030002240000C2A328
+:10837000030002240400C2AF0A0000100000000045
+:108380000000C0A30400C0AF060000100000000001
+:108390000100C293FFFF42240100C2A3AFFF0010FF
+:1083A000000000000400C28F21E8C0030800BE8F57
+:1083B0001000BD270800E00300000000D0FFBD272B
+:1083C0002C00BFAF2800BEAF21F0A00301000224A3
+:1083D0002000C2AF2400C0AF3C8080A33081828FD8
+:1083E0005C8182AF3480828F01004224348082AF6E
+:1083F00000A0033C3E000224880462A05C81848FBC
+:108400003080858F21300000464A400F0000000078
+:108410000600401000000000010004241C1C400F56
+:1084200000000000010002243C8082A33C80828383
+:108430003F004014000000009881842701000524BB
+:10844000010006245C81878F7E47400F00000000FA
+:10845000408082AF00A0023C2000C38F88044224E9
+:108460002118620098818293000062A02000C28FD0
+:10847000010042242000C2AF988183832800022497
+:108480001500621400000000988184270100052473
+:10849000010006245C81878F7E47400F00000000AA
+:1084A000408082AF5C81848F6E47400F00000000E7
+:1084B0000300401000000000070000100000000052
+:1084C000988183830A0002240300621000000000E8
+:1084D000EDFF0010000000005C81848F6E47400FAC
+:1084E0000000000008004010000000005C81848F44
+:1084F0004F3F400F00000000010002243C8082A397
+:108500000700001000000000988183830A00022405
+:108510000300621000000000C7FF00100000000010
+:108520005C81848FCC43400F00000000308082AF1C
+:1085300021E8C0032C00BF8F2800BE8F3000BD276C
+:108540000800E00300000000E0FFBD271C00BFAFF3
+:108550001800BEAF21F0A003010002241000C2AF3A
+:108560001400C0AF01000224388082AF00A0023C9A
+:1085700088044224010043900D0002240300621489
+:1085800000000000DC000010000000003880838F35
+:108590000100022427006214000000001400C28FB2
+:1085A0000A0040140000000000A0023C1000C38F2D
+:1085B000880442242110620000004290548182A36A
+:1085C0001000C28F010042241000C2AF1400C38FFC
+:1085D000348182272120620000A0023C1000C38F5A
+:1085E000880442242110620000004290000082A012
+:1085F0001400C28F010042241400C2AF00A0023C4C
+:108600001000C38F880442242110620000004390B0
+:108610002000022407006214000000001000C28F36
+:10862000010042241000C2AF1400C0AF02000224B7
+:10863000388082AF3880838F0200022427006214C2
+:10864000000000001400C28F0A0040140000000067
+:1086500000A0023C1000C38F880442242110620055
+:1086600000004290998182A31000C28F0100422431
+:108670001000C2AF1400C38FA481822721206200A2
+:1086800000A0023C1000C38F880442242110620025
+:1086900000004290000082A01400C28F010042241A
+:1086A0001400C2AF00A0023C1000C38F8804422413
+:1086B0002110620000004390200002240700621491
+:1086C000000000001000C28F010042241000C2AF61
+:1086D0001400C0AF03000224388082AF3880838F3B
+:1086E0000300022427006214000000001400C28F5F
+:1086F0000A0040140000000000A0023C1000C38FDC
+:10870000880442242110620000004290648182A308
+:108710001000C28F010042241000C2AF1400C38FAA
+:10872000748182272120620000A0023C1000C38FC8
+:10873000880442242110620000004290000082A0C0
+:108740001400C28F010042241400C2AF00A0023CFA
+:108750001000C38F8804422421106200000043905F
+:108760002000022407006214000000001000C28FE5
+:10877000010042241000C2AF1400C0AF0400022464
+:10878000388082AF3880838F04000224270062146F
+:10879000000000001400C28F0A0040140000000016
+:1087A00000A0023C1000C38F880442242110620004
+:1087B000000042907C8182A31000C28F01004224FD
+:1087C0001000C2AF1400C38F908182272120620065
+:1087D00000A0023C1000C38F8804422421106200D4
+:1087E00000004290000082A01400C28F01004224C9
+:1087F0001400C2AF00A0023C1000C38F88044224C2
+:10880000211062000000439020000224070062143F
+:10881000000000001000C28F010042241000C2AF0F
+:108820001400C0AF05000224388082AF3880838FE7
+:108830000500022419006214000000001400C28F19
+:108840000A0040140000000000A0023C1000C38F8A
+:10885000880442242110620000004290558182A3C6
+:108860001000C28F010042241000C2AF1400C38F59
+:10887000208182272120620000A0023C1000C38FCB
+:10888000880442242110620000004290000082A06F
+:108890001400C28F010042241400C2AF00A0023CA9
+:1088A0001000C38F8804422421106200000043900E
+:1088B0000A00022403006214000000000E000010F1
+:1088C000000000001000C28F010042241000C2AF5F
+:1088D00000A0023C1000C38F8804422421106200D3
+:1088E000000043900D00022403006210000000000D
+:1088F0001EFF00100000000034818427276C400F09
+:10890000000000002C8182AFA4818427206C400FDE
+:108910000000000021204000212860004879400F1D
+:1089200000000000188182AF74818427206C400F02
+:108930000000000021204000212860004879400FFD
+:1089400000000000408182AF90818427206C400F9E
+:108950000000000021204000212860004879400FDD
+:10896000000000009C8182AF20818427206C400F92
+:108970000000000021204000212860004879400FBD
+:10898000000000003C8182AF21E8C0031C00BF8FC3
+:108990001800BE8F2000BD270800E0030000000083
+:1089A000F0FFBD270800BEAF21F0A0033100022474
+:1089B0000000C2AF0000C28F0B004010000000009A
+:1089C00000A0023C0000C38F8804422421106200F2
+:1089D000000040A00000C28FFFFF42240000C2AF91
+:1089E000F4FF0010000000000000C28F03004014DC
+:1089F0000000000000A0023C880440A0548180A335
+:108A0000070002240000C2AF0000C28F0A0040101D
+:108A1000000000000000C38F348182272110620013
+:108A2000000040A00000C28FFFFF42240000C2AF40
+:108A3000F5FF0010000000000000C28F020040148B
+:108A400000000000348180A3998180A307000224E4
+:108A50000000C2AF0000C28F0A00401000000000FA
+:108A60000000C38FA481822721106200000040A073
+:108A70000000C28FFFFF42240000C2AFF5FF0010CC
+:108A8000000000000000C28F02004014000000003F
+:108A9000A48180A3648180A3070002240000C2AFE8
+:108AA0000000C28F0A004010000000000000C38FC9
+:108AB0007481822721106200000040A00000C28F54
+:108AC000FFFF42240000C2AFF5FF001000000000CD
+:108AD0000000C28F0200401400000000748180A3D7
+:108AE0007C8180A3070002240000C2AF0000C28F77
+:108AF0000A004010000000000000C38F9081822710
+:108B000021106200000040A00000C28FFFFF42243D
+:108B10000000C2AFF5FF0010000000000000C28F8F
+:108B20000200401400000000908180A3558180A3C2
+:108B3000070002240000C2AF0000C28F0A004010EC
+:108B4000000000000000C38F2081822721106200F6
+:108B5000000040A00000C28FFFFF42240000C2AF0F
+:108B6000F5FF0010000000000000C28F020040145A
+:108B700000000000208180A321E8C0030800BE8F10
+:108B80001000BD270800E00300000000E0FFBD2743
+:108B90001C00BFAF1800BEAF21F0A00321100000E1
+:108BA0001000C2AFF081828FCC81838F2A106200C7
+:108BB0000A00401000000000F081838FCC81828F7A
+:108BC0002310620021204000CC7B400F00000000F9
+:108BD0001000C2AF0900001000000000F081838F78
+:108BE000CC81828F231062000002422421204000A9
+:108BF000CC7B400F000000001000C2AF029D023C81
+:108C00001000C48FCC03458C417B400F0000000056
+:108C10001000C2AF029D023C1000C48FD003458CEF
+:108C2000D37A400F000000001000C2AF1000C48FC4
+:108C3000F67B400F000000000600042421284000BD
+:108C40006564400F0000000021E8C0031C00BF8FD6
+:108C50001800BE8F2000BD270800E00300000000C0
+:108C6000D8FFBD272000BFAF1C00BEAF1800B0AFBB
+:108C700021F0A003211000001000C2AF3080848FCB
+:108C8000CC7B400F00000000218040004881848F91
+:108C9000CC7B400F00000000212000022128400072
+:108CA000417B400F000000001000C2AF029D023C5B
+:108CB0001000C48FD403458CD37A400F000000000D
+:108CC0001000C2AF029D023CD403448C1000C58F3B
+:108CD000317C400F00000000030040040000000051
+:108CE0000400001000000000029D023CD403428CEE
+:108CF0001000C2AF1000C48FF67B400F00000000D0
+:108D000005000424212840006564400F0000000095
+:108D100021E8C0032000BF8F1C00BE8F1800B08F59
+:108D20002800BD270800E00300000000C8FFBD27A1
+:108D30003400BFAF3000BEAF21F0A003211080008F
+:108D40003800C2A3211000002000C2AF2110000093
+:108D50002400C2AF211000002800C2AFCC81838F55
+:108D6000F081828F0300621000000000FBFF001002
+:108D70000000000088BF033C0100023C641062ACAC
+:108D800088BF023C681040AC60EA02348C8182AF3C
+:108D9000A48080A3A58080A3A68080A301000424D2
+:108DA0009B24400F000000001566400F00000000EB
+:108DB00088BF023C5060428CC000427C03004014DB
+:108DC00000000000FAFF00100000000088BF023C15
+:108DD0009061428C4002437C01000224170162141E
+:108DE0000000000001000224A88082AF8C81828FE5
+:108DF000E903422804004014000000008C81828FA7
+:108E0000B5FF42248C8182AF8C81828F650042281D
+:108E100004004014000000008C81828FFBFF42247C
+:108E20008C8182AF8C81828F200342280300401006
+:108E300000000000200302248C8182AF88BF023C26
+:108E40005060428CC000427C0400401400000000CE
+:108E5000088280AF01000224A48082A388BF023C64
+:108E60005060428C8000427C0500401400000000ED
+:108E700001000224088282AF01000224A48082A3A0
+:108E800088BF023C5060428CC000427C070040100A
+:108E90000000000088BF023C5060428C8000427C91
+:108EA0000200401000000000A48080A388BF023CA4
+:108EB0005060428CC003427C04004014000000005B
+:108EC000E88180AF01000224A58082A388BF023C14
+:108ED0005060428C0001427C0500401400000000FC
+:108EE00001000224E88182AF01000224A58082A350
+:108EF00088BF023C5060428CC003427C0700401097
+:108F00000000000088BF023C5060428C0001427C9F
+:108F10000200401000000000A58080A388BF023C32
+:108F20005061428C4001427C04004014000000006B
+:108F3000F48180AF01000224A68082A388BF023C96
+:108F40005061428C0001427C05004014000000008A
+:108F500001000224F48182AF01000224A68082A3D2
+:108F600088BF023C5061428C4001427C07004010A7
+:108F70000000000088BF023C5061428C0001427C2E
+:108F80000200401000000000A68080A3A48082831D
+:108F90000900401400000000A580828306004014F0
+:108FA00000000000A680828303004014000000003F
+:108FB00060EA02348C8182AF3800C28383FF4010A4
+:108FC0000000000088BF023CD060428C0001427C5F
+:108FD0000A00401000000000020004244B00052499
+:108FE000029D023CD8034624213800001965400F39
+:108FF000000000000800001000000000020004242F
+:109000004B000524029D023CE00346242138000069
+:109010001965400F0000000088BF023C9060428C40
+:109020004003427C0A0040100000000003000424BA
+:109030004B000524029D023CD80346242138000041
+:109040001965400F0000000008000010000000003B
+:10905000030004244B000524029D023CE003462447
+:10906000213800001965400F0000000088BF023C55
+:109070009060428C8003427C0A0040100000000097
+:10908000040004244B000524029D023CD80346241E
+:10909000213800001965400F000000000800001092
+:1090A00000000000040004244B000524029D023C43
+:1090B000E0034624213800001965400F000000003D
+:1090C000B881848FCC7B400F00000000212040003D
+:1090D0001F79400F00000000029D063C2120400047
+:1090E00021286000F403C78CF003C68CC177400FC1
+:1090F0000000000021204000212860004879400F36
+:10910000000000002000C2AF2000C48F1F79400F74
+:109110000000000021304000213860001000C4270A
+:10912000029D023CE8034524666D400F00000000EC
+:1091300005000424400005241000C6272138000043
+:109140001965400F00000000EC81848FCC7B400F3C
+:1091500000000000212040001F79400F00000000A7
+:10916000029D063C2120400021286000F403C78CAA
+:10917000F003C68CC177400F0000000021204000A2
+:10918000212860004879400F000000002400C2AF91
+:109190002400C48F1F79400F0000000021304000E0
+:1091A000213860001000C427029D023CE8034524DA
+:1091B000666D400F000000000600042440000524F6
+:1091C0001000C627213800001965400F000000007C
+:1091D000C081848FCC7B400F00000000029D033CC7
+:1091E00021204000F803658C417B400F0000000007
+:1091F0002800C2AF2800C48F1F79400F0000000074
+:1092000021304000213860001000C427029D023C3C
+:10921000E8034524666D400F0000000007000424A9
+:10922000400005241000C627213800001965400FB2
+:1092300000000000E5FE001000000000A88080AFE4
+:1092400088BF023C0100033C641043AC88BF023C71
+:10925000681040AC21E8C0033400BF8F3000BE8FDF
+:109260003800BD270800E00300000000F8FFBD271C
+:109270000000BEAF21F0A0030800C4AF0800C38FF8
+:1092800001000224180062140000000088BF043CA2
+:10929000D0608390F7FF022424106200D06082A087
+:1092A00088BF043CD1608390FBFF0224241062003D
+:1092B000D16082A088BF043C51608390DFFF02240C
+:1092C00024106200516082A088BF033C0100023C70
+:1092D000641062AC88BF033C0100023C681062ACC1
+:1092E000120000100000000088BF033CD0606290B4
+:1092F00008004234D06062A088BF033CD160629015
+:1093000004004234D16062A088BF033C5160629087
+:1093100020004234516062A088BF033C0100023C3F
+:10932000641062AC88BF023C681040AC21E8C00306
+:109330000000BE8F0800BD270800E0030000000009
+:10934000E0FFBD271C00BFAF1800BEAF21F0A00397
+:109350008966400F00000000A48080A3A58080A340
+:10936000A68080A3C728400F00000000010004244D
+:109370009B24400F0000000001000224A88082AF5F
+:10938000F40102248C8182AF030004242128000010
+:10939000029D023CFC034624213800001965400F61
+:1093A0000000000001000224F48182AF01000224C9
+:1093B000A68082A31000C0AF1000C38F0300023C40
+:1093C0003F0D42342A104300060040140000000004
+:1093D0001000C28F010042241000C2AFF6FF00103F
+:1093E00000000000A68080A30300042421280000C0
+:1093F000029D023C08044624213800001965400FF4
+:1094000000000000E80302248C8182AF01000224E6
+:10941000E88182AF01000224A58082A31000C0AFC2
+:109420001000C28F5FEA03342A1062000600401465
+:10943000000000001000C28F010042241000C2AFE3
+:10944000F7FF001000000000A58080A303000424A3
+:1094500021280000029D023C14044624213800000B
+:109460001965400F00000000E80302248C8182AFE0
+:1094700088BF023CD060428C0001427C2100401435
+:109480000000000088BF023C9061428C4002427C98
+:109490001C0040100000000001000224088282AF7E
+:1094A00088BF023CD060428C0001427C0A0040141C
+:1094B0000000000088BF023C9061428C4002427C68
+:1094C000050040100000000001000224A48082A3D7
+:1094D000F3FF001000000000A48080A31000C0AFC4
+:1094E0001000C28F204E4228E1FF40100000000013
+:1094F0001000C28F010042241000C2AFF8FF00101C
+:109500000000000001000224A48082A31000C0AF6C
+:109510001000C28F102742280600401000000000F3
+:109520001000C28F010042241000C2AFF8FF0010EB
+:1095300000000000A48080A360EA02348C8182AF26
+:1095400088BF023CD060428C0001427C2600401063
+:109550000000000088BF023C9061428C4002427CC7
+:109560002100401000000000088280AF88BF023C4C
+:10957000D060428C0001427C0A00401000000000D4
+:1095800088BF023C9061428C4002427C0500401042
+:109590000000000001000224A48082A3F3FF001059
+:1095A00000000000A48080A31000C0AF1000C28F94
+:1095B000D007422806004010000000001000C28FB3
+:1095C000010042241000C2AFF8FF001000000000AC
+:1095D000D2D10224B88182AFB881828FBC8182AFA0
+:1095E000D7FF001000000000030004242128000021
+:1095F000029D023C20044624213800001965400FDA
+:1096000000000000E80302248C8182AF88BF023C86
+:109610009060428C4003427C200040140000000017
+:1096200088BF023C9061428C4002427C1B0040108B
+:1096300000000000E88180AF88BF023C9060428C4F
+:109640004003427C0A0040140000000088BF023C36
+:109650009061428C4002427C0500401000000000F6
+:1096600001000224A58082A3F3FF00100000000087
+:10967000A58080A31000C0AF1000C28F204E4228EA
+:10968000E2FF4010000000001000C28F01004224E1
+:109690001000C2AFF8FF001000000000010002241B
+:1096A000A58082A31000C0AF1000C28F10274228EF
+:1096B00006004010000000001000C28F010042248C
+:1096C0001000C2AFF8FF001000000000A58080A3CA
+:1096D00060EA02348C8182AF88BF023C9060428C89
+:1096E0004003427C270040100000000088BF023C7D
+:1096F0009061428C4002427C220040100000000039
+:1097000001000224E88182AF88BF023C9060428C55
+:109710004003427C0A0040100000000088BF023C69
+:109720009061428C4002427C050040100000000025
+:1097300001000224A58082A3F3FF001000000000B6
+:10974000A58080A31000C0AF1000C28FD0074228B0
+:1097500006004010000000001000C28F01004224EB
+:109760001000C2AFF8FF00100000000035220224F4
+:10977000EC8182AFEC81828FD48182AFD6FF001062
+:10978000000000000300042421280000029D023C88
+:109790002C044624213800001965400F0000000009
+:1097A000F40102248C8182AF88BF023C9060428C1D
+:1097B0008003427C200040140000000088BF023C6F
+:1097C0009061428C4002427C1B004010000000006F
+:1097D000F48180AF88BF023C9060428C8003427C61
+:1097E0000A0040140000000088BF023C9061428CD7
+:1097F0004002427C050040100000000001000224ED
+:10980000A68082A3F3FF001000000000A68080A3C2
+:109810001000C0AF1000C28FD0074228E2FF4010F6
+:10982000000000001000C28F010042241000C2AFEF
+:10983000F8FF00100000000001000224A68082A3AF
+:109840001000C0AF1000C28F102742280600401041
+:10985000000000001000C28F010042241000C2AFBF
+:10986000F8FF001000000000A68080A388130224E7
+:109870008C8182AF88BF023C9060428C8003427C26
+:10988000260040100000000088BF023C9061428C1E
+:109890004002427C21004010000000000100022430
+:1098A000F48182AF88BF023C9060428C8003427C8E
+:1098B0000A0040100000000088BF023C9061428C0A
+:1098C0004002427C0500401000000000010002241C
+:1098D000A68082A3F3FF001000000000A68080A3F2
+:1098E0001000C0AF1000C28FD00742280600401001
+:1098F000000000001000C28F010042241000C2AF1F
+:10990000F8FF001000000000C08180AFC081828F8E
+:10991000E08182AFD7FF001000000000A88080AF78
+:1099200088BF033C0100023C641062AC88BF023C6B
+:10993000681040AC88BF023C9061428C4002427C7F
+:109940001700401400000000030004242128000038
+:10995000029D023C38044624213800001965400F5E
+:10996000000000001000C0AF1000C38F1E00023CBA
+:109970007F8442342A104300060040140000000097
+:109980001000C28F010042241000C2AFF6FF001089
+:10999000000000001400C0AF16000010000000001E
+:1099A0000300042421280000029D023C48044624B0
+:1099B000213800001965400F000000001000C0AF02
+:1099C0001000C38F1E00023C7F8442342A104300E3
+:1099D00006004014000000001000C28F0100422465
+:1099E0001000C2AFF6FF00100000000001000224CA
+:1099F0001400C2AF1400C28F21E8C0031C00BF8F47
+:109A00001800BE8F2000BD270800E0030000000002
+:109A1000E8FFBD271400BFAF1000BEAF21F0A003C8
+:109A200001000224C08082AF01000224C48082AF02
+:109A3000C88080AFF40102248C8182AF2881848F9A
+:109A40001F79400F00000000029D063C21204000CD
+:109A5000212860005C04C78C5804C68CF776400F40
+:109A60000000000021204000212860004879400FBC
+:109A700000000000E48182AF6081848F1F79400F75
+:109A800000000000029D063C2120400021286000CB
+:109A90005C04C78C5804C68CF776400F00000000A9
+:109AA00021204000212860004879400F000000007C
+:109AB000D88182AFE481848F032D400F0000000025
+:109AC000B48182AFD881848F032D400F0000000045
+:109AD000048282AF88BF033C0100023C641062AC88
+:109AE00088BF033C0100023C681062ACA52A400F0D
+:109AF00000000000C08080AFC48080AFFA00042462
+:109B0000775C400F0000000021E8C0031400BF8F05
+:109B10001000BE8F1800BD270800E0030000000001
+:109B200000E85D4100681A4000701B40C0FFBD277F
+:109B30003C00BBAF00601B4082D21A003800BBAFB4
+:109B4000847A5B7F44201B7C00609B403400BEAF66
+:109B50003000A4AF2C00A3AF2800A2AF21F0A003D7
+:109B60000400C0A3A880828F98004010000000006D
+:109B7000A080828F0800C2AF010002240800C38FBA
+:109B800026006210000000000800C38F0200622857
+:109B900006004010000000000800C28F09004010BD
+:109BA00000000000820000100000000002000224FB
+:109BB0000800C38F6B006210000000007C000010E2
+:109BC0000000000088BF043CD060828C0882838F34
+:109BD000C439627CD06082AC88BF043CD060828C87
+:109BE000E881838F444A627CD06082AC88BF043CA9
+:109BF0005060828CF481838F444A627C506082ACD6
+:109C000080BF033C05000224200C62AC010002244A
+:109C1000A08082AF6600001000000000A480828354
+:109C2000120040100000000088BF033CD06062902A
+:109C300004004234D06062A00882828F0600401483
+:109C400000000000B881828F01004224B88182AFF9
+:109C50000B00001000000000B881828FFFFF42243B
+:109C6000B88182AF060000100000000088BF043CED
+:109C7000D0608390FBFF022424106200D06082A099
+:109C8000A5808283120040100000000088BF033CC2
+:109C9000D160629001004234D16062A0E881828F7D
+:109CA0000600401400000000EC81828F0100422475
+:109CB000EC8182AF0B00001000000000EC81828F6D
+:109CC000FFFF4224EC8182AF06000010000000007C
+:109CD00088BF043CD1608390FEFF02242410620000
+:109CE000D16082A0A6808283120040100000000094
+:109CF00088BF033C5160629001004234516062A011
+:109D0000F481828F0600401400000000C081828F21
+:109D100001004224C08182AF0B000010000000004F
+:109D2000C081828FFFFF4224C08182AF06000010F5
+:109D30000000000088BF043C51608390FEFF0224B5
+:109D400024106200516082A080BF023C0A000324FC
+:109D5000200C43AC02000224A08082AF140000104B
+:109D60000000000080BF033C8C81828F200C62AC1D
+:109D700088BF043CD0608390FBFF02242410620063
+:109D8000D06082A088BF043CD1608390FEFF022493
+:109D900024106200D16082A088BF043C516083908F
+:109DA000FEFF022424106200516082A0A08080AFD8
+:109DB00080BF023C100C40AC88BF033C0100023C59
+:109DC000341062AC48010010000000009C80828FBB
+:109DD0002400C2AF010002242400C38FA50062103A
+:109DE000000000002400C38F02006228060040101B
+:109DF000000000002400C28F090040100000000095
+:109E00003401001000000000020002242400C38F6F
+:109E10000D016210000000002E0100100000000083
+:109E2000B081828F8C00401400000000CC81838FB1
+:109E3000F081828F880062100000000000A0043CC6
+:109E4000CC81828F80180200C80482242110620015
+:109E50000000428CD08182AF00A0043CCC81828F74
+:109E600080180200C804822421106200000040AC67
+:109E7000CC81828F01004224CC8182AFCC81828F41
+:109E80000C00C2AF0C00C38F1000C3AF1000C28F14
+:109E900004004104000000001000C38FFF01632490
+:109EA0001000C3AF1000C38F431203004012020022
+:109EB0000C00C38F23106200CC8182AF010002240A
+:109EC000B08182AF0008023C0000C2AF0300022450
+:109ED0000400C2A3D081828F0000C38F24104300EE
+:109EE0002A004010000000000400C2931400C2AF1A
+:109EF000050002241400C38F170062100000000048
+:109F00001400C38F06006228070040100000000004
+:109F1000030002241400C38F090062100000000037
+:109F20004200001000000000070002241400C38F4C
+:109F30000F006210000000003C0000100000000054
+:109F400088BF023C5160439002006334516043A0DB
+:109F5000360000100000000088BF023CD160439032
+:109F600002006334D16043A0300000100000000004
+:109F700088BF043CD060839080FF022425106200DB
+:109F8000D06082A029000010000000000400C293ED
+:109F90001800C2AF050002241800C38F1800621019
+:109FA000000000001800C38F060062280700401060
+:109FB00000000000030002241800C38F0900621093
+:109FC000000000001900001000000000070002243B
+:109FD0001800C38F11006210000000001300001071
+:109FE0000000000088BF043C51608390FDFF022404
+:109FF00024106200516082A00C00001000000000DC
+:10A0000088BF043CD1608390FDFF022424106200CD
+:10A01000D16082A0050000100000000088BF023C53
+:10A02000D06043907F006330D06043A00400C293AF
+:10A03000020042240400C2A30000C28F801002006C
+:10A040000000C2AF0000C28F0300401000000000FB
+:10A05000A0FF00100000000080BF023C05000324A8
+:10A06000200C43AC010002249C8082AF99000010B8
+:10A0700000000000B081828F6C00401000000000E2
+:10A080000004023C0000C2AF020002240400C2A38C
+:10A09000D081828F0000C38F241043002D00401018
+:10A0A000000000000400C2931C00C2AF04000224A0
+:10A0B0001C00C38F17006210000000001C00C38F3B
+:10A0C0000500622807004010000000000200022482
+:10A0D0001C00C38F0900621000000000480000103F
+:10A0E00000000000060002241C00C38F1100621053
+:10A0F00000000000420000100000000088BF023C89
+:10A100005160439001006334516043A03C00001053
+:10A110000000000088BF033CD1606290010042341F
+:10A12000D16062A0010002240600C2A33400001026
+:10A130000000000088BF033CD060629004004234FD
+:10A14000D06062A0010002240500C2A32C00001010
+:10A15000000000000400C2932000C2AF04000224EB
+:10A160002000C38F18006210000000002000C38F81
+:10A1700005006228070040100000000002000224D1
+:10A180002000C38F09006210000000001C000010B6
+:10A1900000000000060002242000C38F120062109D
+:10A1A00000000000160000100000000088BF043C02
+:10A1B00051608390FEFF022424106200516082A04F
+:10A1C0000F0000100000000088BF043CD1608390A5
+:10A1D000FEFF022424106200D16082A00600C0A30A
+:10A1E000070000100000000088BF043CD06083908E
+:10A1F000FBFF022424106200D06082A00500C0A3EF
+:10A200000400C293020042240400C2A30000C28FD3
+:10A21000801002000000C2AF0000C28F0300401097
+:10A22000000000009AFF00100000000080BF023C08
+:10A230000A000324200C43AC020002249C8082AF5D
+:10A240002400001000000000B081828F0C0040103C
+:10A2500000000000FFFF02340000C2AFD081838FF6
+:10A260000000C28F241062000C8082AF80BF033CCC
+:10A270000C80828F200C62AC0400001000000000F3
+:10A2800080BF033C88130224200C62AC88BF043CCE
+:10A29000D0608390FBFF022424106200D06082A073
+:10A2A00088BF043CD1608390FEFF0224241062002A
+:10A2B000D16082A088BF043C51608390FEFF0224DD
+:10A2C00024106200516082A09C8080AFB08180AF7A
+:10A2D000D08180AF80BF023C100C40AC88BF033CF3
+:10A2E0000100023C341062AC21E8C0033400BE8F90
+:10A2F0003000A48F2C00A38F2800A28F0060604143
+:10A30000C00000003C00BA8F00709A403800BA8F3D
+:10A310004000BD2700609A4018000042E8FFBD27BA
+:10A320001400BFAF1000BEAF21F0A00380BF033CFC
+:10A3300030800234000662AC81BF043C00F283909E
+:10A34000F7FF02242410620000F282A081BF033CC8
+:10A350006190629001004234619062A088BF043C29
+:10A3600041608390FEFF022424106200416082A0BD
+:10A3700081BF033C6190629002004234619062A010
+:10A3800088BF043C41608390FDFF022424106200DA
+:10A39000416082A081BF033C619062902000423402
+:10A3A000619062A088BF043C41608390DFFF02247B
+:10A3B00024106200416082A088BF033CC0606290AC
+:10A3C00010004234C06062A088BF043CC16083902A
+:10A3D000FEFF022424106200C16082A088BF043CFA
+:10A3E000C1608390FDFF022424106200C16082A03E
+:10A3F00088BF043CC1608390FBFF022424106200EC
+:10A40000C16082A088BF033C81606290200042341A
+:10A41000816062A088BF043CC0608390FBFF02247F
+:10A4200024106200C06082A088BF033CC0606290BC
+:10A430007F004230C06062A088BF043CC06083904F
+:10A44000F7FF022424106200C06082A088BF033C92
+:10A450008160629040004234816062A088BF033C0A
+:10A46000D060629008004234D06062A088BF033C94
+:10A47000D160629004004234D16062A088BF033C86
+:10A480005160629020004234516062A080BF023C63
+:10A49000000C40AC80BF033C10000224080C62ACEE
+:10A4A00080BF023C100C40AC80BF033CF40102248E
+:10A4B000200C62AC88BF033C1C000224D41062ACA8
+:10A4C00088BF033C1C000224D81062AC157E400FEC
+:10A4D0000000000088BF033C0100023C341062AC65
+:10A4E00080BF033C00800234080C62AC88BF033C90
+:10A4F0000100023C641062AC88BF023C681040ACB2
+:10A50000CC8180AFF08180AF708180AF508180AF0F
+:10A5100021E8C0031400BF8F1000BE8F1800BD27B4
+:10A520000800E00300000000E0FFBD271C00BFAFF3
+:10A530001800BEAF21F0A0032000C4AF2400C5AFB7
+:10A540002000C28F1C8182AF2400C28FF88182AFAD
+:10A550002000C38F8888023C89884234180062003A
+:10A56000101000002110430043210200C317030014
+:10A57000231082002000C2AF2000C28F09004010CB
+:10A580000000000006DF03342000C28F1A006200C2
+:10A59000F4014000121000008C8182AF0300001013
+:10A5A00000000000D00702248C8182AF5081828F8E
+:10A5B00005004018000000005081828F748082AF37
+:10A5C0000300001000000000EE020224748082AF3D
+:10A5D0008C81848FEE78400F00000000029D063CC5
+:10A5E00021204000212860006404C78C6004C68CD0
+:10A5F000F776400F00000000212040002128600075
+:10A600008679400F00000000708082AF7D818283D8
+:10A610001A004014000000007081828F050040186D
+:10A62000000000007081828F8C8182AF03000010D7
+:10A6300000000000EE0202248C8182AF4C818283F4
+:10A6400015004014000000001080838F01000224D8
+:10A6500003006214000000002062400F00000000B0
+:10A6600088BF023C1061439001006334106143A035
+:10A67000108080AF08000010000000001080828F62
+:10A6800003004014000000004662400F000000007C
+:10A6900001000224108082AF6080828F120040107F
+:10A6A000000000007081828F070040180000000049
+:10A6B0007081828F8C8182AF7081828F708082AF37
+:10A6C0000500001000000000EE0202248C8182AF21
+:10A6D000EE020224708082AF88BF023C106143907A
+:10A6E00001006334106143A021E8C0031C00BF8F48
+:10A6F0001800BE8F2000BD270800E0030000000006
+:10A70000E8FFBD271400BFAF1000BEAF21F0A003CB
+:10A710001800C4AF2110A0001C00C2A31800C38FF2
+:10A720001400022403006210000000002100001049
+:10A7300000000000029D023C3082848F6804458C3A
+:10A74000D37A400F00000000E48182AF029D023CFA
+:10A750001882848F6804458CD37A400F0000000073
+:10A76000D88182AF029D023C2482848F6804458C8C
+:10A77000D37A400F000000000C8282AFE481848F06
+:10A78000032D400F00000000B48182AFD881848F78
+:10A79000032D400F00000000048282AF0C82848FE2
+:10A7A000032D400F00000000DC8182AF310000105B
+:10A7B000000000003082848F1F79400F00000000ED
+:10A7C000029D063C21204000212860007404C78CB3
+:10A7D0007004C68CF776400F000000002120400076
+:10A7E000212860004879400F00000000E48182AF1A
+:10A7F0001882848F1F79400F00000000029D063CE4
+:10A8000021204000212860007404C78C7004C68C8D
+:10A81000F776400F00000000212040002128600052
+:10A820004879400F00000000D88182AF029D023CB1
+:10A830002482848F7804458CD37A400F0000000076
+:10A840000C8282AFE481848F032D400F0000000052
+:10A85000B48182AFD881848F032D400F00000000A7
+:10A86000048282AF0C82848F032D400F0000000011
+:10A87000DC8182AF21E8C0031400BF8F1000BE8FBF
+:10A880001800BD270800E00300000000D8FFBD2726
+:10A890002400BFAF2000BEAF21F0A003BC81838F96
+:10A8A000B881828F23106200AC8082AFD481838F05
+:10A8B000EC81828F23106200B08082AFE081838FB1
+:10A8C000C081828F23106200B48082AFB88180AFD4
+:10A8D000EC8180AFC08180AFAC80848FEE78400F78
+:10A8E00000000000029D063C21204000212860005D
+:10A8F0008404C78C8004C68CC177400F0000000020
+:10A9000021204000212860004879400F000000000D
+:10A910001000C2AFB080848FEE78400F00000000BE
+:10A92000029D063C21204000212860008404C78C41
+:10A930008004C68CC177400F000000002120400039
+:10A94000212860004879400F000000001400C2AFC9
+:10A95000B480848F6666023C6766423418008200C9
+:10A9600010100000831A0200C317040023106200B5
+:10A9700021204000CC7B400F000000001800C2AF37
+:10A98000029D023C1000C48F8804458C387A400F29
+:10A9900000000000288182AF029D023C1400C48F99
+:10A9A0008C04458C387A400F00000000608182AF33
+:10A9B0001800C48F21280000387A400F00000000E2
+:10A9C000808182AF21E8C0032400BF8F2000BE8FAA
+:10A9D0002800BD270800E00300000000F8FFBD27A5
+:10A9E0000000BEAF21F0A003B881838FBC81828FAD
+:10A9F0000700621000000000BC81838FAC80828F52
+:10AA000023186200B881828F21104300B88182AF81
+:10AA1000EC81838FD481828F0700621000000000D8
+:10AA2000D481838FB080828F23186200EC81828F63
+:10AA300021104300EC8182AFC081838FE081828F3F
+:10AA40000700621000000000E081838FB480828FD5
+:10AA500023186200C081828F21104300C08182AF21
+:10AA6000029D023C9004428C288182AF029D023CF0
+:10AA70009404428C608182AF21100000808182AFFB
+:10AA800021E8C0030000BE8F0800BD270800E003D6
+:10AA900000000000E0FFBD271C00BFAF1800BEAFE4
+:10AAA00021F0A003EC81828F1000A2AFC081828FC1
+:10AAB0001400A2AFB481848F0482858FDC81868FDD
+:10AAC000B881878FBB2A400F00000000A52C400FE3
+:10AAD0000000000021E8C0031C00BF8F1800BE8FDB
+:10AAE0002000BD270800E0030000000098FFBD27FC
+:10AAF0006400BFAF6000BEAF21F0A0036800C4AF28
+:10AB00006C00C5AF7000C6AF7400C7AF1000C0AF17
+:10AB1000010002241400C2AF010002241800C2AFD9
+:10AB2000010002241C00C2AF7400C38F6800C28FF2
+:10AB3000231062002000C2AF7800C38F6C00C28F68
+:10AB4000231062002400C2AF7C00C38F7000C28F4C
+:10AB5000231062002800C2AF2000C38F2000C28FE4
+:10AB6000211062002C00C2AF2400C38F2400C28FCA
+:10AB7000211062003000C2AF2800C38F2800C28FAE
+:10AB8000211062003400C2AF6800C28F3800C2AF2B
+:10AB90006C00C28F3C00C2AF7000C28F4000C2AFD9
+:10ABA0004400C0AF4800C0AF4C00C0AF5000C0AFC1
+:10ABB0005400C0AF5800C0AF5C00C0A3C080828FFB
+:10ABC00003004014000000002000C0AF2C00C0AF04
+:10ABD000C480828F03004014000000002400C0AF36
+:10ABE0003000C0AFC880828F030040140000000016
+:10ABF0002800C0AF3400C0AF2000C28F070040144F
+:10AC0000000000007400C28F6800C2AFB881828F5C
+:10AC1000B48182AF7880828F308282AF2400C28F6D
+:10AC200007004014000000007800C28F6C00C2AF23
+:10AC3000EC81828F048282AF7C80828F188282AF07
+:10AC40002800C28F07004014000000007C00C28F63
+:10AC50007000C2AFC081828FDC8182AF8080828F22
+:10AC6000248282AF2000C28F130041040000000044
+:10AC700088BF033CD06062907F004230D06062A009
+:10AC80007F0003245C00C293241043005C00C2A335
+:10AC9000FFFF02241400C2AF2000C28F2310020065
+:10ACA0002000C2AF2C00C28F231002002C00C2AFC4
+:10ACB0000A0000100000000088BF043CD0608390B0
+:10ACC00080FF022425106200D06082A05C00C39344
+:10ACD00080FF0224251062005C00C2A32400C28F02
+:10ACE000140041040000000088BF043CD160839040
+:10ACF000FDFF022424106200D16082A05C00C39397
+:10AD0000DFFF0224241062005C00C2A3FFFF0224C4
+:10AD10001800C2AF2400C28F231002002400C2AF6B
+:10AD20003000C28F231002003000C2AF08000010B4
+:10AD30000000000088BF033CD160629002004234F2
+:10AD4000D16062A05C00C293200042345C00C2A3C8
+:10AD50002800C28F120041040000000088BF033C9D
+:10AD60005160629002004234516062A05C00C29364
+:10AD7000080042345C00C2A3FFFF02241C00C2AFE3
+:10AD80002800C28F231002002800C2AF3400C28FF7
+:10AD9000231002003400C2AF0A00001000000000BF
+:10ADA00088BF043C51608390FDFF022424106200A0
+:10ADB000516082A05C00C393F7FF0224241062005C
+:10ADC0005C00C2A32000C28F000042380100432C67
+:10ADD0002400C28F000042380100422C241062007F
+:10ADE00006004010000000002800C28F0300401041
+:10ADF000000000007480828F8C8182AF2800C38F96
+:10AE00002000C28F2A106200010044382800C38F3E
+:10AE10002400C28F2A1062000100423824108200F0
+:10AE20000300401000000000010002241000C2AF27
+:10AE30002000C38F2800C28F2A106200010044380E
+:10AE40002000C38F2400C28F2A1062000100423804
+:10AE500024108200030040100000000002000224C1
+:10AE60001000C2AF2400C38F2000C28F2A106200DE
+:10AE7000010044382400C38F2800C28F2A106200CA
+:10AE8000010042382410820003004010000000003E
+:10AE9000030002241000C2AF2000C28F000042381D
+:10AEA0000100432C2400C28F000042380100422CD4
+:10AEB000241862002800C28F000042380100422C92
+:10AEC0002410620002004010000000001000C0AF1B
+:10AED0001000C38F010002244A0062140000000029
+:10AEE0004000C38F1C00C28F211062004000C2AF1F
+:10AEF0004400C38F2C00C28F211062004400C2AFF7
+:10AF00004800C38F3000C28F211062004800C2AFDA
+:10AF10004400C38F2800C28F2A1043000E00401047
+:10AF2000000000003800C38F1400C28F211062009F
+:10AF30003800C2AF4400C38F3400C28F23106200B8
+:10AF40004400C2AF010002245000C2AF5C00C293B3
+:10AF5000400042345C00C2A34800C28F2800C38F67
+:10AF60002A1062000E004010000000003C00C38F59
+:10AF70001800C28F211062003C00C2AF4800C38F8E
+:10AF80003400C28F231062004800C2AF01000224C7
+:10AF90005400C2AF5C00C293100042345C00C2A3F4
+:10AFA0005C00C293040042345C00C2A35C00C39303
+:10AFB0005000C28F202C027C5400C28F2014027CCF
+:10AFC00021206000213040003A2D400F0000000099
+:10AFD0005000C0AF5400C0AF5800C0AF5C00C39376
+:10AFE000ABFF0224241062005C00C2A34000C38FA8
+:10AFF0007C00C28F0300621000000000B8FF001048
+:10B00000000000001000C38F020002244A006214F6
+:10B01000000000003800C38F1400C28F21106200AE
+:10B020003800C2AF4C00C38F3400C28F21106200C1
+:10B030004C00C2AF4800C38F3000C28F21106200A5
+:10B040004800C2AF4C00C38F2000C28F2A104300BB
+:10B050000E004010000000004000C38F1C00C28F93
+:10B06000211062004000C2AF4C00C38F2C00C28F81
+:10B07000231062004C00C2AF010002245800C2AF8E
+:10B080005C00C293040042345C00C2A34800C28F3B
+:10B090002000C38F2A1062000E0040100000000044
+:10B0A0003C00C38F1800C28F211062003C00C2AF69
+:10B0B0004800C38F2C00C28F231062004800C2AF2B
+:10B0C000010002245400C2AF5C00C293100042345D
+:10B0D0005C00C2A35C00C293400042345C00C2A387
+:10B0E0005C00C3935000C28F202C027C5400C28F9E
+:10B0F0002014027C21206000213040003A2D400FB6
+:10B10000000000005000C0AF5400C0AF5800C0AFF6
+:10B110005C00C393ABFF0224241062005C00C2A356
+:10B120003800C38F7400C28F03006210000000005B
+:10B13000B8FF0010000000001000C38F03000224BD
+:10B140004E006214000000003C00C38F7800C28FE4
+:10B150004A006210000000003C00C38F1800C28F3C
+:10B16000211062003C00C2AF4400C38F2C00C28F8C
+:10B17000211062004400C2AF4C00C38F3400C28F64
+:10B18000211062004C00C2AF4400C38F2400C28F64
+:10B190002A1043000E004010000000003800C38F4A
+:10B1A0001400C28F211062003800C2AF4400C38F68
+:10B1B0003000C28F231062004400C2AF010002249D
+:10B1C0005000C2AF5C00C293400042345C00C2A396
+:10B1D0004C00C28F2400C38F2A1062000E00401062
+:10B1E000000000004000C38F1C00C28F21106200CD
+:10B1F0004000C2AF4C00C38F3000C28F23106200EA
+:10B200004C00C2AF010002245800C2AF5C00C293E0
+:10B21000040042345C00C2A35C00C29310004234BC
+:10B220005C00C2A35C00C3935000C28F202C027C40
+:10B230005400C28F2014027C212060002130400085
+:10B240003A2D400F000000005000C0AF5400C0AFC6
+:10B250005800C0AF5C00C393ABFF0224241062000F
+:10B260005C00C2A33C00C38F7800C28F0300621051
+:10B2700000000000B8FF00100000000021E8C0033B
+:10B280006400BF8F6000BE8F6800BD270800E00328
+:10B2900000000000F8FFBD270000BEAF21F0A003B2
+:10B2A000B481828FB88182AF0482828FEC8182AFB9
+:10B2B000DC81828FC08182AF8480828F908082AF58
+:10B2C0008880828F948082AF8C80828F988082AFBA
+:10B2D0007880828F848082AF7C80828F888082AFEA
+:10B2E0008080828F8C8082AF3082828F788082AF24
+:10B2F0001882828F7C8082AF2482828F808082AF8E
+:10B3000021100000008282AF21100000C88182AFAE
+:10B3100021100000C48182AF21100000E48182AFBF
+:10B3200021100000D88182AF211000000C8282AF72
+:10B33000B48180AF048280AFDC8180AF21E8C0039C
+:10B340000000BE8F0800BD270800E00300000000D9
+:10B35000D0FFBD272C00BFAF2800BEAF21F0A00357
+:10B360003000C4AF3000C48F1F79400F00000000D0
+:10B3700021204000212860001000C6276675400F7C
+:10B38000000000001800C2AF1C00C3AF1000C48F43
+:10B390001400C58F8679400F000000002000C2AF66
+:10B3A000029D023C9804448C9C04458C1800C68F76
+:10B3B0001C00C78FC979400F00000000030040182F
+:10B3C0000000000008000010000000002000C28FF4
+:10B3D000010042242000C2AF2000C28F2400C2AF6F
+:10B3E00003000010000000002000C28F2400C2AF44
+:10B3F0002400C28F21E8C0032C00BF8F2800BE8F1D
+:10B400003000BD270800E00300000000D0FFBD278A
+:10B410002C00BFAF2800BEAF21F0A0033000C4AFA6
+:10B420003000C48F1F79400F000000002120400031
+:10B43000212860001000C6276675400F000000003C
+:10B440001800C2AF1C00C3AF1000C48F1400C58F1A
+:10B450008679400F000000002000C2AF029D023C30
+:10B46000A004448CA404458C1800C68F1C00C78F10
+:10B47000C979400F000000000300401800000000E0
+:10B4800004000010000000002000C28F01004224D0
+:10B490002000C2AF029D023C1800C48F1C00C58F63
+:10B4A000A804468CAC04478CC979400F000000000A
+:10B4B000030040180000000004000010000000001D
+:10B4C0002000C28FFFFF42242000C2AF2000C28FA5
+:10B4D00021E8C0032C00BF8F2800BE8F3000BD279D
+:10B4E0000800E00300000000E0FFBD271800BEAF29
+:10B4F00021F0A003211080002118A0002120C0000D
+:10B500002000C2A32400C3A32800C4A30000C0AF2E
+:10B510002000C2930000C2AF0000C28F00160200DC
+:10B520000000C2AF2400C2830800401000000000E9
+:10B530002800C28305004010000000007080828F48
+:10B540000400C2AF03000010000000008C81828F55
+:10B550000400C2AF0000C28F0400C38F2510430057
+:10B560000000C2AFF081828F010042240800C2AF08
+:10B570000800C28F0C00C2AF0C00C38F040061042E
+:10B58000000000000C00C48FFF0184240C00C4AF35
+:10B590000C00C38F43120300401202000800C48F46
+:10B5A00023188200CC81828F030062140000000007
+:10B5B000ECFF00100000000000A0043CF081828F2E
+:10B5C00080180200C8048224211862000000C28F83
+:10B5D000000062ACF081828F01004224F08182AFD2
+:10B5E000F081828F1000C2AF1000C38F1400C3AF70
+:10B5F0001400C48F04008104000000001400C28FF6
+:10B60000FF0142241400C2AF1400C38F4312030091
+:10B61000401202001000C48F23108200F08182AF1C
+:10B6200021E8C0031800BE8F2000BD270800E003FA
+:10B6300000000000E0FFBD271C00BFAF1800BEAF38
+:10B6400021F0A003214080002400C5AF2128C000C4
+:10B650002C00C7AF3000C28F3800C38F4000C48FAA
+:10B660002000C8A32800C5A31000C2A31100C3A3D3
+:10B670001200C4A3CC81838FF081828F0E006210F0
+:10B68000000000003C80838301000224F9FF621463
+:10B6900000000000F081828F01004324CC81828F62
+:10B6A000F4FF621400000000CC81828FF08182AF31
+:10B6B000F0FF00100000000021100000308282AF77
+:10B6C0002800C38358000224030062140000000015
+:10B6D0002C00C28F308282AF1000C3835800022436
+:10B6E00003006214000000003400C28F308282AF79
+:10B6F0001100C383580002240300621400000000FC
+:10B700003C00C28F308282AF1200C38358000224F3
+:10B7100003006214000000004400C28F308282AF38
+:10B720002800C283580042380100432C1000C28315
+:10B73000580042380100422C251862001100C283D3
+:10B74000580042380100422C251862001200C283C2
+:10B75000580042380100422C2510620005004010BC
+:10B760000000000001000224C08082AF020000102F
+:10B7700000000000C08080AF21180000188283AF55
+:10B780002800C38359000224030062140000000053
+:10B790002C00C28F188282AF1000C383590002248C
+:10B7A00003006214000000003400C28F188282AFD0
+:10B7B0001100C3835900022403006214000000003A
+:10B7C0003C00C28F188282AF1200C383590002244A
+:10B7D00003006214000000004400C28F188282AF90
+:10B7E0002800C283590042380100432C1000C28354
+:10B7F000590042380100422C251862001100C28312
+:10B80000590042380100422C251862001200C28300
+:10B81000590042380100422C2510620005004010FA
+:10B820000000000001000224C48082AF020000106A
+:10B8300000000000C48080AF21100000248282AF8D
+:10B840002800C3835A000224030062140000000091
+:10B850002C00C28F248282AF1000C3835A000224BE
+:10B8600003006214000000003400C28F248282AF03
+:10B870001100C3835A000224030062140000000078
+:10B880003C00C28F248282AF1200C3835A0002247C
+:10B8900003006214000000004400C28F248282AFC3
+:10B8A0002800C2835A0042380100432C1000C28392
+:10B8B0005A0042380100422C251862001100C28350
+:10B8C0005A0042380100422C251862001200C2833F
+:10B8D0005A0042380100422C251062000500401039
+:10B8E0000000000001000224C88082AF02000010A6
+:10B8F00000000000C88080AF211800001C8283AFC8
+:10B900002800C383490002240300621400000000E1
+:10B910002C00C28F1C8282AF1000C3834900022416
+:10B9200003006214000000003400C28F1C8282AF4A
+:10B930001100C383490002240300621400000000C8
+:10B940003C00C28F1C8282AF1200C38349000224D4
+:10B9500003006214000000004400C28F1C8282AF0A
+:10B960002800C283490042380100432C1000C283E2
+:10B97000490042380100422C251862001100C283A0
+:10B98000490042380100422C251862001200C2838F
+:10B99000490042380100422C251062000500401089
+:10B9A0000000000001000224CC8082AF02000010E1
+:10B9B00000000000CC8080AF21100000208282AF08
+:10B9C0002800C3834A000224030062140000000020
+:10B9D0002C00C28F208282AF1000C3834A00022451
+:10B9E00003006214000000003400C28F208282AF86
+:10B9F0001100C3834A000224030062140000000007
+:10BA00003C00C28F208282AF1200C3834A0002240E
+:10BA100003006214000000004400C28F208282AF45
+:10BA20002800C2834A0042380100432C1000C28320
+:10BA30004A0042380100422C251862001100C283DE
+:10BA40004A0042380100422C251862001200C283CD
+:10BA50004A0042380100422C2510620005004010C7
+:10BA60000000000001000224D08082AF020000101C
+:10BA700000000000D08080AF2800C383460002246D
+:10BA800005006214000000002C00C48FF67B400FFC
+:10BA900000000000B88082AF1000C383460002247B
+:10BAA00005006214000000003400C48FF67B400FD4
+:10BAB00000000000B88082AF1100C383460002245A
+:10BAC00005006214000000003C00C48FF67B400FAC
+:10BAD00000000000B88082AF1200C3834600022439
+:10BAE00005006214000000004400C48FF67B400F84
+:10BAF00000000000B88082AF21180000288283AFC8
+:10BB00002800C383500002240300621400000000D8
+:10BB10002C00C28F288282AF1000C3835000022401
+:10BB200003006214000000003400C28F288282AF3C
+:10BB30001100C383500002240300621400000000BF
+:10BB40003C00C28F288282AF1200C38350000224BF
+:10BB500003006214000000004400C28F288282AFFC
+:10BB6000211000002C8282AF2800C38353000224DE
+:10BB700003006214000000002C00C28F2C8282AFF0
+:10BB80001000C3835300022403006214000000006D
+:10BB90003400C28F2C8282AF1100C3835300022471
+:10BBA00003006214000000003C00C28F2C8282AFB0
+:10BBB0001200C3835300022403006214000000003B
+:10BBC0004400C28F2C8282AF2000C3831400C3AF15
+:10BBD000470002241400C38F070062100000000019
+:10BBE0004D0002241400C38F4800621000000000C2
+:10BBF000A4000010000000002400C28F148282AF55
+:10BC00001482828F0300401400000000A72F400F11
+:10BC1000000000001482838F0100022403006214DC
+:10BC200000000000C62F400F000000001482838F28
+:10BC3000020002240300621400000000EC2F400FF9
+:10BC4000000000001482838F0300022403006214AA
+:10BC5000000000000330400F000000001482838FBA
+:10BC60000400022403006214000000001A30400F98
+:10BC7000000000001482838F140002240300621469
+:10BC8000000000003630400F000000001482838F57
+:10BC90001500022403006214000000004030400F31
+:10BCA000000000001482838F1C0002240300621431
+:10BCB000000000004A30400F000000001482838F13
+:10BCC0005A00022403006214000000005230400FAA
+:10BCD000000000001482838F5B00022403006214C2
+:10BCE000000000005E30400F000000001482838FCF
+:10BCF0005C00022463006214000000006630400F04
+:10BD0000000000005F000010000000002400C28F4F
+:10BD1000108282AF148280AFB88080AF1082838F90
+:10BD20006500022403006214000000007430400F1C
+:10BD3000000000001082838F670002240300621459
+:10BD4000000000008230400F000000001082838F4E
+:10BD50006800022403006214000000008F30400FCE
+:10BD6000000000001082838F6A0002240300621426
+:10BD700000000000D330400F000000001082838FCD
+:10BD80006B0002240300621400000000E130400F49
+:10BD9000000000001082838F6C00022403006214F4
+:10BDA00000000000EF30400F000000001082838F81
+:10BDB000DC00022403006214000000000D31400F7B
+:10BDC000000000001082838FDD0002240300621453
+:10BDD000000000001A31400F000000001082838F25
+:10BDE000DE00022403006214000000002631400F30
+:10BDF000000000001082838FDF0002240300621421
+:10BE0000000000004031400F000000001082838FCE
+:10BE1000E000022403006214000000005A31400FC9
+:10BE2000000000001082838FE100022403006214EE
+:10BE3000000000006431400F000000001082838F7A
+:10BE4000E200022403006214000000006D31400F84
+:10BE5000000000001082838FE300022403006214BC
+:10BE600000000000A531400F000000001082838F09
+:10BE7000E40002240300621400000000DD31400FE2
+:10BE80000000000021E8C0031C00BF8F1800BE8F17
+:10BE90002000BD270800E00300000000E8FFBD27E8
+:10BEA0001400BFAF1000BEAF21F0A003B880828F96
+:10BEB0000300401400000000C0030224B88082AFD9
+:10BEC000B880848F1082858F4A29400F00000000BF
+:10BED00054808383010002240300621400000000E8
+:10BEE000010002247D8182A3BC80848F2128000070
+:10BEF000C029400F00000000A52A400F00000000EC
+:10BF000021E8C0031400BF8F1000BE8F1800BD27AA
+:10BF10000800E00300000000E8FFBD271400BFAFE9
+:10BF20001000BEAF21F0A003B880828F0300401440
+:10BF300000000000F0000224B88082AF44818283B8
+:10BF40000500401000000000B880828F6881838F58
+:10BF500021104300B88082AFB880848F1082858F13
+:10BF60004A29400F0000000054808383010002240E
+:10BF70000300621400000000010002247D8182A3FE
+:10BF8000BC80848F21280000C029400F00000000E1
+:10BF9000A52A400F0000000021E8C0031400BF8F55
+:10BFA0001000BE8F1800BD270800E003000000004D
+:10BFB000E8FFBD271400BFAF1000BEAF21F0A00303
+:10BFC000B880828F0300401400000000F0000224BB
+:10BFD000B88082AFB880848F1082858F4A29400F45
+:10BFE00000000000BC80848F01000524C029400FA0
+:10BFF0000000000021E8C0031400BF8F1000BE8FB6
+:10C000001800BD270800E00300000000E8FFBD277E
+:10C010001400BFAF1000BEAF21F0A003B880828F24
+:10C020000300401400000000F0000224B88082AF3A
+:10C03000B880848F1082858F4A29400F000000004D
+:10C04000BC80848F01000524C029400F000000003F
+:10C0500021E8C0031400BF8F1000BE8F1800BD2759
+:10C060000800E00300000000E0FFBD271C00BFAF98
+:10C070001800BEAF21F0A0031000C0AF2882848F4B
+:10C0800021280000317C400F000000000300401414
+:10C09000000000000A000010000000002882848FC9
+:10C0A000F67B400F00000000C8000324021043701C
+:10C0B0001000C2AF1000C48F0F62400F00000000DC
+:10C0C00021E8C0031C00BF8F1800BE8F2000BD27D1
+:10C0D0000800E00300000000F8FFBD270000BEAF2D
+:10C0E00021F0A00314000224BC8082AF21E8C00329
+:10C0F0000000BE8F0800BD270800E003000000001C
+:10C10000F8FFBD270000BEAF21F0A00315000224F8
+:10C11000BC8082AF21E8C0030000BE8F0800BD27AD
+:10C120000800E00300000000F8FFBD270000BEAFDC
+:10C1300021F0A00321E8C0030000BE8F0800BD2746
+:10C140000800E00300000000E8FFBD271400BFAFB7
+:10C150001000BEAF21F0A003772A400F00000000BE
+:10C1600021E8C0031400BF8F1000BE8F1800BD2748
+:10C170000800E00300000000F8FFBD270000BEAF8C
+:10C1800021F0A00321E8C0030000BE8F0800BD27F6
+:10C190000800E00300000000E8FFBD271400BFAF67
+:10C1A0001000BEAF21F0A003A72F400F0000000039
+:10C1B000232A400F0000000021E8C0031400BF8FB5
+:10C1C0001000BE8F1800BD270800E003000000002B
+:10C1D000F8FFBD270000BEAF21F0A0035480838389
+:10C1E0000200022403006214000000000100022487
+:10C1F0007D8182A321E8C0030000BE8F0800BD2717
+:10C200000800E00300000000F8FFBD270000BEAFFB
+:10C2100021F0A003548083830200022402006214F0
+:10C22000000000007D8180A321E8C0030000BE8FD4
+:10C230000800BD270800E00300000000E8FFBD275C
+:10C240001400BFAF1000BEAF21F0A0035480838361
+:10C2500002000224370062140000000004000424DD
+:10C260009A64400F00000000050004249A64400F07
+:10C2700000000000060004249A64400F0000000043
+:10C280000500042421280000029D023CB00446243D
+:10C29000213800001965400F00000000F48080AFD5
+:10C2A00001000224888182A32C82848F212800002F
+:10C2B000317C400F0000000003004014000000002B
+:10C2C00005000010000000002C82848FF67B400FD8
+:10C2D00000000000FC8082AF8426400F00000000B8
+:10C2E00001000424B060400F000000006D63400FA7
+:10C2F000000000001A64400F00000000D163400FEE
+:10C3000000000000F480828F06004014000000004E
+:10C31000FC80828F0300401000000000F3FF00103B
+:10C3200000000000888180A3050004249A64400F67
+:10C330000000000021E8C0031400BF8F1000BE8F72
+:10C340001800BD270800E00300000000F8FFBD272B
+:10C350000000BEAF21F0A003010002246C8182A383
+:10C3600088BF033C1061629020004234106162A0DB
+:10C3700021E8C0030000BE8F0800BD270800E003CD
+:10C3800000000000F8FFBD270000BEAF21F0A003B1
+:10C390006C8180A388BF043C10618390DFFF02247E
+:10C3A00024106200106182A021E8C0030000BE8F4B
+:10C3B0000800BD270800E00300000000E8FFBD27DB
+:10C3C0001400BFAF1000BEAF21F0A00354808383E0
+:10C3D000020002241100621400000000212000006D
+:10C3E0002C82858F317C400F000000000300400448
+:10C3F0000000000005000010000000002C82848F67
+:10C40000F67B400F00000000208082AF115F400FDC
+:10C410000000000001000224898182A321E8C003FA
+:10C420001400BF8F1000BE8F1800BD270800E00366
+:10C4300000000000F8FFBD270000BEAF21F0A00300
+:10C4400088BF043CD1608390F7FF0224241062006F
+:10C45000D16082A021E8C0030000BE8F0800BD2784
+:10C460000800E00300000000F8FFBD270000BEAF99
+:10C4700021F0A00388BF023CD160439008006334E0
+:10C48000D16043A021E8C0030000BE8F0800BD2793
+:10C490000800E00300000000E8FFBD271400BFAF64
+:10C4A0001000BEAF21F0A003548083830200022459
+:10C4B0000D00621400000000212000002C82858FF6
+:10C4C000317C400F00000000030040040000000029
+:10C4D00005000010000000002C82848FF67B400FC6
+:10C4E00000000000708182AF21E8C0031400BF8FFC
+:10C4F0001000BE8F1800BD270800E00300000000F8
+:10C50000E8FFBD271400BFAF1000BEAF21F0A003AD
+:10C5100054808383020002240D0062140000000096
+:10C52000212000002C82858F317C400F000000000C
+:10C53000030040040000000005000010000000009F
+:10C540002C82848FF67B400F00000000508182AF68
+:10C5500021E8C0031400BF8F1000BE8F1800BD2754
+:10C560000800E00300000000F8FFBD270000BEAF98
+:10C5700021F0A003010002244C8182A321E8C00322
+:10C580000000BE8F0800BD270800E0030000000087
+:10C59000F8FFBD270000BEAF21F0A0034C8180A3AF
+:10C5A00021E8C0030000BE8F0800BD270800E0039B
+:10C5B00000000000D8FFBD272400BFAF2000BEAFA1
+:10C5C0001C00B1AF1800B0AF21F0A003CC81838F65
+:10C5D000F081828F0E006210000000003C80838397
+:10C5E00001000224F9FF621400000000F081828F34
+:10C5F00001004324CC81828FF4FF6214000000000C
+:10C60000CC81828FF08182AFF0FF0010000000002B
+:10C61000D51B400F0000000088BF023C9061428C97
+:10C620004002427C0300401400000000FAFF0010AA
+:10C63000000000009080848F1F79400F00000000F0
+:10C6400021804000218860009480848F1F79400FF2
+:10C65000000000001000A0AF1400A0AF21200002D5
+:10C660002128200221304000213860009F1E400F09
+:10C670000000000021E8C0032400BF8F2000BE8F0F
+:10C680001C00B18F1800B08F2800BD270800E00300
+:10C6900000000000E8FFBD271400BFAF1000BEAFD0
+:10C6A00021F0A00354808383020002242B00621433
+:10C6B0000000000001000224848182AF21200000DC
+:10C6C0002C82858F317C400F000000000300400465
+:10C6D000000000000D000010000000002C82848F7C
+:10C6E0001F79400F00000000212040002128600039
+:10C6F000AD75400F0000000021204000212860009F
+:10C700008679400F00000000608282AF2120000087
+:10C710002882858F317C400F000000000300400418
+:10C72000000000000D000010000000002882848F2F
+:10C730001F79400F000000002120400021286000E8
+:10C74000AD75400F0000000021204000212860004E
+:10C750008679400F000000006C8282AF21E8C003A0
+:10C760001400BF8F1000BE8F1800BD270800E00323
+:10C7700000000000F8FFBD270000BEAF21F0A003BD
+:10C78000548083830200022402006214000000002F
+:10C79000848180AF21E8C0030000BE8F0800BD2760
+:10C7A0000800E00300000000E0FFBD271C00BFAF51
+:10C7B0001800BEAF21F0A0031000C0AF1000C28F60
+:10C7C000030042280B004010000000001000C38F3F
+:10C7D000348282272118620001000224000062A036
+:10C7E0001000C28F010042241000C2AFF3FF0010FE
+:10C7F00000000000DE8080A37A5A400F0000000095
+:10C8000000A0023C041244244734400F0000000002
+:10C8100030004014000000001C80838F00A0023C08
+:10C8200004124224000062AC1C80828F0C0040A4E1
+:10C830001C80828F0E0040A41C80828F100040ACB0
+:10C840001C80828F140040AC1C80838F5C0002240B
+:10C85000200062A0010002241000C2AF1000C28FAD
+:10C860000B0042280B004010000000001C80838F4A
+:10C870001000C28F2118620020000224200062A054
+:10C880001000C28F010042241000C2AFF3FF00105D
+:10C89000000000001C80828F2C0040A41C80838F2D
+:10C8A00010000224300062A41C80838F3C82828F9F
+:10C8B000340062AC1C80838F3C82828F380062AC73
+:10C8C0004C8280A3010002241400C2AF02000010B9
+:10C8D000000000001400C0AF1400C28F21E8C003A4
+:10C8E0001C00BF8F1800BE8F2000BD270800E0038A
+:10C8F00000000000C8FFBD273000BFAF2C00BEAF56
+:10C900002800B0AF21F0A0033800C4AF3C00C5AF91
+:10C910002110C0002118E0004000C2A34400C3A3BE
+:10C920003800C28F2C0042941400C2A70B000224CE
+:10C930001800C2AF3800C38F3800C28F3400428C59
+:10C94000380062AC3C00C28F3000429427100200D5
+:10C950001200C2A71400C2970D004014000000008E
+:10C960001400C2273800C48F21284000010006248B
+:10C97000E73B400F000000001300401400000000DF
+:10C980001B0002241800C2AF0F00001000000000BE
+:10C990001400C2970F0042300B004010000000004E
+:10C9A0001400C2273800C48F21284000010006244B
+:10C9B000E73B400F000000000300401400000000AF
+:10C9C0001B0002241800C2AF1800C38F1B000224F2
+:10C9D000CC006210000000001800C28FC900401097
+:10C9E000000000001400C2273800C48F2128400036
+:10C9F000C73F400F000000001600C2A31600C393FB
+:10CA0000020002240300621400000000BD000010B8
+:10CA1000000000001600C293B100401400000000A6
+:10CA20003800C28F300042941000C2A71000C29795
+:10CA30003F0042301000C2A74400C2932000C2AFA2
+:10CA40002000C38F070060100000000001000224D6
+:10CA50002000C38F2D00621000000000A400001011
+:10CA6000000000001000C39708000224A00062101C
+:10CA7000000000001800C0AF6D0002241C00C2A31B
+:10CA80001700C0A31700C2930B00422C980040105F
+:10CA9000000000003800C38F1700C293211062000D
+:10CAA000200042901C00C2A33C00C38F1700C29319
+:10CAB00021106200200042901D00C2A31C00C293FE
+:10CAC00021204000C66B400F000000002180400084
+:10CAD0001D00C29321204000C66B400F00000000E3
+:10CAE00005000212000000000B0002241800C2AF73
+:10CAF0007F000010000000001700C29301004224D4
+:10CB00001700C2A3DFFF0010000000001000C39751
+:10CB10001200C29724106200FFFF423074004014DC
+:10CB2000000000001000C3970F0002247000621084
+:10CB3000000000001800C0AF6D0002241C00C2A35A
+:10CB40003C00C28F200043802A0002242E00621085
+:10CB5000000000001700C0A31700C2930800422C79
+:10CB600029004010000000003800C38F1700C29356
+:10CB700021106200200042901C00C2A33C00C38F21
+:10CB80001700C29321106200200042901D00C2A332
+:10CB90001D00C3932A000224030062140000000059
+:10CBA00019000010000000001D00C3933F00022484
+:10CBB00010006210000000001C00C2932120400001
+:10CBC000C66B400F00000000218040001D00C29392
+:10CBD00021204000C66B400F00000000050002123B
+:10CBE000000000000B0002241800C2AF0600001075
+:10CBF000000000001700C293010042241700C2A3E6
+:10CC0000D5FF0010000000003C00C28F28004380C8
+:10CC10002A00022436006210000000001800C28FB3
+:10CC20003300401400000000080002241700C2A3D3
+:10CC30001700C2930B00422C2D0040100000000092
+:10CC40003800C38F1700C293211062002000429069
+:10CC50001C00C2A33C00C38F1700C29321106200C6
+:10CC6000200042901D00C2A31D00C3932A0002248D
+:10CC700003006214000000001D000010000000000E
+:10CC80001D00C3933F00022410006210000000004A
+:10CC90001C00C29321204000C66B400F0000000022
+:10CCA000218040001D00C29321204000C66B400F30
+:10CCB0000000000005000212000000000B0002242A
+:10CCC0001800C2AF0A000010000000001700C29355
+:10CCD000010042241700C2A3D5FF0010000000008D
+:10CCE0004000C29302004014000000001800C0AFD2
+:10CCF0001400C297010042241400C2A736FF00109E
+:10CD0000000000001800C28F21E8C0033000BF8F70
+:10CD10002C00BE8F2800B08F3800BD270800E0032C
+:10CD200000000000D0FFBD272C00BFAF2800BEAF21
+:10CD300021F0A0033000C4AF3400C5AF2110C00003
+:10CD40003800C2A31C00C0AF3000C28F0000428C6C
+:10CD50001000C2AF1000C28F2100429005004014A5
+:10CD600000000000070002241C00C2AF8600001073
+:10CD7000000000003000C38F3000C28F3400428CAE
+:10CD8000380062AC3400C28F000042940C004014A2
+:10CD9000000000003000C48F3400C58F010006245D
+:10CDA000E73B400F000000001300401400000000AB
+:10CDB0001B0002241C00C2AF0F0000100000000086
+:10CDC0003400C28F000042940F0042300A0040102D
+:10CDD000000000003000C48F3400C58F010006241D
+:10CDE000E73B400F0000000003004014000000007B
+:10CDF0001B0002241C00C2AF3000C48F3400C58F5A
+:10CE0000C73F400F000000001400C2A31400C293EB
+:10CE100005004010000000000B0002241C00C2AFFF
+:10CE200059000010000000003000C28F100040AC1C
+:10CE30003000C38F3000C28F0400428C080062AC07
+:10CE40003000C28F0C0040A43000C28F0E0040A4FE
+:10CE50001400C393010002240500621400000000C6
+:10CE60000B0002241C00C2AF2400001000000000D0
+:10CE70003000C28F1000C48F0800458C8D45400FD4
+:10CE8000000000001800C2AFDC808293090040104F
+:10CE9000000000004547400F000000000500401062
+:10CEA00000000000090002242000C2AF380000107A
+:10CEB000000000003000C28FD88082AF1880838FBE
+:10CEC0001800C28F0D00621000000000DE8080A3F9
+:10CED0001000C28F1800C48F0000458C695B400FA2
+:10CEE00000000000030040140000000008000224BD
+:10CEF0001C00C2AF1800C28F188082AF3000C48FF0
+:10CF00001800838CFBFF022424106200180082ACFE
+:10CF10003800C3837700022407006210000000007D
+:10CF20003800C38361000224030062100000000087
+:10CF30000C000010000000003000C38F1800628C4D
+:10CF400001004234180062AC3000C48F1800838C9A
+:10CF5000FDFF022424106200180082AC0A000010B9
+:10CF6000000000003000C48F1800838CFEFF0224F4
+:10CF700024106200180082AC3000C38F1800628C4D
+:10CF800002004234180062AC1C00C28F2000C2AF05
+:10CF90002000C28F21E8C0032C00BF8F2800BE8F65
+:10CFA0003000BD270800E00300000000C8FFBD27D7
+:10CFB0003400BFAF3000BEAF21F0A0033800C4AFD3
+:10CFC0003C00C5AF2000C0A33800C28F0000428CD7
+:10CFD0002400C2AF2400C28F200042902800C2AFBC
+:10CFE000010002242800C38F0F006210000000001F
+:10CFF000030002242800C38F030062100000000019
+:10D000000F00001000000000FF0F023CF8FF423448
+:10D010001C00C2AFFF0F023CFFFF42341800C2AF3A
+:10D020000B00001000000000F80F02241C00C2AF2B
+:10D03000FFFF02341800C2AF05000010000000001E
+:10D04000F8FF02341C00C2AFFFFF02341800C2AF69
+:10D050003800C28F0800428C1400C2AF2400C48F75
+:10D060001400C58F314B400F000000001000C2AF0C
+:10D070001000C38F1800C28F05006214000000006A
+:10D08000080002242000C2A31000001000000000CD
+:10D090002400C28F1800438C1000C28F2B10430055
+:10D0A00003004014000000000A0002242000C2A374
+:10D0B0001000C28F1C00C38F2B10430003004014CC
+:10D0C000000000003C0002242000C2A33800C38FEF
+:10D0D0001000C28F080062AC3C00C28FFFFF4224E8
+:10D0E0003C00C2AF06004010000000002000C293C8
+:10D0F0000300401400000000D5FF001000000000F5
+:10D100002000C29321E8C0033400BF8F3000BE8FDF
+:10D110003800BD270800E00300000000E0FFBD2745
+:10D120001C00BFAF1800BEAF21F0A0032000C4AFA9
+:10D130001000C0A32000C28F210040A02000C38F98
+:10D1400000A0023CC80C4224000062ACFB5C400F13
+:10D1500000000000211840000100022407006210B6
+:10D1600000000000060002241000C2A306000224F2
+:10D170004C8282A312000010000000002000C48F27
+:10D180007734400F000000001000C2A31000C293CB
+:10D190000B004014000000002000C48F5535400FE4
+:10D1A000000000001000C2A31000C293040040144D
+:10D1B000000000002000C38F01000224210062A0B3
+:10D1C0001000C29321E8C0031C00BF8F1800BE8F5F
+:10D1D0002000BD270800E00300000000D0FFBD27AD
+:10D1E0002C00BFAF2800BEAF21F0A0033000C4AFB9
+:10D1F0001400C0A33000C28F212000000000458C25
+:10D20000695B400F0000000021184000010002246B
+:10D210000700621000000000080002241400C2A3EE
+:10D22000080002244C8282A3C1000010000000000C
+:10D230003000C28F0000428C1800C2AF1800C28FAD
+:10D24000FE014390550002247000621400000000AB
+:10D250001800C28FFF014390AA0002246B006214E1
+:10D26000000000003000C28F0000448C360005240E
+:10D270003A45400F000000002118400046000224FB
+:10D280002D006214000000003000C28F0000448CAA
+:10D29000370005243A45400F0000000021184000E7
+:10D2A0004100022424006214000000003000C28FFC
+:10D2B0000000448C380005243A45400F000000006F
+:10D2C00021184000540002241B00621400000000DA
+:10D2D0003000C28F0000448C390005243A45400FCD
+:10D2E00000000000211840003100022412006214E6
+:10D2F000000000003000C28F0000448C260005248E
+:10D300003A45400F00000000211840002900022487
+:10D3100009006214000000003000C28F040040AC1D
+:10D320003000C38F02000224200062A01C00C0AFA6
+:10D3300081000010000000003000C28F0000448C0B
+:10D34000520005243A45400F00000000211840001B
+:10D35000460002242D006214000000003000C28F3D
+:10D360000000448C530005243A45400F00000000A3
+:10D370002118400041000224240062140000000033
+:10D380003000C28F0000448C540005243A45400F01
+:10D390000000000021184000540002241B00621409
+:10D3A000000000003000C28F0000448C55000524AE
+:10D3B0003A45400F000000002118400033000224CD
+:10D3C00012006214000000003000C28F0000448C84
+:10D3D000420005243A45400F00000000211840009B
+:10D3E0002900022409006214000000003000C28FEE
+:10D3F000040040AC3000C38F03000224200062A070
+:10D400001C00C0AF4C000010000000003000C28FB4
+:10D410000000428C1000C2AF1000C28FFE0143908A
+:10D420005500022408006214000000001000C28FA2
+:10D43000FF014390AA0002240300621400000000D0
+:10D440000700001000000000040002244C8282A3A8
+:10D45000040002241400C2A33500001000000000E4
+:10D460003000C48F1000C28FC9014388C6014398A1
+:10D4700021106000040082AC1000C28FC2014290F3
+:10D480001500C2A31500C2932000C2AF2000C38FB5
+:10D490000F00622C22004010000000000100022456
+:10D4A0002000C38F041062002400C2AF2400C38F89
+:10D4B0005040623010004014000000002400C38F70
+:10D4C0000018623011004014000000002400C38FD7
+:10D4D0000200623003004014000000001000001041
+:10D4E000000000003000C38F01000224200062A071
+:10D4F0000F000010000000003000C38F0200022463
+:10D50000200062A00A000010000000003000C38F5D
+:10D5100003000224200062A00500001000000000AB
+:10D52000050002244C8282A3050002241400C2A339
+:10D530001400C2931C00C2AF1C00C28F21E8C003BC
+:10D540002C00BF8F2800BE8F3000BD270800E003ED
+:10D5500000000000C0FFBD273800BFAF3400BEAFE1
+:10D560003000B0AF21F0A0034000C4AF1C00C0A346
+:10D570004000C28F4000C38F0400448C0000658CC3
+:10D58000695B400F000000002118400001000224E8
+:10D590000700621000000000080002244C8282A3F1
+:10D5A000080002241C00C2A3D300001000000000E9
+:10D5B0004000C28F0000428C2000C2AF2000C28F0A
+:10D5C000FE01439055000224080062140000000090
+:10D5D0002000C28FFF014390AA00022403006214BE
+:10D5E00000000000070000100000000003000224FB
+:10D5F0004C8282A3030002241C00C2A3BE000010C0
+:10D60000000000004000C28F0000448C0E00052482
+:10D610004945400F000000002600C2A74000D08FFF
+:10D620004000C28F0000448C0D0005243A45400F95
+:10D63000000000001F0002A24000C48F4000C28F03
+:10D640002600C3970400428C21104300080082ACDE
+:10D650004000D08F4000C28F0000448C1000052491
+:10D660003A45400F000000001E0002A24000D08F8B
+:10D670004000C28F0000448C160005244945400F2D
+:10D68000000000001C0002A64000C28F1C00429453
+:10D6900008004014000000004000D08F4000C28FFE
+:10D6A0000000448C240005246845400F0000000061
+:10D6B0001C0002A64000C48F4000C58F4000C28FEE
+:10D6C0001E0043904000C28F1C00429402186270FA
+:10D6D0000800A28C211043000C0082AC4000D08FC7
+:10D6E0004000C28F0000448C110005244945400FC2
+:10D6F00000000000140002A64000C28F0000448C0D
+:10D70000130005244945400F000000001400C2AF7B
+:10D710001400C28F07004014000000004000C28FB8
+:10D720000000448C200005246845400F00000000E4
+:10D730001400C2AF4000C28F0000448C0B000524CF
+:10D740004945400F000000002400C2A72400C297F2
+:10D7500007004010000000002400C2970100423082
+:10D76000030040140000000007000010000000004B
+:10D77000030002244C8282A3030002242800C2AFCB
+:10D780005F000010000000004000C28F14004294AF
+:10D79000401902002400C29721106200FFFF4324B9
+:10D7A0002400C2971A006200F40140001210000029
+:10D7B0001000C2AF2600C4974000C28F1E004390E5
+:10D7C0004000C28F1C004294021062702118820037
+:10D7D0001000C28F211862001400C28F2310430072
+:10D7E0001800C2AF4000C48F4000C28F1F0043909A
+:10D7F0001800C28F1B004300F401600012100000EB
+:10D80000180082AC4000C28F1800428CF50F422CE9
+:10D8100006004010000000004000C38F01000224F9
+:10D82000200062A00F000010000000004000C28F26
+:10D830001800438CF4FF02342B1043000600401400
+:10D84000000000004000C38F02000224200062A0FC
+:10D8500004000010000000004000C38F03000224F9
+:10D86000200062A04000C28F2000439003000224E9
+:10D870000F006214000000004000C28F0000448CC2
+:10D880002C0005246845400F000000003C8282AF58
+:10D890004000C48F4000C28F0C00438C1000C28F28
+:10D8A00021106200100082AC0B000010000000008C
+:10D8B0003C8280AF4000C58F4000C48F4000C28FC3
+:10D8C0001400429402110200FFFF43300C00828CCE
+:10D8D000211043001000A2AC2400C39700020224D0
+:10D8E0000500621000000000030002241C00C2A317
+:10D8F000030002244C8282A31C00C2932800C2AF02
+:10D900002800C28F21E8C0033800BF8F3400BE8FCB
+:10D910003000B08F4000BD270800E0030000000089
+:10D92000F0FFBD270800BEAF21F0A0031000C4AF78
+:10D930000000C0AF1000C28F140042940000C2AFBC
+:10D940000000C28F001402000000C2AF1000C28F9E
+:10D950001A0043940000C28F251043000000C2AF9C
+:10D960000000C28F21E8C0030800BE8F1000BD2751
+:10D970000800E00300000000D8FFBD272400BFAF6F
+:10D980002000BEAF21F0A0032800C4AF2C00C5AF1B
+:10D990001400C0AF2800C28F070040100000000034
+:10D9A0002C00C28F0200422C030040140000000033
+:10D9B0000500001000000000FFFF02241C00C2AFA1
+:10D9C000F6000010000000002C00C28FFFFF43246F
+:10D9D0002800C28F2B1062000500401000000000DC
+:10D9E000FFFF02241C00C2AFEC000010000000008A
+:10D9F000DC80829309004010000000004547400F82
+:10DA0000000000000500401000000000FFFF02249D
+:10DA10001C00C2AFE10000100000000000A0023CAA
+:10DA2000C80C44242128000000020624276A400F65
+:10DA30000000000000A0023CC80C42241000C2AF4D
+:10DA40002800C28F1800C2AF1800C48F1505023C11
+:10DA50005B56423419008200101800002310830026
+:10DA600042100200211062004213020080130200E3
+:10DA70001400C2AF1800C58F1505023C5B56423436
+:10DA80001900A200101800002310A3004210020089
+:10DA90002110620042230200211080008019020040
+:10DAA0002318640000120300231043002310A20077
+:10DAB0001800C2AF1800C48F1004023C0541423464
+:10DAC0001900820010180000231083004210020089
+:10DAD0002110620042110200801902001400C28F5E
+:10DAE000251043001400C2AF1800C48F1004023C7C
+:10DAF00005414234190082001018000023108300F1
+:10DB00004210020021106200421902002110600040
+:10DB10008011020023104300231082001800C2AFBE
+:10DB20001800C28F010043241400C28F2510430047
+:10DB30001400C2AF00A0023CC80C43241400C28FE2
+:10DB400002140200BF0162A000A0023CC80C4324E2
+:10DB50001400C28F02120200C00162A000A0023CA9
+:10DB6000C80C43241400C28FC10162A01000C28FF0
+:10DB70002C00C48F2800C38F23188300CD0143A835
+:10DB8000CA0143B81000C28FCD014388CA0143982F
+:10DB9000211060003910422C0600401000000000E7
+:10DBA0001000C38F01000224C20162A01200001005
+:10DBB000000000001000C28FCD014388CA014398C5
+:10DBC0003F00023C5FFD42342B104300060040142E
+:10DBD000000000001000C38F06000224C20162A0F2
+:10DBE0000500001000000000FFFF02241C00C2AF6F
+:10DBF0006A000010000000001000C28F2800C38FD0
+:10DC0000C90143A8C60143B82800C38F2C00C28FA6
+:10DC100021106200FFFF42241800C2AF1800C48F19
+:10DC20001505023C5B5642341900820010180000B2
+:10DC300023108300421002002110620042130200F0
+:10DC4000801302001400C2AF1800C58F1505023CF6
+:10DC50005B5642341900A200101800002310A300E4
+:10DC600042100200211062004223020021108000B5
+:10DC700080190200231864000012030023104300DF
+:10DC80002310A2001800C2AF1800C48F1004023C79
+:10DC9000054142341900820010180000231083004F
+:10DCA000421002002110620042110200801902009D
+:10DCB0001400C28F251043001400C2AF1800C48F97
+:10DCC0001004023C05414234190082001018000083
+:10DCD000231083004210020021106200421902004A
+:10DCE00021106000801102002310430023108200E5
+:10DCF0001800C2AF1800C28F010043241400C28F65
+:10DD0000251043001400C2AF00A0023CC80C4324FD
+:10DD10001400C28F02140200C30162A000A0023CE2
+:10DD2000C80C43241400C28F02120200C40162A076
+:10DD300000A0023CC80C43241400C28FC50162A09D
+:10DD40001000C28FBE0140A01000C38F55000224F6
+:10DD5000FE0162A01000C38FAAFF0224FF0162A08F
+:10DD60002120000000A0023CC80C4524010006242C
+:10DD7000F15B400F00000000211840000100022468
+:10DD80000500621000000000FFFF02241C00C2AF6B
+:10DD900002000010000000001C00C0AF1C00C28F79
+:10DDA00021E8C0032400BF8F2000BE8F2800BD27BC
+:10DDB0000800E0030000000068FFBD279400BFAF2B
+:10DDC0009000BEAF21F0A003211080009C00C5AFE1
+:10DDD000A000C6AF9800C2A32800C2275000C2AF5F
+:10DDE0004C8280A35000C38F00A0023CC80C422488
+:10DDF000000062AC7A5A400F00000000FB5C400F4C
+:10DE000000000000211840000100022407006210F9
+:10DE100000000000060002244C8282A3FFFF0224BF
+:10DE20006400C2AF7E03001000000000212000004B
+:10DE300000A0023CC80C4524695B400F00000000B4
+:10DE400007004014000000001B0002244C8282A343
+:10DE5000FFFF03246400C3AF710300100000000043
+:10DE60005000C28F0000428C2000C2AF2000C28F41
+:10DE7000FE014390550002245A0062140000000085
+:10DE80002000C28FFF014390AA00022455006214B3
+:10DE9000000000005000C28F0000448C36000524B2
+:10DEA0003A45400F000000002118400046000224BF
+:10DEB00043006214000000005000C28F0000448C38
+:10DEC000370005243A45400F0000000021184000AB
+:10DED000410002243A006214000000005000C28F8A
+:10DEE0000000448C380005243A45400F0000000033
+:10DEF0002118400054000224310062140000000088
+:10DF00005000C28F0000448C390005243A45400F70
+:10DF10000000000021184000310002242800621493
+:10DF2000000000005000C28F0000448C2600052431
+:10DF30003A45400F0000000021184000290002244B
+:10DF40001F006214000000009800C2836800C2AF86
+:10DF50006800C38F0D006010000000000100022463
+:10DF60006800C38F03006210000000001D00001055
+:10DF7000000000001F0002244C8282A3FFFF022445
+:10DF80006400C2AF26030010000000005000C28FE2
+:10DF9000040040AC5000C48F5535400F0000000015
+:10DFA00010004010000000001B0002244C8282A3DD
+:10DFB000FFFF03246400C3AF19030010000000003A
+:10DFC00000A0023CC80C42241000C2AF5000C48F15
+:10DFD0001000C28FC9014388C60143982110600018
+:10DFE000040082AC9800C2838400C2AF8400C38F57
+:10DFF0000902601000000000010002248400C38FA9
+:10E0000003006210000000000E020010000000007B
+:10E010001000C28FCD014388CA01439821106000CF
+:10E020001400C2AF1400C28F3910422C2D004010D2
+:10E03000000000005000C38F01000224200062A0F5
+:10E040001000C38F01000224C20162A02120000041
+:10E0500000A0023CC80C452401000624F15B400FDF
+:10E060000000000007004014000000000900022426
+:10E070004C8282A3FFFF02246400C2AFE8020010BA
+:10E08000000000001400C28F2810422C060040142B
+:10E09000000000005000C38F020002241F0062A095
+:10E0A00004000010000000005000C38F0100022493
+:10E0B0001F0062A000A0023CC80C442421280000DC
+:10E0C00000020624276A400F0000000000A0023C66
+:10E0D000C80C4324320002243A0062A04D00001014
+:10E0E000000000001400C38F3F00023C5FFD42347B
+:10E0F0002B10430041004014000000005000C38F6B
+:10E1000002000224200062A01000C38F0600022437
+:10E11000C20162A02120000000A0023CC80C4524DE
+:10E1200001000624F15B400F0000000007004014CE
+:10E1300000000000090002244C8282A3FFFF032498
+:10E140006400C3AFB6020010000000001400C28FCC
+:10E15000E8FD42241800C2AF5000C38F0100022422
+:10E160001F0062A01800C28FEDFF03342B10620065
+:10E170000B004010000000005000C38F5000C28F01
+:10E180001F004290401002001F0062A01800C28FC2
+:10E19000421002001800C2AFF2FF001000000000A1
+:10E1A0005000C28F1F0042908100422C0700401493
+:10E1B00000000000040002244C8282A3FFFF02241E
+:10E1C0006400C2AF960200100000000000A0023CF4
+:10E1D000C80C44242128000000020624276A400FAE
+:10E1E0000000000000A0023CC80C432436000224BA
+:10E1F0003A0062A00700001000000000170002248F
+:10E200004C8282A3FFFF03246400C3AF840200108A
+:10E21000000000005000C28F1F0042904018020012
+:10E220001400C28F21106200DFFF42245800C2AFE9
+:10E230005000C28F200043900100022409006214A4
+:10E24000000000005000C28F1F00439055010224BF
+:10E2500002106270020042245C00C2AF060000108F
+:10E26000000000005000C28F1F0042900012020008
+:10E27000020042245C00C2AF5C00C38F5800C28F12
+:10E2800021106200FFFF43245C00C28F1B0062006C
+:10E29000F4014000121000005800C2AF00A0033C7F
+:10E2A000EBFF0224C80C62A000A0023CC80C43246F
+:10E2B0003C000224010062A000A0023CC80C4324E0
+:10E2C00090FF0224020062A000A0023CC80C43247C
+:10E2D0004D000224030062A000A0023CC80C4324AD
+:10E2E00043000224040062A000A0023CC80C4324A6
+:10E2F00048000224050062A000A0023CC80C432490
+:10E3000050000224060062A000A0023CC80C432476
+:10E3100020000224070062A000A0023CC80C432495
+:10E3200046000224080062A000A0023CC80C43245E
+:10E3300041000224090062A000A0023CC80C432452
+:10E34000540002240A0062A000A0023CC80C42242F
+:10E350000B0040A000A0023CC80C43240200022491
+:10E360000C0062A000A0023CC80C43245000C28FE5
+:10E370001F0042900D0062A000A0023CC80C432484
+:10E38000080002240E0062A000A0023CC80C422437
+:10E390000F0040A05000C38F5000C28F0400428C79
+:10E3A00008004224080062AC00A0023CC80C4324D0
+:10E3B00002000224100062A05000C38F0200022459
+:10E3C0001E0062A000A0023CC80C4224110040A024
+:10E3D00000A0023CC80C432402000224120062A0E8
+:10E3E0005000C38F00020224140062A400A0023C6B
+:10E3F000C80C4224130040A000A0023CC80C4224D8
+:10E40000140040A000A0023CC80C4324F8FF0224E2
+:10E41000150062A000A0023CC80C43245800C28F23
+:10E42000160062A000A0023CC80C43245800C28F12
+:10E4300002120200170062A05000C38F5800C28F62
+:10E440001C0062A400A0023CC80C43243F0002242C
+:10E45000180062A000A0023CC80C4224190040A091
+:10E4600000A0023CC80C4324FFFF02241A0062A053
+:10E4700000A0023CC80C42241B0040A000A0023CAB
+:10E48000C80C43245000C28F0400428C1C0062A0C0
+:10E4900000A0023CC80C43245000C28F0400428CF0
+:10E4A000021202001D0062A000A0023CC80C43241E
+:10E4B0005000C28F0400428C021402001E0062A0B1
+:10E4C00000A0023CC80C43245000C28F0400428CC0
+:10E4D000021602001F0062A000A0023CC80C4324E8
+:10E4E0001400C28F200062A000A0023CC80C43248C
+:10E4F0001400C28F02120200210062A000A0023CA0
+:10E50000C80C43241400C28F02140200220062A02F
+:10E5100000A0023CC80C43241400C28F0216020063
+:10E52000230062A000A0023CC80C4224240040A0AA
+:10E5300000A0023CC80C4224250040A000A0023CE0
+:10E54000C80C432429000224260062A000A0023C3B
+:10E55000C80C44249C00C28FFFFF032424104300F6
+:10E56000270082A000A0023CC80C42246C00C2AF6D
+:10E570009C00C28F7000C2AF7000C28F04004104C3
+:10E58000000000007000C38FFF0063247000C3AF61
+:10E590007000C38F03120300FFFF03242410430005
+:10E5A0006C00C38F280062A000A0023CC80C42246B
+:10E5B0007400C2AF9C00C28F7800C2AF7800C28FD7
+:10E5C0000500410400000000FFFF02347800C38F03
+:10E5D000211862007800C3AF7800C38F03140300D2
+:10E5E000FFFF0324241043007400C38F290062A09E
+:10E5F00000A0023CC80C42247C00C2AF9C00C28F29
+:10E600008000C2AF8000C28F0600410400000000FD
+:10E61000FF00023CFFFF42348000C38F21186200DC
+:10E620008000C3AF8000C38F03160300FFFF0324E5
+:10E63000241043007C00C38F2A0062A0A000C28F78
+:10E6400029004010000000006000C0A36000C393D8
+:10E65000A000C28F21106200000042801300401011
+:10E66000000000006000C2930B00422C0F0040101D
+:10E670000000000000A0023C6000C393C80C4224CC
+:10E68000212062006000C393A000C28F21106200AD
+:10E69000000042902B0082A06000C293010042243F
+:10E6A0006000C2A3E9FF0010000000006000C293F8
+:10E6B0000B00422C1B0040100000000000A0043C96
+:10E6C0006000C393010062246000C2A3FF006330B6
+:10E6D000C80C822421186200200002242B0062A0B2
+:10E6E000F2FF0010000000006000C0A36000C293B1
+:10E6F0000B00422C0B0040100000000000A0023C68
+:10E700006000C393C80C4224211062002B0040A07B
+:10E710006000C293010042246000C2A3F3FF001016
+:10E720000000000000A0023CC80C43244600022464
+:10E73000360062A000A0023CC80C43244100022421
+:10E74000370062A000A0023CC80C432454000224FD
+:10E75000380062A000A0023CC80C4324310002240F
+:10E76000390062A000A0023CC80C4324200002240F
+:10E770003B0062A000A0023CC80C432420000224FD
+:10E780003C0062A000A0023CC80C432420000224EC
+:10E790003D0062A000A0023CC80C432455000224A6
+:10E7A000FE0162A000A0023CC80C4324AAFF022480
+:10E7B000FF0162A05000C48F5000C58F5000C28F6F
+:10E7C0001E0043905000C28F1C00429402186270D9
+:10E7D0000800A28C211043000C0082AC5000C28FB4
+:10E7E0000400448C00A0023CC80C452421300000E9
+:10E7F000F15B400F00000000180040140000000012
+:10E80000090002244C8282A3FFFF02246400C2AFED
+:10E8100003010010000000005000C48F5535400F68
+:10E82000000000000D004010000000001B0002244A
+:10E830004C8282A3FFFF03246400C3AFF8000010E2
+:10E84000000000001F0002244C8282A3FFFF02246C
+:10E850006400C2AFF20000100000000000A0023C03
+:10E86000C80C44242128000000020624276A400F17
+:10E870000000000000A0033CF8FF0224C80C62A0C6
+:10E8800000A0023CC80C4324FFFF0224010062A048
+:10E8900000A0023CC80C4324FFFF0224020062A037
+:10E8A0005000C28F20004390020002240500621431
+:10E8B0000000000000A0023CC80C4324FFFF02241B
+:10E8C000030062A05000C28F1E004290FFFF42244E
+:10E8D0005400C2A75400C397FFFF0234190062100E
+:10E8E000000000005000C48F5400C3975000C28F36
+:10E8F0001C004294021862700800828C2110620091
+:10E900002120400000A0023CC80C4524213000001A
+:10E91000F15B400F00000000050040140000000003
+:10E92000FFFF02246400C2AFBD0000100000000021
+:10E930005400C297FFFF42245400C2A7E5FF001015
+:10E940000000000000A0023CC80C44242128000064
+:10E9500004000624276A400F000000005000C28F08
+:10E960000800428C010042246000C2A36000C593ED
+:10E970005000C48F5000C28F1C0043940800828C4A
+:10E98000211062002B10A2002500401000000000A2
+:10E990005000C28F1E004290FFFF42245400C2A7C5
+:10E9A0005400C397FFFF02341800621000000000FB
+:10E9B0006000C4935400C3975000C28F1C0042945F
+:10E9C00002106270211082002120400000A0023C51
+:10E9D000C80C452421300000F15B400F000000000E
+:10E9E0000500401400000000FFFF02246400C2AFD5
+:10E9F0008B000010000000005400C297FFFF42246B
+:10EA00005400C2A7E6FF0010000000006000C2939F
+:10EA1000010042246000C2A3D4FF001000000000E7
+:10EA20005000C28F1400429440110200FF014224A2
+:10EA30008800C2AF8800C38F04006104000000009A
+:10EA40008800C28FFF0142248800C2AF8800C38FB4
+:10EA5000431203001C00C2AF010002246000C2A3E5
+:10EA60006000C2931C00C38F2B104300160040109F
+:10EA7000000000005000C28F6000C3930C00428C65
+:10EA8000211062002120400000A0023CC80C452457
+:10EA900021300000F15B400F000000000500401431
+:10EAA00000000000FFFF02246400C2AF5C00001001
+:10EAB000000000006000C293010042246000C2A375
+:10EAC000E7FF001000000000A000C28F46004010C9
+:10EAD000000000006000C0A36000C393A000C28FCC
+:10EAE000211062000000428013004010000000006E
+:10EAF0006000C2930B00422C0F0040100000000089
+:10EB000000A0023C6000C393C80C42242120620094
+:10EB10006000C393A000C28F2110620000004290E9
+:10EB2000000082A06000C293010042246000C2A3E2
+:10EB3000E9FF0010000000006000C2930B00422CAF
+:10EB40000C0040100000000000A0043C6000C393D3
+:10EB5000010062246000C2A3FF006330C80C82245D
+:10EB60002118620020000224000062A0F2FF0010C1
+:10EB70000000000000A0023CC80C4324080002244E
+:10EB80000B0062A000A0023CC80C43241100022428
+:10EB9000110062A000A0023CC80C43241100022412
+:10EBA000130062A000A0023CC80C43241100022400
+:10EBB000170062A05000C28F0C00448C00A0023CE1
+:10EBC000C80C452421300000F15B400F000000001C
+:10EBD0001200401400000000FFFF03246400C3AFD4
+:10EBE0000F000010000000005000C28F0C00448C89
+:10EBF00000A0023CC80C452421300000F15B400F0E
+:10EC0000000000000500401400000000FFFF022487
+:10EC10006400C2AF02000010000000006400C0AF3A
+:10EC20006400C28F21E8C0039400BF8F9000BE8FA4
+:10EC30009800BD270800E00300000000D0FFBD27BA
+:10EC40002C00BFAF2800BEAF21F0A0033000C4AF3E
+:10EC50003400C5AF3000C28F0000428C1000C2AF3C
+:10EC60003000C28F3800428C1C00C2AF3400C28F0B
+:10EC700000004294021102001500C2A31000C28FCE
+:10EC8000200042902000C2AF2000C38F0100622804
+:10EC90001F004014000000002000C38F0300622802
+:10ECA0001000401400000000030002242000C38F65
+:10ECB00003006210000000001500001000000000BA
+:10ECC0001000C28F1500C3931F0042901B0062000A
+:10ECD000F4014000101000001500C2A30C00001049
+:10ECE000000000001C00C38F3C82828F080062106D
+:10ECF000000000001000C28F1500C3931F00429057
+:10ED00001B006200F4014000101000001500C2A3B7
+:10ED10001000C48F1C00C58F8D45400F00000000FF
+:10ED20001800C2AF1500C3931800C28F21106200F3
+:10ED30001000C38F212040000000658C21300000AE
+:10ED4000F15B400F000000000400401400000000D0
+:10ED50001400C0A303000010000000000100022402
+:10ED60001400C2A31400C29321E8C0032C00BF8F7B
+:10ED70002800BE8F3000BD270800E003000000001F
+:10ED8000D0FFBD272C00BFAF2800BEAF21F0A003ED
+:10ED90003000C4AF3400C5AF1C00C0AF3400C28F18
+:10EDA000200042902400C2AF020002242400C38F3E
+:10EDB00019006210000000002400C38F03006228C5
+:10EDC0000700401000000000010002242400C38F4F
+:10EDD0001700621000000000190000100000000081
+:10EDE000030002242400C38F03006210000000000F
+:10EDF0001300001000000000FF0F023CFFFF423430
+:10EE00001800C2AFFF0F023CF8FF42341400C2AF3B
+:10EE10000B00001000000000FFFF02341800C2AF1A
+:10EE2000F8FF02341400C2AF05000010000000001B
+:10EE3000FFFF02341800C2AFF80F02241400C2AF63
+:10EE40003000C28F07004010000000003000C38F68
+:10EE50000100022403006210000000000500001001
+:10EE600000000000020002241C00C2AF35000010A8
+:10EE7000000000001C00C28F32004014000000009F
+:10EE80003400C48F3000C58F314B400F00000000AC
+:10EE90001000C2AF1000C38F1800C28F05006214AB
+:10EEA00000000000010002241C00C2AFF1FF0010AE
+:10EEB000000000001000C28F07004010000000009A
+:10EEC0001000C38F01000224030062100000000044
+:10EED0000500001000000000020002241C00C2AF68
+:10EEE000E4FF0010000000001000C28F1400C38F68
+:10EEF0002B10430003004014000000000200022415
+:10EF00001C00C2AF3400C48F3000C58F2130000018
+:10EF100021380000534C400F000000002118400031
+:10EF20001800C28F030062140000000001000224D8
+:10EF30001C00C2AF1000C28F3000C2AFCDFF001066
+:10EF4000000000003400C48F2128000021300000A0
+:10EF500001000724534C400F000000001C00C38F29
+:10EF600002000224050062140000000001000224D7
+:10EF70002000C2AF02000010000000002000C0AF5F
+:10EF80002000C28F21E8C0032C00BF8F2800BE8F55
+:10EF90003000BD270800E00300000000C0FFBD27CF
+:10EFA0003C00BFAF3800BEAF21F0A0034000C4AFAB
+:10EFB0004400C5AF2110C0004800C2A34000C28F6A
+:10EFC0000000428C1400C2AF4000C28F3400428C5B
+:10EFD0001C00C2AF4000C28F3800428C2400C2AF78
+:10EFE0004400C28F00004294021102002800C2A314
+:10EFF0001400C28F200042903000C2AF3000C38F97
+:10F000000100622823004014000000003000C38F7C
+:10F0100003006228130040140000000003000224D3
+:10F020003000C38F030062100000000019000010C0
+:10F03000000000001400C28F2800C3931F004290FC
+:10F040001B006200F4014000101000002800C2A361
+:10F05000FF0F023CF8FF42342000C2AF0D00001049
+:10F06000000000001C00C28F0800401000000000DB
+:10F070001400C28F2800C3931F0042901B0062003F
+:10F08000F4014000101000002800C2A3F8FF023471
+:10F090002000C2AF4800C2930600401400000000E8
+:10F0A0004400C28F000042940F0042308F00401491
+:10F0B000000000002800C293060040140000000079
+:10F0C0004400C28F000042941000422C0600401001
+:10F0D000000000004800C29303004014000000003C
+:10F0E0002C000010000000001C00C28F040040141F
+:10F0F000000000002400C0AF260000100000000047
+:10F100004800C2930D004010000000004400C38F6F
+:10F110001400C28F1F00429000110200000063948F
+:10F12000FFFF42301B006200F4014000121000009B
+:10F130002900C2A303000010000000000100022407
+:10F140002900C2A32900C293120040100000000051
+:10F150001400C48F2400C58F314B400F0000000005
+:10F160002400C2AF2400C38F2000C28F2B10620086
+:10F170000300401400000000060000100000000022
+:10F180002900C293FFFF42242900C2A3EDFF001013
+:10F19000000000002400C28F2000C38F2B1043000A
+:10F1A0004D004010000000004000C38F2400C28FBB
+:10F1B000380062AC1400C48F2400C58F8D45400F09
+:10F1C000000000001800C2AF2400C38F3C82828F71
+:10F1D00011006214000000002800C3931800C28FC1
+:10F1E000211862001400C28F1000428C2B106200A4
+:10F1F00009004014000000001400C28F200043905A
+:10F200000300022404006210000000001000C0AFE0
+:10F210003F00001000000000DC80829308004010D6
+:10F22000000000004547400F0000000004004010AF
+:10F23000000000002C00C0AF3700001000000000EC
+:10F24000D88080AFDE8080A32800C3931800C28FCF
+:10F25000211062001400C38F212040000000658C43
+:10F26000695B400F000000002118400001000224EB
+:10F2700004006210000000001000C0AF1200001077
+:10F28000000000004800C2930C0040100000000085
+:10F290001400C48F4400C28F000042940F0042301B
+:10F2A000FFFF4230401902000000828C2110430011
+:10F2B0001000C2AF04000010000000001400C28F54
+:10F2C0000000428C1000C2AFFFFF0224188082AF02
+:10F2D0000F0000100000000001000224DD8082A366
+:10F2E0001000C0AF0A000010000000001400C48F1E
+:10F2F0004400C28F000042940F004230FFFF4230B2
+:10F30000401902000000828C211043001000C2AF9F
+:10F310001000C28F2C00C2AF2C00C28F21E8C003A6
+:10F320003C00BF8F3800BE8F4000BD270800E003BF
+:10F3300000000000D0FFBD272C00BFAF2800BEAFEB
+:10F3400021F0A0033000C4AF3400C5AF2110C000CD
+:10F350003800C2A31400C0AF4C8280A31000C0A329
+:10F360001000C2930B00422C0E0040100000000061
+:10F370001000C3931000C227212062003000C38F09
+:10F380001000C2932110620020004290080082A069
+:10F390001000C293010042241000C2A3F0FF00102D
+:10F3A000000000003400C28F000040A43000C48F71
+:10F3B0003400C58F443D400F000000001300401092
+:10F3C000000000001800C2273800C3933000C48F2B
+:10F3D000212840003400C68F21386000DF3D400FF7
+:10F3E000000000001400C2AF1400C28F09004014D6
+:10F3F000000000003000C48F0E3D400F00000000F0
+:10F400001400C2AF0300001000000000140002242A
+:10F410001400C2AF1400C28F4C8282A31400C28FAA
+:10F4200021E8C0032C00BF8F2800BE8F3000BD270D
+:10F430000800E00300000000D0FFBD272C00BFAF94
+:10F440002800BEAF21F0A0033000C4AF3000C28F4F
+:10F450002C0042941C00C2A71400C2273000C48FA5
+:10F46000212840009044400F000000001000C2AF6F
+:10F470001000C28F1F004014000000001C00C227B3
+:10F480003000C48F212840007D40400F0000000064
+:10F490002000C2AF2000C38F1400C28F1A0062A4E4
+:10F4A0001400C38FFF0F023C241062001800C2AF8B
+:10F4B0001800C28F021402001800C2AF2000C38FD0
+:10F4C0001800C28F140062A41C00C2273000C48F31
+:10F4D000212840000F3B400F000000002118400091
+:10F4E0000100022403006210000000000900022451
+:10F4F0001000C2AF1000C28F21E8C0032C00BF8FE4
+:10F500002800BE8F3000BD270800E0030000000087
+:10F51000D0FFBD272C00BFAF2800BEAF21F0A00355
+:10F520003000C4AF3400C5AF010002241000C2A3F4
+:10F530003000C38F3000C28F3400428C380062AC80
+:10F540003000C48F3400C58F01000624E73B400F14
+:10F55000000000001C00C2AF1C00C28F0500401458
+:10F56000000000001B0002241000C2A37400001061
+:10F57000000000001000C393010002246D0062141B
+:10F58000000000001100C0A33400C28F00004294AC
+:10F590001400C2A73000C48F3400C58F2130000092
+:10F5A000E73B400F000000001C00C2AF1C00C28FF0
+:10F5B000000042901200C2A33400C38F3400C28FF7
+:10F5C0000000429401004224000062A41200C39390
+:10F5D000E500022404006210000000001200C29343
+:10F5E0000C004014000000001C00C28F09004010F5
+:10F5F000000000001100C293010042241100C2A3C8
+:10F60000FF0042300300401400000000E1FF001042
+:10F61000000000001C00C28F3C00401400000000ED
+:10F620003000C28F3800428C1800C2AF1800C38F60
+:10F630003C82828F20006214000000003000C28FE4
+:10F640000000428C20004390030002240500621059
+:10F6500000000000020002241000C2A3C5FF001039
+:10F66000000000003000C38F1800C28F080062AC99
+:10F670003000C48F01000524853E400F00000000CB
+:10F68000211840001500022405006214000000004B
+:10F69000020002241000C2A3B6FF00100000000008
+:10F6A0003400C38F1400C297000062A41000C0A3EE
+:10F6B000B0FF0010000000003000C38F1800C28FA0
+:10F6C000080062AC3000C48F01000524853E400F65
+:10F6D00000000000211840001500022405006214FB
+:10F6E00000000000020002241000C2A3A1FF0010CD
+:10F6F000000000003400C38F1400C297000062A411
+:10F700001000C0A39BFF0010000000001100C39375
+:10F710000100022497FF6214000000001000C0A343
+:10F720003400C38F1400C297000062A491FF001040
+:10F73000000000003400C38F1400C297000062A4D0
+:10F740001000C293050040140000000001000224D4
+:10F750002000C2AF02000010000000002000C0AF77
+:10F760002000C28F21E8C0032C00BF8F2800BE8F6D
+:10F770003000BD270800E00300000000D8FFBD27CF
+:10F780002400BFAF2000BEAF21F0A0032800C4AF0B
+:10F790002C00C5AF3000C6AF2110E0003400C2A37A
+:10F7A0001000C0A32800C38F2800C28F3400428CF1
+:10F7B000380062AC2800C48F3000C58F01000624D9
+:10F7C000E73B400F000000001400C2AF1400C28FDE
+:10F7D00005004014000000001B0002241800C2AF06
+:10F7E0005A000010000000001400C48F2C00C58FC8
+:10F7F0000B000624476B400F000000003400C39349
+:10F800001200022406006214000000001400C38FDE
+:10F81000100002240B0062A0040000100000000091
+:10F820001400C38F200002240B0062A01400C28FBA
+:10F830000C0040A01400C28F140040A41400C28F1A
+:10F840001A0040A41400C28F1C0040AC5A3E400F66
+:10F85000000000001400C38F378282930D0062A065
+:10F860001400C38F388282970E0062A41400C38FE5
+:10F8700042828297100062A43400C39312000224D3
+:10F880000C006210000000001400C38F4A828297AF
+:10F89000120062A41400C38F4E828297160062A4E5
+:10F8A0001400C38F40828297180062A407000010E2
+:10F8B000000000001400C28F120040A41400C28F88
+:10F8C000160040A41400C28F180040A42800C38F63
+:10F8D0001400C28F1C00428C140062AC2800C38F3D
+:10F8E0001400C28F0E0042941C0062A42800C38F33
+:10F8F0001400C28F100042941E0062A42800C38F1F
+:10F900001400C28F0B004290300062A42800C38F05
+:10F910003000C28F000042942C0062A42800C48FE3
+:10F920003000C58F0F3B400F000000002118400041
+:10F9300001000224030062100000000009000224FC
+:10F940001000C2A31000C2931800C2AF1800C28FEB
+:10F9500021E8C0032400BF8F2000BE8F2800BD27F0
+:10F960000800E00300000000E0FFBD271800BEAF64
+:10F9700021F0A0030800DEAF0400C2270C00C2AFD4
+:10F9800080BF023C3002428C1400C2AF80BF023CF8
+:10F990002002428C1000C2AF0800C38F80BF023C1F
+:10F9A0002002428C000062AC0C00C38F80BF023C7E
+:10F9B0003002428C000062AC0C00C28F1400C38F76
+:10F9C0000000428CEEFF6214000000000800C28FAD
+:10F9D0001000C38F0000428CE9FF62140000000099
+:10F9E0000200C3970000C29725106200388282A7E8
+:10F9F0000600C3970000C29725106200408282A7CC
+:10FA000021E8C0031800BE8F2000BD270800E003D6
+:10FA100000000000D8FFBD272400BFAF2000BEAF0C
+:10FA200021F0A0032800C4AF2110A0002C00C2A325
+:10FA30002800C28F0000428C1000C2AF2800C28F85
+:10FA40000800428C1400C2AF2800C48FDD3E400F76
+:10FA5000000000001400C2AF1400C28F0500401463
+:10FA600000000000150002241C00C2AF3A00001084
+:10FA7000000000001000C28F20004390010002240B
+:10FA800009006214000000001000C48F1400C58F2C
+:10FA9000F80F062421380000534C400F00000000EE
+:10FAA00015000010000000001000C28F20004390DD
+:10FAB0000200022409006214000000001000C48F3C
+:10FAC0001400C58FF8FF063421380000534C400F56
+:10FAD0000000000008000010000000001000C48FAB
+:10FAE0001400C58FFF0F023CF8FF46342138000098
+:10FAF000534C400F000000002800C28F0800428CC9
+:10FB00001800C2AF1000C48F1800C58F1400C68F34
+:10FB100021380000534C400F000000002800C38F24
+:10FB20001400C28F080062AC2C00C39301000224B1
+:10FB300008006214000000001000C48F1400C58F7C
+:10FB4000EF44400F000000001C00C2AF0200001094
+:10FB5000000000001C00C0AF1C00C28F21E8C003E1
+:10FB60002400BF8F2000BE8F2800BD270800E003BF
+:10FB700000000000C8FFBD273400BFAF3000BEAF9B
+:10FB800021F0A0033800C4AF1400C0AF3800C28F0A
+:10FB90000000428C1000C2AF3800C28F0800428CB7
+:10FBA0001800C2AF1000C28F200042902800C2AFE0
+:10FBB000020002242800C38F190062100000000018
+:10FBC0002800C38F030062280700401000000000D7
+:10FBD000010002242800C38F1700621000000000FB
+:10FBE0001900001000000000030002242800C38F49
+:10FBF000030062100000000013000010000000006D
+:10FC0000FF0F023CF7FF42342000C2AFFF0F023C5F
+:10FC1000FFFF42342400C2AF0B00001000000000C0
+:10FC2000F7FF02342000C2AFFFFF02342400C2AF4E
+:10FC30000500001000000000F70F02242000C2AFF2
+:10FC4000FFFF02342400C2AF1800C28F0200422C12
+:10FC50000300401000000000020002241800C2AFA0
+:10FC60001800C28F1C00C2AF1000C48F1800C58FCF
+:10FC7000314B400F000000001800C28F28004010D8
+:10FC8000000000001000C48F1800C58F314B400FDA
+:10FC9000000000001400C2AF1400C38F2400C28F04
+:10FCA00004006214000000001800C0AF1C00001027
+:10FCB000000000001400C28F030040140000000088
+:10FCC00017000010000000001800C28F010042243D
+:10FCD0001800C2AF1400C38F2000C28F0900621049
+:10FCE000000000001000C28F1800438C1800C28F63
+:10FCF0002B10430003004010000000000300001020
+:10FD000000000000020002241800C2AF1800C38FD8
+:10FD10001C00C28FD8FF6214000000001800C0AFA2
+:10FD20001800C28F21E8C0033400BF8F3000BE8F9F
+:10FD30003800BD270800E00300000000D8FFBD2701
+:10FD40002400BFAF2000BEAF21F0A0032800C4AF45
+:10FD5000480002241400C2AF4C8280A32800C28F46
+:10FD60002C0042941000C2A72800C28F1800428CB9
+:10FD70000000427C4200401000000000DC808293C2
+:10FD80000A004010000000004547400F000000003E
+:10FD90000600401000000000090002244C8282A3EB
+:10FDA000FFFF0224570000101C00C2AF2800C28FC2
+:10FDB0000000448C2128000021300000534C400FEB
+:10FDC000010007242800C48F7D40400F1000C52784
+:10FDD0001800C2AF1800C28F0800401400000000D5
+:10FDE0001B0002244C8282A3FFFF02241400C2AF36
+:10FDF0001400C28F430000101C00C2AF5A3E400FD7
+:10FE0000000000001800C38F4E828297160062A483
+:10FE10001800C38F40828297180062A4000000007F
+:10FE20001800C38F2800C28F1400428C1C0062ACE3
+:10FE30001800C38F2800C28F300042940B0062A0CC
+:10FE40002800C48F0F3B400F1000C527030040104F
+:10FE500000000000050000101400C0AF09000224DB
+:10FE60004C8282A3FFFF02241400C2AF2800C48F7B
+:10FE70001800838CFEFF022424106200180082AC5C
+:10FE80001200C0A71200C2970300422C16004010B7
+:10FE9000000000001200C397211060000011020052
+:10FEA000231043008018020000A0023C501142249D
+:10FEB000211862002800C28F0700621400000000B1
+:10FEC0001200C397348282272118620001000224A5
+:10FED00005000010000062A01200C2970100422439
+:10FEE000E8FF00101200C2A71400C38F48000224CC
+:10FEF00002006214000000001400C0AF1400C28FA2
+:10FF00001C00C2AF1C00C28F21E8C0032400BF8FB9
+:10FF10002000BE8F0800E0032800BD27D0FFBD27CA
+:10FF20002800BFAF2400BEAF2000B0AF21F0A00377
+:10FF30003000C4AF3400C5AF1800C0A33400C28F76
+:10FF4000000042940F0042301100401400000000F5
+:10FF50003400C28F000042940D00401000000000E9
+:10FF60003000C38F3000C28F3400428C380062AC46
+:10FF70003000C48F3400C58F01000624E73B400FDA
+:10FF8000000000001000C2AF0700001000000000D9
+:10FF90003000C48F3400C58F21300000E73B400F94
+:10FFA000000000001000C2AF1000C28F000042909D
+:10FFB0001500C2A31000C28F040040100000000012
+:10FFC0001500C29305004014000000000200022446
+:10FFD0001700C2A37F000010000000001500C393AB
+:10FFE000E500022405006214000000000100022464
+:10FFF0001700C2A377000010000000001000C28F9D
+:020000041D01DC
+:100000000B0042901500C2A31400C0A31400C293B9
+:100010000800422C18004010000000001000C38FA0
+:100020001400C29321104300000042901600C2A3A6
+:100030001600C29321204000CE6B400F000000004C
+:100040001600C2A33000C48F1800C39301006224BD
+:100050001800C2A3FF006230211882001600C2936C
+:10006000200062A01400C293010042241400C2A325
+:10007000E6FF0010000000001000C28F0B0042904D
+:100080001500C2A31000C28F080042901600C2A340
+:100090001400C0A31400C2930300422C18004010A7
+:1000A000000000001000C38F1400C29321106200F2
+:1000B000080042901600C2A31600C29321204000FF
+:1000C000CE6B400F000000001600C2A33000C48FAA
+:1000D0001800C393010062241800C2A3FF0062301D
+:1000E000211882001600C293200062A01400C2935F
+:1000F000010042241400C2A3E6FF0010000000002B
+:100100003000C38F3400C28F000042942C0062A4E0
+:100110001000C28F000042901500C2A31500C393C7
+:10012000E500022405006214000000000100022422
+:100130001700C2A302000010000000001700C0A3B7
+:100140003000C38F1000C28F1C00428C140062ACC0
+:100150003000D08F1000C48F4836400F00000000E0
+:10016000040002AE1000C28F0B0042901500C2A323
+:100170003000C38F1500C293300062A41500C293F3
+:10018000100042300B004010000000003000C38F10
+:100190001000C28F0E0042941C0062A43000C38F76
+:1001A0001000C28F100042941E0062A409000010CB
+:1001B000000000003000C38F1000C28F1600429470
+:1001C0001C0062A43000C38F1000C28F180042943C
+:1001D0001E0062A41700C29321E8C0032800BF8F4D
+:1001E0002400BE8F2000B08F3000BD270800E00340
+:1001F00000000000D8FFBD272400BFAF2000BEAF25
+:1002000021F0A0032800C4AF2C00C5AF2800C38F85
+:100210002800C28F3400428C380062AC2800C48FA2
+:100220002C00C58F01000624E73B400F00000000B2
+:100230001000C2AF1000C28F040040140000000084
+:100240001800C0AF31000010000000001000C28F85
+:10025000000042901400C2A31400C2930200401494
+:10026000000000001000C0AF1000C28F2500401039
+:10027000000000001400C393E5000224040062148F
+:10028000000000001000C0AF1E00001000000000C1
+:100290001000C28F0B0042901400C2A31400C3933D
+:1002A0000F00022417006214000000002C00C38F0E
+:1002B0002C00C28F0000429401004224000062A47E
+:1002C0002800C48F2C00C58F21300000E73B400F71
+:1002D000000000001000C2AF1000C28F04004014E4
+:1002E000000000001800C0AF08000010000000006F
+:1002F0001000C28F0B0042901400C2A3E7FF001051
+:10030000000000001000C28F1800C2AF1800C28F9A
+:1003100021E8C0032400BF8F2000BE8F2800BD2726
+:100320000800E00300000000D0FFBD272C00BFAF95
+:100330002800BEAF21F0A0033000C4AF3400C5AF29
+:100340002110C0003800C2A31800C0AF3000C28F17
+:100350000000428C2000C2AF3000C28F3400428CBB
+:100360001C00C2AF3000C38F1C00C28F380062ACCB
+:100370003000C48F3400C58F01000624E73B400FD6
+:10038000000000001000C2AF1000C28F0700401430
+:1003900000000000010002244C8282A31B00022402
+:1003A0002400C2AF45000010000000001000C28F02
+:1003B000000042901400C2A31000C28F040040103D
+:1003C000000000001400C29305004014000000006B
+:1003D0000B0002241800C2AF2E0000100000000025
+:1003E0001400C393E500022405006214000000001D
+:1003F0000B0002241800C2AF26000010000000000D
+:100400001000C28F0B0042901400C2A31000C38FD3
+:10041000E5FF0224000062A01000C48F4836400FA0
+:10042000000000001C00C2AF1800C28F070040147B
+:10043000000000003000C48F3400C58F0F3B400F18
+:10044000000000000500401400000000010002242C
+:100450001800C2AF0F000010000000001C00C38F86
+:100460003C82828F0B006210000000003800C293B3
+:1004700008004010000000001C00C48F2000C58F41
+:10048000603B400F00000000000042380100422C99
+:100490001800C2AF1800C28F040040140000000012
+:1004A0004C8280A303000010000000000100022421
+:1004B0004C8282A31800C28F2400C2AF2400C28FD6
+:1004C00021E8C0032C00BF8F2800BE8F3000BD275D
+:1004D0000800E00300000000C0FFBD273C00BFAFE4
+:1004E0003800BEAF21F0A0034000C4AF4400C5AF48
+:1004F0001100C0A3010002242800C2A74C8280A3DF
+:100500004400C28F070040140000000019000224BC
+:100510004C8282A3FFFF02243000C2AFD100001042
+:10052000000000004400C28F200042244000C48F1D
+:1005300021284000213000004948400F0000000001
+:100540000700401400000000120002244C8282A325
+:10055000FFFF02243000C2AFC20000100000000004
+:100560001000C0A31000C2930B00422C0E004010DC
+:10057000000000001000C3931000C2272120620079
+:100580004400C38F1000C2932110620020004290EB
+:10059000080082A01000C293010042241000C2A3F0
+:1005A000F0FF0010000000004400C28F2C004294B5
+:1005B0002A00C2A72800C0A74400C38F4400C28FEE
+:1005C0003400428C380062AC2800C2274400C48F3B
+:1005D0002128400001000624E73B400F00000000F6
+:1005E0002C00C2AF2C00C28F070040140000000096
+:1005F0001B0002244C8282A3FFFF02243000C2AF02
+:1006000098000010000000001000C0A31000C2936A
+:100610000B00422C12004010000000002C00C38F81
+:100620001000C293212043001000C3931000C22782
+:1006300021106200000083800800428003006210E5
+:1006400000000000010002241100C2A31000C293A8
+:10065000010042241000C2A3ECFF001000000000C3
+:100660001100C29307004014000000001100022492
+:100670004C8282A3FFFF02243000C2AF7900001039
+:10068000000000001100C0A3DD8080A32800C22765
+:100690004400C48F2128400021300000E73B400F78
+:1006A000000000002C00C2AF2C00C28F0D004014CF
+:1006B00000000000DD808393010002240300621427
+:1006C0000000000032000010000000001B000224A7
+:1006D0004C8282A3FFFF02243000C2AF61000010F1
+:1006E000000000002C00C28F000042800300401474
+:1006F0000000000026000010000000001000C0A351
+:100700001000C2930B00422C1200401000000000A9
+:100710002C00C38F1000C293212043001000C3930C
+:100720001000C22721106200000083800800428070
+:100730000300621000000000010002241100C2A3A7
+:100740001000C293010042241000C2A3ECFF00106D
+:10075000000000001100C2930700401400000000D8
+:10076000110002244C8282A3FFFF02243000C2AF9A
+:100770003C000010000000001100C0A32800C29738
+:10078000010042242800C2A7C0FF001000000000A2
+:100790002A00C2972800C2A74400C38F4400C28F1A
+:1007A0003400428C380062AC2800C2274400C48F59
+:1007B000212840007D40400F000000002C00C2AF07
+:1007C0002C00C28F07004014000000001B00022410
+:1007D0004C8282A3FFFF02243000C2AF2100001030
+:1007E000000000001000C0A31000C2930B00422CB8
+:1007F0000E004010000000002C00C38F1000C293B8
+:10080000212043004400C38F1000C29321106200D6
+:1008100020004290000082A01000C29301004224F8
+:100820001000C2A3F0FF0010000000002800C22743
+:100830004400C48F212840000F3B400F00000000FF
+:100840000700401400000000090002244C8282A32B
+:10085000FFFF02243000C2AF0200001000000000C1
+:100860003000C0AF3000C28F21E8C0033C00BF8F12
+:100870003800BE8F4000BD270800E00300000000E4
+:10088000D0FFBD272C00BFAF2800BEAF21F0A003D2
+:100890003000C4AF3400C5AF1000C0AF1400C0AF0B
+:1008A0001400C28F030042281B004010000000000B
+:1008B0001400C38F3482822721106200000042900E
+:1008C00010004010000000001400C38F3482822703
+:1008D00021106200000040A01400C38F21106000AE
+:1008E00000110200231043008018020000A0023C07
+:1008F00050114224211062001000C2AF0600001007
+:10090000000000001400C28F010042241400C2AF96
+:10091000E3FF0010000000001000C28F060040142A
+:1009200000000000200002244C8282A32000C0AFFF
+:1009300078010010000000001000C28F2000422447
+:100940003000C48F21284000213000004948400F6A
+:10095000000000000B004014000000001400C38FD2
+:10096000348282272118620001000224000062A064
+:10097000120002244C8282A32000C0AF6501001047
+:10098000000000003400C28F000042901800C2A393
+:100990001000C38F00A0023C04124224000062AC8D
+:1009A0001000C28F040040AC1000C28F080040ACA1
+:1009B0001000C28F2C0040A41000C38F200002241E
+:1009C000300062A41000C38F1C80828F3400428CE0
+:1009D000340062AC1000C38F1C80828F3800428CC0
+:1009E000380062AC00A0023C281244241000C58FDD
+:1009F0006D44400F000000001000C48F00A0023CB6
+:100A00002812452401000624213800003D32400F01
+:100A100000000000DB004014000000001800C2933A
+:100A2000BFFF42242400C2AF2400C38F3700622CD2
+:100A3000CE004010000000002400C28F8018020089
+:100A4000029D023CC4044224211062000000428C3A
+:100A500008004000000000001000C28F2C004294EB
+:100A60001A00C2A71A00C2271000C48F2128400014
+:100A700001000624CA40400F000000001C00C2AF65
+:100A80001C00C28F0C014014000000001A00C22795
+:100A90001000C48F2128400021300000CD3C400FC1
+:100AA000000000001C00C2AF1C00C28F02014014F5
+:100AB000000000001A00C2271000C48F2128400047
+:100AC000770006244933400F000000001C00C2AF2D
+:100AD0001000C28F300042941000423005004010D8
+:100AE000000000001F0002244C8282A3FF000224A9
+:100AF0001C00C2AF1C00C28FEF00401400000000B9
+:100B00001000C48F2128000002000624464A400F2E
+:100B1000000000001C00C2AF3400C28F01004380FF
+:100B20002B000224E4006214000000001000C28FB9
+:100B30001800438C02006334180043ACDE00001040
+:100B4000000000001000C28F1400428C2D004010E5
+:100B5000000000001000C28F2C0042941A00C2A7AF
+:100B60001A00C2271000C48F2128400077000624F5
+:100B70004933400F000000001C00C2AF1000C28FBC
+:100B80003000429410004230050040100000000088
+:100B90001F0002244C8282A3FF0002241C00C2AF6B
+:100BA0001C00C28FC4004014000000001000C48F5D
+:100BB0002128000002000624464A400F00000000E1
+:100BC0001C00C2AF1C00C28F0300401000000000D8
+:100BD0001A0002244C8282A33400C28F0100438099
+:100BE0002B000224B4006214000000001000C28F29
+:100BF0001800438C02006334180043ACAE000010B0
+:100C0000000000001000C28F2C0042941A00C2A7FE
+:100C10001A00C2271000C48F2128400001000624BA
+:100C2000CA40400F000000001C00C2AF1C00C28F71
+:100C3000A1004014000000001A00C2271000C48F59
+:100C40002128400021300000CD3C400F0000000072
+:100C50001C00C2AF1C00C28F9700401400000000AF
+:100C60001A00C2271000C48F2128400077000624F4
+:100C70004933400F000000001C00C2AF1000C28FBB
+:100C80003000429410004230050040100000000087
+:100C90001F0002244C8282A3FF0002241C00C2AF6A
+:100CA0001C00C28F84004014000000001000C48F9C
+:100CB0002128000002000624464A400F00000000E0
+:100CC0001C00C2AF1C00C28F0300401000000000D7
+:100CD0001A0002244C8282A33400C28F0100438098
+:100CE0002B00022474006214000000001000C28F68
+:100CF0001800438C02006334180043AC6E000010EF
+:100D0000000000001000C28F2C0042941A00C2A7FD
+:100D10001A00C2271000C48F212840007200062448
+:100D20004933400F000000001C00C2AF3400C28FE6
+:100D3000010043802B0002245F00621400000000C9
+:100D40001000C28F30004294100042305A0040140C
+:100D5000000000001000C28F1800438C01006334B3
+:100D6000180043AC54000010000000001F000224D3
+:100D70004C8282A3FF0002241C00C2AF4E00001070
+:100D8000000000001000C48F00A0023C281245247F
+:100D90006D44400F000000001800C3937700022448
+:100DA0000F006210000000001800C39357000224D7
+:100DB0000B006210000000001800C39361000224C1
+:100DC00007006210000000001800C39341000224D5
+:100DD0000300621000000000350000100000000059
+:100DE0001A00C0A71A00C2271000C48F2128400093
+:100DF00021300000CD3C400F000000001C00C2AFBD
+:100E00001C00C28F2C004014000000001A00C227F2
+:100E10001000C48F21284000770006244933400F7A
+:100E2000000000001C00C2AF1000C28F30004294CE
+:100E30001000423005004010000000001F00022496
+:100E40004C8282A3FF0002241C00C2AF1C00C28F90
+:100E500019004014000000001000C48F2128000079
+:100E600002000624464A400F000000001C00C2AFEA
+:100E70001C00C28F03004010000000001A00022472
+:100E80004C8282A33400C28F010043802B000224D5
+:100E900009006214000000001000C28F1800438C8B
+:100EA00002006334180043AC03000010000000008F
+:100EB0000B0002241C00C2AF6B5C400F000000005E
+:100EC00006004010000000001000C48F1800838C42
+:100ED000FEFF022424106200180082AC1C00C28FA6
+:100EE00009004010000000001400C38F34828227E4
+:100EF0002118620001000224000062A01000C0AFAF
+:100F000002000010000000004C8280A31000C28F7D
+:100F10002000C2AF2000C28F21E8C0032C00BF8F89
+:100F20002800BE8F3000BD270800E003000000004D
+:100F3000F8FFBD270000BEAF21F0A0030800C4AF3A
+:100F40004C8280A30800C28F1000428C21E8C003AD
+:100F50000000BE8F0800BD270800E003000000006D
+:100F6000D8FFBD272400BFAF2000BEAF21F0A003F3
+:100F70002800C4AF00A0023C140F42241000C2AFEE
+:100F80004C8280A36B5C400F000000000700401003
+:100F900000000000180002244C8282A3FFFF0224FC
+:100FA0001800C2AF58000010000000001000C28FEF
+:100FB000200042242800C48F212840002130000056
+:100FC0004948400F000000000700401400000000E6
+:100FD000120002244C8282A3FFFF02241800C2AF39
+:100FE00049000010000000001000C38F00A0023C68
+:100FF00004124224000062AC1000C28F040040AC16
+:101000001000C28F080040AC1000C28F2C0040A41A
+:101010001000C38F20000224300062A41000C38F90
+:101020001C80828F3400428C340062AC1000C38F6D
+:101030001C80828F3800428C380062AC00A0023CD9
+:10104000281244241000C58F6D44400F000000009A
+:101050001000C48F00A0023C281245240100062481
+:10106000213800003D32400F000000001400C2AFE4
+:101070001400C28F07004010000000000B00022483
+:101080004C8282A3FFFF02241800C2AF1E00001092
+:10109000000000001000C28F300042941000423067
+:1010A0000700401000000000130002244C8282A3BD
+:1010B000FFFF02241800C2AF130000100000000060
+:1010C0001000C28F2C0042241000C48F2128400041
+:1010D00001000624CA40400F000000001400C2AF07
+:1010E0001400C28F04004014000000001800C0AFBC
+:1010F0000500001000000000010002244C8282A3C1
+:10110000FFFF02241800C2AF1800C28F21E8C003FD
+:101110002400BF8F2000BE8F2800BD270800E003F9
+:1011200000000000E8FFBD271400BFAF1000BEAFF5
+:1011300021F0A0031800C4AFDC80829303004010AC
+:10114000000000004547400F000000001800C28F5B
+:10115000100040AC1800C28F0E0040A41800C28FCF
+:101160000C0040A41800C38F1800C28F0400428CEA
+:10117000080062ACD88080AF21E8C0031400BF8FA4
+:101180001000BE8F1800BD270800E003000000001B
+:10119000F8FFBD270000BEAF21F0A0034C82829370
+:1011A00021E8C0030000BE8F0800BD270800E0034F
+:1011B00000000000E8FFBD271000BEAF21F0A00333
+:1011C0001800C4AF1C00C5AF1800C28F0400C2AF26
+:1011D0001C00C28F0800C2AF3C0002240000C2A362
+:1011E0000C00C0A30C00C2930000C3932B1043005B
+:1011F0000E004010000000000C00C3930400C28FDA
+:10120000212062000C00C3930800C28F21106200ED
+:1012100000004290000082A00C00C2930100422412
+:101220000C00C2A3EFFF00100000000021E8C00383
+:101230001000BE8F1800BD270800E003000000006A
+:10124000E0FFBD271C00BFAF1800BEAF21F0A00318
+:101250002000C4AF2400C5AF1400C0AF2000C28F6F
+:101260000000428C1000C2AF2000C48FDD3E400F52
+:1012700000000000211840002400C28F000043AC91
+:101280002400C28F0000428C0500401400000000C2
+:10129000150002241400C2AF41000010000000003D
+:1012A0001000C28F2000439001000224100062143D
+:1012B000000000002400C28F1000C48F0000458C85
+:1012C000F80F062421380000534C400F00000000A6
+:1012D00021184000FFFF02342800621400000000C3
+:1012E000090002241400C2AF240000100000000016
+:1012F0001000C28F200043900200022410006214EC
+:10130000000000002400C28F1000C48F0000458C34
+:10131000F8FF063421380000534C400F0000000055
+:1013200021184000FFFF0234140062140000000086
+:10133000090002241400C2AF1000001000000000D9
+:101340002400C28F1000C48F0000458CFF0F023CA8
+:10135000F8FF463421380000534C400F00000000D5
+:1013600021184000FF0F023CFFFF423403006214CB
+:1013700000000000090002241400C2AF1400C28F54
+:1013800007004014000000002400C28F1000C48F2A
+:101390000000458CEF44400F000000001400C2AF75
+:1013A0001400C28F21E8C0031C00BF8F1800BE8F3D
+:1013B0002000BD270800E00300000000D8FFBD2783
+:1013C0002400BFAF2000BEAF21F0A0032800C4AFAF
+:1013D0002C00C5AF1800C0A32800C48F2C00C58FF7
+:1013E0008D45400F000000001400C2AFDC808293E6
+:1013F00009004010000000004547400F00000000B9
+:101400000500401000000000090002241C00C2AFCB
+:101410002E00001000000000D88080AFDE80829394
+:1014200009004014000000002800C28F0000448C16
+:101430002128000000020624276A400F0000000057
+:1014400001000224DE8082A31000C0A32800C28F06
+:101450001F0043901000C2932B104300190040104E
+:10146000000000001800C2931600401400000000A5
+:101470001400C3270000628C212040000100422498
+:10148000000062AC2800C28F0000458C21300000B3
+:10149000F15B400F00000000211840000100022411
+:1014A0000300621000000000090002241800C2A31B
+:1014B0001000C293010042241000C2A3E3FF0010F9
+:1014C000000000001800C2931C00C2AF1C00C28FB5
+:1014D00021E8C0032400BF8F2000BE8F2800BD2755
+:1014E0000800E00300000000F8FFBD270000BEAFC9
+:1014F00021F0A0030800C4AF2110A0000C00C2A777
+:101500000C00C3970800C28F2110620000004290B7
+:1015100021E8C0030000BE8F0800BD270800E003DB
+:1015200000000000F0FFBD270800BEAF21F0A003BF
+:101530001000C4AF2110A0001400C2A71400C3976C
+:101540001000C28F21106200000042900000C2A370
+:101550001400C3971000C28F211062000100429056
+:101560000100C2A30100C2930200C2A70200C297F9
+:10157000001202000200C2A70000C3930200C2973B
+:10158000251043000200C2A70200C29721E8C00351
+:101590000800BE8F1000BD270800E0030000000017
+:1015A000E0FFBD271C00BFAF1800BEAF21F0A003B5
+:1015B0002000C4AF2110A0002400C2A72400C297BD
+:1015C0002000C48F212840004945400F0000000042
+:1015D0001000C2A72400C29702004224FFFF42303D
+:1015E0002000C48F212840004945400F0000000022
+:1015F0001200C2A71200C2971400C2AF1400C28F1B
+:10160000001402001400C2AF1000C3971400C28F70
+:10161000251043001400C2AF1400C28F21E8C0039C
+:101620001C00BF8F1800BE8F2000BD270800E003FC
+:1016300000000000F0FFBD270800BEAF21F0A003AE
+:101640001000C4AF1400C5AF1000C28F200042903C
+:101650000400C2AF0400C38F010062282F004014B1
+:10166000000000000400C38F030062281200401431
+:1016700000000000030002240400C38F0300621076
+:101680000000000025000010000000001400C28FC0
+:10169000FEFF43241000C28F1F00429002186270A8
+:1016A0001000C28F1000428C211062000000C2AFF7
+:1016B0001A000010000000001400C28F0700401044
+:1016C000000000001400C38F010002240300621018
+:1016D0000000000008000010000000001000C28F91
+:1016E0000C00438C1400C28F211062000000C2AFB6
+:1016F0000A000010000000001400C28FFEFF432407
+:101700001000C28F1F004290021862701000C28F3A
+:101710001000428C211062000000C2AF0000C28F96
+:1017200021E8C0030800BE8F1000BD270800E003B9
+:1017300000000000D8FFBD272400BFAF2000BEAFCF
+:1017400021F0A0032800C4AF2110A0002C00C2A3E8
+:101750004C8280A32C00C393D8FF02242410620083
+:1017600007004010000000001F0002244C8282A3EA
+:10177000FFFF02241800C2AF3C0000100000000070
+:101780002800C28F2C0042941000C2A72800C38FEB
+:101790002800C28F3400428C380062AC2800C48F0D
+:1017A0001000C5277D40400F000000001400C2AFAC
+:1017B0001400C28F07004014000000001B00022428
+:1017C0004C8282A3FFFF02241800C2AF2700001042
+:1017D000000000001400C28F0B004290080042304D
+:1017E00007004010000000001F0002244C8282A36A
+:1017F000FFFF02241800C2AF1C0000100000000010
+:101800002800C28F30004294100042300700401080
+:10181000000000001400C28F2C00C393100063343A
+:101820000B0043A004000010000000001400C38F50
+:101830002C00C2930B0062A02800C48F1000C527A3
+:101840000F3B400F000000000700401400000000A4
+:10185000090002244C8282A3FFFF02241800C2AFB9
+:1018600002000010000000001800C0AF1800C28F76
+:1018700021E8C0032400BF8F2000BE8F2800BD27B1
+:101880000800E00300000000C0FFBD273C00BFAF20
+:101890003800BEAF21F0A0034000C4AF4400C5AF84
+:1018A0004800C6AF4C00C7AF4400C38F4800C28F8A
+:1018B000021062701000C2AF4000C28F1400C2AFAD
+:1018C0001C00C0AF3000C0A74C00C28F1800428C73
+:1018D0000000427C08004014000000001D000224AB
+:1018E0004C8282A3090002241C00C2AF3400C0AFA6
+:1018F00001010010000000001000C28F040040141D
+:10190000000000003400C0AFFB0000100000000029
+:101910006B5C400F00000000080040100000000059
+:10192000180002244C8282A3180002241C00C2AFBB
+:101930003400C0AFF000001000000000DE8080A383
+:101940004C00C28F0000428C1800C2AF4C00C28F06
+:101950000E0042942000C2A74C00C28F1000428C9F
+:101960002800C2AF4C00C28F1800C48F0800458CFD
+:101970008D45400F000000002400C2AF4C00C28F14
+:101980000C0043942400C28F211043002400C2AFF6
+:10199000D880838F4C00C28F0F00621000000000BF
+:1019A000DC8082930A004010000000004547400F91
+:1019B00000000000060040100000000009000224A2
+:1019C0004C8282A33400C0AFCB00001000000000A6
+:1019D0004C00C28FD88082AF1880838F2400C28FC2
+:1019E0001B00621000000000DC8082930A0040109F
+:1019F000000000004547400F0000000006004010B6
+:101A000000000000090002244C8282A33400C0AF11
+:101A1000B900001000000000DE8080A31800C28F13
+:101A20002400C48F0000458C695B400F000000005B
+:101A300005004014000000001B0002244C8282A319
+:101A4000080002241C00C2AF2400C28F188082AF9D
+:101A50004C00C28F1400428C2C00C2AF1C00C28FFD
+:101A600096004014000000001000C28F9300401048
+:101A7000000000002800C38F2C00C28F05006214F4
+:101A8000000000004C00C28F1800438C0400633437
+:101A9000180043AC2000C3970002022462006214C5
+:101AA00000000000010002243200C2A3DC80829307
+:101AB0000A004010000000004547400F00000000F1
+:101AC0000600401000000000090002244C8282A39E
+:101AD0003400C0AF88000010000000002000C0A744
+:101AE0004C00C38F4C00C28F0C0042940100422472
+:101AF0000C0062A44C00C38F1800C28F1F004290DC
+:101B00000C006394FFFF42301500621400000000D7
+:101B10004C00C28F0C0040A44C00C28F1800428CB5
+:101B20008000427C09004010000000004C00C48F7F
+:101B300021280000853E400F000000001C00C2AFBD
+:101B40003200C0A306000010000000004C00C48F4B
+:101B500001000524EB33400F000000001C00C2AF61
+:101B60001C00C38F15000224060062140000000050
+:101B7000150002244C8282A33400C0AF5E00001026
+:101B8000000000001C00C28F27004014000000006D
+:101B90004C00C28F1800C48F0800458C8D45400F43
+:101BA000000000002400C2AF4C00C28F0C00439420
+:101BB0002400C28F211043002400C2AF4C00C28F0A
+:101BC000D88082AF3200C2931500401000000000A0
+:101BD0001800C28F2400C48F0000458C695B400F41
+:101BE000000000000A004014000000001B00022456
+:101BF0004C8282A3080002241C00C2AFFFFF022413
+:101C0000188082AF3400C0AF3B000010000000001D
+:101C10002400C28F188082AF030000100000000073
+:101C20002400C28F188082AF1C00C28F8BFF40142B
+:101C3000000000001800C48F2000C3970100622438
+:101C40002000C2A7FFFF63300000828C21186200D1
+:101C50001400C28F00004290000062A01400C28FE6
+:101C6000010042241400C2AF2800C28F01004224A8
+:101C70002800C2AF1000C28FFFFF42241000C2AF85
+:101C80003000C297010042243000C2A74C00C28F2E
+:101C90001800428C8000427C0400401000000000CC
+:101CA0002C00C28F010042242C00C2AF010002248C
+:101CB000DC8082A369FF0010000000004C00C38F8D
+:101CC0002000C2970E0062A44C00C38F2800C28F70
+:101CD000100062AC4C00C38F2C00C28F140062ACA9
+:101CE0003000C3974400C28F1B006200F401400023
+:101CF000121000003400C2AF3400C28F21E8C003CC
+:101D00003C00BF8F3800BE8F4000BD270800E003B5
+:101D100000000000D8FFBD272400BFAF2000BEAFE9
+:101D200021F0A003D880828F1800C2AF1800C28FA4
+:101D30000000428C1400C2AF1800C28F1400C48F80
+:101D40000800458C8D45400F000000001000C2AF18
+:101D50001800C28F0C0043941000C28F2110430062
+:101D60001000C2AF1400C28F1000C48F0000458C59
+:101D700021300000F15B400F00000000050040141E
+:101D800000000000090002241C00C2AF0300001084
+:101D900000000000DC8080A31C00C0AF1C00C28FCC
+:101DA00021E8C0032400BF8F2000BE8F2800BD277C
+:101DB0000800E00300000000F8FFBD270000BEAFF0
+:101DC00021F0A0030800C4AF4C8280A30800C28F9A
+:101DD0000800C38F1000448C1400628C261082000F
+:101DE0000100422C21E8C0030000BE8F0800BD277F
+:101DF0000800E00300000000C0FFBD273C00BFAFAB
+:101E00003800BEAF21F0A0034000C4AF4400C5AF0E
+:101E10004800C6AF4C00C7AF4400C38F4800C28F14
+:101E2000021062701000C2AF4000C28F1400C2AF37
+:101E30002800C0AF2C00C0A74C8280A34C00C28FEA
+:101E40000000428C1800C2AF4C00C28F0E004294BA
+:101E50002400C2A74C00C28F1000428C1C00C2AFED
+:101E60004C00C28F1800428C4000427C0600401497
+:101E7000000000001E0002244C8282A33000C0AF8C
+:101E8000A100001000000000DC8082930A004010D6
+:101E9000000000004547400F000000000600401011
+:101EA00000000000090002244C8282A33000C0AF71
+:101EB0009500001000000000D880838F4C00C28F76
+:101EC00023006210000000002400C39700020224D7
+:101ED0001F006210000000004C00C28FD88082AF4B
+:101EE0004C00C28F1800C48F0800458C8D45400FF0
+:101EF000000000002000C2AF4C00C28F0C004394D1
+:101F00002000C28F211043002000C2AFDE8080A3DA
+:101F10001800C28F2000C48F0000458C695B400F01
+:101F20000000000008004014000000000800022427
+:101F30004C8282A3080002242800C2AF3000C0AF48
+:101F400071000010000000002000C28F188082AFD6
+:101F50001000C28F60004010000000004C00C28FD3
+:101F60001400438C1C00C28F0700621400000000A4
+:101F70003D0002244C8282A33D0002242800C2AF0F
+:101F800055000010000000002400C3970002022446
+:101F900039006214000000002400C0A74C00C38F69
+:101FA0004C00C28F0C004294010042240C0062A439
+:101FB0004C00C38F1800C28F1F0042900C00639426
+:101FC000FFFF42300F006214000000004C00C28F7F
+:101FD0000C0040A44C00C48F01000524EB33400FDB
+:101FE000000000002800C2AF2800C28F050040108A
+:101FF000000000000F0002244C8282A33600001073
+:10200000000000004C00C28F1800C48F0800458CEF
+:102010008D45400F000000002000C2AF4C00C28F71
+:102020000C0043942000C28F211043002000C2AF57
+:102030004C00C28FD88082AFDE8080A31800C28F90
+:102040002000C48F0000458C695B400F0000000039
+:102050000700401400000000080002244C8282A304
+:10206000080002242800C2AF1B000010000000007E
+:102070002000C28F188082AF1400C58F1800C48F53
+:102080002400C397010062242400C2A7FFFF63302D
+:102090000000828C21106200000042900000A2A08B
+:1020A0001400C28F010042241400C2AF1C00C28F72
+:1020B000010042241C00C2AF2C00C2970100422440
+:1020C0002C00C2A71000C28FFFFF42241000C2AF35
+:1020D0009FFF0010000000004C00C38F2400C29737
+:1020E0000E0062A44C00C38F1C00C28F100062ACB3
+:1020F0002C00C3974400C28F1B006200F401400013
+:10210000121000003000C2AF3000C28F21E8C003BF
+:102110003C00BF8F3800BE8F4000BD270800E003A1
+:1021200000000000C0FFBD273800BFAF3400BEAFC5
+:102130003000B0AF21F0A0034000C4AF4400C5AFF1
+:102140002110C0004800C2A32800C0A32800C293E9
+:102150000B00422C0B004010000000002800C3932D
+:102160004400C28F2118620020000224000062A0F7
+:102170002800C293010042242800C2A3F3FF0010EC
+:10218000000000004000C28F000043802E000224A7
+:1021900005006210000000004000C28F0000428075
+:1021A00004004014000000002C00C0AF73000010B9
+:1021B000000000004000C48FB96A400F000000001A
+:1021C0001400C2A71400C2970D00422C0800401052
+:1021D000000000001800C227212040004000C58FE9
+:1021E000516A400F000000000400001000000000D1
+:1021F0002C00C0AF61000010000000001800C227D2
+:102200004800C39321204000212860007749400FF7
+:102210000000000004004014000000002C00C0AFCB
+:1022200056000010000000001800C22721204000C6
+:102230002E0005247B6B400F000000001000C2AF91
+:102240001000C28F0F004010000000001000C28F6D
+:10225000000040A01000C28F010042241000C2AF55
+:102260001000C48FB96A400F000000000400422C27
+:1022700004004014000000002C00C0AF3F0000101C
+:10228000000000001800C22721204000B96A400F5A
+:10229000000000000900422C04004014000000006F
+:1022A0002C00C0AF35000010000000002800C0A3C3
+:1022B0002800D0931800C22721204000B96A400F9F
+:1022C000000000002B1002020E0040100000000071
+:1022D0002800C3934400C28F212062002800C393CA
+:1022E0001000C2272110620008004290000082A066
+:1022F0002800C293010042242800C2A3ECFF001072
+:10230000000000001000C28F1A0040100000000002
+:102310001000C28F00004280160040100000000034
+:102320002800C0A32800D0931000C48FB96A400FC2
+:10233000000000002B1002020E0040100000000000
+:102340002800C3934400C28F212062002800C39359
+:102350001000C28F2110620000004290080082A08D
+:102360002800C293010042242800C2A3EDFF001000
+:1023700000000000010002242C00C2AF2C00C28F1C
+:1023800021E8C0033800BF8F3400BE8F3000B08F0B
+:102390004000BD270800E00300000000C8FFBD2783
+:1023A0003400BFAF3000BEAF21F0A0033800C4AF8F
+:1023B0002110A0003C00C2A33C00C2933800C48F8F
+:1023C000212840007749400F00000000040040141D
+:1023D000000000002800C0AF7900001000000000DD
+:1023E0001000C0A31000C2930800422C1B00401034
+:1023F000000000001000C3933800C28F211062005B
+:10240000000043802E00022414006210000000002F
+:102410001000C3933800C28F211062000000428078
+:102420000E004010000000001000C3931000C227EF
+:10243000212062001000C3933800C28F2110620077
+:1024400000004290080082A01000C29301004224C4
+:102450001000C2A3E3FF0010000000001000C293B0
+:102460001100C2A31000C2930800422C0B004010C0
+:10247000000000001000C393010062241000C2A3FA
+:10248000FF0063301000C2272118620020000224E0
+:10249000080062A0F3FF0010000000001100C393C9
+:1024A0003800C28F21106200000043802E000224F9
+:1024B0001A006214000000001100C29301004224BF
+:1024C0001100C2A31100C3933800C28F2110620013
+:1024D0000000428011004010000000001000C39373
+:1024E000010062241000C2A3FF0063301000C22765
+:1024F000212062001100C393010062241100C2A3D5
+:10250000FF0063303800C28F21106200000042904B
+:10251000080082A0EBFF0010000000001000C29332
+:102520000B00422C0B004010000000001000C39371
+:10253000010062241000C2A3FF0063301000C22714
+:102540002118620020000224080062A0F3FF00109E
+:10255000000000002300C0A31800C3832000022451
+:1025600003006214000000005F0002241800C2A3F0
+:102570001000C0A31000C2930C00422C0E004010AB
+:10258000000000001000C3933800C28F21206200B9
+:102590001000C3931000C22721106200080042906F
+:1025A000000082A01000C293010042241000C2A3C8
+:1025B000F0FF001000000000010002242800C2AF5C
+:1025C0002800C28F21E8C0033400BF8F3000BE8FC7
+:1025D0003800BD270800E00300000000D8FFBD2739
+:1025E0002400BFAF2000BEAF21F0A0032800C4AF7D
+:1025F0002110A0002C00C2A31800C0A32800C48F83
+:10260000B96A400F000000001000C2AF1400C0AF54
+:102610001400C28F1000C38F2A104300B500401071
+:10262000000000001400C38F2800C28F2110620038
+:1026300000004280210042280800401000000000F5
+:102640001400C38F2800C28F211062000000438055
+:102650000500022469006214000000001400C38F0A
+:102660002800C28F21106200000043802200022453
+:1026700062006210000000001400C38F2800C28FA7
+:1026800021106200000043802B0002245B006210D6
+:10269000000000001400C38F2800C28F21106200C8
+:1026A000000043802C00022454006210000000004F
+:1026B0001400C38F2800C28F2110620000004380E5
+:1026C0002F0002244D006210000000001400C38F90
+:1026D0002800C28F21106200000043803A000224CB
+:1026E00046006210000000001400C38F2800C28F53
+:1026F00021106200000043803B0002243F00621072
+:10270000000000001400C38F2800C28F2110620057
+:10271000000043803C0002243800621000000000EA
+:102720001400C38F2800C28F211062000000438074
+:102730003D00022431006210000000001400C38F2D
+:102740002800C28F21106200000043803E00022456
+:102750002A006210000000001400C38F2800C28FFE
+:1027600021106200000043805B00022423006210FD
+:10277000000000001400C38F2800C28F21106200E7
+:10278000000043805C0002241C0062100000000076
+:102790001400C38F2800C28F211062000000438004
+:1027A0005D00022415006210000000001400C38FB9
+:1027B0002800C28F21106200000043807C000224A8
+:1027C0000E006210000000001400C38F2800C28FAA
+:1027D00021106200000043802E0002240A006214CF
+:1027E000000000001800C3930100022403006210DF
+:1027F0000000000004000010000000001C00C0AF3A
+:102800003E000010000000002C00C2931400401491
+:10281000000000001400C38F2800C28F2110620046
+:10282000000043802A0002240A0062100000000019
+:102830001400C38F2800C28F211062000000438063
+:102840003F0002240300621000000000040000109A
+:10285000000000001C00C0AF2800001000000000B5
+:102860001400C38F2800C28F211062000000438033
+:102870002E00022403006214000000000100022464
+:102880001800C2A31400C38F2800C28F2110620059
+:102890000000428061004228110040140000000046
+:1028A0001400C38F2800C28F2110620000004280F4
+:1028B0007B0042280A004010000000001400C38F73
+:1028C0002800C28F212062001400C38F2800C28F0D
+:1028D0002110620000004290E0FF4224000082A02C
+:1028E0001400C28F010042241400C2AF48FF001040
+:1028F00000000000010002241C00C2AF1C00C28FB7
+:1029000021E8C0032400BF8F2000BE8F2800BD2710
+:102910000800E00300000000C8FFBD273400BFAF7F
+:102920003000BEAF21F0A0033800C4AF3C00C5AFFB
+:102930004000C6AF3C00C28F2000C2AF3800C28F3B
+:102940000000428C1800C2AF4000C28F2800C2AF06
+:10295000010002242800C38F07006210000000005D
+:10296000020002242800C38F0A0062100000000049
+:102970000D000010000000003800C28F2000C38F3F
+:102980001000428C211062002000C2AF060000102F
+:10299000000000003800C28F1400438C2000C28F5A
+:1029A000231062002000C2AFDC8082930B00401035
+:1029B000000000004547400F0000000007004010E5
+:1029C00000000000090002244C8282A3FFFF0224C1
+:1029D0002400C2AFB4000010000000003800C28F15
+:1029E0000400428C1400C2AF3800C38F1400C28FA1
+:1029F000080062AC3800C28F1400428C1400C2AFD1
+:102A00002000C38F1400C28F2B104300070040101A
+:102A1000000000001F0002244C8282A3FFFF032459
+:102A20002400C3AFA0000010000000003800C48FD5
+:102A30001800838CFBFF022424106200180082AC73
+:102A40003800C38F2000C28F100062AC2000C28FFC
+:102A50002C00C2AF2C00C28F040041040000000013
+:102A60002C00C38FFF0163242C00C3AF2C00C38F45
+:102A7000431203001000C2AF1000C28F401A0200C0
+:102A80002000C28F231043002000C2AF3800C38F44
+:102A90002000C28F0E0062A41800C28F1F00439056
+:102AA0001000C28F1B004300F401600012100000F0
+:102AB0001400C2AF1800C28F1F0043901400C28FD1
+:102AC000021862701000C28F231043001000C2AFC2
+:102AD0003800C38F1000C28F0C0062A41400C28F94
+:102AE00051004010000000003800C48F1400C58F52
+:102AF000EB33400F000000001C00C2A31C00C29377
+:102B000049004010000000001C00C3933C00022458
+:102B10003F006214000000003800C28F1800428C91
+:102B20000000427C1C004010000000003800C38FF1
+:102B30003800C28F0400428C080062AC1400C38FBE
+:102B40000100022408006210000000001400C28F7F
+:102B5000FFFF42243800C48F21284000EB33400F90
+:102B6000000000001C00C2A33800C48F2128000010
+:102B7000853E400F000000002B00401000000000C8
+:102B80000F0002244C8282A3FFFF02242400C2AF64
+:102B900045000010000000003800C38F3800C28FCD
+:102BA0000400428C080062AC1400C28FFFFF422474
+:102BB0003800C48F21284000EB33400F0000000094
+:102BC0001C00C2A31C00C2930700401000000000BC
+:102BD0000F0002244C8282A3FFFF03242400C3AF12
+:102BE00031000010000000003800C38F00020224F2
+:102BF0000E0062A43800C38F1800C28F1F004290DD
+:102C0000FFFF42240C0062A4070000100000000037
+:102C10000F0002244C8282A3FFFF02242400C2AFD3
+:102C200021000010000000003800C28F1800C48F7F
+:102C30000800458C8D45400F000000001400C2AF15
+:102C40003800C28F0C0042941000C2AF1400C38F32
+:102C50001000C28F211062001400C2AFD88080AF74
+:102C6000DE8080A31800C28F1400C48F0000458C42
+:102C7000695B400F000000000700401400000000E6
+:102C80001B0002244C8282A3FFFF03242400C3AF55
+:102C900005000010000000001400C28F188082AFF1
+:102CA0004C8280A32400C0AF2400C28F21E8C0035F
+:102CB0003400BF8F3000BE8F3800BD270800E0030E
+:102CC00000000000C0FFBD273C00BFAF3800BEAF12
+:102CD00021F0A0034000C4AF4400C5AFDE8080A354
+:102CE0004000C28F200042903000C2AF0100022499
+:102CF0003000C38F120062100000000003000224A5
+:102D00003000C38F03006210000000001D0000109F
+:102D1000000000004400C28F801002001400C2AF07
+:102D2000FF0F023CFFFF42342400C2AFFF0F023C02
+:102D3000F8FF42342800C2AF190000100000000064
+:102D40004400C38F21106000401002002110430096
+:102D50001400C2AF1400C28F010042301000C2A3A1
+:102D60001400C28F421002001400C2AFFFFF0234F1
+:102D70002400C2AFF80F02242800C2AF08000010E0
+:102D8000000000004400C28F401002001400C2AFD7
+:102D9000FFFF02342400C2AFF8FF02342800C2AFA4
+:102DA0004000C48F1400C28F421A02000800828CB7
+:102DB000211043001800C2AF1400C28FFF0142303F
+:102DC0001400C2AF1480838F1800C28F6C0062148D
+:102DD000000000004000C28F200043900300022446
+:102DE00009006214000000001400C38F00A0023C20
+:102DF000500F4224211062000000428C1C00C2AF20
+:102E0000C2000010000000004000C28F200043906C
+:102E10000200022409006214000000001400C38FA5
+:102E200000A0023C500F4224211062000000429496
+:102E30001C00C2AFB5000010000000004000C28FAF
+:102E40002000439001000224B00062140000000042
+:102E50001400C38F00A0023C500F422421106200D6
+:102E6000000042901C00C2AF1000C293040040104A
+:102E7000000000001C00C28F021102001C00C2AF43
+:102E80001400C28F01004224FF0142301400C2AF7F
+:102E90001400C28F2200401400000000D4808293EE
+:102EA0000D004010000000004000C48F21280000E9
+:102EB0002130000001000724534C400F00000000A7
+:102EC00005004010000000002400C28F2C00C2AF9B
+:102ED00097000010000000001800C28F010042247B
+:102EE0002120400000A0023C500F4524695B400FA8
+:102EF000000000000700401400000000FFFF023443
+:102F0000148082AF2400C28F2C00C2AF8800001052
+:102F1000000000001800C28F01004224148082AF1C
+:102F20001400C38F00A0023C500F42242110620005
+:102F3000000042902000C2AF1000C2930800401071
+:102F4000000000002000C28F001902001C00C28F88
+:102F5000211043001C00C2AF6C00001000000000F4
+:102F60002000C28F0F004230001A02001C00C28FE6
+:102F7000211043001C00C2AF6400001000000000DC
+:102F8000D48082930D004010000000004000C48FE8
+:102F9000212800002130000001000724534C400F7D
+:102FA0000000000005004010000000002400C28F57
+:102FB0002C00C2AF5E000010000000001800C48F9B
+:102FC00000A0023C500F4524695B400F0000000048
+:102FD0000700401400000000FFFF0234148082AF9D
+:102FE0002400C28F2C00C2AF51000010000000006E
+:102FF0001800C28F148082AF4000C28F200043901F
+:103000000300022409006214000000001400C38FB2
+:1030100000A0023C500F4224211062000000428CAC
+:103020001C00C2AF39000010000000004000C28F39
+:1030300020004390020002240900621400000000F6
+:103040001400C38F00A0023C500F422421106200E4
+:10305000000042941C00C2AF2C00001000000000D1
+:103060004000C28F20004390010002242700621418
+:10307000000000001400C38F00A0023C500F422447
+:1030800021106200000042901C00C2AF1000C293E9
+:1030900004004010000000001C00C28F021102005A
+:1030A0001C00C2AF1400C28F01004224FF01423055
+:1030B0001400C2AF1400C38F00A0023C500F422482
+:1030C00021106200000042902000C2AF1000C293A5
+:1030D00008004010000000002000C28F001902000C
+:1030E0001C00C28F211043001C00C2AF070000105B
+:1030F000000000002000C28F0F004230001A0200C2
+:103100001C00C28F211043001C00C2AF1C00C28FE4
+:103110002800C38F2B104300030040140000000060
+:103120002800C28F1C00C2AF1C00C28F2C00C2AF8F
+:103130002C00C28F21E8C0033C00BF8F3800BE8F37
+:103140004000BD270800E00300000000C8FFBD27C5
+:103150003400BFAF3000BEAF21F0A0033800C4AFD1
+:103160003C00C5AF4000C6AF2110E0004400C2A340
+:103170003800C28F20004390030002241000621028
+:10318000000000003800C28F20004390020002249B
+:103190000B006210000000003800C28F2000439036
+:1031A000010002240600621000000000FF0F023C34
+:1031B000FFFF42342400C2AF4101001000000000B4
+:1031C0003800C28F200042902800C2AF2800C38F71
+:1031D0000100622812004014000000002800C38F84
+:1031E000030062280C0040140000000003000224C9
+:1031F0002800C38F030062100000000008000010C8
+:1032000000000000FF0F023CFFFF42342000C2AF6D
+:103210000300001000000000FFFF02342000C2AFD6
+:10322000DE8080A34400C293240040100000000010
+:103230001000C0A31480828F1800C2AF3800C28F64
+:103240001E0043901000C2932B1043001700401043
+:10325000000000001480848F00A0023C500F452421
+:1032600021300000F15B400F000000000500401419
+:10327000000000002000C28F2400C2AF1001001027
+:10328000000000001000C293010042241000C2A3FD
+:103290003800C28F1C0043941800C28F21104300D5
+:1032A0001800C2AFE5FF001000000000D48080A32A
+:1032B0002400C0AF02010010000000003800C28FDF
+:1032C000200042902C00C2AF010002242C00C38FCA
+:1032D0000C00621000000000030002242C00C38FC9
+:1032E0000300621000000000130000100000000046
+:1032F0003C00C28F801002001400C2AF1100001009
+:10330000000000003C00C38F21106000401002004C
+:10331000211043001400C2AF1400C28F01004230DC
+:103320001100C2A31400C28F421002001400C2AFE9
+:1033300004000010000000003C00C28F401002009A
+:103340001400C2AF3800C48F1400C28F421A0200AA
+:103350000800828C211043001C00C2AF1400C28FF1
+:10336000FF0142301400C2AF1480838F1C00C28F53
+:103370003300621000000000D480829321004010CE
+:10338000000000001000C0A31480828F1800C2AF9C
+:103390003800C28F1E0043901000C2932B104300D0
+:1033A00017004010000000001480848F00A0023C31
+:1033B000500F452421300000F15B400F0000000059
+:1033C00005004014000000002000C28F2400C2AF9E
+:1033D000BB000010000000001000C2930100422456
+:1033E0001000C2A33800C28F1C0043941800C28F83
+:1033F000211043001800C2AFE5FF001000000000DC
+:10340000D48080A31C00C48F00A0023C500F452430
+:10341000695B400F0000000007004014000000003E
+:10342000FFFF0234148082AF2000C28F2400C2AF9D
+:10343000A3000010000000001C00C28F148082AFA7
+:103440003800C28F2000439003000224230062143E
+:10345000000000001400C38F00A0023C500F422463
+:10346000211862004000C28F000062A01400C38FC8
+:1034700000A0023C510F4224211862004000C28F7C
+:1034800000FF423002120200000062A01400C38F4D
+:1034900000A0023C520F4224212062004000C38F52
+:1034A000FF00023C2410620002140200000082A00F
+:1034B0001400C38F00A0023C530F4224212062005D
+:1034C0004000C38F000F023C24106200021602006D
+:1034D000000082A077000010000000003800C28FBA
+:1034E000200043900200022411006214000000003A
+:1034F0001400C38F00A0023C500F42242118620028
+:103500004000C28F000062A01400C38F00A0023CE4
+:10351000510F4224211862004000C28F00FF423048
+:1035200002120200000062A0620000100000000011
+:103530003800C28F20004390010002245D00621415
+:10354000000000001400C38F00A0023C500F422472
+:1035500021106200000042901200C2A31100C29329
+:103560000A004010000000004000C28F0F004230EF
+:10357000001902001200C2930F00423025106200B1
+:103580001200C2A303000010000000004000C28F20
+:103590001200C2A31400C38F00A0023C500F4224AB
+:1035A000211862001200C293000062A01400C28FB2
+:1035B00001004224FF0142301400C2AF1400C28F48
+:1035C0001F004014000000003800C48F21280000B4
+:1035D0002130000001000724534C400F0000000080
+:1035E00005004010000000002000C28F2400C2AF80
+:1035F00033000010000000001C00C28F01004224B4
+:103600002120400000A0023C500F4524695B400F80
+:10361000000000000700401400000000FFFF02341B
+:10362000148082AF2000C28F2400C2AF240000109B
+:10363000000000001C00C28F01004224148082AFF1
+:103640001400C38F00A0023C500F422421106200DE
+:10365000000042901200C2A31100C2930600401065
+:10366000000000004000C28F021102001200C2A33D
+:103670000A000010000000004000C28F0212020089
+:103680000F0044301200C393F0FF022424106200A4
+:1036900021188000251062001200C2A31400C38FFD
+:1036A00000A0023C500F4224211862001200C29375
+:1036B000000062A001000224D48082A32400C0AFD5
+:1036C0002400C28F21E8C0033400BF8F3000BE8FBA
+:1036D0003800BD270800E00300000000E8FFBD2718
+:1036E0001400BFAF1000BEAF21F0A0031800C4AF9C
+:1036F000212000001800C58F21300000C74D400F69
+:103700000000000021E8C0031400BF8F1000BE8F2E
+:103710001800BD270800E0030000000070FFBD276F
+:103720008800BFAF8400BEAF8000B0AF21F0A0031F
+:10373000211080009400C5AF9800C6AF9000C2A3CE
+:10374000010002241200C2A79400C28F1800C2AF69
+:103750002000C2277000C2AF7000C48F1C80858F0C
+:103760006D44400F000000004C8280A31800C28FFF
+:10377000000042901000C2A31000C2930700401442
+:10378000000000001F0002244C8282A3FFFF0224DD
+:103790007400C2AFC4010010000000001000C39309
+:1037A0007800C3AF2E0002247800C38F0700621098
+:1037B000000000005C0002247800C38FC10062108A
+:1037C0000000000007010010000000001800C28F78
+:1037D000010042241800C2AF1800C28F00004290BE
+:1037E0001000C2A31000C3932E0002248B006214A9
+:1037F000000000001800C28F010042241800C2AF70
+:103800001800C28F000042901000C2A37000C28F47
+:103810003400438C3C82828F070062140000000059
+:103820001F0002244C8282A3FFFF02247400C2AF57
+:103830009D010010000000007000C38F7000C28F57
+:103840003400428C380062AC010002241200C2A78E
+:103850001200C2277000C48F2128400001000624F6
+:10386000E73B400F000000001400C2AF1400C28FFD
+:1038700007004014000000001B0002244C8282A3B9
+:10388000FFFF03247400C3AF870100100000000095
+:103890007000D08F1400C48F4836400F0000000025
+:1038A000340002AE7000C38F7000C28F3400428CAF
+:1038B000380062AC7000C28F3400428C1C0040148F
+:1038C000000000007000C28F5C000324200043A0B1
+:1038D000010002241100C2A31100C2930B00422C6C
+:1038E0000B004010000000007000C38F1100C29355
+:1038F0002118620020000224200062A01100C2935F
+:10390000010042241100C2A3F3FF001000000000D8
+:103910007000C38F3C82828F380062AC7000C38F0E
+:103920003C82828F340062AC17000010000000005F
+:103930007000C38F2E000224200062A07000C38F8D
+:103940002E000224210062A0020002241100C2A362
+:103950001100C2930B00422C0B004010000000002D
+:103960007000C38F1100C29321186200200002244E
+:10397000200062A01100C293010042241100C2A3E2
+:10398000F3FF0010000000001200C0A71200C227C1
+:103990007000C48F2128400001000624E73B400F3F
+:1039A0000000000007004014000000001B0002247B
+:1039B0004C8282A3FFFF02247400C2AF3A010010C0
+:1039C000000000001000C3935C0002240900621490
+:1039D000000000001800C28F010042241800C2AF8E
+:1039E0001800C28F000042901000C2A3F5FF001023
+:1039F000000000001000C29368FF401400000000A7
+:103A00001C80848F7000C58F6D44400F0000000043
+:103A10007400C0AF24010010000000001000C29329
+:103A200008004014000000001C80848F7000C58FC7
+:103A30006D44400F000000007400C0AF1A01001078
+:103A4000000000001000C3935C0002241700621401
+:103A5000000000001000C3935C00022409006214FF
+:103A6000000000001800C28F010042241800C2AFFD
+:103A70001800C28F000042901000C2A3F5FF001092
+:103A8000000000001000C29344FF4014000000003A
+:103A90001C80848F7000C58F6D44400F00000000B3
+:103AA0007400C0AF00010010000000001F000224DD
+:103AB0004C8282A3FFFF03247400C3AFFA000010FE
+:103AC000000000001800C28F010042241800C2AF9D
+:103AD0001800C28F000042901000C2A31000C393D0
+:103AE0005C00022407006214000000001F00022492
+:103AF0004C8282A3FFFF02247400C2AFEA000010D0
+:103B0000000000001000C2931D00401400000000DF
+:103B10001C80838F3C82828F340062AC1C80838F38
+:103B20003C82828F380062AC1C80838F5C00022450
+:103B3000200062A0010002241100C2A31100C29360
+:103B40000B00422C0B004010000000001C80838FF3
+:103B50001100C2932118620020000224200062A0FC
+:103B60001100C293010042241100C2A3F3FF001010
+:103B7000000000007400C0AFCB0000100000000087
+:103B80007000C38F3C82828F340062AC7000C38FA0
+:103B90003C82828F380062AC7000C38F5C000224CC
+:103BA000200062A0010002241100C2A31100C293F0
+:103BB0000B00422CF9FE4010000000007000C38F83
+:103BC0001100C2932118620020000224200062A08C
+:103BD0001100C293010042241100C2A3F3FF0010A0
+:103BE000000000001100C0A31000C2931900401093
+:103BF000000000001000C3935C0002241500621056
+:103C0000000000001100C2930C00422C1100401073
+:103C10000000000000A0043C1100C39301006224D6
+:103C20001100C2A3FF006330040F82242118620038
+:103C30001000C293000062A01800C28F010042244D
+:103C40001800C2AF000042901000C2A3E6FF0010AF
+:103C5000000000001100C3930C0002240F00621446
+:103C6000000000001000C2930C0040100000000093
+:103C70001000C3935C0002240800621000000000E2
+:103C80001800C28F010042241800C2AF0000429009
+:103C90001000C2A3F3FF00100000000000A0023CCF
+:103CA0001100C393040F422421106200000040A0C1
+:103CB00000A0023C040F442421280000E748400FE4
+:103CC000000000000500401400000000FFFF032476
+:103CD0007400C3AF74000010000000001100C0A306
+:103CE0001100C2930B00422C17004010000000008E
+:103CF0001100C3931000C227212062007000C38FFF
+:103D00001100C2932110620020004290500082A056
+:103D10007000C38F1100C2932120620000A0023CFA
+:103D20001100C393040F422421106200000042904E
+:103D3000200082A01100C293010042241100C2A3FE
+:103D4000E7FF00100000000000A0023C28124424FD
+:103D50007000C58F6D44400F0000000000A0023CC1
+:103D6000281244247000C58F010006242138000069
+:103D70003D32400F0000000007004010000000002E
+:103D80000C0002244C8282A3FFFF02247400C2AF05
+:103D9000450000100000000000A0023C2812422450
+:103DA000300043941000022407006210000000005D
+:103DB0001F0002244C8282A3FFFF03247400C3AFC0
+:103DC00039000010000000001100C0A31100C293D0
+:103DD0000B00422C0F004010000000007000C38F49
+:103DE0001100C2932120620000A0023C1100C39385
+:103DF000281242242110620020004290200082A05C
+:103E00001100C293010042241100C2A3EFFF001071
+:103E1000000000007000C38F00A0023C2812422462
+:103E20000400428C340062AC7000C38F7000C28FFB
+:103E30003400428C380062AC1000C2930800401479
+:103E4000000000001C80848F7000C58F6D44400FFF
+:103E5000000000007400C0AF13000010000000005C
+:103E60001000C3935C0002244CFE621400000000AA
+:103E70001800C28F010042241800C2AF1800C28F80
+:103E8000000042901000C2A31000C293F4FF40143F
+:103E9000000000001C80848F7000C58F6D44400FAF
+:103EA000000000007400C0AF7400C28F21E8C0039E
+:103EB0008800BF8F8400BE8F8000B08F9000BD2728
+:103EC0000800E00300000000B0FFBD274C00BFAFBA
+:103ED0004800BEAF21F0A0035000C4AF5400C5AFEE
+:103EE0005000C28F05004010000000005400C28F37
+:103EF0004000C2A303000010000000000A000224DA
+:103F00004000C2A34000C2931000C2A300A0023C24
+:103F1000281242241C00C2AF2000C0A33000C0AF52
+:103F20004C8280A35000C28F0600401400000000A5
+:103F300000A0023C641242241400C2AF0B00001027
+:103F4000000000005000C28F1400C2AF5400C28FA6
+:103F500006004014000000001F0002244C8282A3CF
+:103F60003C00C0AFB3010010000000001000C3838C
+:103F70001400C28F21106200FFFF42241800C2AF5C
+:103F80001C00C48F1C80858F6D44400F0000000012
+:103F90001C00C28F200043802E0002249600621471
+:103FA000000000001C00C28F210043802E0002246C
+:103FB00091006214000000001C00C28F3400428C8B
+:103FC0002400C2AF010002242800C2A71C00C38F36
+:103FD0001C00C28F3400428C380062AC2800C2271B
+:103FE0001C00C48F2128400001000624E73B400F3D
+:103FF000000000003800C2AF3800C28F0600401435
+:10400000000000001B0002244C8282A33C00C0AFD1
+:1040100088010010000000003800C48F4836400FAF
+:1040200000000000448282AF4482828F0600401468
+:10403000000000001C00C38F3C82828F340062AC01
+:1040400004000010000000001C00C38F4482828F17
+:10405000340062AC1C00C38F1C00C28F3400428C41
+:10406000380062AC2800C0A72800C2271C00C48FFB
+:104070002128400001000624E73B400F000000001B
+:104080003800C2AF3800C28F0600401400000000A4
+:104090001B0002244C8282A33C00C0AF65010010CB
+:1040A000000000003800C48F4836400F00000000B8
+:1040B000448282AF4482838F2400C28F1600621430
+:1040C000000000004482838F2400C28F2A00621403
+:1040D000000000003800C28F00004390E500022479
+:1040E0000D006210000000003800C28F0B004390EA
+:1040F0000800022408006210000000003800C28F8F
+:104100000B0043900F000224030062100000000027
+:1041100019000010000000002800C297010042248E
+:104120002800C2A72800C2271C00C48F21284000F5
+:1041300021300000E73B400F000000003800C2AF14
+:104140003800C28F06004014000000001B0002244B
+:104150004C8282A33C00C0AF36010010000000007A
+:104160003800C48F4836400F00000000448282AF00
+:10417000D0FF0010000000002C00C0AF2C00C28F48
+:104180000B00422816004010000000001C00C38FE6
+:104190002C00C28F212062003800C38F2C00C28FF8
+:1041A0002110620000004290200082A01C80838FBA
+:1041B0002C00C28F212062003800C38F2C00C28FD8
+:1041C0002110620000004290200082A02C00C28FCB
+:1041D000010042242C00C2AFE8FF001000000000E4
+:1041E0001C00C38F2400C28F340062AC1C00C38F3C
+:1041F0002400C28F380062AC1C00C28F20004380B4
+:104200005C0002240A006214000000001400C38F46
+:104210005C000224000062A01400C28F010040A0D4
+:104220001400C28F3C00C2AF020100100000000069
+:104230001C00C28F3400438C3C82828F8400621049
+:10424000000000000A0002242100C2A31C00C38F4A
+:104250002100C2832110620020004380200002243C
+:1042600006006214000000002100C293FFFF4224F8
+:104270002100C2A3F5FF0010000000002100C2834E
+:10428000080042282D004014000000002100C283D5
+:104290000800422819004014000000003000C62722
+:1042A0000000C48C211880001400C28F21386200E5
+:1042B0001C00C58F2100C393FFFF62242100C2A30D
+:1042C0002014037C2110A200200042900000E2A0F4
+:1042D000010084240000C4AC1000C3833000C28FEE
+:1042E000EAFF6214000000003000C0AF01000224A9
+:1042F0002000C2A3E5FF0010000000003000C52729
+:104300000000A38C212060001400C28F21208200B5
+:104310002E000224000082A0010063240000A3AC50
+:104320001000C3833000C28F04006214000000003C
+:104330003000C0AF010002242000C2A31C00C38FC4
+:104340002100C2832110620020004380200002244B
+:1043500006006214000000002100C293FFFF422407
+:104360002100C2A3F5FF0010000000002100C2835D
+:1043700019004004000000003000C6270000C48C73
+:10438000211880001400C28F213862001C00C58FE4
+:104390002100C393FFFF62242100C2A32014037CE9
+:1043A0002110A200200042900000E2A0010084241D
+:1043B0000000C4AC1000C3833000C28FEBFF621456
+:1043C000000000003000C0AF010002242000C2A3A2
+:1043D000E6FF0010000000003000C5270000A38C9D
+:1043E000212060001400C28F212082005C00022482
+:1043F000000082A0010063240000A3AC1000C3836E
+:104400003000C28F04006214000000003000C0AF12
+:10441000010002242000C2A31C00C38F1C00C28F15
+:104420003400428C380062AC1C00C48F9451400FA1
+:10443000000000007EFF4010000000000800022481
+:104440004C8282A33C00C0AF7A0000100000000044
+:104450003000C28FFFFF42243000C2AF2C00C0AF3B
+:104460002000C2934C004010000000003000C28FBA
+:104470002A00C2A73000C28F2C00C38F2310430034
+:104480001B004018000000002C00C38F1400C28FD6
+:1044900021106200000042903400C2A32C00C38FA0
+:1044A0001400C28F212062003000C38F1400C28F1D
+:1044B0002110620000004290000082A03000C38FF3
+:1044C0001400C28F211862003400C293000062A061
+:1044D0003000C28FFFFF42243000C2AF2C00C28FD9
+:1044E000010042242C00C2AFE2FF001000000000D7
+:1044F0002A00C297010042242C00C2AF1800C38FCB
+:104500001400C28F231062003000C2AF3000C28F8F
+:104510002C00C38F231043001B0040180000000034
+:104520002C00C38F1400C28F211062000000429043
+:104530003400C2A32C00C38F1400C28F212062005C
+:104540003000C38F1400C28F21106200000042901F
+:10455000000082A03000C38F1400C28F21186200B7
+:104560003400C293000062A03000C28FFFFF4224DB
+:104570003000C2AF2C00C28F010042242C00C2AF19
+:10458000E2FF0010000000001800C28F000040A0F1
+:1045900026000010000000003000C28F2A00C2A7D1
+:1045A0003000C28F2C00C38F231043001B00401823
+:1045B000000000002C00C38F1400C28F2110620085
+:1045C000000042903400C2A32C00C38F1400C28F9D
+:1045D000212062003000C38F1400C28F21106200BE
+:1045E00000004290000082A03000C38F1400C28FF0
+:1045F000211862003400C293000062A03000C28F14
+:10460000FFFF42243000C2AF2C00C28F01004224C1
+:104610002C00C2AFE2FF0010000000002A00C29789
+:104620001400C38F21104300010040A01400C28F6A
+:104630003C00C2AF3C00C28F21E8C0034C00BF8FDA
+:104640004800BE8F5000BD270800E00300000000B6
+:10465000D8FFBD272400BFAF2000BEAF21F0A003CC
+:104660002800C4AF010002241200C2A71200C22712
+:104670002800C48F2128400001000624E73B400F9A
+:10468000000000001800C2AF1800C28F05004014DF
+:1046900000000000FF0002241C00C2AFA7000010B1
+:1046A000000000001800C48F4836400F00000000D2
+:1046B000448282AF4482828F1B00401400000000BD
+:1046C0002800C38F5C000224200062A01000C0A359
+:1046D0001000C2930B00422C0B00401000000000A1
+:1046E0002800C38F1000C29321186200200002240A
+:1046F000200062A01000C293010042241000C2A357
+:10470000F3FF0010000000002800C38F3C82828F5E
+:10471000340062AC2800C38F3C82828F380062ACC8
+:1047200085000010000000004482828F1400C2AF98
+:104730002800C38F4482828F340062AC2800C38F6C
+:104740004482828F380062AC1200C2272800C48FD6
+:104750002128400001000624E73B400F0000000034
+:104760001800C2AF1800C28F0500401400000000FE
+:10477000FF0002241C00C2AF700000100000000007
+:104780001800C48F4836400F00000000448282AFFA
+:104790004482828F06004014000000002800C38F6E
+:1047A0003C82828F340062AC0400001000000000E4
+:1047B0002800C38F4482828F340062AC2800C38FEC
+:1047C0002800C28F3400428C380062AC1200C0A7AF
+:1047D0001200C2272800C48F2128400001000624AF
+:1047E000E73B400F000000001800C2AF1800C28F66
+:1047F0000500401400000000FF0002241C00C2AFAE
+:104800004E000010000000001800C48F4836400F12
+:1048100000000000448282AF4482838F1400C28F64
+:1048200016006214000000004482838F1400C28FBF
+:1048300029006214000000001800C28F000043909D
+:10484000E50002240D006210000000001800C28F75
+:104850000B004390080002240800621000000000D2
+:104860001800C28F0B0043900F0002240300621057
+:104870000000000018000010000000001200C22715
+:104880002800C48F2128400021300000E73B400F62
+:10489000000000001800C2AF1800C28F05004014CD
+:1048A00000000000FF0002241C00C2AF2300001023
+:1048B000000000001200C297010042241200C2A7AB
+:1048C0001800C48F4836400F00000000448282AFB9
+:1048D000D1FF0010000000001000C0A31000C29320
+:1048E0000B00422C0E004010000000002800C38F77
+:1048F0001000C293212062001800C38F1000C293E1
+:104900002110430000004290200082A01000C293BA
+:10491000010042241000C2A3F0FF001000000000BC
+:104920002800C38F1400C28F340062AC2800C38FEC
+:104930001400C28F380062AC1C00C0AF1C00C28FD4
+:1049400021E8C0032400BF8F2000BE8F2800BD27B0
+:104950000800E00300000000E8FFBD271400BFAF1F
+:104960001000BEAF21F0A0031800C4AF212000004A
+:104970001800C58F213000006652400F0000000073
+:1049800021E8C0031400BF8F1000BE8F1800BD27A0
+:104990000800E00300000000C8FFBD273400BFAFDF
+:1049A0003000BEAF21F0A003211080003C00C5AF55
+:1049B0004000C6AF3800C2A33C00C28F1400C2AF93
+:1049C00000A0023C140F42242800C2AF4C8280A3F6
+:1049D0006B5C400F0000000007004010000000006A
+:1049E000180002244C8282A3FFFF02242C00C2AFD5
+:1049F00090010010000000001000C0A31400C28F3E
+:104A00000000428013004010000000001400C28F1C
+:104A1000000043802E0002240E00621000000000FF
+:104A20001400C28F000043805C0002240900621061
+:104A3000000000001400C28F010042241400C2AF25
+:104A40001000C293010042241000C2A3EBFF00102B
+:104A5000000000001000C2930900422C070040141F
+:104A6000000000001F0002244C8282A3FFFF0224EA
+:104A70002C00C2AF6F010010000000001400C28FB4
+:104A8000000043802E000224200062140000000079
+:104A90001400C28F010042241400C2AF1000C0A352
+:104AA0001400C28F000042800E0040100000000081
+:104AB0001400C28F000043805C00022409006210D1
+:104AC000000000001400C28F010042241400C2AF95
+:104AD0001000C293010042241000C2A3F0FF001096
+:104AE000000000001000C2930400422C0700401494
+:104AF000000000001F0002244C8282A3FFFF02245A
+:104B00002C00C2AF4B010010000000001400C28F47
+:104B1000000043805C0002240600621400000000D4
+:104B20001400C28F010042241400C2AFF7FF00102E
+:104B3000000000001400C28F00004280AEFF40144D
+:104B4000000000003C00C28F1400C2AF2800C48FD8
+:104B50001C80858F6D44400F000000001400C28F40
+:104B6000000042901000C2A31000C3932E00022444
+:104B700057006214000000001400C28F010042249C
+:104B80001400C2AF1400C28F000042901000C2A3F4
+:104B90001000C3932E0002240E00621000000000DB
+:104BA0001000C2930B004010000000001000C393DF
+:104BB0005C00022407006210000000001F000224B5
+:104BC0004C8282A3FFFF02242C00C2AF1901001007
+:104BD000000000001000C3932E0002242300621482
+:104BE000000000001C80828F3400438C3C82828F46
+:104BF00007006214000000001F0002244C8282A300
+:104C0000FFFF02242C00C2AF0A01001000000000C8
+:104C10001400C28F010042241400C2AF1400C28FDE
+:104C2000000042901000C2A31000C3935C00022455
+:104C30000A006210000000001000C293070040103C
+:104C4000000000001F0002244C8282A3FFFF022408
+:104C50002C00C2AFF700001000000000029D023CD3
+:104C6000A0054424B74D400F000000001000C3937E
+:104C70005C00022409006214000000001400C28FCE
+:104C8000010042241400C2AF1400C28F0000429001
+:104C90001000C2A3F5FF0010000000001000C29336
+:104CA000AEFF4014000000001C80848F2800C58FD8
+:104CB0006D44400F000000001F0002244C8282A3BC
+:104CC000FFFF02242C00C2AFDA0000100000000039
+:104CD0001000C3935C0002243B006214000000003B
+:104CE0001C80838F3C82828F340062AC1C80838F57
+:104CF0003C82828F380062AC1C80838F5C0002246F
+:104D0000200062A0010002241000C2A31000C29380
+:104D10000B00422C0B004010000000001C80838F11
+:104D20001000C2932118620020000224200062A01B
+:104D30001000C293010042241000C2A3F3FF001030
+:104D4000000000001400C28F010042241400C2AF12
+:104D50001400C28F000042901000C2A31000C39341
+:104D60005C0002240B006214000000001C80848F91
+:104D70002800C58F6D44400F000000001F00022472
+:104D80004C8282A3FFFF02242C00C2AFA9000010B6
+:104D9000000000001000C29370FF401400000000EB
+:104DA0001C80848F2800C58F6D44400F00000000D8
+:104DB0001F0002244C8282A3FFFF02242C00C2AFFA
+:104DC0009C000010000000002400C0A31400C28F4B
+:104DD000000042901000C2A31100C0A31000C293B3
+:104DE00019004010000000001000C3935C00022472
+:104DF00015006210000000001100C2930C00422C4C
+:104E000011004010000000001100C3930100622453
+:104E10001100C2A3FF0063301000C22721186200F6
+:104E20001000C293080062A01400C28F0100422447
+:104E30001400C2AF1400C28F000042901000C2A341
+:104E4000E6FF0010000000001100C3931000C2270D
+:104E500021106200080040A01800C3832E00022425
+:104E600023006214000000001900C2830F004010EC
+:104E7000000000001900C3832E0002240B00621002
+:104E8000000000001C80848F2800C58F6D44400FF7
+:104E9000000000001F0002244C8282A3FFFF0224B6
+:104EA0002C00C2AF63000010000000001900C38393
+:104EB0002E0002240E006214000000001A00C283BB
+:104EC0000B004010000000001C80848F2800C58F5C
+:104ED0006D44400F000000001F0002244C8282A39A
+:104EE000FFFF02242C00C2AF52000010000000009F
+:104EF0001800C22721204000B74D400F00000000DD
+:104F00000300401000000000170000100000000027
+:104F10001000C3935C00022409006214000000002A
+:104F20001400C28F010042241400C2AF1400C28FCB
+:104F3000000042901000C2A3F5FF00100000000026
+:104F40001000C293A1FF4014000000001C80848F59
+:104F50002800C58F6D44400F000000002C00C0AF3A
+:104F600034000010000000001800C227212040007B
+:104F70001454400F0000000009004014000000001D
+:104F80001C80848F2800C58F6D44400F00000000F6
+:104F9000FFFF02242C00C2AF26000010000000001A
+:104FA0001800C22721204000B74D400F000000002C
+:104FB0000B004010000000001C80848F2800C58F6B
+:104FC0006D44400F000000001B0002244C8282A3AD
+:104FD000FFFF02242C00C2AF1600001000000000EA
+:104FE0001400C28F000043805C0002240900621498
+:104FF000000000001400C28F010042241400C2AF60
+:105000001400C28F000042901000C2A3F4FF0010F1
+:10501000000000001000C2936CFF4014000000006C
+:105020001C80848F2800C58F6D44400F0000000055
+:105030002C00C0AF2C00C28F21E8C0033400BF8F0A
+:105040003000BE8F3800BD270800E00300000000DC
+:10505000C8FFBD273400BFAF3000BEAF21F0A003B2
+:105060003800C4AF00A0023C281242241000C2AF96
+:105070001800C0A72400C0A32400C2930C00422C37
+:105080000F0040100000000000A0023C2400C39369
+:10509000040F4224212062002400C3933800C28FF1
+:1050A0002110620000004290000082A02400C29300
+:1050B000010042242400C2A3EFFF00100000000002
+:1050C00000A0023C040F442421280000E748400FC0
+:1050D000000000000600401400000000120002243E
+:1050E0004C8282A32800C0AF6F00001000000000B7
+:1050F0002400C0A32400C2930B00422C0F004010D8
+:10510000000000001000C38F2400C2932120620021
+:1051100000A0023C2400C393040F4224211062002B
+:1051200000004290200082A02400C293010042248B
+:105130002400C2A3EFFF0010000000001000C38F86
+:105140001C80828F3400428C340062AC1000C38F0C
+:105150001C80828F3800428C380062AC1000C28FF5
+:10516000040040AC1000C28F080040AC1000C38F98
+:105170001C80828F0000428C000062AC1800C227A5
+:105180001000C48F2128400012000624CD3C400F9F
+:105190000000000004004010000000002800C0AF24
+:1051A0004100001000000000D48082930F004010E6
+:1051B000000000001000C28F0000448C2128000075
+:1051C0002130000001000724534C400F0000000074
+:1051D0000600401000000000090002244C8282A357
+:1051E0002800C0AF30000010000000001000C28F87
+:1051F0003400438C3C82828F040062140000000063
+:105200002000C0AF04000010000000001000C28F9A
+:105210003400428C2000C2AF1000C38F1000C28F38
+:105220003400428C380062AC1800C2271000C48FD2
+:105230002128400001000624E73B400F0000000049
+:105240001400C2AF1400C28F06004014000000001A
+:105250001B0002244C8282A32800C0AF1200001061
+:10526000000000001400C48F4836400F000000000A
+:105270001C00C2AF1000C28F0000448C1C00C58F00
+:105280002000C68FB154400F000000000500401000
+:1052900000000000010002242800C2AF020000103C
+:1052A000000000002800C0AF2800C28F21E8C00322
+:1052B0003400BF8F3000BE8F3800BD270800E003E8
+:1052C00000000000B0FFBD274C00BFAF4800BEAFDC
+:1052D00021F0A0035000C4AF5400C5AF5800C6AFC2
+:1052E0001800C2273800C2AFD88080AF2000022447
+:1052F0001200C2A75000C28F0000448C2128000079
+:1053000000020624276A400F000000002E0002243D
+:105310001800C2A3010002241000C2A71000C29707
+:105320000B00422C0B004010000000001000C3973F
+:105330001000C2272118620020000224080062A089
+:105340001000C297010042241000C2A7F3FF001012
+:1053500000000000100002242300C2A32400C0A308
+:105360005400C28F3200C2A75400C38FFF0F023C0B
+:1053700024106200021402002C00C2A73400C0AF47
+:10538000378282932500C2A3388282972600C2A763
+:10539000428282972800C2A72A00C0A72E00C0A779
+:1053A0003000C0A71000C0A71000C2971200C3971A
+:1053B0002B1043000F004010000000005000C28F6F
+:1053C0001000C3970000428C212062001000C39798
+:1053D0003800C28F2110620000004290000082A0BD
+:1053E0001000C297010042241000C2A7EEFF001077
+:1053F000000000002E0002241900C2A35800C28F32
+:105400003200C2A75800C38FFF0F023C2410620075
+:10541000021402002C00C2A71000C0A71000C297FF
+:105420001200C3972B104300110040100000000031
+:105430005000C28F1000C4971200C3970000428C26
+:1054400021106200212044001000C3973800C28F51
+:105450002110620000004290000082A01000C2975C
+:10546000010042241000C2A7ECFF00100000000061
+:105470005000C48F5400C58F8D45400F00000000C0
+:105480003C00C2AF5000C28F3C00C48F0000458C6E
+:1054900021300000F15B400F0000000006004014C6
+:1054A00000000000090002244C8282A34000C0AF2B
+:1054B0000300001000000000010002244000C2AF01
+:1054C0004000C28F21E8C0034C00BF8F4800BE8F50
+:1054D0005000BD270800E00300000000E8FFBD27E2
+:1054E0001400BFAF1000BEAF21F0A0031800C4AF7E
+:1054F0002110A0001C00C2A31C00C29321200000A8
+:105500001800C58F21300000213840004B55400F56
+:105510000000000021E8C0031400BF8F1000BE8F00
+:105520001800BD270800E00300000000B8FFBD27F9
+:105530004400BFAF4000BEAF21F0A003211880009F
+:105540004C00C5AF5000C6AF2110E0004800C3A317
+:105550005400C2A300A0023C140F42241000C2AFAA
+:1055600000A0023C281242241400C2AF1C00C0A7B5
+:10557000029D023CA405448CA40543240400638CD2
+:10558000A40542240800428C2800C4AF2C00C3AFFD
+:105590003000C2AF3400C0A34C8280A31000C48F7F
+:1055A0001C80858F6D44400F000000004C00C48FAC
+:1055B000B74D400F00000000070040100000000041
+:1055C0000C0002244C8282A3FFFF02243800C2AFE9
+:1055D00080020010000000001C80828F3400438C89
+:1055E0003C82828F09006210000000001C80828FC4
+:1055F0001000C38F3400448C3400628C030082108E
+:10560000000000000B000010000000001C80848FD0
+:105610001000C58F6D44400F000000001F000224E1
+:105620004C8282A3FFFF02243800C2AF690200103F
+:10563000000000001C00C297010042241C00C2A709
+:105640001C00C2271C80848F2128400001000624F2
+:10565000E73B400F000000001800C2AF1800C28FE7
+:105660000B004014000000001C80848F1000C58FC8
+:105670006D44400F000000001B0002244C8282A3F6
+:10568000FFFF02243800C2AF5202001000000000E9
+:105690001C00C297010042241C00C2A71C00C227A4
+:1056A0001C80848F2128400021300000E73B400F00
+:1056B000000000001800C2AF1800C28F0B00401499
+:1056C000000000001C80848F1000C58F6D44400FC7
+:1056D000000000001B0002244C8282A3FFFF022472
+:1056E0003800C2AF3B020010000000005400C2931B
+:1056F0002B004014000000001800C28F0000428000
+:10570000E8014010000000001800C28F0000439024
+:10571000E50002240B006210000000001C80848F52
+:105720001000C58F6D44400F0000000016000224D9
+:105730004C8282A3FFFF02243800C2AF2502001072
+:10574000000000001C00C297010042241C00C2A7F8
+:105750001C00C2271C80848F2128400021300000BB
+:10576000E73B400F000000001800C2AF1800C28FD6
+:10577000E1FF4014000000001C80848F1000C58FE2
+:105780006D44400F000000001B0002244C8282A3E5
+:10579000FFFF02243800C2AF0E020010000000001C
+:1057A000488280A32000C0A748828293BD01401494
+:1057B000000000001800C28F00004280EE00401080
+:1057C000000000001800C28F00004390E500022492
+:1057D000C1006210000000001800C28F0B0043904F
+:1057E00008000224BC006210000000001800C28FF4
+:1057F0000B0043900F000224B7006210000000006D
+:105800001800C28F0B004290100042307000401010
+:10581000000000002000C297010042242000C2A71F
+:105820002200C0A32200C2930800422C15004010A1
+:10583000000000001800C38F2200C2932110430013
+:1058400000004380200002240E00621000000000CF
+:105850002200C3931000C227212062001800C38FCA
+:105860002200C2932110430000004290180082A041
+:105870002200C293010042242200C2A3E9FF0010CB
+:10588000000000001800C28F08004380200002249E
+:1058900025006210000000002200C3930100622472
+:1058A0002200C2A3FF0063301000C227211862004B
+:1058B0002E000224180062A02300C0A32300C2937C
+:1058C0000300422C18004010000000001800C38F95
+:1058D0002300C293211062000800438020000224AC
+:1058E00011006210000000002200C3930100622436
+:1058F0002200C2A3FF0063301000C22721206200F3
+:105900001800C38F2300C293211062000800429048
+:10591000180082A02300C293010042242300C2A3E6
+:10592000E6FF0010000000002200C3931000C22711
+:1059300021106200180040A02800C227212040004A
+:10594000B74D400F000000000B00401000000000A9
+:105950001C80848F1000C58F6D44400F0000000034
+:105960000C0002244C8282A3FFFF02243800C2AF45
+:1059700098010010000000001C80828F1000C38F6F
+:105980003400448C3400628C0B0082140000000050
+:105990001C80848F1000C58F6D44400F00000000F4
+:1059A0001F0002244C8282A3FFFF02243800C2AFF2
+:1059B0008801001000000000020002241C00C2A7A1
+:1059C00001000224DF8082A34600001000000000D6
+:1059D0002800C22721204000212800000C000624B6
+:1059E000276A400F000000002200C0A32200C293DB
+:1059F0000B00422C0E004010000000001400C38F6A
+:105A00002200C293212062001800C38F2200C2939B
+:105A10002110430000004290200082A02200C29387
+:105A2000010042242200C2A3F0FF00100000000089
+:105A30001400C38F00A0023C04124224000062AC98
+:105A40001400C38F1C00C2972C0062A41400C38FE3
+:105A50001C80828F3400428C340062AC1400C38FEF
+:105A60001C80828F3800428C380062AC1400C28FD8
+:105A7000040040AC1400C28F080040AC1C00C227D8
+:105A80001400C48F2128400001000624CA40400FA2
+:105A9000000000000B004010000000001C80848FFC
+:105AA0001000C58F6D44400F00000000010002246B
+:105AB0004C8282A3FFFF02243800C2AF45010010D0
+:105AC000000000001C00C297010042241C00C2A775
+:105AD00004000010000000001C00C29701004224D6
+:105AE0001C00C2A7DF8082930F004010000000005E
+:105AF000DF8080A31C80838F1C80828F3400428CC7
+:105B0000380062AC1C00C2271C80848F2128400012
+:105B100001000624E73B400F000000001800C2AF60
+:105B200008000010000000001C00C2271C80848FA9
+:105B30002128400021300000E73B400F000000001A
+:105B40001800C2AF1800C28F17FF401400000000F9
+:105B50001C80848F1000C58F6D44400F0000000032
+:105B60001B0002244C8282A3FFFF02243800C2AF34
+:105B700018010010000000002000C297C50040106E
+:105B8000000000001E00C0A71C80838F1C80828F35
+:105B90003400428C380062AC1E00C2271C80848F07
+:105BA0002128400001000624E73B400F00000000D0
+:105BB0001800C2AF1800C28F0B0040140000000094
+:105BC0001C80848F1000C58F6D44400F00000000C2
+:105BD0001B0002244C8282A3FFFF02243800C2AFC4
+:105BE000FC000010000000001800C48F4836400F71
+:105BF000000000001E00C2A7029D023CA005442434
+:105C0000B74D400F000000000B00401000000000E6
+:105C10001C80848F1000C58F6D44400F0000000071
+:105C20000C0002244C8282A3FFFF02243800C2AF82
+:105C3000E800001000000000020002241C00C2A7BF
+:105C40001C80838F1C80828F3400428C380062ACB1
+:105C50001C00C2271C80848F2128400001000624DC
+:105C6000E73B400F000000001800C2AF1800C28FD1
+:105C70000B004014000000001C80848F1000C58FB2
+:105C80006D44400F000000001B0002244C8282A3E0
+:105C9000FFFF02243800C2AFCE0000100000000059
+:105CA0001800C48F4836400F00000000448282AFC5
+:105CB0001E00C3974482828F11006214000000000E
+:105CC0001E00C3974482828F2A00621400000000E5
+:105CD0001800C28F00004390E50002240800621003
+:105CE000000000001800C28F0B004390080002243F
+:105CF00003006210000000001E0000100000000001
+:105D00001C00C297010042241C00C2A71C00C2272D
+:105D10001C80848F2128400021300000E73B400F89
+:105D2000000000001800C2AF1800C28F0B00401422
+:105D3000000000001C80848F1000C58F6D44400F50
+:105D4000000000001B0002244C8282A3FFFF0224FB
+:105D50003800C2AF9F000010000000001800C48F80
+:105D60004836400F00000000448282AFD0FF001090
+:105D7000000000002800C227212040002128000048
+:105D80000C000624276A400F000000002200C0A378
+:105D90002200C2930B00422C0E00401000000000B5
+:105DA0002200C3931000C227212062001800C38F75
+:105DB0002200C2932110430000004290180082A0EC
+:105DC0002200C293010042242200C2A3F0FF00106F
+:105DD000000000002800C22721204000FC57400F8F
+:105DE000000000000B004010000000001C80848FA9
+:105DF0001000C58F6D44400F000000000100022418
+:105E00004C8282A3FFFF02243800C2AF7100001051
+:105E1000000000001C00C297010042241C00C2A721
+:105E20001C80838F1C80828F3400428C380062ACCF
+:105E30001C00C2271C80848F2128400001000624FA
+:105E4000E73B400F000000001800C2AF1800C28FEF
+:105E50000B004014000000001C80848F1000C58FD0
+:105E60006D44400F000000001B0002244C8282A3FE
+:105E7000FFFF02243800C2AF5600001000000000EF
+:105E80002000C297FFFF42242000C2A746FE001058
+:105E90000000000001000224488282A342FE00109C
+:105EA000000000002800C227212040000C0005242B
+:105EB000B24F400F00000000090040140000000035
+:105EC0001C80848F1000C58F6D44400F00000000BF
+:105ED000FFFF02243800C2AF3E00001000000000A7
+:105EE0002800C22721204000212800000C000624A1
+:105EF000276A400F000000002200C0A32200C293C6
+:105F00000B00422C0E004010000000002200C39342
+:105F10001000C227212062001C80838F2200C293C0
+:105F20002110620020004290180082A02200C2933B
+:105F3000010042242200C2A3F0FF00100000000074
+:105F4000029D023CA0054424B74D400F0000000014
+:105F50000B004010000000001C80848F1000C58FD3
+:105F60006D44400F000000000C0002244C8282A30C
+:105F7000FFFF02243800C2AF16000010000000002E
+:105F80002800C22721204000FC57400F00000000DD
+:105F90000B004010000000001C80848F1000C58F93
+:105FA0006D44400F00000000010002244C8282A3D7
+:105FB000FFFF02243800C2AF0600001000000000FE
+:105FC0001C80848F1000C58F6D44400F00000000BE
+:105FD0003800C0AF3800C28F21E8C0034400BF8F33
+:105FE0004000BE8F4800BD270800E003000000000D
+:105FF00098FFBD276400BFAF6000BEAF21F0A003D3
+:106000006800C4AF6B5C400F00000000050040104A
+:1060100000000000FFFF02245800C2AF4B00001038
+:10602000000000001800C227212040001C80858F3E
+:106030006D44400F000000001400C0A31400C29380
+:106040000B00422C0E004010000000001C80838FCB
+:106050001400C293212062001400C3936800C28F11
+:106060002110620000004290200082A01400C29320
+:10607000010042241400C2A3F0FF00100000000041
+:1060800000A0023C281244241C80858F6D44400FE0
+:10609000000000001C80848F00A0023C28124524D0
+:1060A00001000624213800003D32400F00000000AE
+:1060B0001000C2AF1000C28F0A00401000000000A4
+:1060C0001800C2271C80848F212840006D44400F97
+:1060D00000000000FFFF02245800C2AF1B000010A8
+:1060E000000000001C80828F2C0042241C80848FC2
+:1060F0002128400001000624CA40400F0000000093
+:106100001000C2AF1000C28F090040140000000050
+:106110001800C2271C80848F212840006D44400F46
+:10612000000000005800C0AF080000100000000090
+:106130001800C2271C80848F212840006D44400F26
+:1061400000000000FFFF02245800C2AF5800C28FB9
+:1061500021E8C0036400BF8F6000BE8F6800BD27C8
+:106160000800E0030000000098FFBD276400BFAFF7
+:106170006000BEAF21F0A0036800C4AF6C00C5AFE3
+:106180007000C6AF1000C2275000C2AF4C8280A37F
+:106190005000C28F200042246800C48F2128400094
+:1061A000010006244948400F000000000700401489
+:1061B00000000000120002244C8282A3FFFF022490
+:1061C0005C00C2AFF0000010000000007000C28F41
+:1061D000300040A05B00C0A35B00C2930C00422CC7
+:1061E00014004010000000005B00C3936800C28FE1
+:1061F00021106200000042800E00401000000000EC
+:106200007000C38F5B00C293212062005B00C393C8
+:106210006800C28F21106200000042901C0082A022
+:106220005B00C293010042245B00C2A3EAFF00109E
+:10623000000000007000C38F5B00C2932110620059
+:106240001C0040A07000C38F6C00C28F290062A0A8
+:106250007000C38F1C80828F3400428C2C0062AC93
+:106260005000C38F00A0023C04124224000062AC24
+:106270005000C28F040040AC5000C28F080040ACF8
+:106280005000C28F2C0040A45000C38F6C00C28FFE
+:10629000300062A45000C38F1C80828F3400428C77
+:1062A000340062AC5000C38F1C80828F3800428C57
+:1062B000380062AC00A0023C281244245000C58F74
+:1062C0006D44400F000000005000C48F00A0023C4D
+:1062D0002812452401000624010007243D32400F06
+:1062E000000000005400C2AF5400C28F07004010ED
+:1062F000000000000B0002244C8282A3FFFF022456
+:106300005C00C2AFA0000010000000005000C28F6F
+:106310002C0042945800C2A75800C2275000C48FD6
+:1063200021284000720006244933400F000000007D
+:106330005400C2AF5400C28F8F0040140000000010
+:106340005000C28F30004394080002245A006210AB
+:10635000000000005B00C0A35A00C0A35A00C29313
+:106360000800422C18004010000000005000C38FAD
+:106370005A00C293211062002000438020000224B2
+:1063800011006210000000007000C38F5B00C29318
+:10639000212043005000C38F5A00C2932110620095
+:1063A00020004290000082A05B00C29301004224C2
+:1063B0005B00C2A35A00C293010042245A00C2A348
+:1063C000E6FF0010000000005000C28F280043804C
+:1063D000200002240D006214000000005000C28F53
+:1063E00029004380200002240800621400000000FD
+:1063F0005000C28F2A004380200002240300621450
+:106400000000000009000010000000007000C48FB0
+:106410005B00C393010062245B00C2A3FF006230F3
+:10642000211844002E000224000062A0080002246B
+:106430005A00C2A35A00C2930B00422C180040100D
+:10644000000000005000C38F5A00C2932110620068
+:106450002000438020000224110062100000000090
+:106460007000C38F5B00C293212043005000C38F94
+:106470005A00C2932110620020004290000082A0C6
+:106480005B00C293010042245B00C2A35A00C29386
+:10649000010042245A00C2A3E6FF001000000000E1
+:1064A0007000C28F5B00C39321106200000040A007
+:1064B00017000010000000005B00C0A35B00C29347
+:1064C0000B00422C0E004010000000007000C38F33
+:1064D0005B00C293212043005000C38F5B00C29336
+:1064E0002110620020004290000082A05B00C29355
+:1064F000010042245B00C2A3F0FF00100000000076
+:106500007000C28F5B00C39321106200000040A0A6
+:106510007000C38F5000C28F300042940D0062A003
+:106520007000C38F5000C28F1400428C100062AC08
+:106530007000C48F5000C28F1E004294001C0200E5
+:106540005000C28F1C00429421106200140082ACE3
+:106550007000C38F5000C28F2C004294180062ACB0
+:106560007000C38F01000224300062A05C00C0AF45
+:1065700005000010000000001B0002244C8282A3D2
+:10658000FFFF02245C00C2AF5C00C28F21E8C003A1
+:106590006400BF8F6000BE8F6800BD270800E00365
+:1065A0000000000098FFBD276400BFAF6000BEAFD1
+:1065B00021F0A0036800C4AF1000C2275000C2AF92
+:1065C0004C8280A36800C28F3000429007004014C4
+:1065D00000000000070002244C8282A3FFFF022477
+:1065E0005C00C2AFD6000010000000006800C28F3F
+:1065F0001C80838F2C00448C3400628C0700821036
+:10660000000000001F0002244C8282A3FFFF02242E
+:106610005C00C2AFCA000010000000006800C28F1A
+:106620001C0043245000C28F20004224212060001F
+:1066300021284000010006244948400F00000000C6
+:106640000700401400000000120002244C8282A3C4
+:10665000FFFF02245C00C2AFB90000100000000080
+:106660005000C38F00A0023C04124224000062AC20
+:106670005000C28F040040AC5000C28F080040ACF4
+:106680005000C38F6800C28F1800428C0100422462
+:106690002C0062A45000C38F6800C28F2900429072
+:1066A000300062A45000C38F1C80828F3400428C63
+:1066B000340062AC5000C38F1C80828F3800428C43
+:1066C000380062AC00A0023C281244245000C58F60
+:1066D0006D44400F000000005000C48F00A0023C39
+:1066E0002812452401000624010007243D32400FF2
+:1066F000000000005400C2AF5400C28F07004010D9
+:10670000000000000B0002244C8282A3FFFF022441
+:106710005C00C2AF8A000010000000005000C28F71
+:1067200030004394080002245A0062100000000068
+:106730005800C0A35900C0A35900C2930800422CBE
+:1067400018004010000000005000C38F5900C29391
+:1067500021106200200043802000022411006210FA
+:10676000000000006800C38F5800C293212043003E
+:106770005000C38F5900C293211062002000429044
+:10678000000082A05800C293010042245800C2A316
+:106790005900C293010042245900C2A3E6FF001031
+:1067A000000000005000C28F280043802000022417
+:1067B0000D006214000000005000C28F29004380C9
+:1067C0002000022408006214000000005000C28F64
+:1067D0002A0043802000022403006214000000000D
+:1067E00009000010000000006800C48F5800C39327
+:1067F000010062245800C2A3FF0062302118440047
+:106800002E000224000062A0080002245900C2A346
+:106810005900C2930B00422C1800401000000000E9
+:106820005000C38F5900C2932110620020004380A2
+:106830002000022411006210000000006800C38FD5
+:106840005800C293212043005000C38F5900C293C7
+:106850002110620020004290000082A05800C293E4
+:10686000010042245800C2A35900C29301004224EF
+:106870005900C2A3E6FF0010000000006800C28FAC
+:106880005800C39321106200000040A017000010C0
+:10689000000000005800C0A35800C2930B00422C17
+:1068A0000E004010000000006800C38F5800C29323
+:1068B000212043005000C38F5800C2932110620072
+:1068C00020004290000082A05800C29301004224A0
+:1068D0005800C2A3F0FF0010000000006800C28F43
+:1068E0005800C39321106200000040A06800C38FCD
+:1068F0005000C28F300042940D0062A06800C38F28
+:106900005000C28F1400428C100062AC6800C48F2B
+:106910005000C28F1E004294001C02005000C28F23
+:106920001C00429421106200140082AC6800C38FE6
+:106930005000C28F2C004294180062AC5C00C0AFC3
+:106940005C00C28F21E8C0036400BF8F6000BE8F6F
+:106950006800BD270800E00300000000F0FFBD272D
+:106960000800BEAF21F0A00388BF023C1061428C3A
+:106970000001427C0000C2AF0000C38F00006238FB
+:106980000100422C0000C2AF0000C28F21E8C0030A
+:106990000800BE8F1000BD270800E00300000000C3
+:1069A000F8FFBD270000BEAF21F0A00300020224C3
+:1069B00021E8C0030000BE8F0800BD270800E003E7
+:1069C00000000000F8FFBD270000BEAF21F0A003CB
+:1069D0005082828F21E8C0030000BE8F0800BD27CF
+:1069E0000800E00300000000F8FFBD270000BEAF74
+:1069F00021F0A00388BF033C006162901000423484
+:106A0000006162A081BF033C60906290020042344A
+:106A1000609062A088BF033C5060629002004234E4
+:106A2000506062A088BF043C40608390FDFF022458
+:106A300024106200406082A088BF033C0061629025
+:106A400008004234006162A021E8C0030000BE8F4C
+:106A50000800BD270800E00300000000E8FFBD2794
+:106A60001400BFAF1000BEAF21F0A003955C400F33
+:106A70000000000088BF023C506043900200633475
+:106A8000506043A021E8C0031400BF8F1000BE8FE8
+:106A90001800BD270800E00300000000D0FFBD275C
+:106AA0002C00BFAF2800BEAF21F0A0033000C4AF60
+:106AB0002110A0003800C6AF3400C2A30800022491
+:106AC0001000C2A788BF043C50608390FDFF0224E1
+:106AD00024106200506082A0029D043C3400C393E5
+:106AE00021106000401002002110430080180200B5
+:106AF000B405822421106200000042902000C2A34D
+:106B00003800C28F1C00C2AF029D043C3400C39306
+:106B10002110600040100200211043008018020084
+:106B2000B405822421106200010042901800C2A323
+:106B30002000C28F400042342000C2AF2000C29328
+:106B400021204000A25C400F000000001F00C29303
+:106B500021204000A25C400F000000001E00C293F4
+:106B600021204000A25C400F000000001D00C293E5
+:106B700021204000A25C400F000000001C00C293D6
+:106B800021204000A25C400F000000001800C293CA
+:106B900021204000A25C400F00000000029D023C4A
+:106BA0003400C393B4054424211060004010020057
+:106BB0002110430080100200211044000400428C88
+:106BC0000F00401000000000029D023C3400C393FF
+:106BD000B40544242110600040100200211043003D
+:106BE00080100200211044000400438C01000224A4
+:106BF0000300621000000000100000100000000000
+:106C0000BC5C400F000000001400C2A31000C2973B
+:106C1000FFFF42241000C2A71400C393FF00022408
+:106C20001A006214000000001000C2971700401004
+:106C300000000000F2FF001000000000029D023C76
+:106C40003400C393B40544242110600040100200B6
+:106C50002110430080100200211044000400438CE6
+:106C6000020002240900621400000000BC5C400F16
+:106C700000000000BC5C400F000000001500C2A333
+:106C8000BC5C400F000000001400C2A3029D023C47
+:106C90003400C393B4054424211060004010020066
+:106CA0002110430080100200211044000400438C96
+:106CB000010002241F006214000000001400C0A3A1
+:106CC0001200C0A31200C393FF0002241900621037
+:106CD000000000001400C2931600401400000000E1
+:106CE000FFFF02241000C2A7BC5C400F00000000A0
+:106CF0001400C2A31000C297FFFF42241000C2A7D5
+:106D00001400C29306004014000000001000C29757
+:106D10000300401000000000F3FF0010000000001E
+:106D20001200C293010042241200C2A3E5FF00102A
+:106D300000000000FF000424A25C400F00000000DF
+:106D4000029D043C3400C3932110600040100200F7
+:106D50002110430080180200B40582242110620033
+:106D600008004290050040140000000088BF023C6B
+:106D70005060439002006334506043A01400C28FFF
+:106D80003000C38F000062AC3000C28F21E8C00326
+:106D90002C00BF8F2800BE8F3000BD270800E00305
+:106DA00000000000D0FFBD272C00BFAF2800BEAF01
+:106DB00021F0A0033000C4AF3400C5AF01000224AD
+:106DC0001900C2A33000C28F401202001C00C2AFE3
+:106DD0001400C22721204000070005241C00C68F94
+:106DE000A75A400F000000001400C2930D0040108D
+:106DF000000000001400C2272120400007000524E5
+:106E00001C00C68FA75A400F000000001400C29358
+:106E100004004010000000002000C0AF620000101D
+:106E200000000000FF0202241000C2A7400002245C
+:106E30001200C2A71200C297060040100000000016
+:106E40001200C297FFFF42241200C2A7F9FF0010F0
+:106E500000000000BC5C400F000000001800C2A34E
+:106E60001000C297FFFF42241000C2A74000022476
+:106E70001200C2A71200C2970600401000000000D6
+:106E80001200C297FFFF42241200C2A7F9FF0010B0
+:106E9000000000001800C393FF00022406006214E3
+:106EA000000000001000C297030040100000000026
+:106EB000E8FF0010000000001000C297070040101B
+:106EC000000000001800C393FE00022403006214B7
+:106ED0000000000004000010000000001900C0A322
+:106EE00028000010000000001000C0A71000C2978A
+:106EF0000002422C1D004010000000003400C28F30
+:106F0000130040100000000080BF033CFF0002247B
+:106F1000205A62AC80BF023C105A428C0000427C76
+:106F20000300401400000000FAFF00100000000001
+:106F30001000C3973400C28F2118620080BF023C4A
+:106F4000205A428C000062A00300001000000000E4
+:106F5000BC5C400F000000001000C29701004224FA
+:106F60001000C2A7E1FF001000000000FF00042491
+:106F7000A25C400F00000000FF000424A25C400F50
+:106F800000000000FF000424A25C400F000000008D
+:106F900088BF033C5060629002004234506062A09F
+:106FA0001900C2932000C2AF2000C28F21E8C003A5
+:106FB0002C00BF8F2800BE8F3000BD270800E003E3
+:106FC00000000000D8FFBD272400BFAF2000BEAFE7
+:106FD00021F0A0032800C4AF2C00C5AF2110C000D1
+:106FE0003000C2A3010002241800C2A32800C28FEF
+:106FF00007004014000000003000C2930400401459
+:10700000000000001800C0A3610000100000000094
+:107010001400C3272800C28F401202002120600004
+:107020000900052421304000A75A400F000000004D
+:107030001400C29304004010000000001800C0A318
+:107040004F00001000000000FE000424A25C400F6E
+:10705000000000001000C0A71000C2970002422CE0
+:10706000160040100000000080BF043C1000C397D1
+:107070002C00C28F2110620000004290205A82AC86
+:1070800080BF023C105A428C0000427C0300401436
+:1070900000000000FAFF00100000000080BF023C6A
+:1070A000205A428C1200C2A31000C2970100422451
+:1070B0001000C2A7E8FF001000000000FF00042439
+:1070C000A25C400F00000000FF000424A25C400FFF
+:1070D00000000000BC5C400F000000001200C2A3D2
+:1070E0001200C2930F004330050002240400621016
+:1070F000000000001800C0A31E00001000000000E7
+:107100001000C0A780BF033CFF000224205A62ACDD
+:1071100080BF023C105A428C0000427C03004014A5
+:1071200000000000FAFF00100000000080BF023CD9
+:10713000205A428C1200C2A31000C29701004224C0
+:107140001000C2A71200C293060040140000000005
+:107150001000C2970300401000000000E9FF00107B
+:10716000000000001000C297020040140000000060
+:107170001800C0A3FF000424A25C400F0000000020
+:1071800088BF023C5060439002006334506043A0CB
+:107190001800C29321E8C0032400BF8F2000BE8FD7
+:1071A0002800BD270800E00300000000F8FFBD270D
+:1071B0000000BEAF21F0A00388BF023C1061428CEA
+:1071C000C000427CFF00423021E8C0030000BE8FB7
+:1071D0000800BD270800E00300000000F0FFBD2705
+:1071E0000800BEAF21F0A003211080001000C2A350
+:1071F0001000C2930000C2A30000C293FFFF42240C
+:107200000000C2A3FF004330FF0002240C00621004
+:1072100000000000471D02240400C2AF0400C28F1A
+:10722000FFFF4224211840000400C3AFFFFF0224E7
+:10723000F1FF621000000000F8FF001000000000E5
+:107240000000000021E8C0030800BE8F0800E00332
+:107250001000BD27F8FFBD270000BEAF21F0A0033E
+:1072600080BF033C80BF023C105A428CFF7F4230FB
+:10727000105A62AC21E8C0030000BE8F0800BD2791
+:107280000800E00300000000E0FFBD271C00BFAFC6
+:107290001800BEAF21F0A003211080002000C2A37F
+:1072A00080BF023C105A428CC000427C0300401454
+:1072B00000000000FAFF00100000000080BF033C47
+:1072C0002000C293205A62AC0A7E400F00000000EA
+:1072D0001000C2A32110000021E8C0031C00BF8FD2
+:1072E0001800BE8F2000BD270800E003000000004A
+:1072F000E8FFBD271400BFAF1000BEAF21F0A00310
+:1073000080BF023C105A428CC000427C03004014F3
+:1073100000000000FAFF00100000000080BF033CE6
+:10732000FF000224205A62AC0A7E400F00000000D9
+:10733000FF00423021E8C0031400BF8F1000BE8F51
+:107340001800BD270800E00300000000F8FFBD277B
+:107350000000BEAF21F0A0030800C4AF80BF023C14
+:10736000105A40AC80BF033C005A62904000423447
+:10737000005A62A080BF043C015A8390FEFF0224A1
+:1073800024106200015A82A088BF043C806183906F
+:10739000BFFF022424106200806182A088BF043CE9
+:1073A00081618390FEFF022424106200816182A02B
+:1073B00088BF043C8061839080FF02242510620016
+:1073C000806182A080BF043C015A839080FF022428
+:1073D00025106200015A82A021E8C0030000BE8F80
+:1073E0000800BD270800E00300000000C0FFBD2723
+:1073F0003C00BFAF3800BEAF21F0A0030100022463
+:107400001200C2A3030002241800C2A788BF033CD5
+:107410005060629002004234506062A080BF023C23
+:107420003000C2AF9303023C008742341C00C2AF5D
+:107430000600023C801A42342000C2AF2000C28FF6
+:10744000401802001C00C28F1B004300F4016000C2
+:10745000121000002800C2AF2000C28F40180200A6
+:107460001C00C28F1B004300F401600010100000DC
+:1074700004004010000000002800C28F01004224D8
+:107480002800C2AF2800C28F0101422C0300401423
+:1074900000000000000102242800C2AF2800C28FB3
+:1074A00004004010000000002800C28FFFFF4224AB
+:1074B0002800C2AF2800C28FFF0042302400C2AFB4
+:1074C0002400C28FFF0042303000C38F305A62ACBC
+:1074D00080BF033C005A629020004234005A62A0F0
+:1074E00020000424D35C400F0000000001000424AD
+:1074F000775C400F000000001000C0A71000C2978A
+:107500000A00422C0900401000000000FF00042483
+:10751000A25C400F000000001000C297010042244E
+:107520001000C2A7F5FF00100000000088BF043C57
+:1075300050608390FDFF022424106200506082A0FE
+:1075400001000424775C400F000000001400C227F3
+:10755000212040002128000021300000A75A400FC0
+:10756000000000001400C393FF0002240800621012
+:10757000000000001400C293F70043300100022411
+:1075800003006214000000000A0000100000000068
+:107590001200C0A388BF033C5060629002004234D6
+:1075A000506062A01200C2932C00C2AF7D00001098
+:1075B00000000000FF0F02241000C2A71400C22721
+:1075C000212040000100052421300000A75A400F6F
+:1075D000000000001000C297FFFF42241000C2A765
+:1075E0001400C29306004010000000001000C29773
+:1075F0000300401000000000F0FF00100000000039
+:107600001000C29708004014000000001200C0A340
+:1076100088BF023C5060439002006334506043A036
+:107620005E0000100000000002000424775C400FA0
+:107630000000000080BF023C3400C2AF9303023C54
+:10764000008742342800C2AF3101023C002D423491
+:107650002400C2AF2400C28F401802002800C28F4D
+:107660001B004300F4016000121000001C00C2AFB8
+:107670002400C28F401802002800C28F1B00430064
+:10768000F401600010100000040040100000000031
+:107690001C00C28F010042241C00C2AF1C00C28F1C
+:1076A0000101422C030040140000000000010224EC
+:1076B0001C00C2AF1C00C28F04004010000000007C
+:1076C0001C00C28FFFFF42241C00C2AF1C00C28FEF
+:1076D000FF0042302000C2AF2000C28FFF004230C6
+:1076E0003400C38F305A62AC80BF033C60C00234A8
+:1076F000005A62AC80BF033C005A629020004234C2
+:10770000005A62A01400C227212040001000052466
+:1077100021300000A75A400F000000001400C227CB
+:10772000212040000600052400020624A75A400F2D
+:1077300000000000FF0002241000C2A71000C29742
+:107740000E00401000000000212000002128000051
+:10775000695B400F00000000211840000100022476
+:1077600006006210000000001000C297FFFF4224D4
+:107770001000C2A7F1FF0010000000001000C29727
+:1077800006004014000000001200C0A388BF023CA5
+:107790005060439002006334506043A01200C293D3
+:1077A0002C00C2AF2C00C28F21E8C0033C00BF8F69
+:1077B0003800BE8F4000BD270800E0030000000035
+:1077C00000E85D4100681A4000701B4090FFBD2733
+:1077D0006C00BBAF00601B4082D21A006800BBAFD8
+:1077E000847A5B7F12D000006400BAAF10D0000032
+:1077F0006000BAAF44201B7C00609B405C00BFAFC0
+:107800005800BEAF5400B9AF5000B8AF4C00AFAF96
+:107810004800AEAF4400ADAF4000ACAF3C00ABAFF2
+:107820003800AAAF3400A9AF3000A8AF2C00A7AF32
+:107830002800A6AF2400A5AF2000A4AF1C00A3AF72
+:107840001800A2AF21F0A0031081828F1000C2AFF8
+:10785000010002241000C38F3400621000000000F9
+:107860001000C38F020062280600401000000000D4
+:107870001000C28F09004010000000006F000010CF
+:1078800000000000020002241000C38F2F006210CD
+:107890000000000069000010000000000B0004243C
+:1078A0008660400F00000000E48082AFE480828F99
+:1078B0001B00401800000000EC80838FE480828F62
+:1078C00021106200EC8082AFE880828F01004224A8
+:1078D000E88082AFE880828F0A00422810004014BE
+:1078E00000000000EC80848F6666023C67664234CC
+:1078F000180082001010000083180200C317040053
+:10790000231062007C8282AFE88080AFEC8080AF81
+:1079100001000224108182AF480000100000000026
+:10792000108180AF45000010000000007C82848F31
+:107930001460400F000000005C8282AF020002244D
+:10794000108182AF3D00001000000000555F400F25
+:1079500000000000108180AF88BF023C5061428C63
+:107960000000427C0600401000000000E080828F92
+:1079700001004224E08082AF0200001000000000FD
+:10798000E08080AF898182831500401400000000F0
+:1079900088BF023C5060428CC000427C060040140C
+:1079A0000000000001000224898182A32080828FD0
+:1079B0000A004224208082AF88BF023C5060428C83
+:1079C0008000427C060040140000000001000224F8
+:1079D000898182A32080828FF6FF4224208082AF9B
+:1079E000AC818283150040140000000088BF023C77
+:1079F0005060428CC003427C06004014000000002E
+:107A000001000224AC8182A3FC80828F0100422409
+:107A1000FC8082AF88BF023C5060428C0001427CF7
+:107A2000060040140000000001000224AC8182A383
+:107A3000FC80828FFFFF4224FC8082AF80BF023C2B
+:107A4000100840AC88BF033C00010224341062AC33
+:107A500021E8C0035C00BF8F5800BE8F5400B98F6F
+:107A60005000B88F4C00AF8F4800AE8F4400AD8FF0
+:107A70004000AC8F3C00AB8F3800AA8F3400A98F38
+:107A80003000A88F2C00A78F2800A68F2400A58F78
+:107A90002000A48F1C00A38F1800A28F00606041FB
+:107AA000C00000006400BA8F130040036000BA8F6A
+:107AB000110040036C00BA8F00709A406800BA8FC2
+:107AC0007000BD2700609A401800004200E85D4148
+:107AD000F4FFBD2700601B400800BBAF04201B7CE7
+:107AE000001C7B3700609B4021F0A0030081828F47
+:107AF0000000C2AF010002240000C38F2D006210FD
+:107B0000000000000000C38F020062280600401041
+:107B1000000000000000C28F0900401000000000BB
+:107B20003F00001000000000020002240000C38F8C
+:107B30002E0062100000000039000010000000005C
+:107B40006482828F0F004014000000007082828FD8
+:107B500004004018000000007082828FFFFF422462
+:107B6000708282AF8482828F04004018000000007F
+:107B70008482828FFFFF4224848282AF010002242C
+:107B8000648282AF88BF043C1061828C2880838F1E
+:107B90008410627C106182AC80BF033C050002242B
+:107BA000200A62AC01000224008182AF1C00001098
+:107BB000000000006482828F050040100000000079
+:107BC00088BF023C1061439002006334106143A0FF
+:107BD00080BF023C0A000324200A43AC02000224B6
+:107BE000008182AF0E000010000000006482828FCE
+:107BF000060040100000000088BF043C1061839024
+:107C0000FDFF022424106200106182A080BF033CAB
+:107C10002480828F200A62AC008180AF648280AFB2
+:107C200080BF023C100A40AC88BF033C0010022415
+:107C3000341062AC21E8C0030800BA8F00609A409B
+:107C400018000042E8FFBD271400BFAF1000BEAF10
+:107C500021F0A0032080828F048182AF2080828F58
+:107C60000F00422803004010000000000F00022413
+:107C7000208082AF2080828FD107422803004014E9
+:107C800000000000D0070224208082AF2080848F73
+:107C9000EE78400F000000002130400021386000E5
+:107CA000029D023C0007448C0407458CC177400FBD
+:107CB00000000000029D063C2120400021286000B9
+:107CC0000C07C78C0807C68CEC75400F000000003D
+:107CD00021204000212860008679400F000000002C
+:107CE000248082AFF480828F1000401000000000DA
+:107CF00088BF043C10618390FEFF022424106200C0
+:107D0000106182A02080828F100042280B0040105A
+:107D10000000000088BF023C106143900100633402
+:107D2000106143A0050000100000000088BF023C65
+:107D30001061439001006334106143A021E8C00347
+:107D40001400BF8F1000BE8F1800BD270800E0038D
+:107D500000000000E8FFBD271400BFAF1000BEAF59
+:107D600021F0A003FC80828F02004104000000008B
+:107D7000FC8080AFFC80828F2D01422803004014DC
+:107D8000000000002C010224FC8082AFA0818283CD
+:107D90001900401400000000FC80848FCC7B400F51
+:107DA000000000005C82848F21284000317C400F5D
+:107DB0000000000003004004000000000700001065
+:107DC0000000000088BF023C506143900100633412
+:107DD000506143A00D0000100000000088BF043C6B
+:107DE00050618390FEFF022424106200506182A043
+:107DF000060000100000000088BF043C5061839022
+:107E0000FEFF022424106200506182A088818283D8
+:107E10002600401400000000FC80828FF6FF422400
+:107E200021204000CC7B400F000000005C82848F4A
+:107E300021284000317C400F000000001200400467
+:107E400000000000FC80828F0A00422421204000B4
+:107E5000CC7B400F00000000212040005C82858F19
+:107E6000317C400F000000000700400400000000CB
+:107E7000FC80828F64004228030040140000000050
+:107E80000800001000000000F48080AF88BF023CB2
+:107E90001061439001006334106143A0030000109F
+:107EA0000000000001000224F48082AF88818383F7
+:107EB000010002242C00621400000000FC80828F6C
+:107EC000FFFF422421204000CC7B400F0000000037
+:107ED0005C82848F21284000317C400F000000002C
+:107EE0001800400400000000FC80828F0100422442
+:107EF00021204000CC7B400F0000000021204000EA
+:107F00005C82858F317C400F000000000D00400432
+:107F100000000000FC80828F6400422809004014A9
+:107F2000000000005C82848F21280000317C400F1B
+:107F300000000000030040100000000008000010D6
+:107F400000000000F48080AF88BF023C10614390C5
+:107F500001006334106143A0030000100000000022
+:107F600001000224F48082AF6C818383010002242B
+:107F70001900621400000000FC80828FFBFF422485
+:107F800021204000CC7B400F000000005C82848FE9
+:107F900021284000317C400F000000000300400415
+:107FA00000000000080000100000000088BF043C32
+:107FB00010618390DFFF022424106200106182A010
+:107FC000050000100000000088BF023C10614390D3
+:107FD00020006334106143A0029D023C5C82848FC8
+:107FE0001007458C317C400F00000000030040105A
+:107FF000000000000400001000000000212000002C
+:10800000B060400F00000000029D023C5C82848F43
+:108010001407458C317C400F000000000300401025
+:1080200000000000040000100000000021200000FB
+:10803000B060400F0000000021E8C0031400BF8FB3
+:108040001000BE8F1800BD270800E00300000000EC
+:10805000D0FFBD272800BFAF2400BEAF2000B0AFC7
+:1080600021F0A0033000C4AF3000C28F1C004228B2
+:108070000800401000000000029D023C1807428CDE
+:108080001000C2AF1000C28F1800C2AF5A0000101B
+:10809000000000003000C28FFF0342280C00401493
+:1080A00000000000E080828F330042280800401466
+:1080B00000000000029D023C1C07428C1000C2AF71
+:1080C0001000C28F1800C2AF4B000010000000006B
+:1080D0001400C0AF1400C28F1F0042284600401099
+:1080E00000000000029D043C1400C28F80180200B2
+:1080F00080068224211062000000428C808282AFC0
+:108100003000C38F8082828F2A10430035004010D8
+:10811000000000008082828F548282AF029D043C66
+:108120001400C28F80180200800682242110620091
+:10813000FCFF428C788282AF7882838F5482828F58
+:1081400023106200688282AF3000C38F5482828F16
+:1081500023106200748282AF7482848FCC7B400FC4
+:1081600000000000218040006882848FCC7B400F9B
+:10817000000000002120000221284000417B400F28
+:1081800000000000588282AF029D023C5882848F1A
+:108190002007458CD37A400F00000000588282AF40
+:1081A0001400C38F211060008010020021104300D2
+:1081B0004010020021204000CC7B400F0000000056
+:1081C000212040005882858F367A400F0000000041
+:1081D0001000C2AF1000C28F1800C2AF060000101E
+:1081E000000000001400C28F010042241400C2AF3E
+:1081F000B8FF0010000000001800C28F21E8C00383
+:108200002800BF8F2400BE8F2000B08F3000BD2714
+:108210000800E00300000000F0FFBD270800BEAF2B
+:1082200021F0A0031000C4AF81BF043C4090828CB9
+:108230001000C38F049C627C409082AC81BF033CE1
+:108240000090629002004234009062A00000C0AF33
+:108250000000C28FC8004228060040100000000045
+:108260000000C28F010042240000C2AFF8FF0010DE
+:108270000000000081BF043C00908390FDFF0224B9
+:1082800024106200009082A081BF023C0090428CCA
+:108290000000427C0300401400000000FAFF0010C0
+:1082A0000000000081BF023C7090428C21E8C003B6
+:1082B0000800BE8F1000BD270800E003000000008A
+:1082C000F0FFBD270800BEAF21F0A0031000C4AF2F
+:1082D0001000C28F010042380100422C0000C2AFE2
+:1082E000010002240000C38F100062100000000093
+:1082F0000000C38F0200622806004010000000004A
+:108300000000C28F1D004010000000003900001066
+:1083100000000000020002240000C38F2C00621045
+:1083200000000000330000100000000088BF043C83
+:1083300010618390FEFF022424106200106182A06D
+:1083400088BF033C00010224641062AC88BF033C78
+:1083500000010224681062AC88BF033C00100224B4
+:10836000641062AC88BF033C00100224681062AC49
+:10837000E08080AF1F0000100000000088BF043CB8
+:1083800050618390FEFF022424106200506182A09D
+:1083900088BF033C1061629001004234106162A00A
+:1083A00088BF033C00010224641062AC88BF023C19
+:1083B000681040AC88BF033C00100224641062AC1B
+:1083C00088BF023C681040AC0A00001000000000AA
+:1083D00088BF033C1061629001004234106162A0CA
+:1083E00088BF033C00100224641062AC88BF023CCA
+:1083F000681040AC21E8C0030800BE8F1000BD2704
+:108400000800E00300000000D0FFBD272C00BFAF34
+:108410002800BEAF21F0A00388BF043C0061839018
+:10842000FDFF022424106200006182A088BF043C8A
+:1084300000618390FBFF022424106200006182A08F
+:1084400088BF043C00618390FEFF02242410620078
+:10845000006182A0137E400F000000001000C2AF38
+:1084600088BF023C0030428C0003427C1C00C2AF3B
+:108470000B0040140000000088BF033C00100224E1
+:10848000083062AC88BF023C0030428C0003427C62
+:108490000300401400000000FAFF0010000000007C
+:1084A0001C00C28F1800C2AF1800C28F1400C2AFE8
+:1084B00081BF023C30F240AC81BF033C99AA023C30
+:1084C0005566423430F262AC81BF033C6655023CD3
+:1084D000AA99423430F262AC81BF033C1800023CDE
+:1084E00008F062AC81BF023C04F040AC81BF033CA9
+:1084F0003333023C3333423430F262AC1400C28F67
+:108500001C00C2AF1C00C28F15004010000000000C
+:1085100088BF023C0030428C0003427C2000C2AF86
+:108520000B0040140000000088BF033C0010022430
+:10853000083062AC88BF023C0030428C0003427CB1
+:108540000300401400000000FAFF001000000000CB
+:108550002000C28F1800C2AF04000010000000000D
+:1085600088BF033C00100224043062AC1000C48FAA
+:10857000227E400F0000000080BF023C000840AC9B
+:1085800080BF033C70000224080862AC80BF023C3C
+:10859000100840AC80BF033CF4010224200862AC08
+:1085A00088BF033C1C000224B41062AC88BF033CAB
+:1085B00010000224B81062AC88BF033C0001022402
+:1085C000341062AC80BF033C00800234080862AC07
+:1085D00088BF033C00010224641062AC88BF023CE7
+:1085E000681040AC80BF023C000A40AC80BF033C36
+:1085F00010000224080A62AC80BF023C100A40ACA2
+:1086000080BF033C88130224200A62AC88BF033C6D
+:108610001C000224C41062AC88BF033C1C0002246E
+:10862000C81062AC157E400F0000000088BF033CFC
+:1086300000100224341062AC80BF033C008002347E
+:10864000080A62AC88BF033C00100224641062ACCC
+:1086500088BF023C681040AC88BF033C1061629048
+:1086600001004234106162A06C8180A34C8180A320
+:1086700021E8C0032C00BF8F2800BE8F3000BD272B
+:108680000800E00300000000E0FFBD271C00BFAFB2
+:108690001800BEAF21F0A0031000C0AF21200000E1
+:1086A0003564400F0000000088BF023C5060428CDF
+:1086B000C000427C0300401400000000FAFF0010DC
+:1086C00000000000208080AFFC8080AF2563400F59
+:1086D0000000000001000424B060400F0000000012
+:1086E00088BF023C9061428C4002437C010002241E
+:1086F0002F00621400000000115F400F0000000016
+:108700001000C28F010042241000C2AF1000C28FBF
+:10871000E9034228F2FF4014000000002563400FE7
+:108720000000000088BF023C5060428CC000427CC8
+:1087300004004014000000002080828F0A004224C0
+:10874000208082AF88BF023C5060428C8000427C17
+:1087500004004014000000002080828FF6FF4224B5
+:10876000208082AF88BF023C5060428CC003427CB4
+:108770000400401400000000FC80828F01004224AD
+:10878000FC8082AF88BF023C5060428C0001427C7A
+:108790000400401400000000FC80828FFFFF422490
+:1087A000FC8082AF1000C0AFCDFF001000000000C1
+:1087B00021200000B060400F0000000021E8C0034D
+:1087C0001C00BF8F1800BE8F2000BD270800E003EB
+:1087D00000000000F0FFBD270800BEAF21F0A0039D
+:1087E0001000C4AF0000C0AF1000C28F801802009C
+:1087F0000000C28F2A1043000C004010000000004F
+:108800000000000000000000000000000000000068
+:108810000000000000000000000000000000C28F07
+:1088200001004224F0FF00100000C2AF21E8C003A5
+:108830000800BE8F0800E0031000BD27E8FFBD2739
+:108840001400BFAF1000BEAF21F0A0031800C4AFEA
+:108850001800C28FE8030324021043702120400057
+:10886000F561400F0000000021E8C0031400BF8F35
+:108870001000BE8F1800BD270800E00300000000B4
+:10888000F8FFBD270000BEAF21F0A0038481828FD6
+:108890001C0040100000000088BF023C1061428CA8
+:1088A0000000427C1700401400000000288080AFC8
+:1088B0007082828F0A004014000000006082828F64
+:1088C0000500401400000000E8030224708282AF1B
+:1088D00003000010000000006082828F708282AF6F
+:1088E00090030224248082AF7082828F030040189C
+:1088F00000000000FCFF0010000000000100022446
+:10890000288082AF21E8C0030000BE8F0800BD2789
+:108910000800E00300000000E8FFBD271400BFAF1F
+:108920001000BEAF21F0A0038481828F310040107F
+:108930000000000088BF023C1061428C0000427CB5
+:108940002C0040140000000001000224288082AFA7
+:108950008482828F0A004014000000006C82828FA3
+:108960000500401400000000E8030224848282AF66
+:1089700003000010000000006C82828F848282AFAE
+:1089800090030224248082AF8482828F03004018E7
+:1089900000000000FCFF0010000000002080848F19
+:1089A000EE78400F000000002130400021386000C8
+:1089B000029D023C2807448C2C07458CC177400F50
+:1089C00000000000029D063C21204000212860009C
+:1089D0003407C78C3007C68CEC75400F00000000D0
+:1089E00021204000212860008679400F000000000F
+:1089F000248082AF21E8C0031400BF8F1000BE8F17
+:108A00001800BD270800E00300000000E8FFBD27B4
+:108A10001400BFAF1000BEAF21F0A0032120000062
+:108A200021280000029D023C141546242138000034
+:108A30001965400F00000000010004241C000524FB
+:108A400000A0023CBC044624213800001965400FF8
+:108A5000000000000200042421280000029D023CC6
+:108A600028154624213800001965400F0000000039
+:108A70000300042421280000029D023C38154624EE
+:108A8000213800001965400F000000005480838FDA
+:108A90000200022408006214000000000400042404
+:108AA00021280000029D023C441546242138000084
+:108AB0001965400F0000000021E8C0031400BF8FBB
+:108AC0001000BE8F1800BD270800E0030000000062
+:108AD000D0FFBD272C00BFAF2800BEAF21F0A00300
+:108AE0001000C427029D023C501545243480868F17
+:108AF000666D400F00000000020004245A000524A7
+:108B00001000C627213800001965400F0000000042
+:108B10001C81828F3E004018000000001C81848F61
+:108B2000CC7B400F00000000029D033C2120400050
+:108B30006815658C417B400F000000002000C2AF2B
+:108B40002000C48F1F79400F00000000213040003A
+:108B5000213860001000C427029D023C54154524B2
+:108B6000666D400F00000000030004244B00052444
+:108B70001000C627213800001965400F00000000D2
+:108B80002080848FCC7B400F00000000212040001B
+:108B90001F79400F00000000029D063C212040008C
+:108BA000212860007415C78C7015C68CF776400FAD
+:108BB0000000000021204000212860004879400F7B
+:108BC00000000000888282AF8882848F1F79400F66
+:108BD0000000000021304000213860001000C42750
+:108BE000029D023C54154524666D400F00000000B4
+:108BF000040004244B0005241000C627213800007F
+:108C00001965400F0000000008000010000000007F
+:108C1000030004244B000524029D023C60154624F9
+:108C2000213800001965400F00000000E322400FCA
+:108C3000000000001823400F000000005480838FC4
+:108C4000020002240D006214000000006D63400F5A
+:108C500000000000AC81828303004010000000008F
+:108C60001A64400F000000008981828303004010D5
+:108C700000000000D163400F0000000021E8C003A5
+:108C80002C00BF8F2800BE8F3000BD270800E003F6
+:108C900000000000E8FFBD271400BFAF1000BEAF0A
+:108CA00021F0A0032120000021280000029D023CA9
+:108CB00014154624213800001965400F00000000FB
+:108CC0000100042421280000029D023C781546245E
+:108CD000213800001965400F0000000088BF023CE9
+:108CE0005061428C0000427C0A00401000000000ED
+:108CF0000500042421280000029D023C8C15462416
+:108D0000213800001965400F000000000800001025
+:108D1000000000000500042421280000029D023C00
+:108D200098154624213800001965400F0000000006
+:108D3000029D023C5C82848FB815458C317C400FCB
+:108D40000000000003004004000000000A000010C2
+:108D5000000000000300042421280000029D023CC2
+:108D6000A4154624213800001965400F00000000BA
+:108D70000400001000000000030004249A64400F67
+:108D8000000000001A64400F000000006D63400FF7
+:108D900000000000D163400F0000000021E8C00384
+:108DA0001400BF8F1000BE8F1800BD270800E0031D
+:108DB00000000000D0FFBD272C00BFAF2800BEAFD1
+:108DC00021F0A003029D023C5C82848FF415458C47
+:108DD000317C400F000000000A004010000000003D
+:108DE000029D023C5C82848FF815458C317C400FDB
+:108DF00000000000030040100000000026000010EA
+:108E000000000000070004249A64400F00000000E6
+:108E1000029D023C5C82848FF415458C317C400FAE
+:108E200000000000030040100000000008000010D7
+:108E300000000000070004240A000524029D023CF3
+:108E4000BC154624213800001965400F00000000C1
+:108E5000029D023C5C82848FF815458C317C400F6A
+:108E60000000000003004010000000002F00001070
+:108E700000000000070004240A000524029D023CB3
+:108E8000D0154624213800001965400F000000006D
+:108E900026000010000000005C82848FF67B400FEB
+:108EA000000000002000C2AF1000C427029D023C59
+:108EB000E41545242000C68F666D400F00000000B9
+:108EC000070004242D0005241000C62721380000C7
+:108ED0001965400F0000000088BF023C5061428CC1
+:108EE0000000427C0A00401000000000070004243B
+:108EF00023000524029D023CEC1546242138000085
+:108F00001965400F0000000008000010000000007C
+:108F10000700042423000524029D023CF01546248A
+:108F2000213800001965400F0000000021E8C0034F
+:108F30002C00BF8F2800BE8F3000BD270800E00343
+:108F400000000000D0FFBD272C00BFAF2800BEAF3F
+:108F500021F0A0032080848F6666023C676642345D
+:108F6000180082001010000083180200C3170400CC
+:108F7000231062002000C2AF1000C427029D023CF3
+:108F8000FC1545242000C68F666D400F00000000D0
+:108F900007000424550005241000C62721380000CE
+:108FA0001965400F0000000004000424212800007F
+:108FB000029D023C44154624213800001965400FEB
+:108FC000000000002080848FCC7B400F0000000058
+:108FD000212040001F79400F00000000029D063C48
+:108FE00021204000212860000C16C78C0816C68C72
+:108FF000F776400F0000000021204000212860008B
+:109000004879400F00000000888282AF8882848FF8
+:109010001F79400F0000000021304000213860001F
+:109020001000C427029D023C54154524666D400F74
+:1090300000000000040004244B0005241000C62793
+:10904000213800001965400F00000000898180A3CD
+:1090500021E8C0032C00BF8F2800BE8F3000BD2741
+:109060000800E00300000000D8FFBD272400BFAFC8
+:109070002000BEAF21F0A003FC80828F02004104DB
+:1090800000000000FC8080AF1000C427029D023C5D
+:10909000E4154524FC80868F666D400F00000000BB
+:1090A00007000424212800001000C62721380000F2
+:1090B0001965400F00000000AC8180A321E8C003C7
+:1090C0002400BF8F2000BE8F2800BD270800E003CA
+:1090D00000000000E0FFBD271C00BFAF1800BEAFBE
+:1090E00021F0A003211080002000C2A31000C0A323
+:1090F0001000C2930800422C200040100000000025
+:10910000B0FF03241000C29321106200FF00423020
+:1091100021204000AD68400F000000002120000029
+:10912000AD68400F0000000010000424AD68400F3F
+:10913000000000001100C0A31100C2830A00400417
+:10914000000000002000C29321204000CF68400FA3
+:10915000000000001100C293010042241100C2A3CC
+:10916000F5FF0010000000001000C293010042242F
+:109170001000C2A3DEFF00100000000021E8C003C1
+:109180001C00BF8F1800BE8F2000BD270800E00321
+:1091900000000000E0FFBD271C00BFAF1800BEAFFD
+:1091A00021F0A003211080002400C5AF2000C2A33D
+:1091B000B0FF03242000C29321106200FF00423060
+:1091C00021204000AD68400F000000002120000079
+:1091D000AD68400F0000000010000424AD68400F8F
+:1091E000000000001000C0A31000C2932400C38F31
+:1091F0002A10430009004010000000001800042459
+:10920000CF68400F000000001000C293010042240C
+:109210001000C2A3F4FF0010000000002400C28F61
+:109220001000C2A31000C283090040040000000027
+:1092300021200000CF68400F000000001000C29302
+:10924000010042241000C2A3F6FF0010000000003D
+:1092500021E8C0031C00BF8F1800BE8F2000BD276F
+:109260000800E00300000000E0FFBD271C00BFAFC6
+:109270001800BEAF21F0A003211080002000C2A37F
+:10928000B0FF03242000C29321106200FF0042308F
+:1092900021204000AD68400F0000000021200000A8
+:1092A000AD68400F0000000010000424AD68400FBE
+:1092B000000000001000C0A31000C2830900400499
+:1092C0000000000021200000CF68400F00000000D7
+:1092D0001000C293010042241000C2A3F6FF001048
+:1092E0000000000021E8C0031C00BF8F1800BE8FE3
+:1092F0002000BD270800E00300000000D8FFBD27C4
+:109300002400BFAF2000BEAF21F0A00321108000D9
+:109310002800C2A32800C2931C00C2AF010002248F
+:109320001C00C38F15006210000000001C00C38FDA
+:109330000200622806004010000000001C00C28FDE
+:1093400009004010000000001400001000000000A0
+:10935000020002241C00C38F0D00621000000000F8
+:109360000E00001000000000029D023C380742245D
+:109370001400C2AF0900001000000000029D023C72
+:10938000380B42241400C2AF04000010000000009B
+:10939000029D023C380F42241400C2AF1000C0A34B
+:1093A0001000C2930800422C28004010000000006A
+:1093B0001000C293C01102001800C2AFB0FF032416
+:1093C0001000C29321106200FF00423021204000B3
+:1093D000AD68400F0000000021200000AD68400F84
+:1093E0000000000010000424AD68400F00000000E1
+:1093F0001100C0A31100C2830F0040040000000050
+:109400001100C3931400C28F211862001800C28F8C
+:10941000211062000000429021204000CF68400FE0
+:10942000000000001100C293010042241100C2A3F9
+:10943000F0FF0010000000001000C2930100422461
+:109440001000C2A3D6FF00100000000021E8C003F6
+:109450002400BF8F2000BE8F2800BD270800E00336
+:1094600000000000D0FFBD272C00BFAF2800BEAF1A
+:1094700021F0A0033000C4AF3400C5AF3800C6AF40
+:109480002110E0003C00C2A31C00C0AF3400C28F1A
+:109490001000C2A31000C2930F0042301100C2A3FB
+:1094A0001000C29302110200100042341200C2A345
+:1094B0003000C28FB0FF032421106200FF00423051
+:1094C00021204000AD68400F000000001100C29351
+:1094D00021204000AD68400F000000001200C29340
+:1094E00021204000AD68400F000000001400C0AF14
+:1094F0001400C38F3800C28F211062000000429018
+:1095000097004010000000001400C38F3800C28F85
+:1095100021106200000042905300422C14004010C1
+:10952000000000002000C5271400C38F3800C28F40
+:109530002110620000004490211080008018020079
+:1095400021186400029D023C3813422460FF42242B
+:10955000211062002120A0002128400005000624DF
+:10956000CD69400F000000003C000010000000002A
+:109570001400C38F3800C28F211062000000429097
+:109580007F00422C2E004010000000001400C38F0A
+:109590003800C28F21106200000042905C00422C13
+:1095A00014004014000000002000C5271400C38FE1
+:1095B0003800C28F2110620000004490211080000A
+:1095C0008018020021186400029D023C38144224D5
+:1095D0005CFE4224211062002120A00021284000CE
+:1095E00005000624CD69400F000000001B0000109C
+:1095F000000000002000C5271400C38F3800C28F70
+:1096000021106200000044902110800080180200A8
+:1096100021186400029D023C3814422461FE422459
+:10962000211062002120A00021284000050006240E
+:10963000CD69400F0000000008000010000000008D
+:109640002000C22721204000029D023C38134524FF
+:1096500005000624CD69400F000000001800C0AFCF
+:109660001800C28F050042283200401000000000A0
+:109670001C00C28F800042281B0040100000000028
+:109680003C00C2930A004014000000001800C38F81
+:109690001000C227211043001000429021204000FA
+:1096A000CF68400F000000000A000010000000001A
+:1096B0001800C38F1000C2272110430010004290F1
+:1096C00027100200FF00423021204000CF68400FE9
+:1096D000000000001C00C28F010042241C00C2AF29
+:1096E0000F000010000000003000C28FB1FF032403
+:1096F00021106200FF00423021204000AD68400F81
+:10970000000000001800C38F1000C2272110430082
+:109710001000429021204000CF68400F0000000060
+:109720001800C28F010042241800C2AFCCFF001005
+:109730000000000021200000CF68400F0000000062
+:109740001C00C28F010042241C00C2AF1400C28F53
+:10975000010042241400C2AF65FF001000000000A9
+:1097600021E8C0032C00BF8F2800BE8F3000BD272A
+:109770000800E00300000000E8FFBD271400BFAFB1
+:109780001000BEAF21F0A003212000003564400F7F
+:1097900000000000212000000A000524029D023C78
+:1097A00014154624213800001965400F0000000000
+:1097B0000100042414000524029D023C10164624D6
+:1097C000213800001965400F000000000200042449
+:1097D00014000524029D023C18164624213800007E
+:1097E0001965400F00000000030004241400052444
+:1097F000029D023C24164624213800001965400FC2
+:10980000000000000400042414000524029D023C12
+:1098100030164624213800001965400F0000000072
+:109820000500042414000524029D023C3C16462435
+:10983000213800001965400F0000000021E8C00336
+:109840001400BF8F1000BE8F1800BD270800E00372
+:1098500000000000E8FFBD271400BFAF1000BEAF3E
+:1098600021F0A003212000003564400F000000001B
+:10987000212000000A000524029D023C1415462404
+:10988000213800001965400F000000000100042489
+:1098900020000524029D023C4C164624213800007D
+:1098A0001965400F00000000020004242128000078
+:1098B000029D023C54164624213800001965400FD1
+:1098C000000000000300042421280000029D023C47
+:1098D00060164624213800001965400F0000000082
+:1098E0000400042421280000029D023C6C1646243A
+:1098F000213800001965400F000000000500042415
+:1099000021280000029D023C7816462421380000E0
+:109910001965400F00000000060004242128000003
+:10992000029D023C80164624213800001965400F34
+:10993000000000000700042421280000029D023CD2
+:1099400088164624213800001965400F00000000E9
+:1099500021E8C0031400BF8F1000BE8F1800BD2780
+:109960000800E00300000000E8FFBD271400BFAFBF
+:109970001000BEAF21F0A003212000003564400F8D
+:1099800000000000212000000A000524029D023C86
+:1099900014154624213800001965400F000000000E
+:1099A0000100042414000524029D023C9016462464
+:1099B000213800001965400F0000000021E8C003B5
+:1099C0001400BF8F1000BE8F1800BD270800E003F1
+:1099D00000000000E8FFBD271400BFAF1000BEAFBD
+:1099E00021F0A003010004249A64400F000000004D
+:1099F0000100042414000524029D023C3016462474
+:109A0000213800001965400F0000000021E8C00364
+:109A10001400BF8F1000BE8F1800BD270800E003A0
+:109A200000000000E8FFBD271400BFAF1000BEAF6C
+:109A300021F0A003212000003564400F0000000049
+:109A40000100042421280000029D023CA0164624A7
+:109A5000213800001965400F0000000021E8C00314
+:109A60001400BF8F1000BE8F1800BD270800E00350
+:109A700000000000D8FFBD272400BFAF2000BEAF0C
+:109A800021F0A0032800C4AF2C00C5AF3000C6AF42
+:109A90002110E0003400C2A3212000003564400FF3
+:109AA000000000000100042421280000029D023C67
+:109AB000B4164624213800001965400F000000004C
+:109AC0002800C48F1F79400F0000000021304000A3
+:109AD000213860001000C427029D023CC0164524B6
+:109AE000666D400F000000000300042421280000E0
+:109AF0001000C627213800001965400F0000000043
+:109B00002C00C48F1F79400F00000000213040005E
+:109B1000213860001000C427029D023CC81645246D
+:109B2000666D400F0000000004000424212800009E
+:109B30001000C627213800001965400F0000000002
+:109B40003400C28313004010000000003000C48FB6
+:109B50001F79400F000000002130400021386000D4
+:109B60001000C427029D023CD0164524666D400FAC
+:109B70000000000005000424212800001000C62772
+:109B8000213800001965400F000000000800001097
+:109B9000000000000500042421280000029D023C72
+:109BA000D8164624213800001965400F0000000037
+:109BB00021E8C0032400BF8F2000BE8F2800BD27EE
+:109BC0000800E00300000000E8FFBD271400BFAF5D
+:109BD0001000BEAF21F0A003212000003564400F2B
+:109BE000000000002120000021280000029D023C0E
+:109BF000E4164624213800001965400F00000000DB
+:109C00000200042421280000029D023CF016462494
+:109C1000213800001965400F0000000004000424F2
+:109C200021280000029D023C001746242138000034
+:109C30001965400F0000000021E8C0031400BF8F29
+:109C40001000BE8F1800BD270800E00300000000D0
+:109C5000E8FFBD271400BFAF1000BEAF21F0A00386
+:109C60001800C4AF1C00C5AF2110C0002000C2A363
+:109C70001800C28F0800422C730140100000000041
+:109C80001800C28F80180200029D023C181742245F
+:109C9000211062000000428C08004000000000001B
+:109CA0002000C393010004241C00C58F029D023CC8
+:109CB00010174624213860001965400F000000008D
+:109CC000020004241C00C58F029D023C1417462488
+:109CD000213800001965400F000000000300042433
+:109CE0001C00C58F029D023C141746242138000039
+:109CF0001965400F00000000040004241C00C58FFB
+:109D0000029D023C14174624213800001965400FBB
+:109D100000000000050004241C00C58F029D023CC9
+:109D200014174624213800001965400F0000000078
+:109D3000060004241C00C58F029D023C1417462413
+:109D4000213800001965400F0000000007000424BE
+:109D50001C00C58F029D023C1417462421380000C8
+:109D60001965400F000000003701001000000000DE
+:109D7000010004241C00C58F029D023C14174624D8
+:109D8000213800001965400F000000002000C39337
+:109D9000020004241C00C58F029D023C10174624BB
+:109DA000213860001965400F000000000300042402
+:109DB0001C00C58F029D023C141746242138000068
+:109DC0001965400F00000000040004241C00C58F2A
+:109DD000029D023C14174624213800001965400FEB
+:109DE00000000000050004241C00C58F029D023CF9
+:109DF00014174624213800001965400F00000000A8
+:109E0000060004241C00C58F029D023C1417462442
+:109E1000213800001965400F0000000007000424ED
+:109E20001C00C58F029D023C1417462421380000F7
+:109E30001965400F00000000030100100000000041
+:109E4000010004241C00C58F029D023C1417462407
+:109E5000213800001965400F0000000002000424B2
+:109E60001C00C58F029D023C1417462421380000B7
+:109E70001965400F000000002000C3930300042474
+:109E80001C00C58F029D023C10174624213860003B
+:109E90001965400F00000000040004241C00C58F59
+:109EA000029D023C14174624213800001965400F1A
+:109EB00000000000050004241C00C58F029D023C28
+:109EC00014174624213800001965400F00000000D7
+:109ED000060004241C00C58F029D023C1417462472
+:109EE000213800001965400F00000000070004241D
+:109EF0001C00C58F029D023C141746242138000027
+:109F00001965400F00000000CF00001000000000A5
+:109F1000010004241C00C58F029D023C1417462436
+:109F2000213800001965400F0000000002000424E1
+:109F30001C00C58F029D023C1417462421380000E6
+:109F40001965400F00000000030004241C00C58FA9
+:109F5000029D023C14174624213800001965400F69
+:109F6000000000002000C393040004241C00C58FDF
+:109F7000029D023C10174624213860001965400FED
+:109F800000000000050004241C00C58F029D023C57
+:109F900014174624213800001965400F0000000006
+:109FA000060004241C00C58F029D023C14174624A1
+:109FB000213800001965400F00000000070004244C
+:109FC0001C00C58F029D023C141746242138000056
+:109FD0001965400F000000009B0000100000000009
+:109FE000010004241C00C58F029D023C1417462466
+:109FF000213800001965400F000000000200042411
+:10A000001C00C58F029D023C141746242138000015
+:10A010001965400F00000000030004241C00C58FD8
+:10A02000029D023C14174624213800001965400F98
+:10A0300000000000040004241C00C58F029D023CA7
+:10A0400014174624213800001965400F0000000055
+:10A050002000C393050004241C00C58F029D023C10
+:10A0600010174624213860001965400F00000000D9
+:10A07000060004241C00C58F029D023C14174624D0
+:10A08000213800001965400F00000000070004247B
+:10A090001C00C58F029D023C141746242138000085
+:10A0A0001965400F0000000067000010000000006C
+:10A0B000010004241C00C58F029D023C1417462495
+:10A0C000213800001965400F000000000200042440
+:10A0D0001C00C58F029D023C141746242138000045
+:10A0E0001965400F00000000030004241C00C58F08
+:10A0F000029D023C14174624213800001965400FC8
+:10A1000000000000040004241C00C58F029D023CD6
+:10A1100014174624213800001965400F0000000084
+:10A12000050004241C00C58F029D023C1417462420
+:10A13000213800001965400F000000002000C39383
+:10A14000060004241C00C58F029D023C1017462403
+:10A15000213860001965400F00000000070004244A
+:10A160001C00C58F029D023C1417462421380000B4
+:10A170001965400F000000003300001000000000CF
+:10A18000010004241C00C58F029D023C14174624C4
+:10A19000213800001965400F00000000020004246F
+:10A1A0001C00C58F029D023C141746242138000074
+:10A1B0001965400F00000000030004241C00C58F37
+:10A1C000029D023C14174624213800001965400FF7
+:10A1D00000000000040004241C00C58F029D023C06
+:10A1E00014174624213800001965400F00000000B4
+:10A1F000050004241C00C58F029D023C1417462450
+:10A20000213800001965400F0000000006000424FA
+:10A210001C00C58F029D023C141746242138000003
+:10A220001965400F000000002000C39307000424BC
+:10A230001C00C58F029D023C101746242138600087
+:10A240001965400F0000000021E8C0031400BF8F13
+:10A250001000BE8F1800BD270800E00300000000BA
+:10A26000F8FFBD270000BEAF21F0A0030800C4AF77
+:10A2700080BF033C0800C28F205A62AC80BF023C02
+:10A28000105A428C0000427C030040140000000081
+:10A29000FAFF00100000000080BF023C205A428CF0
+:10A2A00021E8C0030000BE8F0800BD270800E003BE
+:10A2B00000000000E8FFBD271400BFAF1000BEAFD4
+:10A2C00021F0A003211080001800C2A388BF043C25
+:10A2D00010618390BFFF022424106200106182A0ED
+:10A2E00088BF043C50608390DFFF0224241062008A
+:10A2F000506082A01800C293212040009868400F4F
+:10A300000000000088BF033C50606290200042348F
+:10A31000506062A088BF033C1061629040004234EC
+:10A32000106162A021E8C0031400BF8F1000BE8F2F
+:10A330001800BD270800E00300000000E8FFBD276B
+:10A340001400BFAF1000BEAF21F0A00321108000A9
+:10A350001800C2A388BF033C1061629040004234E1
+:10A36000106162A088BF043C50608390DFFF02242C
+:10A3700024106200506082A01800C2932120400087
+:10A380009868400F0000000088BF033C5060629056
+:10A3900020004234506062A088BF033C106162908C
+:10A3A00040004234106162A021E8C0031400BF8F56
+:10A3B0001000BE8F1800BD270800E0030000000059
+:10A3C000E0FFBD271C00BFAF1800BEAF21F0A00307
+:10A3D000211080002000C2A31000C0A31000C2936F
+:10A3E0000800422C2000401000000000B0FF0324B1
+:10A3F0001000C29321106200FF0042302120400073
+:10A40000AD68400F0000000021200000AD68400F43
+:10A410000000000010000424AD68400F00000000A0
+:10A420001100C0A31100C2830A0040040000000014
+:10A430002000C29321204000CF68400F00000000A0
+:10A440001100C293010042241100C2A3F5FF0010C5
+:10A45000000000001000C293010042241000C2A3BB
+:10A46000DEFF00100000000021E8C0031C00BF8FC9
+:10A470001800BE8F2000BD270800E0030000000088
+:10A48000E0FFBD271C00BFAF1800BEAF21F0A00346
+:10A490001000C0AF80BF033C20810234005A62AC80
+:10A4A00088BF043C10618390BFFF02242410620027
+:10A4B000106182A088BF043C50608390DFFF0224BB
+:10A4C00024106200506082A088BF033C106162903B
+:10A4D0007F004230106162A01000C0AF1000C28F38
+:10A4E000D007422C06004010000000001000C28F70
+:10A4F000010042241000C2AFF8FF0010000000006D
+:10A5000088BF043C1061839080FF02242510620004
+:10A51000106182A01000C0AF1000C28FD007422C83
+:10A5200006004010000000001000C28F010042240D
+:10A530001000C2AFF8FF00100000000088BF023C0E
+:10A540005060439020006334506043A0D500042441
+:10A55000AD68400F0000000010000424AD68400FFB
+:10A5600000000000D3000424AD68400F000000008C
+:10A5700021200000AD68400F00000000A800042466
+:10A58000AD68400F000000003F000424AD68400F9C
+:10A5900000000000D8000424AD68400F0000000057
+:10A5A00021200000AD68400F00000000400004249E
+:10A5B000AD68400F00000000A0000424AD68400F0B
+:10A5C00000000000C8000424AD68400F0000000037
+:10A5D000DA000424AD68400F0000000012000424DB
+:10A5E000AD68400F0000000081000424AD68400FFA
+:10A5F00000000000F0000424AD68400F00000000DF
+:10A60000A4000424AD68400F00000000D900042419
+:10A61000AD68400F00000000F2000424AD68400F58
+:10A6200000000000A6000424AD68400F00000000F8
+:10A6300026000424AD68400F00000000010004243F
+:10A64000AD68400F0000000021200000AD68400F01
+:10A650000000000021200000AD68400F0000000055
+:10A6600001000424AD68400F00000000212000001C
+:10A67000F068400F000000001000C0AF1000C28F53
+:10A68000D007422C06004010000000001000C28FCE
+:10A69000010042241000C2AFF8FF001000000000CB
+:10A6A000AF000424AD68400F0000000021E8C003A3
+:10A6B0001C00BF8F1800BE8F2000BD270800E003DC
+:10A6C00000000000E8FFBD271400BFAF1000BEAFC0
+:10A6D00021F0A003212000003564400F000000009D
+:10A6E00001000424BF64400F00000000C8000424DF
+:10A6F000775C400F00000000212000003564400F0F
+:10A700000000000021200000BF64400F0000000096
+:10A71000C8000424775C400F0000000021E8C0035B
+:10A720001400BF8F1000BE8F1800BD270800E00383
+:10A7300000000000211080005600C0100C00CA2C40
+:10A740004D0040152618A400030063302338040090
+:10A75000290060100300E7300600E0102330C70036
+:10A760000000A3980300A3882128A700000083B855
+:10A77000212087000F00C3302338C3001100E010F0
+:10A78000213060002138E5000000A3980300A38871
+:10A790000400A8980700A8880800A9980B00A988B9
+:10A7A0000C00AA980F00AA88000083AC040088ACB3
+:10A7B000080089AC1000A52410008424F2FFA7141F
+:10A7C000FCFF8AAC0300C3302338C3002A00E0102A
+:10A7D000213060002138E5000000A3980300A38821
+:10A7E0000400A52404008424FBFFA714FCFF83AC11
+:10A7F00021000010000000000500E0102330C70019
+:10A800000000A3982128A700000083B8212087001A
+:10A810000F00C3302338C3000D00E010213060006A
+:10A820002138E5000000A38C0400A88C0800A98C46
+:10A830000C00AA8C000083AC040088AC080089AC32
+:10A840001000A52410008424F6FFA714FCFF8AAC96
+:10A850000300C3302338C3000700E010213060003C
+:10A860002138E5000000A38C0400A5240400842402
+:10A87000FCFFA714FCFF83AC0600C0102138C50004
+:10A880000000A3900100A52401008424FCFFA7146C
+:10A89000FFFF83A00800E0030000000021108000FB
+:10A8A0002600C0101000CA2C1F004015FF00A53064
+:10A8B000005205002528AA00005405002528AA00FA
+:10A8C0000300833005006010040007242338E300F0
+:10A8D0002330C700000085B8212087000F00C33057
+:10A8E0002338C3000800E010213060002138E40064
+:10A8F000000085AC040085AC080085AC1000842401
+:10A90000FBFF8714FCFF85AC0300C3302338C30072
+:10A910000500E010213060002138E40004008424A8
+:10A92000FEFF8714FCFF85AC0400C0102138C40072
+:10A9300001008424FEFF8714FFFF85A00800E003C8
+:10A9400000000000254085000300083103000011CD
+:10A9500021108000380000100000AA900000AA8C8E
+:10A960000101093C01012935C07909002340490151
+:10A9700024400F010700001124600A01050088111E
+:10A98000000000000000A5240000AA902A0000108A
+:10A99000000084240400AB8C00008AAC23406901D1
+:10A9A00024400F010700001124600B0105008811ED
+:10A9B000000000000400A5240000AA901E00001062
+:10A9C000040084240800AA8C04008BAC23404901B5
+:10A9D00024400F010700001124600A0105008811BE
+:10A9E000000000000800A5240000AA90120000103A
+:10A9F000080084240C00AB8C08008AAC2340690159
+:10AA000024400F010700001124600B01050088118C
+:10AA1000000000000C00A5240000AA900600001011
+:10AA20000C0084241000AA8C0C008BAC1000842431
+:10AA3000CEFF00101000A5240300401500008AA0DE
+:10AA40000800E003000000000100AB900300601567
+:10AA500001008BA00800E003000000000200AA90A3
+:10AA60000300401502008AA00800E0030000000077
+:10AA70000300AB900300601503008BA00800E00307
+:10AA8000000000000400AA900300401504008AA002
+:10AA90000800E003000000000500AB900300601513
+:10AAA00005008BA00800E003000000000600AA904B
+:10AAB0000300401506008AA00800E0030000000023
+:10AAC0000700AB900300601507008BA00800E003AF
+:10AAD000000000000800AA9008008424D6FF00109F
+:10AAE0000800A52400008A90211080000300401572
+:10AAF000000000000800E0030000022401008A902A
+:10AB000003004015000000000800E00301000224DB
+:10AB100002008A9003004015000000000800E003D6
+:10AB20000200022403008A900300401582200400E2
+:10AB30000800E003030002240100842480200400B4
+:10AB400000008A8C0101093C01012935C079090006
+:10AB50002340490124400F010600001124600A012E
+:10AB6000040088110000000000008A9022000010FC
+:10AB70000000842404008B8C2340690124400F01D1
+:10AB80000600001124600B01040088110000000081
+:10AB900004008A90180000100400842408008A8CA5
+:10ABA0002340490124400F010600001124600A01DE
+:10ABB000040088110000000008008A900E000010B8
+:10ABC000080084240C008B8C2340690124400F0171
+:10ABD0000600001124600B01040088110000000031
+:10ABE0000C008A90040000100C00842410008A8C51
+:10ABF000D7FF00101000842404004015000000005E
+:10AC0000000084240800E0032310820001008A90E1
+:10AC10000400401500000000010084240800E00347
+:10AC20002310820002008A900400401500000000FA
+:10AC3000020084240800E0032310820003008A90AD
+:10AC4000030084240800E00323108200B0FFBD2726
+:10AC50000000A1AF0400A2AF0800A3AF0C00A4AF96
+:10AC60001000A5AF1400A6AF1800A7AF1C00A8AF36
+:10AC70002000A9AF2400AAAF2800ABAF2C00ACAFD6
+:10AC80003000ADAF3400AEAF3800AFAF3C00B8AF6E
+:10AC90004000B9AF4400BFAF124000004800A8AF69
+:10ACA000104000005000A8AF00680440006005405C
+:10ACB000A86D400F000000005000A88F1100000197
+:10ACC0004800A88F130000010000A18F0400A28F8C
+:10ACD0000800A38F0C00A48F1000A58F1400A68F6E
+:10ACE0001800A78F1C00A88F2000A98F2400AA8F0E
+:10ACF0002800AB8F2C00AC8F3000AD8F3400AE8FAE
+:10AD00003800AF8F3C00B88F4000B98F4400BF8F30
+:10AD10005000BD27C0000000180000422518A40004
+:10AD20000300623020004014214080000400C92C40
+:10AD30001C0020152138A0000000AF8CFEFE183C3E
+:10AD4000FFFE053727700F002168E50180800C3C6D
+:10AD50002458AE0180808335245063011200405591
+:10AD60002128E0002148A000212860000000E28C9A
+:10AD7000FCFFC6240400D92C000082AC0400E724A8
+:10AD800008002017040084240000ED8C27600D00CB
+:10AD90002158A90124506C0124184501F4FF60508A
+:10ADA0000000E28C2128E0000E00C010FFFFC2244A
+:10ADB0000000A790FFFFC624000087A00100A52483
+:10ADC000F9FFE014010084240600C010FFFFC22434
+:10ADD000FFFF0324FFFF4224000080A0FDFF431477
+:10ADE000010084240800E0032110000103008230E8
+:10ADF00018004014FF00A530003A05002540A700C8
+:10AE000000340800253806018080033C2130800092
+:10AE1000FEFE043CFFFE8934808068340000CF8C45
+:10AE20002610E7012168E90127700F0027C80200FA
+:10AE300021C049002458AE01246019032450680140
+:10AE40000300401524188801F4FF60500400C62454
+:10AE50002120C00000008390FF0069300300251509
+:10AE6000211080000800E00300000000F9FF6014DA
+:10AE7000010084240800E00321100000E0FFBD274A
+:10AE800000A0053C1000B0AF0000B0241800B2AF25
+:10AE90001400B1AF2190800000A0113C1C00BFAF96
+:10AEA000776D400F212000021C01238E0100042435
+:10AEB000380064AC7B6D400F212000021C01228E03
+:10AEC0001000508C0D0000121C012A8E0400028E0E
+:10AED00008004018FFFF4724804807002140300148
+:10AEE0000800068D09F8C000040007AEF8FF001046
+:10AEF0000400028EF3FF00100000108E3400428D1B
+:10AF0000030040100000000009F8400000000000AD
+:10AF1000CB6D400F21204002029D073C4D17E624D7
+:10AF20002110860000004590200082240100A330FB
+:10AF30000800E0030A108300029D073C4D17E62439
+:10AF40002110860000004590E0FF82240200A3301B
+:10AF50000800E0030A108300029D053C4D17A3245E
+:10AF600021208300000082900800E00307004230A7
+:10AF7000029D053C4D17A3242120830000008290F0
+:10AF80000800E003030042300800E0038000822C48
+:10AF9000029D053C4D17A3242120830000008290D0
+:10AFA0000800E00320004230029D053C4D17A32419
+:10AFB00021208300000082900800E003040042305A
+:10AFC000029D053C4D17A3242120830000008290A0
+:10AFD0000800E00317004230029D053C4D17A324F2
+:10AFE00021208300000082900800E003020042302C
+:10AFF000029D053C4D17A324212083000000828080
+:10B000000800E00397004230029D053C4D17A32441
+:10B0100021208300000082900800E00310004230ED
+:10B02000029D053C4D17A32421208300000082804F
+:10B030000800E00388004230029D053C4D17A32420
+:10B0400021208300000082900800E00301004230CC
+:10B05000029D053C4D17A32421208300000082900F
+:10B060000800E003440042300800E0037F00823023
+:10B070000800E003200082240800E003E0FF8224AF
+:10B08000E8FFBD271000BFAFAA6C400F21280000C9
+:10B090001000BF8F0800E0031800BD27E8FFBD27A0
+:10B0A000212800001000BFAF2F6C400F0A000624BB
+:10B0B0001000BF8F0800E0031800BD270000838048
+:10B0C000213880002150000021700000215800002C
+:10B0D0000E00601021680000029D093C4D172825D4
+:10B0E0002110680000004280880043300800605052
+:10B0F0000000E3800100E7240000EC8003008011E1
+:10B1000021188801F8FF0010000062800000E38031
+:10B110002B000824030068102D000F2404006F1476
+:10B12000000000002D00783801000E2F0100E724F8
+:10B130001100C014100003240000E2803000192424
+:10B140001C0059140A0006240100E7240000E380D3
+:10B1500078000924080006240400691001000D2469
+:10B1600058000C2414006C14FF7F023C0100E724FB
+:10B1700010000010100006240F00C314FF7F023CD3
+:10B180000000EF80300008240C00E815FFFF433476
+:10B190000100E7240000E380780018240400781000
+:10B1A00001000D245800192404007914FFFF4334D2
+:10B1B0000100E724FF7F023CFFFF43341A006600D2
+:10B1C000F401C0002148E0000000E7802400E01006
+:10B1D00012600000029D083C4D1718252178600080
+:10B1E0002110F80000004390040079300700201778
+:10B1F000D0FFE8240300683019000011010063301B
+:10B20000A9FFF924C9FFE8240A4023032A180601EC
+:10B2100001007938C2170800253859001100E054A0
+:10B2200001006F2D2A388A010800E01401000D2466
+:10B2300008006055010029250250467123C8EA0123
+:10B240002A102803020040502150480101000B241D
+:10B250000100292500002781E2FFE0542110F800B9
+:10B2600001006F2D2460CF0123300A000B50CC0069
+:10B27000080060112110400122000B2400A00A3CAC
+:10B2800004024BAD0300C0150080023CFF7F0E3C62
+:10B29000FFFFC2350200A0100A488D000000A9ACD3
+:10B2A0000800E00300000000E8FFBD271000BFAF6A
+:10B2B000717C400F000000001000BF8F0800E00309
+:10B2C0001800BD27E8FFBD271000BFAF0400828C27
+:10B2D00021188000FFFF06240100042421284000DB
+:10B2E00003004610000060AC04000010040066ACCF
+:10B2F000B66D400F00000000212840001000BF8FF5
+:10B300002110A0000800E0031800BD27E8FFBD27BA
+:10B310001000B0AF1400BFAF100083940200623081
+:10B320000E004010218080000000838C0E0060041D
+:10B330001400BF8F0C00848C03006410232883004A
+:10B34000B86D400F0800048E0800058E0C00068EB4
+:10B35000040005AE03000010000006AEFFFF072446
+:10B36000040087AC1400BF8F1000B08F21100000C4
+:10B370000800E0031800BD27D8FFBD271C00B1AFAF
+:10B380001800B0AF2000BFAF0C00A28C2180A0003D
+:10B3900021888000010005240600401421200002BD
+:10B3A0001000A427B86D400F1000B1A323000010B7
+:10B3B000000000AE0000068EFFFF03240100C5243C
+:10B3C0000D00A314000005AE0800078E00A0083C85
+:10B3D000040405250800E0148000062410000A96E5
+:10B3E000040005AE10004935000006AE080005AEA9
+:10B3F0000C0006AE100009A6C36C400F0000000050
+:10B4000000000E8E04000C8EFFFFCD2501008B2561
+:10B410000A00042400000DAE000091A107002416CC
+:10B4200004000BAE1000189608000F330300E01163
+:10B4300021200002C36C400F0000000021102002F8
+:10B440002000BF8F1C00B18F1800B08F0800E003F0
+:10B450002800BD27E0FFBD271000B0AF0280C570F7
+:10B460001800B2AF1400B1AF1C00BFAF2188C000FC
+:10B470002190800011000012212800001000E694A5
+:10B480002120E0000100C230060040104000C3341B
+:10B490001000E3A400A0043C0900032407000010EE
+:10B4A000040283ACC36C400F00000000212800029E
+:10B4B000B86D400F21204002212820021C00BF8FC0
+:10B4C0001800B28F1400B18F1000B08F2110A000AF
+:10B4D0000800E0032000BD2710008794FFFFE33041
+:10B4E000241065004000E6340600401001000324EB
+:10B4F000100086A40900052400A0043C040285ACC9
+:10B50000211800000800E00321106000C8FFBD27DB
+:10B51000FFFFA9242128C0002130E000029D073C44
+:10B5200021408000FFFF0B241000A42782000A2482
+:10B53000AC19E2243000BFAF2200ABA72000AAA7BD
+:10B540001C00A9AF1400A8AF2800A2AF1000A9AF3B
+:10B550008B6E400F1800A8AF1400A38F3000BF8F70
+:10B560003800BD270800E003000060A02110A00003
+:10B57000FF7F053CE8FFBD272138C000FFFFA53451
+:10B580001000BFAF436D400F213040001000BF8F4F
+:10B590000800E0031800BD27E8FFBD272110A00028
+:10B5A000FF7F053C2000A6AF2400A7AFFFFFA53416
+:10B5B0002000A7271000BFAF436D400F213040008F
+:10B5C0001000BF8F0800E0031800BD270800E0034B
+:10B5D000211000000800E003211000000800E00333
+:10B5E000211000000800E003211000000800E00323
+:10B5F000211000000800E003211000000800E00313
+:10B60000211000000800E003211000000800E00302
+:10B61000211000000800E003211000000800E003F2
+:10B62000FFFF02240800E003000000000800E00320
+:10B63000000000000800E003000000000800E00334
+:10B64000000000000800E003000000000800E00324
+:10B65000000000000000828CE8FFBD2704004014B9
+:10B660001000BFAF0200032409F8A000000083AC63
+:10B670001000BF8F211000000800E0031800BD2754
+:10B680000800E003FFFF02240800E003FFFF02249C
+:10B690000800E003211000000800E0032110A000D2
+:10B6A000FFFF001000000000FFFF0010000000007E
+:10B6B0000800E003000000000800E00300000000B4
+:10B6C00000601A40BFFF1B3CFFFF7B3724D05B03A9
+:10B6D00000609A40180000420800E003FFFF0224C7
+:10B6E000E0FFBD271400B1AF1000B0AF1800BFAF2E
+:10B6F00021888000080080102180A000070000122F
+:10B700001800BF8F000024823174400FFFFF102605
+:10B71000FAFF0010010031261800BF8F1400B18F0E
+:10B720001000B08F0800E0032000BD27FFFF0010CD
+:10B7300000000000E0FFBD271800B2AF1400B1AF59
+:10B740001000B0AF1C00BFAF218880002190C00066
+:10B750000C00A010FFFFB02400002482F673400FFD
+:10B7600021284002FFFF0324FFFF1026030043149B
+:10B770000100312604000010FFFF0224F7FF0356EA
+:10B7800000002482211000001C00BF8F1800B28F1F
+:10B790001400B18F1000B08F0800E0032000BD2717
+:10B7A000E0FFBD271800B2AF1400B1AF1000B0AF7A
+:10B7B0001C00BFAF2180A000219080002188C00024
+:10B7C0000D0000122100022E200007240B38020277
+:10B7D0002128E0002120200221304002CD6D400FC1
+:10B7E00023800702FFFF0324F5FF4314FFFF022419
+:10B7F000030000101C00BF8F211000001C00BF8F31
+:10B800001800B28F1400B18F1000B08F0800E00351
+:10B810002000BD27D0FFBD271400B1AF2188E00074
+:10B820004000A78F1800B2AF1000B0AF0100F23097
+:10B830002180C0000100432E1C00B3AF2A981102E2
+:10B84000029D063C241073002800B6AF2400B5AF5B
+:10B850002000B4AF2C00BFAF21A0A0007018C624F8
+:10B86000FFFF16242328300221A880000400401086
+:10B8700021180000E86D400F000000002118400072
+:10B8800021208002212800020E0076102130A00223
+:10B89000CD6D400F000000000B0056102A20300232
+:10B8A0000A0040520A802402029D053C7018A6241A
+:10B8B0002120A0020300601223283002E86D400F0F
+:10B8C000000000002A2030020A8024022110000219
+:10B8D0002C00BF8F2800B68F2400B58F2000B48FB6
+:10B8E0001C00B38F1800B28F1400B18F1000B08FFE
+:10B8F0000800E0033000BD27C8FFBD272C00B5AF0E
+:10B900001C00B1AF21A8C0002188E0002130000058
+:10B91000213800002800B4AF2400B3AF2000B2AF3C
+:10B920001800B0AF3000BFAF219080002198A00078
+:10B930004800B48FC979400F4C00B083110040100B
+:10B94000029D023C6819468C6C19478C21204002EC
+:10B95000F776400F21286002212040002128600056
+:10B960006675400F1000A6270B000010029D063CD4
+:10B97000000025A20000A48E0100832421000010F5
+:10B980000000A3AEEE78400FD0FF04261000A2AF57
+:10B990001400A3AF029D063C7019C48C7419C58CA9
+:10B9A0001400A78FC979400F1000A68F160041041C
+:10B9B000211020022E0006243000052400008D8274
+:10B9C0002660A60101008B2D23208B0200008A90A7
+:10B9D000FFFF942401004825204C087C3A002729C9
+:10B9E0000800E014000088A0F4FF9114000085A076
+:10B9F000DFFFA0563100052431000E24FFFF2EA2E8
+:10BA0000FFFF3126211020023000BF8F2C00B58FA0
+:10BA10002800B48F2400B38F2000B28F1C00B18F98
+:10BA20001800B08F0800E0033800BD2718FBBD27C1
+:10BA3000E404BFAFE004BEAFDC04B7AFD804B6AFD8
+:10BA4000D404B5AFD004B4AFCC04B3AFC804B2AF24
+:10BA5000C404B1AFC004B0AF1800838CEC04A5AF30
+:10BA60001000628CE804A4AF0100052409F840002E
+:10BA7000F004A6AF9404A0AF34054010FFFF0324E8
+:10BA8000EC04A68F0000C4800100C52429058010A5
+:10BA9000EC04A5AF2500072406008710EC04A88F4E
+:10BAA000F673400FE804A58F9404A48F1F050010BF
+:10BAB00001008324000012810B004416FFFF0624BE
+:10BAC000E804A58FF673400F25000424EC04AC8F26
+:10BAD0009404AA8F01008B2501004925EC04ABAF2B
+:10BAE000E7FF00109404A9AF9C04A0AF2D00072429
+:10BAF0002B0005242000042423000324300002240A
+:10BB0000030047169C04AD8F100000100100A835FB
+:10BB1000030045169C04AE8F0C0000100200C835CF
+:10BB2000030044169C04AF8F080000100400E835A1
+:10BB3000030043169C04B08F040000100800083670
+:10BB4000080042169C04B18F10002836EC04B28F16
+:10BB50009C04A8AF01005326EC04B3AFE8FF00102B
+:10BB6000000072822A0014240E005416D0FF4526CD
+:10BB7000F004A28FFCFF1F2403005E2424B0DF0327
+:10BB8000EC04B98F0000D88E01003727EC04B7AF62
+:10BB90009804B8AF0000F2820400D526110000100E
+:10BBA000F004B5AF0A00A32C160060109804A0AFF3
+:10BBB0000A0003249804AC8FEC04AD8F0258837103
+:10BBC0000100AA25EC04AAAF2148720100005281AD
+:10BBD000D0FF2825D0FF44260A00872CF5FFE0146B
+:10BBE0009804A8AF9804A88F070001052E0011241F
+:10BBF0009C04B08F2370080001000F369C04AFAF87
+:10BC00009804AEAF2E0011242600511668000C24B3
+:10BC1000EC04B28F2A00062401005326EC04B3AFD3
+:10BC2000000072820D004616D0FF4226F004BE8F3F
+:10BC3000EC04B78F0300D8270100F626FCFF192477
+:10BC400024A81903EC04B6AF0000D2820000A68E2F
+:10BC50000400B4260F000010F004B4AF0A005F2CFB
+:10BC60000F00E013213000000A000324EC04AA8F27
+:10BC70000220C37001004825EC04A8AF21489200BF
+:10BC800000001281D0FF47260A00E52CF7FFA01420
+:10BC9000D0FF26250000C328FFFF0B240B306301D3
+:10BCA00068000C2412004C166C001524EC04A58FBF
+:10BCB0000100AD800700B2159C04B38F9C04B08FC7
+:10BCC0000100AE2480000F369C04AFAF03000010CB
+:10BCD000EC04AEAF000171369C04B1AFEC04B28F3E
+:10BCE00001005426EC04B4AF27000010000092823B
+:10BCF0001200551671000724EC04A48F01009680F1
+:10BD00000700D2169C04BF8F9C04B98F01009724B2
+:10BD1000000838379C04B8AF03000010EC04B7AF3C
+:10BD20000002FE379C04BEAFEC04A58F0100A224E4
+:10BD3000EC04A2AF14000010000052800900471666
+:10BD40004C000B24EC04AA8F9C04A88F010044250E
+:10BD5000EC04A4AF00009280000809350A0000102E
+:10BD60009C04A9AF09004B16EC04B18FEC04AE8F14
+:10BD70009C04AC8F0100CD25EC04ADAF00048335ED
+:10BD80000000B2819C04A3AFEC04B18F9C04A38F8C
+:10BD90000100302602006F300400E011EC04B0AF67
+:10BDA000FBFF1424249874009C04B3AF9C04A58F5B
+:10BDB0000100B5300400A012BCFF4326EFFF17249A
+:10BDC00024B0B7009C04B6AF3500782C550400139E
+:10BDD00021100000029D053C80F803009018A22469
+:10BDE00021F0E2030000D98F0800200300000000CA
+:10BDF0009C04A78F0002F2349C04B2AF9C04AA8F6B
+:10BE0000F7FF042400104835244804010D000010F9
+:10BE10009C04A9AF9C04A38F00026B349C04ABAFBD
+:10BE200015000010080014249C04AD8F0002AC35EE
+:10BE30009C04ACAF9C04AF8FF7FF10242470F0017A
+:10BE40009C04AEAF0C0000100A0014249C04B38FB5
+:10BE500000407136070000109C04B1AF9C04B58F00
+:10BE60000040B4369C04B4AF9C04B78F0802F63689
+:10BE70009C04B6AF10001424FFFF18240300D8144C
+:10BE80009C04BE8F0400001001000624EFFF1F2455
+:10BE900024C8DF039C04B9AF9C04A58F0010B63002
+:10BEA0000B00C0120008A2300C004014F004AB8F4D
+:10BEB000F004A98FFCFF0224030027252410E200D0
+:10BEC0000000528C2120400210000010C32F1200ED
+:10BED00009004010F004AD8FF004AB8FF8FF0A2486
+:10BEE0000700642524408A000000048D0400058DAD
+:10BEF0000700001008000225FCFF0C240300A32506
+:10BF000024106C000000448C21280000040042240E
+:10BF1000F004A2AF218080002188A0002198C000F9
+:10BF20005F00B2270800C01221B800000700A1047A
+:10BF30002118000023801000238811002B1010000E
+:10BF40002388220201001724211800001B0010166C
+:10BF5000212800021A00711425101102330000126A
+:10BF60009C04AE8F0040C6311B00B400F401800277
+:10BF7000102000000A008F280300E05137009124B0
+:10BF80000400001030008424570090242120200257
+:10BF90000A2006021B00B400F4018002000044A243
+:10BFA000FFFF7326FFFF522612A80000EEFFA01627
+:10BFB000122800001E000010FFFF6226251011024B
+:10BFC0001A004010C3AF1400212820022130800243
+:10BFD0002138A002687F400F212000020A00582863
+:10BFE00006000017300045249C04BF8F57005924D9
+:10BFF0000040FE33370045240A283E03000045A2D6
+:10C00000212000022128200221308002497E400F99
+:10C010002138A002218040002188600025104300C3
+:10C02000FFFF5226E6FF0010FFFF7326FFFF622688
+:10C03000070040049C04A88F30000324FFFF422423
+:10C04000000043A2FDFF4104FFFF52269C04A88F7D
+:10C0500010001331250060129C04AE8F2000A5272C
+:10C060009804A98F233845022128270108000231AE
+:10C070000C004010C1FFA424080008240700881603
+:10C08000FEFF8C2401004B8230000A2404006A5118
+:10C090001000833A03000010C0FFA4241000833A6C
+:10C0A0000A2083010900C052FFFF83240600E056E6
+:10C0B000FFFF84249C04A68F0600CD300300A0114E
+:10C0C000FFFF8324FFFF8424FFFF83240700620413
+:10C0D0009C04AE8F30000224FFFF6324000042A2C4
+:10C0E000FDFF6104FFFF52269C04AE8F0800C4319F
+:10C0F0001600801008000F2408008F56100011242D
+:10C100000100508230000324040003521000112467
+:10C11000000043A20D000010FFFF52260B009116F5
+:10C12000212840029C04B28FFFFFA3240040543218
+:10C1300002008016580004247800042430001524DE
+:10C140000000A4A0FFFF7224000075A01000C01220
+:10C15000010045260B00E0162D0002249C04B78F39
+:10C160000200F6320300C0129C04B98F05000010D3
+:10C170002B0002240400383305000053010045263B
+:10C1800020000224000042A2FFFF522601004526A3
+:10C1900023F0A5031F0300106000C627F004AC8F36
+:10C1A000F8FF0A2407008B2524406A010000098D4E
+:10C1B0000400078D6000A9AF6400A7AF6000B08FD6
+:10C1C0006400B18F080005250055337EFF077F3AD4
+:10C1D000F004A5AF2300E017A004A6AF21200002C1
+:10C1E0002128200221300002C979400F2138200285
+:10C1F0000700405021200002029D033C9804A78FB5
+:10C20000E804A48F90196524040300100300062499
+:10C210002128200221300000C979400F2138000078
+:10C2200009004304029D043C029D063C9C04AD8F22
+:10C230009804A78FE804A48F9C19C5240400062441
+:10C24000F80200101000ADAF941985249C04AE8F45
+:10C250009804A78FE804A48F04000624F1020010BC
+:10C260001000AEAFFFFF0F240400CF14A404A0AF52
+:10C270000600142413000010A004B4AF2800D52831
+:10C280001100A0162140000267005E3A4700593AAB
+:10C290002BB81E002BC0190024B0F8020600C016EF
+:10C2A000D9FFC2249C04B38F08007F320400E0133E
+:10C2B00027000724D9FFC224A404A2AF2700072423
+:10C2C000A004A7AF21400002214820026900A0A3DA
+:10C2D0009004A0AFA004BE8FA804B2AF0A0021064C
+:10C2E000B404A0AF21500001029D083C7C19058DCB
+:10C2F0002D000924268825027002A9A321404001AF
+:10C3000002000010214820027002A0A38004A6278A
+:10C31000212000016675400F212820016900AD270A
+:10C320006902AC2721A86000FFFF8B250100A3252F
+:10C3300021A04000B804A3AFAC04A3AF21986000D3
+:10C3400024000010B004ABAF6819108F6C19118F66
+:10C350002120C0022128E00221382002C177400FAD
+:10C360002130000221204000212860008004A627FF
+:10C370006675400F029D173C8019E68E8419E78E82
+:10C3800021204000212860008804A2AFEE75400FF4
+:10C390008C04A3AF2120400021300002212860003E
+:10C3A000F776400F21382002212040008679400F87
+:10C3B00021286000B004AF8F300056240000F6A1A1
+:10C3C0009004AE8FFFFFE4250100C625B004A4AFA2
+:10C3D0009004A6AF8004B68F8404B78F213000008C
+:10C3E000213800002120C002C979400F2128E00235
+:10C3F000D5FF4014029D183C650019246C005912A9
+:10C4000066005F2A0600E013660007244500022448
+:10C4100067004212470002240300001000000000E1
+:10C420000500471267000224580142126900A683E2
+:10C4300000020010B804B08F9004B28F10004012B8
+:10C44000B804A38FB004A58F6902A9270100A42412
+:10C450002B5089000E004011A004AD8F00008B907E
+:10C460006902AC27010084242B408C0000006BA2E1
+:10C47000FAFF00150100732605000010A004AD8F1F
+:10C4800030001324000073A001007324A004AD8FBA
+:10C490000600A0152E0004249C04AE8F0800C631AF
+:10C4A0000500C010212080022E000424000064A298
+:10C4B00001007326212080022128A00221300000E3
+:10C4C000C979400F213800002F004010A004AF8F21
+:10C4D0001D00E01121208002029D113C6819268E6A
+:10C4E0006C19278E21208002F776400F2128A002A8
+:10C4F00021204000212860006675400F8804A6278F
+:10C500008804A48F8C04A58F21A040008679400F59
+:10C5100021A8600030005624FFFFDE27000076A22D
+:10C520000800C01301007326212080022128A002E8
+:10C5300021300000C979400F21380000E7FF401486
+:10C54000029D113C212080022128A0022130000000
+:10C55000C979400F213800000B004010B804A78FA4
+:10C56000FFFF7726213000007002B02721208002D3
+:10C570002128A0021000B7AF1800B0AF3E6E400FE8
+:10C580001400A0AFAC04A2AFA801C013FFFFC227E4
+:10C5900030000424FFFF0324FFFF4224000064A2B4
+:10C5A000FDFF431401007326A10100106900A6835A
+:10C5B0009004B88F3900001321208002B004A28FAC
+:10C5C000B804B98F01005F900100432400003FA32D
+:10C5D0000500C017010030279C04B28F08004732C5
+:10C5E0001800E01001006D24B804AA8F2E00092461
+:10C5F000010049A11200C01302005025B004A88F09
+:10C600006902A527020003252B1065000A004010CF
+:10C610000000000000006B90FFFFDE2700000BA26F
+:10C620000700C01301001026010063246902AC2733
+:10C63000F6FF00102B106C001500C0179004A48F9B
+:10C6400001006D246902A6272B98A6011000601234
+:10C650009004A48FFFFF0E261000AEAF010075807E
+:10C660007002B4271400B5AF1800B4AFB804A78F98
+:10C6700021A0000021A800009004A627212080020C
+:10C680003E6E400F2128A002AC04A2AF9004A48FFC
+:10C69000FFFF83243D0000109004A3AF2128A002D7
+:10C6A00021300000C979400F213800002B004010D4
+:10C6B000B804A78FFFFF02249004A2AF029D0F3C95
+:10C6C0006819E68D6C19E78D21208002F776400FFE
+:10C6D0002128A00221204000212860006675400F1B
+:10C6E0008804A6278804B08F8C04B18F2130000005
+:10C6F00021380000212000022128200221A0400032
+:10C70000C979400F21A86000030040149004B68F3F
+:10C71000E9FF0010FFFFC226212000028679400FAA
+:10C7200021282002B804B18F30005024000030A22C
+:10C730000500C017010030269C04B88F080017338D
+:10C740001300E01221208002B804B98F2E001F24AC
+:10C75000020030270D00001001003FA3300002242A
+:10C760000000E2A00500C0170100F0249C04AA8F7D
+:10C77000080052310600401221208002B804A98F1F
+:10C780002E000524010025A1020030252120800271
+:10C790002128A00221300000C979400F2138000073
+:10C7A0002F004010000000001D00C0132120800257
+:10C7B000029D0B3C6819668D6C19678D21208002E3
+:10C7C000F776400F2128A002212040002128600098
+:10C7D0006675400F8804A6278804A48F8C04A58F53
+:10C7E00021A040008679400F21A860003000482435
+:10C7F000FFFFDE27000008A20800C013010010267A
+:10C80000212080022128A00221300000C979400F98
+:10C8100021380000E7FF4014029D0B3C21208002DC
+:10C820002128A00221300000C979400F21380000E2
+:10C830000B004010AC04A78F7002AC27FFFF13263B
+:10C840009004A627212080022128A0021000B3AF67
+:10C850001800ACAF3E6E400F1400A0AFAC04A2AF06
+:10C860000700C013FFFFC22730000424FFFF03248A
+:10C87000FFFF4224000004A2FDFF43140100102624
+:10C88000B404BE8F1400C0539004A48F9C04A68FE0
+:10C890000800CD301000A0559004A48F3000032470
+:10C8A000AC04B58F2BA0B0020600805200001682A7
+:10C8B000FFFF102600000E82FBFFC3112BA0B00269
+:10C8C000000016822E00CF3A0100E42D2318040246
+:10C8D000010070249004A48FA804B18F02000526E3
+:10C8E000000011A2060081047804A8272D00172457
+:10C8F000232004002130A00004000010010017A232
+:10C900002B001824010018A22130A0000A00902852
+:10C9100017000016213800010A0005241A008500BE
+:10C92000F401A000FFFFE724101000001220000017
+:10C9300030005F240A009928F8FF20130000FFA0B0
+:10C94000FFFFE52430008A242B18A800FFFFEAA08F
+:10C95000B60060102198C0000000A7900100A52437
+:10C960000000C7A02B18A800F9FF00100100C62482
+:10C9700030008924300008240000A8A00100A9A0EC
+:10C980000200A624A90000102198C000A004AB8FCB
+:10C99000010010249004A38F0B80CB032A280302EC
+:10C9A0001300A014FEFF4D2616006014B004AE8FD5
+:10C9B000212080022128A00221300000C979400FE7
+:10C9C000213800001E004010B804A48F029D0C3CCA
+:10C9D0008819868D8C19878D21208002C979400F96
+:10C9E0002128A00216004104B804A48FFEFF4D26A2
+:10C9F00001001324FFFF1E26A804ADAFECFE0010BB
+:10CA0000B404B3AF6902A6270100C4252BF0860049
+:10CA10000E00C0130000000000008F906902B627CE
+:10CA2000010084242B18960000006FA2FFFF10263F
+:10CA3000F9FF6014010073260400001000000000DC
+:10CA400030001124000091A001009324060000167C
+:10CA50002E0019249C04B88F080017330500E0123B
+:10CA6000219000002E001924000079A20100122458
+:10CA700001007326212080022128A002213000001D
+:10CA8000C979400F213800004C0040509C04B58FFC
+:10CA90003800001221208002029D113C6C19278E63
+:10CAA0006819268E21208002F776400F2128A002E7
+:10CAB000212040008804A6276675400F21286000C9
+:10CAC0008804A48F8C04A58F21A040008679400F94
+:10CAD00021A8600030005F2400007FA28804A48F9A
+:10CAE0008C04A58F2130000021380000C979400F47
+:10CAF00001007326150040149004A28FE7FF4050F8
+:10CB0000029D113C12000010FFFF10266C19278EA9
+:10CB100021208002F776400F2128A002212040002A
+:10CB2000212860006675400F8804A6278804A48F1A
+:10CB30008C04A58F21A040008679400F21A86000B9
+:10CB400030004A2400006AA201007326FFFF10266D
+:10CB500007000012212080022128A00221300000BD
+:10CB6000C979400F21380000E8FF40146819268E6B
+:10CB7000212080022128A00221300000C979400F25
+:10CB8000213800000D0040509C04B58FB804A78FD9
+:10CB9000FFFF68267002A9272130000021208002B3
+:10CBA0002128A0021000A8AF1800A9AF3E6E400FC8
+:10CBB0001400A0AFAC04A2AF9C04B58F0800B4323F
+:10CBC0000B0080120000000018000012FFFF022678
+:10CBD00030000424FFFF0324FFFF4224000064A26E
+:10CBE000FDFF431401007326110000106900A683A5
+:10CBF0000F0040126900A68330000324AC04B28FFA
+:10CC00002B8053020600005200006C82FFFF732647
+:10CC100000006782FBFFE3102B80530200006C8250
+:10CC20002E008B392B280B00219865026900A68302
+:10CC3000B804B08FAC04AD8F7002A3936900BE2717
+:10CC40000B80C6030500601023886D02FFFF1026CD
+:10CC50000100312611000010000003A29C04AE8FD9
+:10CC60000200D331060060129C04B68FFFFF10262D
+:10CC70002B0003240100312608000010000003A24D
+:10CC80000400CF320600E0119C04BF8FFFFF102686
+:10CC900020000424000004A2010031269C04BF8F60
+:10CCA000A404B98F9804A88F0100F43321903902AD
+:10CCB0000100982E2A98480224B813030700E012B6
+:10CCC00021200000029D023CE804A48F7018462435
+:10CCD000E86D400F2328120121204000FFFF15249A
+:10CCE00005009510E804A68F21200002CD6D400FAD
+:10CCF0002128200221204000A404A58F2740040001
+:10CD00002B5008002B4805002488490106002012FA
+:10CD100000000000E804A48F029D103CE86D400F65
+:10CD200050180626212040000C0095109804A78F6B
+:10CD30000B0080122A28F2000A0060120B3845020C
+:10CD40009804B48F029D153CE804A48F7018A626A1
+:10CD5000E86D400F232892029804A78F2A28F2003A
+:10CD60000B3845026F0000102110E000F004B38F73
+:10CD7000FCFF062403007E262458C60300006D8DA8
+:10CD80009C04AC8F9804A78FE804A48F040072253C
+:10CD90007804A527010006247804ADA31000ACAFE9
+:10CDA00020000010F004B2AFF004A48FFCFF0324B5
+:10CDB000030096242478C3020000F18D0400EE25C0
+:10CDC000F004AEAF0400201621802002029D173C23
+:10CDD000A419F12621802002FFFF18240900D8148D
+:10CDE000FFFFC324B96A400F212020020700001072
+:10CDF000218002020600201321282002FFFF632465
+:10CE000001001026FBFF6304000019822128200284
+:10CE1000233011029804A78FE804A48F9C04BF8FCD
+:10CE20001000BFAF056E400F000000003E00001074
+:10CE30009404AD8F9C04B18F000822320D00401085
+:10CE40009C04AB8FF004A58FFCFF07240300B524DE
+:10CE500024A0A7029404A88F00008A8EC34F080064
+:10CE600004009026F004B0AF000048AD2C00001084
+:10CE7000040049AD000272310B0040529C04A38FA4
+:10CE8000F004AF8FFCFF0E240300F32524306E0264
+:10CE90000000CC8C9404AD8F0400DE24F004BEAFFF
+:10CEA0001F00001000008DADF004A48F000176304B
+:10CEB0000900C01203008324FCFF022424F862004E
+:10CEC0000000F78F9404B88F0400F927F004B9AF7D
+:10CED000130000100000F8A69C04AA8F80005131B6
+:10CEE00009002012FCFF0C24FCFF152424A075006F
+:10CEF0000000898E9404A88F04009026F004B0AF3F
+:10CF000007000010000028A124586C000000678D65
+:10CF10009404A58F04007225F004B2AF0000E5ACC4
+:10CF2000211000009404AD8F2118A201D4FA001042
+:10CF30009404A3AFE804AE8F9404BE8F1000D39581
+:10CF4000FFFF0324400066320A18C603E404BF8FC3
+:10CF5000E004BE8FDC04B78FD804B68FD404B58F3D
+:10CF6000D004B48FCC04B38FC804B28FC404B18F83
+:10CF7000C004B08F211060000800E003E804BD2762
+:10CF800000A0063CE8FFBD271C01C28C1000BFAF0B
+:10CF9000211880000400448C2130A0008B6E400FCB
+:10CFA000212860001000BF8F0800E0031800BD2793
+:10CFB0000800E003FFFF02240800E00321108000C6
+:10CFC0000800E003211000000800E0032110000029
+:10CFD0000800E00301000224E0FFBD271400B1AF08
+:10CFE0001000B0AF1800BFAF1800A38C2180A000C4
+:10CFF0001000628C218880002120A00009F84000E8
+:10D000000100052419004010FFFF03240000078ED3
+:10D010000A00283AFFFFE6242120200221280002EE
+:10D020000100032D0600C004000006AE10000B96A0
+:10D03000C0006A7D244843010700201121302002EE
+:10D0400018000C8E0400908D09F80002000000000A
+:10D0500005000010213040000400058E0100A424CA
+:10D060000000B1A0040004AE2118C0001800BF8F5A
+:10D070001400B18F1000B08F211060000800E00391
+:10D080002000BD27E8FFBD271000BFAFF673400F9B
+:10D09000000000001000BF8F0800E0031800BD274B
+:10D0A00000A0033CE8FFBD271C01628C1000BFAF4D
+:10D0B000F673400F0400458C1000BF8F0800E0039A
+:10D0C0001800BD272024047C80BF033C1062658CBF
+:10D0D0000002A27CFDFF40100000000080BF033C66
+:10D0E000206264AC0800E00300000000405005002E
+:10D0F00042550A00C04A0500427D040025482F0120
+:10D10000C042040000800E3C25482E014068070004
+:10D11000426D0D00C0620700427D060025608F0150
+:10D12000C05A060025608E012470C501FFFF4F25FF
+:10D13000FE07E12D5600201000000000FFFFAF2584
+:10D14000FE07E12D6E0020100000000023384D0185
+:10D150004B00E0040000000042400800C07F0900CE
+:10D1600025400F014248090042580B00C07F0C00C7
+:10D1700025586F0142600C002B780B0123400B01F6
+:10D180002B102F0123482F012B782C012578E20149
+:10D190000500E01123482C0121400B012B780B01E5
+:10D1A00021482C0121482F012A7800012140080143
+:10D1B0002148290121482F01FFFFE724EEFFE10468
+:10D1C000000000000800201525500D000300001588
+:10D1D000000000000D00001000000A242548000196
+:10D1E00000000824E0FF4A25203827710700E010DE
+:10D1F0000000000023504701223007000630C8001D
+:10D200000440E8000448E900254826011400401DB8
+:10D2100000000000010007242338EA002000E12C70
+:10D22000050020140000000025400900000009242A
+:10D23000FAFF0015E0FFE7240800E01000000000FE
+:10D24000253009000640E8000648E90020000F24C8
+:10D250002338E7010430E6002540060100000A24D7
+:10D26000C2220800407D090025208F0040280900C7
+:10D27000022B0500007D0A002528AF002528AE00FE
+:10D2800025100400251805000800E0030000000038
+:10D290003B004015000000002A78000121400801F1
+:10D2A0002148290121482F0125782801A3FFE011F9
+:10D2B0000000000008002015000000000300001519
+:10D2C000000000009DFF001000000A242548000116
+:10D2D00000000824E0FF4A252038277197FFE0105E
+:10D2E0000000000023504701223007000630C8002C
+:10D2F0000440E8000448E90090FF0010254826019A
+:10D300001B00A015000000002A78600121586B0165
+:10D3100021608C0121608F0125788B011800E011BC
+:10D3200000000000080080150000000003006015E8
+:10D330000000000085FF001000000D242560600142
+:10D3400000000B24E0FFAD25203887717FFFE0103F
+:10D35000000000002368A701223007000630CB0040
+:10D360000458EB000460EC0078FF00102560860193
+:10D3700040780C002578EB01C1FFE01100000000AF
+:10D38000F8FF053CBEFF00100000042440380500F3
+:10D39000423D0700FFFFE924FE07212D0C0020106D
+:10D3A0000000000002FCE7240F80013CFFFF213455
+:10D3B0002428A100E03F013C2528A1000000C7ACC3
+:10D3C00025100400251805000800E00300000000F7
+:10D3D0001300E01400000000404805002548240127
+:10D3E000F6FF2011000000000080013C2440A10055
+:10D3F0000100E724FFFFE7242A4880002120840061
+:10D400002128A5002128A9001000013C2B08A1001B
+:10D41000F8FF201400000000E2FF00102528A800FB
+:10D42000F8FF053C00000724E4FF0010252007005A
+:10D4300040480500424D0900FFFF2C25FE07812DC5
+:10D440000F0020100000000021482601FFFF2C25BE
+:10D45000FE07812D21002010000000000F80013CFC
+:10D46000FFFF21342428A100006509002528AC0015
+:10D4700025100400251805000800E0030000000046
+:10D480000063050025608401F9FF801100000000A1
+:10D490000400201100000000F8FF053CF4FF00101C
+:10D4A00000000424010029250080013C2450A10033
+:10D4B000FFFF29252A608000212084002128A50063
+:10D4C0002128AC001000013C2B08A100F8FF20141B
+:10D4D00000000000DCFF00102528AA00C042050063
+:10D4E0004265040025400C01C03A04000080013C64
+:10D4F000254001010080013C050020192428A100DD
+:10D50000F07F013C2528A100D9FF00100000042471
+:10D5100001000A24235049012000412D0700201456
+:10D5200000000000E0FF4A212B2007000D0008103A
+:10D5300025380401F8FF00100000083409004011EC
+:10D540000000000022580A00042067010458680106
+:10D55000063847010640480102008010253867015F
+:10D560000200E7340004E7240004EC2C21400C0105
+:10D57000C262070001008C312338EC00C222070090
+:10D580004065080025208C004060080002630C0004
+:10D59000B7FF00102528AC00253804002540050001
+:10D5A0000080013C2458A10040480500424D09007C
+:10D5B000FFFF2C25FE07812D370020100000000002
+:10D5C00033040A2423504901350041292F0020103B
+:10D5D0000000000020004129060020140000000087
+:10D5E000E0FF4A250000042406284501050000103C
+:10D5F00004284501030040190000000006204401F2
+:10D6000004204401234005012338E4000000C4AC99
+:10D610000400C5AC080000150B0029250300E01428
+:10D62000000000000D000010000009242540E0006B
+:10D6300000000724E0FF2925202004710700801046
+:10D640000000000023482401225004000650470136
+:10D65000043887000440880025400A01C2220700E0
+:10D660004065080025208C0040280800022B05009A
+:10D67000006509002528AC002528AB002510040012
+:10D68000251805000800E003000000000400CBACF2
+:10D69000FAFF00100000C0ACFCFF201100000000E9
+:10D6A000F8FF053C000004240000C4ACF3FF0010A8
+:10D6B0000400C5AC0080013C2440A10040380500B6
+:10D6C000423D0700FF0701242A00E110000000008E
+:10D6D00033040A24233847012200E0180000000028
+:10D6E0003500E12808002014000000002A00001581
+:10D6F000000000002550A400240040150000000098
+:10D7000025000010000000000500001500000000CA
+:10D710002B50040023200400232805002328AA00FE
+:10D720001F00EA3001000924044849012348090088
+:10D730002000E12804002014000000000000042460
+:10D74000020000102428A9002420890005000015EB
+:10D75000000000002B5004002320040023280500B3
+:10D760002328AA0025100400251805000800E0035E
+:10D770000000000000530500255044010900401539
+:10D7800000000000F7FF001000000000F03F053C23
+:10D79000F4FF00100000042425280800F1FF001009
+:10D7A00000000424F8FF053CEEFF001000000424F4
+:10D7B0000080013C2638E10040580500425D0B0026
+:10D7C000C0520500427D040025504F01C04A0400AC
+:10D7D0000080083C255048014070070042750E004B
+:10D7E000C06A0700427D06002568AF01C0620600DE
+:10D7F0002568A801FFFF6F25FE07E12D8D00201091
+:10D8000000000000FFFFCF25FE07E12DBB00201028
+:10D81000000000000080013C2428A10023406E018C
+:10D820002C0000110000000015000019000000008D
+:10D830002000012D0700201400000000E0FF082157
+:10D840002B300C0023000D102560A601F8FF0010FE
+:10D8500000000D341F00001100000000222008000D
+:10D8600004308C0004208D0006600C0106680D0158
+:10D870001800C01025608C001600001002008C35C6
+:10D8800025580E00234008002000012D0700201419
+:10D8900000000000E0FF08212B3009000D000A10F5
+:10D8A00025484601F8FF001000000A340900001165
+:10D8B00000000000222008000430890004208A00B3
+:10D8C0000648090106500A010200C01025488900D7
+:10D8D000020029352678A7001C00E00500000000A2
+:10D8E00021482C012B782C0121504D0121504F0152
+:10D8F00002004D11000000002B784D013700E011AF
+:10D900000000000001002F310200E01100000000C3
+:10D910000200293542480900C07F0A0025482F012E
+:10D9200042500A000080013C2550410101006B2556
+:10D93000FF0701242900611500000000F07F013C71
+:10D940002528A10037000010000004242B782C01AA
+:10D9500023482C012B104F0123504F012B784D01F0
+:10D960002578E2010700E01123504D010080013CC1
+:10D970002628A1002B7809002348090023500A001B
+:10D9800023504F010800401500000000030020153F
+:10D99000000000000D00001000000B2425502001A5
+:10D9A00000000924E0FF6B252040487107000011AA
+:10D9B000000000002358680122200800062089008A
+:10D9C0000448090104500A01255044012578490101
+:10D9D0000200E01500000000000005246800601946
+:10D9E000000000000004292500042F2D21504F01C4
+:10D9F0002B784F0121586F01C27A09000100EF31E5
+:10DA000023482F01C2220900407D0A0025208F00F3
+:10DA100040780A00027B0F002528AF00007D0B0034
+:10DA20002528AF0025100400251805000800E00394
+:10DA3000000000002A7820012148290121504A01D4
+:10DA40002300601521504F01257849011400E01191
+:10DA50000000000008004015000000000300201531
+:10DA60000000000067FF001000000B24255020017B
+:10DA700000000924E0FF6B252040487161FF001180
+:10DA800000000000235868012220080006208900B9
+:10DA90000448090104500A015AFF001025504401AE
+:10DAA000FF0701241500C111000000002140E7001C
+:10DAB000257806010300E01500000000D9FFE0040E
+:10DAC0000000000025100600D8FF001025180700F0
+:10DAD000257849012700E01500000000FF07012418
+:10DAE000D0FFC115000000002678A7002100E00546
+:10DAF00000000000F3FF0010000000002A78800101
+:10DB000021608C012168AD011700C0152168AF01AB
+:10DB10002578AC01C3FFE011000000000800A0154B
+:10DB200000000000030080150000000039FF001015
+:10DB300000000E242568800100000C24E0FFCE25A3
+:10DB40002040A87133FF0011000000002370C801BD
+:10DB50002220080006208C0004600C0104680D01DE
+:10DB60002CFF00102568A4012578AC01D5FFE01139
+:10DB700000000000F8FF053CAAFF0010000004248C
+:10DB80000100082423400B012000012D0700201470
+:10DB900000000000E0FF08212B3009000D000A10F2
+:10DBA00025484601F8FF001000000A340900001162
+:10DBB00000000000222008000430890004208A00B0
+:10DBC0000648090106500A010200C01025488900D4
+:10DBD0000200293583FF001000000B24405005008F
+:10DBE00042550A00C04A0500427D040025482F0125
+:10DBF000C042040000800E3C25482E01406807000A
+:10DC0000426D0D00C0620700427D060025608F0155
+:10DC1000C05A060025608E012628A7002428AE00E1
+:10DC2000FFFF4F25FE07E12D4700201000000000F8
+:10DC3000FFFFAF25FE07E12D6F0020100000000060
+:10DC400002FCAF2521504F0119002C0112380000B1
+:10DC50001070000019000B011220000010300000AD
+:10DC600019002B0112580000106800002130CB0071
+:10DC70002B78CB002138ED002138EF000200ED10A9
+:10DC8000000000002B78ED002170CF0119000C017D
+:10DC900012400000104800002130C8002B78C80056
+:10DCA0002138E9002138EF000200E91000000000EF
+:10DCB0002B78E9002170CF01257886000200E01161
+:10DCC000000000000100E73425480E000600200592
+:10DCD000254007002A780001214008012148290138
+:10DCE00021482F01FFFF4A25FFFF4F25FE07E12DA9
+:10DCF00068002010000000000004082500040F2D1B
+:10DD000021482F012B782F0121504F01C27A0800A2
+:10DD10000100EF3123400F01C2220800407D0900BD
+:10DD200025208F0040780900027B0F002528AF00D6
+:10DD3000007D0A002528AF002510040025180500E5
+:10DD40000800E003000000002A78000121400801DB
+:10DD5000214829011C00401521482F012578280160
+:10DD60001400E01100000000080020150000000071
+:10DD70000300001500000000ADFF001000000A24A1
+:10DD80002548000100000824E0FF4A2520702E717C
+:10DD9000A7FFC0110000000023504E0122380E00E2
+:10DDA0000638E8000440C8010448C901A0FF00107B
+:10DDB00025482701FF0701243300A11100000000BE
+:10DDC000DDFF001000000000257828012E00E0157E
+:10DDD000000000000500A0150000000040780C00C5
+:10DDE0002578EB012800E01100000000FF07012466
+:10DDF0002100A115000000002A78600121586B0164
+:10DE000021608C011900A01521608F0125788B01FC
+:10DE10001400E01100000000080080150000000060
+:10DE2000030060150000000085FF001000000D24B5
+:10DE30002560600100000B24E0FFAD2520308671D5
+:10DE40007FFFC010000000002368A60122700600BA
+:10DE50000670CB010458CB000460CC0078FF0010A2
+:10DE600025608E01B4FF00100000042425788B018A
+:10DE70000500E01500000000F07F013C2528A1000E
+:10DE8000ADFF001000000424F8FF053CAAFF0010BD
+:10DE900000000424F8FF401D0000000001000E24D3
+:10DEA0002370CA012000C12D0700201400000000CB
+:10DEB000E0FFCE212B3008000D000910254026017F
+:10DEC000F8FF0010000009340900C0110000000034
+:10DED00022380E000430E8000438E9000640C8018A
+:10DEE0000648C9010200C0102540E80002000835BC
+:10DEF0000004082500040F2D21482F0183FF001086
+:10DF0000C25709004050050042550A00C04A0500AA
+:10DF1000427D040025482F01C042040000800E3CD1
+:10DF200025482E0140680700426D0D00C0620700C1
+:10DF3000427D060025608F01C05A060025608E01D3
+:10DF40002628A7002428AE00FFFF4F25FE07E12D5D
+:10DF5000CB00201000000000FFFFAF25FE07E12DE1
+:10DF6000F40020100000000023504D01FF034A255B
+:10DF700042400800C07F090025400F0142480900C7
+:10DF8000023C0C00F401E0001B00270112700000AD
+:10DF900010480000FFFF86311900CE00122000005B
+:10DFA000004C0900027C080025482F012B78240131
+:10DFB0000600E01123482401FFFFCE2521482C0153
+:10DFC0002B082C01FCFF201000000000F401E000F1
+:10DFD0001B00270112380000104800001900C7007C
+:10DFE00012200000004C0900FFFF0F3125482F01CF
+:10DFF0002B7824010600E01123482401FFFFE724C9
+:10E0000021482C012B082C01FCFF201000000000EF
+:10E0100000740E002170C7011900CB0112380000F6
+:10E0200010200000000008242B780701234007017E
+:10E030002B102F0123482F012B7824012578E20192
+:10E040000B00E01123482401FFFFCE2521400B01E6
+:10E050002B780B0121482C0121482F0102002C11A3
+:10E06000000000002B782C01F7FFE01100000000F9
+:10E0700006002C150000000025200B002548080094
+:10E0800000000D242A00001025380D00023C0C0071
+:10E09000F401E0001B002701126800001048000096
+:10E0A000FFFF86311900CD0012200000004C09004E
+:10E0B000027C080025482F012B7824010600E0117E
+:10E0C00023482401FFFFAD2521482C012B082C01FA
+:10E0D000FCFF201000000000F401E0001B002701FD
+:10E0E00012380000104800001900C700122000007C
+:10E0F000004C0900FFFF0F3125482F012B78240128
+:10E100000600E01123482401FFFFE72421482C01E9
+:10E110002B082C01FCFF201000000000006C0D00FB
+:10E120002168A7011900AB0112380000102000007F
+:10E13000000008242B780701234007012B102F0132
+:10E1400023482F012B7824012578E2010B00E011F0
+:10E1500023482401FFFFAD2521400B012B780B0143
+:10E1600021482C0121482F0102002C110000000041
+:10E170002B782C01F7FFE011000000000600C0051D
+:10E18000000000002A78A0012168AD012170CE01B5
+:10E190002170CF01FFFF4A25257828010200E011F8
+:10E1A000000000000100AD3525480E0025400D009F
+:10E1B000FFFF4F25FE07E12D150020100000000095
+:10E1C0000004082500040F2D21482F012B782F0172
+:10E1D00021504F01C27A08000100EF3123400F01A6
+:10E1E000C2220800407D090025208F0040780900E8
+:10E1F000027B0F002528AF00007D0A002528AF0014
+:10E2000025100400251805000800E00300000000A8
+:10E210004400401D0000000001000E242370CA01CC
+:10E220002000C12D0700201400000000E0FFCE21D7
+:10E230002B2008000D00091025402401F8FF0010D4
+:10E24000000009340900C0110000000022300E0057
+:10E250000420C8000430C9000640C8010648C901AE
+:10E26000020080102540C80002000835000408257F
+:10E2700000040F2D21482F01D6FF0010C2570900BE
+:10E280002A78000121400801214829011700401582
+:10E2900021482F01257828011400E011000000001A
+:10E2A0000800201500000000030000150000000019
+:10E2B00029FF001000000A2425480001000008245E
+:10E2C000E0FF4A2520702E7123FFC01100000000DE
+:10E2D00023504E0122300E000630C8000440C80111
+:10E2E0000448C9011CFF00102548260105004D15F2
+:10E2F0000000000040780C002578EB012B00E011B5
+:10E3000000000000FF0701240A00A1110000000026
+:10E31000BBFF401100000000257828012300E01514
+:10E3200000000000F07F013C2528A100B4FF001090
+:10E33000000004242A78600121586B0121608C01BF
+:10E340001700A01521608F0125788B01F5FFE011E2
+:10E3500000000000080080150000000003006015A8
+:10E360000000000000FF001000000D242560600187
+:10E3700000000B24E0FFAD2520708E71FAFEC01165
+:10E38000000000002368AE0122300E000630CB00F2
+:10E390000458CB010460CC01F3FE00102560860117
+:10E3A00025788B010200E01100000000F8FF053C19
+:10E3B00093FF0010000004240000052425480500F8
+:10E3C00025380500253004000C00C01000000000B6
+:10E3D0000600C104000000000080093C2B5005002D
+:10E3E00023280500233006002330CA001E0407241A
+:10E3F0002040C8702338E80004300601C2420500FE
+:10E400004055060025400A014050060002530A000C
+:10E4100025482A010055070025482A012510080033
+:10E42000251809000800E003000000000000052492
+:10E4300025380500253004000500C010000000004C
+:10E440001E0407242048C9702338E900043026013F
+:10E45000C24205004055060025400A01404806001A
+:10E46000024B09000055070025482A012510080025
+:10E47000251809000800E00300000000C23D040068
+:10E48000FF00E7300080013C24308100FFFFE924D9
+:10E49000FE00212D0C002010000000008003E72466
+:10E4A000404A0400024B09002530C900402F0400F7
+:10E4B000004D07002530C90025100500251806006D
+:10E4C0000800E00300000000000005242120840073
+:10E4D000F7FF8010000000000900E01400000000B9
+:10E4E000FFFFE724212084008000013C2B088100ED
+:10E4F000FBFF201400000000E8FF001000000000F7
+:10E50000FF07072400FF013C010021342B08810094
+:10E51000E7FF201400000000E5FF0010F8FF063CB4
+:10E52000C03A0500425D04002538EB00C03204000B
+:10E530000080013C2538E1000080013C2448A10016
+:10E54000404005004245080080FC0825FFFF0B25E0
+:10E55000FE00612D11002010000000000200C0101C
+:10E56000000000000100E7348000E7248000EB2C6D
+:10E5700021400B01025A070001006B312338EB00E8
+:10E5800040380700423A0700C05D08002538EB001C
+:10E590002510E9000800E003000000007F040124CA
+:10E5A00007000115000000004058070025586601CB
+:10E5B0000300601100000000F6FF0010C0FF023CE5
+:10E5C000FF0001290400201400000000807F013CAE
+:10E5D000F0FF00102510210101000A2423504801FA
+:10E5E0002000412D0300201400000000E9FF00106E
+:10E5F0002510090020000C2423608A01045887019B
+:10E600002530CB0006384701000008240080013C7B
+:10E61000D2FF00102538E100C03A05004255040041
+:10E620002538EA000080013C2538E1004050050013
+:10E6300042550A001E0406242330CA000B00C018ED
+:10E64000000000002000C12C020020140000000087
+:10E65000000007340200A1040638C7002338070071
+:10E66000251007000800E0030000000002008010F1
+:10E67000000000000100A534F07F013C01002134BE
+:10E680002B08A1000300201400000000F5FF00107B
+:10E690000080023CFF7F023CF2FF0010FFFF42348B
+:10E6A000C03A0500425504002538EA000080013CCC
+:10E6B0002538E1004050050042550A001E0406249A
+:10E6C0002330CA000B00C004000000002000C12C51
+:10E6D0000200201400000000000007340200A10422
+:10E6E0000638C70023380700251007000800E0039C
+:10E6F0000000000002008010000000000100A534AE
+:10E70000F07F013C010021342B08A10003002014FC
+:10E7100000000000F5FF00100080023CF3FF001035
+:10E72000FFFF0224FEFF0924405005004058070067
+:10E73000255864012558660125504B0103004015FA
+:10E74000000000003C0000100000022402008010C5
+:10E750004040050001000825E0FF013C0100213494
+:10E760002B08010136002010000000000200C0103C
+:10E770004040070001000825E0FF013C0100213472
+:10E780002B0801012E002010000000001600A1043B
+:10E79000000000000300E00400000000260000105C
+:10E7A000FFFF02242B508600232086002B58AA004E
+:10E7B0002328AA002B50A70025504B01030040112D
+:10E7C0002328A7001C000010010002242550A400EB
+:10E7D000030040110000000017000010FFFF02249A
+:10E7E00015000010000002240300E10400000000F6
+:10E7F00011000010010002242B5086002320860007
+:10E800002B58AA002328AA002B50A70025504B0103
+:10E81000030040112328A70007000010FFFF022477
+:10E820002550A40003004011000000000200001069
+:10E8300001000224000002240800E00300000000A0
+:10E84000FDFF0010251009000080013C2628A100D2
+:10E8500025100400251805000800E0030000000052
+:10E86000FF7F013CFFFF21342428A1002510040074
+:10E87000251805000800E0030000000002008010D9
+:10E880004040050001000825E0FF013C0100213463
+:10E890002B08010103002014000000000C000010F0
+:10E8A000010002240200C0104040070001000825BA
+:10E8B000E0FF013C010021342B080101030020147A
+:10E8C00000000000020000100100022400000224E9
+:10E8D0000800E003000000000080013C2628A100A1
+:10E8E000C24D0400FF002931C25D0500FF006B31FD
+:10E8F0000080073C0042040025400701005205004B
+:10E9000025504701FFFF2D25FE00A12D610020109D
+:10E9100000000000FFFF6D25FE00A12D77002010F4
+:10E920000000000023602B010D00800500000000A6
+:10E9300020008129030020140000000015000010B1
+:10E9400002000A2425300A0006508A0104688A0160
+:10E950001000A611000000000E00001002004A3551
+:10E9600025480B0023600C0020008129030020149F
+:10E9700000000000070000100200082425300800F5
+:10E9800006408801046888010200A611000000000A
+:10E990000200083524608700266885011000A00564
+:10E9A0000000000021400A012B680A011700A01195
+:10E9B0000000000001000D310200A0110000000065
+:10E9C000020008354240080001002925FF0001240B
+:10E9D0000E002115000000000C00001000000824AB
+:10E9E0002B680A010400A01123400A0123400800FB
+:10E9F0000300001026608701500000110000000095
+:10EA000020300671234826010440C8000E0020195A
+:10EA1000000000008000082580000D2D21482D01F8
+:10EA2000026A08000100AD3123400D01404008009A
+:10EA300042420800C06D090025400D0125100C015F
+:10EA40000800E00300000000010006242330C90094
+:10EA50002000C12C39002010000000000080013C83
+:10EA60002540010120000D242368A6010448A801C7
+:10EA7000020020110640C8000100083500000924EA
+:10EA800080000D25E3FFA10500000000E1FF00105C
+:10EA9000010009240E00201500000000214008019B
+:10EAA000050000110000000020600C7123482C01BB
+:10EAB00098FF001004408801FF0001240F0061113D
+:10EAC000000000000080013C1800A11400000000BC
+:10EAD000216808011B00A01500000000FF000124B0
+:10EAE0001400611500000000266885001500A005CF
+:10EAF000000000000D00001000000000080060157C
+:10EB00000000000021504A010A00401100000000EE
+:10EB100020604C7123586C0182FF001004508A0160
+:10EB200021684A010700A01500000000C4FF001082
+:10EB300025100500C2FF001025100400C0FF0010C2
+:10EB400000000224BEFF0010C0FF023CC23D0400D2
+:10EB5000FF00E730C24D0500FF00293100800A3C6C
+:10EB6000003204002530CA000042050025400A0199
+:10EB70002660850024504C01FFFFEC24FE00812D0F
+:10EB80002100201000000000FFFF2C25FE00812D39
+:10EB900036002010000000001900C80012580000C4
+:10EBA00002006011103000000100C6340300C004F0
+:10EBB0000000000040300600FFFFE72482FF2C2504
+:10EBC0002138EC00FFFFEC24FE00812D3A002010DC
+:10EBD000000000008000C6248000CC2C2138EC000E
+:10EBE0000262060001008C312330CC004030060068
+:10EBF00042320600C06507002530CC002510CA004F
+:10EC00000800E003000000000D00E0140000000018
+:10EC10002130C6000500C010000000002058CB7055
+:10EC20002338EB00D8FF001004306601FF000124F8
+:10EC30001F0021110000000015000010000000005E
+:10EC40002160C6001A008015000000000400201595
+:10EC50000000000021600801150080110000000084
+:10EC6000FF0001240F002115000000000A002015FC
+:10EC70000000000021400801050000110000000014
+:10EC800020580B7123482B01C3FF0010044068017A
+:10EC9000DBFF001025100A00216008010400801528
+:10ECA00000000000807F013CD5FF001025104101CD
+:10ECB000D3FF0010C0FF023CFAFFE01C0000000080
+:10ECC00001000B24235867012000612DF0FF201064
+:10ECD0000000000020000C2423608B010438860112
+:10ECE0000200E010063066010200C634000007246E
+:10ECF0008000CC24B7FF810500000000B5FF0010A4
+:10ED00000100072400800B3CC2450400FF000831CD
+:10ED1000C2550500FF004A31003A04002538EB00D7
+:10ED2000004A050025482B012670850024586E01F5
+:10ED3000FFFF0E25FE00C12D3F0020100000000047
+:10ED4000FFFF4E25FE00C12D5300201000000000E3
+:10ED50002B08E900030020140000000042380700DF
+:10ED60000100082582630900F40180011B00EC000A
+:10ED70001220000010300000FF3F2D311900A401C7
+:10ED800012280000803306002B70C5000400C0115B
+:10ED90002330C500FFFF84242130C9002B70C90037
+:10EDA000F40180011B00CC0012380000103000007C
+:10EDB0001900A70112280000803306002B70C5003F
+:10EDC0000400C0112330C500FFFFE7242130C90033
+:10EDD0002B70C900807304002138EE000200C010BF
+:10EDE000003907000100E7347E000E242370CA01B9
+:10EDF00021400E01FFFF0E25FE00C12D3400201022
+:10EE0000000000008000E7248000EE2C21400E016D
+:10EE1000027207000100CE312338EE0040380700AF
+:10EE2000423A0700C07508002538EE002510EB00B7
+:10EE30000800E003000000000800001500000000CA
+:10EE40002138E7000500E010000000002060EC70B1
+:10EE500023400C01BAFF0010043887010400481554
+:10EE600000000000217029012F00C01100000000E7
+:10EE7000FF000124080041110000000012000011F1
+:10EE8000000000002170E7002700C015000000000E
+:10EE900022000010000000000800401500000000E3
+:10EEA000214829011D0020110000000020602C7164
+:10EEB00023504C01A6FF001004488901217029014C
+:10EEC0001900C01500000000D9FF001025100B002C
+:10EED0001200001D0000000001000C2423608801C6
+:10EEE0002000812DF8FF20100000000020000E24DB
+:10EEF0002370CC010440C7010200001106388701CD
+:10EF00000200E734000008248000EE24BDFFC105A4
+:10EF100000000000BBFF001001000824807F013CBE
+:10EF2000C3FF001025106101C1FF0010C0FF023CAB
+:10EF30000080013C12008010243081000200810416
+:10EF400000000000232004009E0005242038877064
+:10EF50002328A7000420E400800084248000882C5B
+:10EF60002128A80003420400010008312320880062
+:10EF70004020040042220400C045050025208800EE
+:10EF8000251086000800E003000000000F0080103C
+:10EF9000000000009E000624202885702330C50054
+:10EFA0000420A400800084248000872C2130C70026
+:10EFB000023A04000100E7302320870040200400CB
+:10EFC00042220400C03D06002520870025100400D1
+:10EFD0000800E00300000000002A04000080013C5B
+:10EFE0002528A100C23D0400FF00E7309E00062452
+:10EFF0002330C7000C00C018000000002000C1280A
+:10F00000030020140000000005000010000002248E
+:10F01000020081040628C5002328050025100500EC
+:10F020000800E00300000000807F013C0100213463
+:10F030002B0881000300201400000000F8FF0010DE
+:10F040000080023CFF7F023CF5FF0010FFFF4234CE
+:10F05000002A04000080013C2528A100C23D0400D4
+:10F06000FF00E7309E0006242330C7000C00C004D8
+:10F07000000000002000C128030020140000000050
+:10F080000500001000000224020081040628C500CB
+:10F0900023280500251005000800E00300000000FB
+:10F0A000807F013C010021342B08810003002014E3
+:10F0B00000000000F8FF00100080023CF6FF001086
+:10F0C000FFFF0224FEFF0824403004004038050002
+:10F0D0002548C7001B0020110000000000FF013C74
+:10F0E000010021342B08C10019002010000000008D
+:10F0F00000FF013C010021342B08E1001400201026
+:10F1000000000000020081044230060023300600A7
+:10F110000200A10442380700233807002A08C7006C
+:10F12000030020100000000007000010FFFF022471
+:10F130002A08E60003002010000000000200001072
+:10F1400001000224000002240800E0030000000087
+:10F15000FDFF0010251008004010040042100200BE
+:10F160000800E003000000000080013C2610810040
+:10F170000800E003000000004030040000FF013CF4
+:10F18000010021342B08C1000300201400000000FE
+:10F190000A000010010002244030050000FF013C7D
+:10F1A000010021342B08C1000300201400000000DE
+:10F1B0000200001001000224000002240800E00305
+:10F1C00000000000B8FFBD274800A4AF4000BEAF5C
+:10F1D0003400B5AF3000B4AF2C00B3AF4400BFAFC4
+:10F1E0003C00B7AF3800B6AF2800B2AF2400B1AFD3
+:10F1F0002000B0AF00008880029D063C4D17C4245B
+:10F2000021100401000047804800B38F8800E330DC
+:10F210004C00A5AF1000A0AF1400A0AF21F000007B
+:10F220001800A0AF21A000000800601021A8000075
+:10F23000010073260000688221500401000049810A
+:10F2400088002531FBFFA054010073262D00042403
+:10F25000D40004112B000C24D7000C51010073269C
+:10F260004D17D724217017010000CD910400A6315D
+:10F270001B00C01001000F24029D163C1800AFAF08
+:10F280006819C68E6C19C78ED0FF12252128A002DE
+:10F29000F776400F212080022120400221A8400063
+:10F2A000EE78400F21A06000213040002120A00214
+:10F2B0002128800221386000EE75400F010073267E
+:10F2C0000000688225F0D2032190170100005192BE
+:10F2D00021A0400004003032E9FF001621A86000A0
+:10F2E0002E0016248A001651010073261800A48FE0
+:10F2F000280080104C00A48F4500063965000D39A8
+:10F300000100AB2D0100CC2C25406C012100001127
+:10F310004C00A48F01007326000064822D000E248F
+:10F3200021280000AF008E10213800002B000F2490
+:10F33000A3008F500100732621C097000000169390
+:10F340000400D7320D00E012029D193C4D1726270C
+:10F35000809005002150450240280A0001007326D4
+:10F360002148A400000064822118860000006290F9
+:10F3700004005F30F6FFE017D0FF25251400B18FA1
+:10F38000238005000B280702213825021400A7AFAF
+:10F390004C00A48F050080104800AB8F1800AC8F84
+:10F3A0004C00A88F0A986C01000013AD1400A28FC6
+:10F3B00028004010029D1F3CC39F0200029D0F3C8D
+:10F3C00026705300029D0D3C081AE68D0C1AE78D3D
+:10F3D0002390D30121B04000B819B32503000010D9
+:10F3E000090003241000001221180002FFFF7024FE
+:10F3F00007C01202C0C803000100173321403303C5
+:10F400002120C000F7FFE0122128E0000000068D57
+:10F41000F776400F0400078D21386000213040004E
+:10F42000F2FF0016211800026A00C00621208002A7
+:10F43000F776400F2128A0022120400021286000FB
+:10F44000827D400F2130C00221A0400021A8600031
+:10F45000029D1F3C141AF68F040080162438B60251
+:10F46000F07F023C5800E210220003242590950210
+:10F470000100452E2B501E002448AA005D00205597
+:10F48000220015241000A78F0E00E0142110800226
+:10F490002118A0024400BF8F4000BE8F3C00B78FF0
+:10F4A0003800B68F3400B58F3000B48F2C00B38F86
+:10F4B0002800B28F2400B18F2000B08F0800E00335
+:10F4C0004800BD2721208002127A400F2128A00287
+:10F4D00021A0400021A86000211080022118A00274
+:10F4E0004400BF8F4000BE8F3C00B78F3800B68FFE
+:10F4F0003400B58F3000B48F2C00B38F2800B28F4A
+:10F500002400B18F2000B08F0800E0034800BD2721
+:10F510000000688221F817010000F99304003833D5
+:10F5200072FF0013029D163C010003241800A3AFD4
+:10F530006819C68E6C19C78ED0FF12252128A0022B
+:10F54000F776400F212080022120400221804000D8
+:10F55000EE78400F218860002138600021282002C9
+:10F560002120000221304000EE75400F010073267B
+:10F57000000068821400A98F2150170121A04000CB
+:10F5800000004291FFFF25250400473021A86000BC
+:10F5900025F0D203E6FFE0141400A5AF57FF0010DA
+:10F5A00045000639010073260000688201000B2423
+:10F5B0002BFF00101000ABAF29FF00100000688285
+:10F5C0005DFF00100000648200A01E3CADFF001033
+:10F5D0000402C3AFC177400F2128A00297FF00109B
+:10F5E00021204000010073260000648252FF0010B9
+:10F5F0000100072400A0143C040295AE21A00000E5
+:10F60000A0FF001021A800000055A77CFFFFE32405
+:10F61000FE07622C214080002150C000C007AB7C57
+:10F620003F0040100098A97C029D043C1C1A858C68
+:10F6300001FCE424253025012148C00021788A00FE
+:10F64000C048090042570800FF03E72525482A0162
+:10F650004100E018C0400800070006311D00C0143A
+:10F66000C000057D40670900C2300800FF07E4289C
+:10F670002540CC0031008010C2480900029D033CA7
+:10F680001C1A798C2178000024C039012550F8011A
+:10F69000070040512138000021100001029D083C64
+:10F6A0002C1A058D21404000247025012148C001FD
+:10F6B000C06A0B002520A70100350400216000006E
+:10F6C000252088012528C900211080000800E003BA
+:10F6D0002118A0000300A2242118000021400201EB
+:10F6E000029D183C2BC8020121482301241A0F8FC8
+:10F6F000214839012168000024502F012560AA010A
+:10F70000D9FF801140670900C07709004240080016
+:10F7100025400E0142480900D2FF00100100E724F5
+:10F720000400E01421108000253889002900E0142D
+:10F73000026809000800E0032118A000C06A0B005D
+:10F74000FF07A735002D07002120000021108000B1
+:10F750000800E0032118A00001001924233027032A
+:10F760003800D82818000053010008242328060078
+:10F770002000A2302718C0000660C80004186900E5
+:10F780000668C90040180300256083012000C330CB
+:10F790000B60A3010B68030021500001040040141A
+:10F7A0000418A800021809000440A3002518480105
+:10F7B0002B20030021280000254084012548A501B5
+:10F7C000A5FF00102138E60021480000A2FF00102C
+:10F7D0002138E60002FC04240300A0152018A371C0
+:10F7E00020700E712000C325F5FF632494FF601084
+:10F7F00021788A002710600004386900061048004C
+:10F8000004306800421002002538E2002000623017
+:10F810000B38C2000B300200232083002140C000BF
+:10F8200086FF00102148E00080BF033C105A648C22
+:10F830000000827CFDFF40100000000080BF033C00
+:10F84000205A628C0800E003000000000800E0037A
+:10F8500000606241E8FFBD271000BFAF00680540AF
+:10F860008000063C2520A600006884400010032488
+:10F8700088BF023C477E400F081043AC1000BF8F8A
+:10F880000800E0031800BD27010084300300801049
+:10F89000000000000800E003206060410800E00371
+:10F8A00000606041E8FFBD271000BFAF137E400F2E
+:10F8B0000000000088BF043C0030838C0003627CA1
+:10F8C0000800401499AA0F3C0010062488BF053C8C
+:10F8D0000830A6AC0030888C0003077DFDFFE010E7
+:10F8E00099AA0F3C66550D3C81BF0B3C5566EE3521
+:10F8F000AA99AC3501000A2481BF093C30F260AD01
+:10F9000081BF043C30F26EAD30F26CAD18F62AAD1A
+:10F9100010F6828CFFFF0010000000000800E003DA
+:10F92000206062412118E0002140A0002138C00081
+:10F930003A006014216080002B10A6008C0040105B
+:10F94000000000002030C670C200C014232806004A
+:10F95000023407001B000601F401C000FFFFEB307A
+:10F9600002740C001248000010C000001250000089
+:10F9700002482B71007C18002528EE012B68A90095
+:10F980001B000601F401C0000900A0512320A900BA
+:10F990002128A7002B40A70004000015FFFF4A25DF
+:10F9A0002BC8A900FC002057FFFF4A252320A900EF
+:10F9B0001B008600F401C000FFFF833112680000C5
+:10F9C00010280000124800000258AB710014050016
+:10F9D000254043002B600B011B008600F401C00092
+:10F9E00009008051005C0A00214007012B3007010B
+:10F9F0000400C014FFFFA9252B700B012B380E004B
+:10FA000023482701005C0A002520690121300000FD
+:10FA1000211080000800E0032118C0002B58A3002B
+:10FA200021200000FAFF6015213000002048697095
+:10FA30008E0020112B10870120000D242370A901B6
+:10FA4000045023010678C70125684F0106C8C50187
+:10FA500002540D001B002A03F401400106C0CC0132
+:10FA600004282501FFFFAF312570B80004C02C0128
+:10FA7000021C0E000438270112200000105800005C
+:10FA80001260000002408F70004C0B0025582301CB
+:10FA90002B3068011B002A03F40140010B00C05009
+:10FAA0002318680121586D012B106D0106004014C8
+:10FAB000FFFF8C242B3068010400C010231868015C
+:10FAC000FFFF8C2521586D01231868011B006A0077
+:10FAD000F4014001FFFFCB3112480000104000004C
+:10FAE0001230000002482F710024080025408B00CE
+:10FAF0002BC809011B006A00F40140010B002053D0
+:10FB0000007C0C0021400D012B280D010600A014E3
+:10FB1000FFFFC6242B7009010400C011007C0C00FB
+:10FB200021400D01FFFFC624007C0C002520E601CA
+:10FB30001900870010280000231809012B606500B8
+:10FB400009008055FFFF8424121000002668A300DE
+:10FB50002B5002030100B82D24380A03ACFFE050FB
+:10FB600021300000FFFF8424A9FF00102130000095
+:10FB70004500C01001000A242050EA7049004015D9
+:10FB8000200009242328070101000624024C070055
+:10FB9000FFFFED301B00A900F401200102CC0C0096
+:10FBA00012500000101800001258000002504D7151
+:10FBB00000240300254099002B700A011B00A900B6
+:10FBC000F40120010900C01123780A012140070136
+:10FBD0002B2807010400A014FFFF6B252B100A013E
+:10FBE0006B004054FFFF6B2523780A011B00E901DD
+:10FBF000F4012001FFFF983112C8000010400000FE
+:10FC00001250000002602D73007408002540D801D6
+:10FC10002B680C011B00E901F40120010900A0116F
+:10FC2000001C0B00214007012B480701050020158F
+:10FC3000FFFF2A272B380C012B60070023504C01B3
+:10FC4000001C0B0025206A00211080000800E00342
+:10FC50002118C0000620A4000418C8002540640034
+:10FC60000460CC003AFF00100438C7002B20650068
+:10FC700001004538255085002B200A002110800006
+:10FC80000800E0032118C0001B004601F401C00079
+:10FC9000123800002050EA70BBFF401123280701F2
+:10FCA0002000092423782A010438470106C8E80106
+:10FCB000024C07001B002903F40120010670EC012F
+:10FCC00004104801FFFFED3025784E0002240F009C
+:10FCD0001230000010280000127000000240CD70A9
+:10FCE000001C0500255864002BC068011B00290377
+:10FCF000F40120010A00001304604C01215867013F
+:10FD00002B50670106004015FFFFCE242BC0680171
+:10FD10000400001323C86801FFFFCE2521586701A6
+:10FD200023C868011B002903F4012001FFFFE4310F
+:10FD30001228000010400000123000000250AD7088
+:10FD4000001C0800254064002B580A011B002903F1
+:10FD5000F40120010B00601100C40E0021400701D6
+:10FD60002B10070107004014FFFFA6242B780A017F
+:10FD70000500E05125300603FFFFC624214007019E
+:10FD800000C40E002530060382FF001023280A015C
+:10FD900095FF00102140070104FF00102128A70053
+:10FDA000E8FFBD272140E0001000B2AF0C00B1AF6A
+:10FDB0000800B0AF2190A0032150C000215880005E
+:10FDC000400000152138A0002B10A6005C00401058
+:10FDD0002070CE707900C01523280E00024C0A0056
+:10FDE0001B00E900F4012001FFFF4F3102640B000A
+:10FDF000128000001030000002280F72006C060014
+:10FE00002530AC012B40C5001B00E900F4012001A6
+:10FE10000A0000112318C5002130CA002B38CA007F
+:10FE20000600E0142318C5002BC8C5000000383BAD
+:10FE30002188CA000B3038022318C5001B00690056
+:10FE4000F4012001FFFF713112C8000010C0000052
+:10FE500002582F73007C18002540F1012B380B014C
+:10FE60001B006900F40120010A00E01023180B01B7
+:10FE700021400A012B480A010600201523180B0116
+:10FE80002B100B0121200A0100004A380B408A0088
+:10FE900023180B010660C301030040122168000013
+:10FEA00000004CAE04004DAE0000A28F0400A38FF2
+:10FEB0001000B28F0C00B18F0800B08F0800E00373
+:10FEC0001800BD272B70A8000A00C05120700E71C9
+:10FED0001000B28F0C00B18F0800B08F211080008D
+:10FEE0002118A0000000A4AF0400A5AF0800E003A3
+:10FEF0001800BD273700C01520000F242B6886008E
+:10FF00000100AC392B3005012528CC000700A010DA
+:10FF10002160600123808A002388E8002B40900044
+:10FF2000233828022158000221606001DEFF4012C0
+:10FF30002168E00000004CAEDBFF001004004DAE75
+:10FF40007E00C0100100092420704E718200C0158F
+:10FF500020000F242330EA00024C0A00FFFF4F313B
+:10FF60001B00C900F401200102240B001240000014
+:10FF70001028000002380F71001C050025286400BD
+:10FF80002B10A7001B00C900F4012001ABFF40109B
+:10FF90002318A7002128AA002B30AA00A7FFC054CD
+:10FFA0002318A7002B80A70000000D3A2160AA00AB
+:10FFB0000B288D01A1FF00102318A7000620A40024
+:10FFC0000418C701253864000450C60183FF0010DF
+:10FFD0000458CB0123C0EE010448C80106C806033B
+:10FFE0002578390106200503024C0F001B0089000B
+:10FFF000F401200106380B030468C501FFFFF1314D
+:020000041D02DB
+:1000000025C8A7010480CB010438CA01021C1900CD
+:100010001230000010600000125800000250D17031
+:10002000002C0C002540A3002B100A011B008900A6
+:10003000F40120010B00405023180A0121400F0158
+:100040002B100F0106004014FFFFCB242B200A01C8
+:100050000400801023180A01FFFF6B2521400F01C7
+:1000600023180A011B006900F4012001FFFF25335A
+:100070001250000010400000123000000250517178
+:1000800000640800254085012B880A011B006900D7
+:10009000F40120010B00201200140B0021400F017D
+:1000A0002B680F010700A015FFFFC6242BC80A010B
+:1000B0000500201325484600FFFFC62421400F01FC
+:1000C00000140B00254846001900270110300000DD
+:1000D00023400A012B580601070060151228000072
+:1000E0002660C8000100912D2B1805022420230250
+:1000F00006008010000000002350A7002B38AA0043
+:100100002368CF002330A7012128400166FF401259
+:1001100023780502232806012B400F022380A80024
+:100120000430100306C0CF012560D8000668D00156
+:1001300000004CAE5CFF001004004DAE1B00260119
+:10014000F401C0001250000020704E7182FFC011F7
+:100150002330EA0020000F242380EE010450CA015E
+:1001600006200702024C0A001B008900F40120014E
+:1001700006680B020430C701FFFF4F312538CD0060
+:10018000021C0700126000001040000002308F7156
+:10019000002C08002540A3002B1006011B0089003D
+:1001A000F4012001050040100458CB0121400A0150
+:1001B0002B880A01190020122B10060123180601B2
+:1001C0001B006900F4012001FFFFE5301268000008
+:1001D000106000000238AF7100440C0025300501AA
+:1001E0002B20C7001B006900F40120015CFF805038
+:1001F0002330C7002130CA002B80CA0058FF0056A8
+:100200002330C7002BC8C7000000383B2188CA0034
+:100210000B30380252FF00102330C700000059385D
+:1002200021C00A01E5FF00100B401903FFFFFFFF8B
+:100230005261704D616E205665723A312E302E3902
+:1002400000000000496E736572742053442D4361B1
+:100250007264206F720000003C3C45534320544FB1
+:1002600020524553554D4500496E76616C696420B6
+:1002700046696C652054797065000000506C6561BA
+:100280007365206F6E6C7920757365002A2E424667
+:1002900042206F72202A2E47434F2046696C6573B7
+:1002A0000000000050415553450000004572726F38
+:1002B0007220544553540000457874727564657219
+:1002C000204F46460000000046696C65204572726A
+:1002D0006F72203A7365656B20707400556E6B6E9B
+:1002E0006F776E204572726F72000000203C45539C
+:1002F0004320544F20524553455400003C00000019
+:10030000000002430000C8C2546F6F6C3A20506571
+:100310006E000000546F6F6C3A20457874727564FB
+:1003200065720000546F6F6C3A2045787472756482
+:1003300065723200546F6F6C3A204E6F74204465C2
+:1003400066696E6564000000546F6F6C3A20526FEE
+:100350007574657200000000546F6F6C3A204E6F28
+:100360006E6500007200000046696C65204572727F
+:100370006F7220202020000046696C65204E6F744B
+:1003800020466F756E6400004F70656E00000000BF
+:100390002A2E2A0046696E642046697273742045CD
+:1003A00072726F72000000004E6F2066696C657398
+:1003B000206F6E20636172640000000046696C6506
+:1003C00000000000253375006F6600000000004447
+:1003D0000000FE420000FE42204F4B2000000000C3
+:1003E000544553540000000025362E3266000000AC
+:1003F000CDCCCCCCCCE45540000020455A20444F15
+:10040000574E2020202020005920464F525741525D
+:1004100044202000484F4D45205820202020000037
+:10042000484F4D452059202020200000484F4D4581
+:10043000205A202020200000484F4D452041424FA7
+:100440005254454400000000484F4D4520434F4D55
+:10045000504C455445000000CDCCCCCCCCE45540AC
+:1004600039B4C876BE9FF63F0000C84200000000C5
+:10047000CDCCCCCCCCE455400000204500000000A1
+:10048000CDCCCCCCCCE4554000808443000048C3A4
+:10049000000002430000C8C2000000000000E03F6E
+:1004A000000000000000E03F000000000000E0BF8E
+:1004B00054454D5045524154555245204348414EB4
+:1004C00047450000440B019D6C0D019D6C0D019D85
+:1004D0006C0D019D6C0D019D6C0D019D6C0D019DC0
+:1004E0006C0D019D6C0D019D6C0D019D6C0D019DB0
+:1004F0006C0D019D6C0D019D6C0D019D6C0D019DA0
+:100500006C0D019D6C0D019D040D019D6C0D019DF7
+:100510006C0D019D6C0D019D6C0D019D580A019D96
+:100520006C0D019D6C0D019D6C0D019D6C0D019D6F
+:100530006C0D019D6C0D019D6C0D019D6C0D019D5F
+:100540006C0D019D440B019D6C0D019D6C0D019D79
+:100550006C0D019D6C0D019D6C0D019D6C0D019D3F
+:100560006C0D019D6C0D019D6C0D019D6C0D019D2F
+:100570006C0D019D6C0D019D6C0D019D6C0D019D1F
+:100580006C0D019D6C0D019D040D019D6C0D019D77
+:100590006C0D019D6C0D019D6C0D019D580A019D16
+:1005A0002E2E00002020202020202020202020008F
+:1005B00000000000009500000000000000000000A6
+:1005C00001F90000000000000000000009AF000079
+:1005D00000000000010000000A1B000000000000F5
+:1005E000010000000CC3000000000000000000003B
+:1005F0000DAF0000020000000000000010FF00002E
+:10060000000000000000000011FF000000000000DA
+:100610000100000012FF00000000000001000000C7
+:1006200018FF0000000000000100000019FF00009A
+:10063000000000000100000020FF0000000000009A
+:100640000000000021FF000000000000000000008A
+:1006500026DF0000010000000000000037730000EA
+:1006600000000000000000003A2500000300000028
+:10067000000000003B25000000000000000000001A
+:1006800000040000FF030000FE030000FC03000064
+:10069000FA030000F7030000F2030000EC0300007F
+:1006A000E3030000D8030000C9030000B603000004
+:1006B0009F03000083030000610300003B03000070
+:1006C00010030000E1020000AF0200007B02000006
+:1006D0004702000013020000E0010000B101000029
+:1006E000840100005A0100003501000013010000E0
+:1006F000F4000000D9000000C1000000000000006C
+:1007000000000000389C2C4100000000000039402F
+:10071000000080BF00C0794400C07944000080BF61
+:10072000000020410000000000000000389C2C4127
+:100730000000000000003940000000000000000040
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:10077000E0E0606060FFFF6363E3E3030303FFFF08
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F000FFFFC0C0C0C7C7C6C6FFFF060606070783
+:1008000000000000000000000000000000000000E8
+:1008100000000000000000000000000000000000D8
+:1008200000000000000000000000000000000000C8
+:1008300000000000000000000000000000000000B8
+:1008400000000000000000000000000000000000A8
+:100850000000000000000000000000000000000098
+:100860000000000000000000000000000000000088
+:100870000000000000000000000000000000000078
+:100880000000000000000000000000000000000068
+:100890000000000000000000000000000000000058
+:1008A0000000000000000000000000000000000048
+:1008B000000000000000000000000040C0C0C0C0F8
+:1008C000C0C0C0C0C0C0C0C0C0C0C0C08080000028
+:1008D0000000000000000000000000000000000018
+:1008E0000000000000000000000000000000000008
+:1008F00000000000000040C0C0C0C0C0C0C0C08038
+:10090000000000000080C0C0C0C0C0C0C0C0400027
+:1009100000000000000000000000000000000000D7
+:1009200000000000000000000000000000000000C7
+:10093000000000000000000000000000FFFFFFFFBB
+:10094000FFFFFF7171F1F1FFFFFFFFFF7F3F00002D
+:10095000009C9C9C9C9C9C9C9C9CFCFCFCFCFCF837
+:10096000F0000004FCFCFCFCFCFCF81C1C1CFCFC67
+:10097000FCFCFCF8F00000FFFFFF0F7FFFFFFFFF14
+:10098000FCE000E0FC3F07FFFFFFFFFFFFFF000070
+:1009900000009C9C9C9C9C9C9C9C9CFCFCFCFCFCEF
+:1009A000F8F0000000FCFCFCFCFCFCF81C1C1CFC2F
+:1009B000FCFCFCFCF8F00000000000407F7F7F7F23
+:1009C0007F7F7F400000073F7F7F7F7F7C704000FC
+:1009D0003F7F7F7F7F7F7F7171717F7F7F7F7F7F91
+:1009E0007F400000FFFFFFFFFFFFFF7070707F7F01
+:1009F0007F7F7F7F3F00407F7F7F0000031F7F7FDF
+:100A00007F7F7F0F0100407F7F7F7F7F7F7F400060
+:100A1000003F7F7F7F7F7F7F7171717F7F7F7F7FCF
+:100A20007F7F4000407F7F7F7F7F7F7F4000407FD0
+:100A30007F7F7F7F7F7F400000000000000000007C
+:100A400000000000000000000000000000000000A6
+:100A50000000000000000000000000000000000096
+:100A60000000000007070707070707040000000051
+:100A70000000000000000000000000000000000076
+:100A80000000000000000000000000000000000066
+:100A90000000000000000000000000000000000056
+:100AA0000000000000000000000000000000000046
+:100AB0000000000000000000000000000000000036
+:100AC0000000000000000000000000000000000026
+:100AD0000000000000000000000000000000000016
+:100AE0000000000000000000000000000000000006
+:100AF00000000000000000000000000000000000F6
+:100B000000000000000000000000000000000000E5
+:100B100000000000000000000000000000000000D5
+:100B200000000000000000000000000000000000C5
+:100B300000000000000000000000000000000000B5
+:100B400000000000000000000000000000000000A5
+:100B50000000000000000000000000000000000095
+:100B6000000000000000000000C060301088E45465
+:100B70006E6E26F32F272323272FF3266E5664CC81
+:100B8000983020E08000000000000000000000001D
+:100B90000000000000000000000000000000000055
+:100BA0000000000000000000000000000000000045
+:100BB0000000000000000000000000000000000035
+:100BC0000000000000000000000000000000000025
+:100BD0000000000000000000000000000000000015
+:100BE000000000000000C0FC472632F93F10080852
+:100BF00008F80F0908080808080809FF080808107D
+:100C0000173DF326655FFCC00000000000000000F7
+:100C100000000000000000000000000000000000D4
+:100C200000000000000000000000000000000000C4
+:100C300000000000000000000000000000000000B4
+:100C400000000000000000000000000000000000A4
+:100C50000000000000000000000000000000000094
+:100C60000000000000000F74C888107FD0302060A2
+:100C7000607FC04040404040404040FF60602030C6
+:100C800010F01F90D8E87C0F00000000000000006A
+:100C90000000000000000000000000000000000054
+:100CA0000000000000000000000000000000000044
+:100CB0000000000000000000000000000000000034
+:100CC0000000000000000000000000000000000024
+:100CD0000000000000000000000000000000000014
+:100CE000000000000000000003070D3B276E5CA819
+:100CF000C888977CD090101090D03C97D8E8B8CC9A
+:100D000067371B0D07010000000000000000000015
+:100D100000000000000000000000000000000000D3
+:100D200000000000000000000000000000000000C3
+:100D300000000000000000000000000000C0C040F3
+:100D40004040C0C08000C000C0C0C0C08080C000A3
+:100D500080C0C0C0C0000000000000C0C0C0C0C053
+:100D600000000000C0C0C0C0C0C0C080000080C083
+:100D7000C0C1C1C1810303C383030101010000801D
+:100D8000C00000000000C0C0404040C0C080000063
+:100D9000C0C000000080C00000C0C0C0C08080C0D3
+:100DA0000080C0C0C0C00000000080C0C0C0C00043
+:100DB000000000000000000000000000003F3F268F
+:100DC0002226361F0F003F0000003F3F00000000BA
+:100DD00033333434343C18000000003F3D04040435
+:100DE000040404003F3F060E1E1E362700061F3077
+:100DF000303030301F06003F030F1C38381C0F0303
+:100E00003F00000000003F3F262226361F0F000053
+:100E10000001033E03010000000000003F0000004D
+:100E2000001F1F3434343434340033333434343C0E
+:100E3000180000000000000000000000000000009A
+:100E400000000000000000000000000000000000A2
+:100E50000000000000000000000000000000000092
+:100E60000000000080808000E0F0F81818B0A000BA
+:100E7000E0F0F818F8F0E000F8F8F810F8F8F018DA
+:100E8000F8F8F00000000000000000000000000082
+:100E90000000000000000000000000000000000052
+:100EA0000000000000000000000000000000000042
+:100EB0000000000000000000000000000000000032
+:100EC0000000000000000000000000000000000022
+:100ED0000000000000000000000000000000000012
+:100EE00000000000030303000001030303010000EE
+:100EF00000010303030100000303030003030300D5
+:100F000003030300000000000000000000000000D8
+:100F100000000000000000000000000000000000D1
+:100F200000000000000000000000000000000000C1
+:100F300000000000000000000000000000000000B1
+:100F400000000000000000000000000000000000A1
+:100F50000000000000000000000000000000000091
+:100F60000000000000000000000000000000000081
+:100F70000000000000000000000000000000000071
+:100F80000000000000000000000000000000000061
+:100F90000000000000000000000000000000000051
+:100FA0000000000000000000000000000000000041
+:100FB0000000000000000000000000000000000031
+:100FC0000000000000000000000000000000000021
+:100FD0000000000000000000000000000000000011
+:100FE0000000000000000000000000000000000001
+:100FF00000000000000000000000000000000000F1
+:1010000000000000000000000000000000000000E0
+:1010100000000000000000000000000000000000D0
+:1010200000000000000000000000000000000000C0
+:1010300000000000000000000000000080402020B0
+:1010400040800000000000000000000000000000E0
+:101050000000000000000000000000000000000090
+:101060000000000000000000000000000000000080
+:101070000000000000000000000000000000000070
+:101080000000000000000000000000000000000060
+:101090000000000000000000000000000000000050
+:1010A0000000000000000000000000000000000040
+:1010B00000000000000000000000FC0300C0C0C0F1
+:1010C000C00003FC00000000000000000000000061
+:1010D00000000000000000000000020502003C4289
+:1010E0008181816600000000000000000000000017
+:1010F00000000000000000000000000000000000F0
+:1011000000000000000000000000000000000000DF
+:10111000000080402010100808080404040404089B
+:1011200008081010204080000000000000000000AF
+:1011300000000000000000000000FF0000FFFFFFB3
+:10114000FF0000FF000000000000000000000000A1
+:10115000000000000000000000000000000080808F
+:10116000808000000000000000000000000000007F
+:10117000000000000000000000000000000000006F
+:10118000800000008000000000000000000000005F
+:10119000F00E010000000000000080E0E0E0000030
+:1011A000000000000000010EF00000000000000040
+:1011B00000000000000000000000FF0000FFFFFF33
+:1011C000FF0000FF00000000000000000000000021
+:1011D00000000000000000000000000000007F048C
+:1011E000040000324A4A7C007E04027C00000000B9
+:1011F00000000000000000000000000000000003EC
+:1012000004631C3348300000000000F00808F000C0
+:10121000010E3040880404020101000000000000BB
+:10122000000000008040300E01E010902000E0102F
+:1012300010E000000000000080C0FFF0F8FFFFFF9A
+:10124000FFF8F0FFC0800000000000000000000078
+:10125000000000000000000000000000000000008E
+:10126000000000000000000000000000000000007E
+:10127000000000000000000000000000000000006E
+:101280000000000000000000000000030404030050
+:101290000000000000010102020204040404040230
+:1012A000020201010000000000070908070007080A
+:1012B0000807000000000000FFFFFFFFFFFFFFFF27
+:1012C000FFFF7F3F1F0F0000000000000000000034
+:1012D000000000000000000000020502003C428106
+:1012E0008181660000000000000000000000000096
+:1012F00000000000000000000000000000000000EE
+:1013000000000000000000000000000000FF0919BC
+:10131000294680FF1111110E00FF0678807806FF24
+:1013200000000000000000000000000000000000BD
+:101330000000000000000000000000000000005F4E
+:1013400000000003000300143E143E14242A7F2AE8
+:1013500012433308666136495522500005030000E8
+:10136000001C2241000041221C0014083E08140801
+:10137000083E08080050300000080808080800600F
+:1013800060000020100804023E5149453E04027FDF
+:101390000000426151494622414949361814127FE2
+:1013A0001027454545393E49494932010171090730
+:1013B0003649494936264949493E0036360000003B
+:1013C000563600000814224100141414141400416D
+:1013D00022140802015109063E4159555E7E090951
+:1013E000097E7F494949363E414141227F41414181
+:1013F0003E7F494949417F090909013E4141493A36
+:101400007F0808087F00417F4100304040403F7F17
+:10141000081422417F404040407F020C027F7F023F
+:1014200004087F3E4141413E7F090909061E2121F2
+:10143000215E7F0909097600264949493201017F69
+:1014400001013F4040403F1F2040201F7F201020CF
+:101450007F41221C2241070870080761514945431A
+:10146000007F410000020408102004020102044031
+:1014700040404040000102040020545454787F440E
+:101480004444383844444444384444447F385454F1
+:10149000541804047E0505085454543C7F08040481
+:1014A0007800447D40002040443D007F10284400E7
+:1014B00000417F40007C047804787C08040478387C
+:1014C000444444387C14141408081414147C007C1C
+:1014D000080404485454542004043F44443C40400D
+:1014E000207C1C2040201C3C4030403C44281028DC
+:1014F000440C5050503C4464544C44000836414124
+:1015000000007F0000414136080002010204020091
+:10151000000000005261704D616E205665723A31D4
+:101520002E302E3900000000472D436F6465204C9B
+:10153000696E653A0000000048656164205370657B
+:1015400065643A004578742E20526174653A000053
+:101550002531750025352E31666D6D2F7300000025
+:101560004E6F74205365740000007042000000004C
+:1015700079E9263108ACAC3F4578747275646572C0
+:1015800020436F6E74726F6C0000000048656174D8
+:101590006572204F6E200000486561746572204FAF
+:1015A00066660000203C31303043204D6F746F720E
+:1015B000204F4646000000000000C84254454D50F0
+:1015C00045524154555245204552524F5200000059
+:1015D000544845524D4953544F52204552524F5250
+:1015E0000000000025337543000000002A000000C1
+:1015F0002000000000C07944000080BF25337552F0
+:10160000504D00000000000084471B47ACC5A73FB9
+:101610004D454E550000000052554E2046494C4560
+:10162000000000004D414E55414C204D4F564500A5
+:10163000544F4F4C2053455455500000484F4D4592
+:1016400020544F4F4C204845414400004D414E55D9
+:10165000414C000058204C696D69743A000000004C
+:1016600059204C696D69743A000000005A204C6999
+:101670006D69743A000000005820537465703A0098
+:101680005920537465703A005A20537465703A00BB
+:101690004155544F3A204C6F6164696E672E2E009D
+:1016A000484F4D494E4720504C45415345205741E6
+:1016B000495400004D4F564520544F3A0000000059
+:1016C000583D25362E326600593D25362E326600AD
+:1016D0005A3D25362E3266004E4F205A204D4F5629
+:1016E0004500000050726F672E456E6400000000D8
+:1016F00052657475726E20746F204D656E750000B2
+:101700003C3C3C205072657373204573632E00008F
+:101710003E0000002020000048A2019DA09C019DE9
+:10172000709D019D409E019D109F019DE09F019D28
+:10173000B0A0019D80A1019DC4B2019D78B3019D1F
+:101740000CB3019D54B4019DD8B4019D002020200C
+:101750002020202020202828282828202020202061
+:101760002020202020202020202020202080101039
+:10177000101010101010101010101010100404048D
+:10178000040404040404041010101010101041414B
+:101790004141414101010101010101010101010139
+:1017A000010101010101010110101010101042424D
+:1017B0004242424202020202020202020202020209
+:1017C00002020202020202021010101020000000A9
+:1017D0000000000000000000000000000000000009
+:1017E00000000000000000000000000000000000F9
+:1017F00000000000000000000000000000000000E9
+:1018000000000000000000000000000000000000D8
+:1018100000000000000000000000000000000000C8
+:1018200000000000000000000000000000000000B8
+:1018300000000000000000000000000000000000A8
+:101840000000000000000000000000000000000098
+:101850003030303030303030303030303030303088
+:101860003030303030303030303030303030303078
+:101870002020202020202020202020202020202068
+:101880002020202020202020202020202020202058
+:10189000F0BD019D9CC1019D20CF019D9CC1019D7A
+:1018A00020CF019D20CF019D20CF019D20CF019D04
+:1018B00020CF019D20CF019D20CF019D14BE019D11
+:1018C0005CBE019D20CF019D20CF019D20CF019DB9
+:1018D00020CF019D28BE019D20CF019D20CF019DDD
+:1018E0004CBE019D20CF019D20CF019D20CF019DA9
+:1018F00020CF019D20CF019D20CF019D20CF019DB4
+:1019000020CF019D20CF019D20CF019D6CCD019D59
+:10191000FCBD019D9CC1019D9CC1019D9CC1019D7F
+:1019200020CF019DFCBD019D20CF019D20CF019DB9
+:1019300020CF019D20CF019D34CE019D20BE019D71
+:1019400068BE019D20CF019D20CF019DA8CD019DA6
+:1019500020CF019D34BE019D20CF019D20CF019D50
+:1019600074BE019D00000000000000000000244043
+:101970000000000000001040000000000000008097
+:101980007B14AE47E17A843F2D431CEBE2361A3FCD
+:101990004E614E002B496E66000000002D496E66B8
+:1019A00000000000286E756C6C290000B0CF019D0E
+:1019B000B8CF019DC0CF019DC8CF019DD0CF019D63
+:1019C000000000000000144000000000000039404A
+:1019D00000000000008883400000000084D7174109
+:1019E0000080E03779C34142176E05B5B5B893441E
+:1019F000F5F93FE9034F3849321D30F948778252F3
+:101A00003CBF737FDD4F1565000000000000F03F14
+:101A1000FFFFFFFFFFFFFF7F00000000000010003E
+:101A20000000000000000001FFFFFFFFFFFF0F00AC
+:101A30000C00000000000000010001041F0C1D004C
+:101A40000C0000001400000024F9019D7C0400003B
+:101A50000C00000000000000010001041F0C1D002C
+:101A60001C00000014000000A0FD019D8C0400007B
+:101A7000440E185011107C11117D11127E000000CF
+:101A800000000000FFFFFFFF00000000000000005A
+:101A90000000000000000000000000000000000046
+:101AA000840000A0A00000A0BC0000A0800000A056
+:101AB0007C0300A001000000000000000000000006
+:101AC0000000000000000000000000000000000016
+:101AD0000000000000000000000000000000000006
+:101AE00000000000000000000000000000000000F6
+:101AF00000000000000000000000000000000000E6
+:101B000000000000FFFFFFFFFFFFFFFF00000000DD
+:101B10000004000009100000000000003817029DBA
+:101B2000FFFFFFFF000000000000000000040000B5
+:101B30000A100100000000003817029DFFFFFFFFA0
+:101B40000000000000000000000000000200020091
+:101B5000000000003817029DFDFFFFFF000000009D
+:101B60000000000000000000000000000000000075
+:101B700000000000010000001E000000FFFF000048
+:101B800001000000FFFF0000FFFFFFFFC80E00A0E4
+:101B900090010000F5FF000001000000200000A0FF
+:101BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:101BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:101BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:101BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:101BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:101BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:101C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:101C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:101C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:101C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:101C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:101C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:101C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:101C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:101C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:101C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:101CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:101CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:101CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:101CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:101CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:101CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:101D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:101D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:101D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:101D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:101D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:101D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:101D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:101D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:101D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:101D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:101DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:101DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:101DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:101DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:101DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:101DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:101E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:101E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:101E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:101E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:101E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:101E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:101E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:101E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:101E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:101E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:101EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:101EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:101EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:101ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:101EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:101EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:101F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:101F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:101F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:101F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:101F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:101F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:101F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:101F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:101F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:101F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:101FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:101FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:101FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:101FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:101FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:101FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10200000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10201000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10202000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10203000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10204000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10205000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10206000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10207000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10208000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10209000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:1020A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1020B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1020C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1020D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1020E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1020F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10210000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10211000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10212000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10213000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10214000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10215000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10216000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10217000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10218000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10219000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:1021A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1021B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1021C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1021D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1021E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1021F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10220000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10221000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10222000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10223000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10224000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10225000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10226000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10227000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10228000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10229000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:1022A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1022B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1022C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1022D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1022E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1022F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10230000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10231000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10232000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10233000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10234000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10235000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10236000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10237000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10238000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10239000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:1023A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1023B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1023C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1023D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1023E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1023F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10240000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10241000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10242000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10243000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10244000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10245000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10246000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10247000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10248000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10249000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:1024A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1024B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1024C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1024D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1024E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1024F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10250000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10251000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10252000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10253000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10254000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10255000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10256000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10257000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10258000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10259000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:1025A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1025B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1025C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1025D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1025E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1025F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10260000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10261000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10263000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10264000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10265000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10266000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10267000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10268000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10269000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:1026A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1026B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1026C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1026D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1026E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1026F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10270000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10271000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10272000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10273000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10274000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10275000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10276000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10277000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10278000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10279000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:1027A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1027B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1027C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1027D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1027E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1027F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10280000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10281000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10282000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10283000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10284000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10285000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10286000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10287000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10288000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10289000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:1028A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1028B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1028C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1028D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1028E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1028F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10290000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10291000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10292000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10293000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10294000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10295000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10296000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10297000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10298000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10299000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:1029A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1029B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1029C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1029D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1029E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1029F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:102A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:102A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:102A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:102A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:102A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:102A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:102A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:102A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:102A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:102A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:102AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:102AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:102AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:102AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:102AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:102AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:102B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:102B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:102B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:102B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:102B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:102B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:102B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:102B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:102B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:102B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:102BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:102BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:102BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:102BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:102BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:102BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:102C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:102C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:102C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:102C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:102C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:102C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:102C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:102C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:102C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:102C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:102CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:102CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:102CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:102CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:102CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:102CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:102D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:102D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:102D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:102D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:102D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:102D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:102D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:102D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:102D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:102D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:102DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:102DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:102DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:102DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:102DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:102DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:102E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:102E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:102E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:102E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:102E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:102E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:102E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:102E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:102E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:102E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:102EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:102EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:102EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:102ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:102EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:102EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:102F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:102F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:102F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:102F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:102F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:102F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:102F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:102F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:102F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:102F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:102FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:102FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:102FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:102FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:102FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:102FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10300000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10301000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10302000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10303000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10304000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10305000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10306000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10307000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10308000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10309000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1030A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1030B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1030C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1030D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1030E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1030F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10310000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10311000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10312000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10313000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10314000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10315000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10316000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10317000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10318000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10319000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1031A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1031B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1031C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1031D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1031E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1031F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10320000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10321000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10322000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10323000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10324000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10325000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10326000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10327000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10328000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10329000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1032A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1032B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1032C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1032D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1032E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1032F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10330000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10331000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10332000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10333000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10334000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10335000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10336000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10337000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10338000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10339000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1033A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1033B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1033C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1033D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1033E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1033F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10340000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10341000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10342000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10343000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10344000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10345000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10346000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10347000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10348000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10349000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1034A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1034B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1034C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1034D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1034E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1034F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10350000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10351000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10352000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10353000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10354000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10355000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10356000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10357000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10358000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10359000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1035A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1035B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1035C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1035D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1035E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1035F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10360000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10361000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10362000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10363000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10364000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10365000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10366000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10367000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10368000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10369000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1036A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1036B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1036C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1036D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1036E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1036F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10370000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10371000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10372000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10373000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10374000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10375000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10376000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10377000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10378000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10379000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1037A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1037B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1037D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1037E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1037F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10380000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10381000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10382000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10383000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10384000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10385000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10388000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10389000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1038A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1038B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1038C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1038D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1038E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1038F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10390000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10391000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10392000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10393000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10394000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10395000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10396000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10397000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10398000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10399000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1039A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1039B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1039D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1039E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1039F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:103A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:103A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:103A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:103A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:103A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:103A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:103A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:103A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:103A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:103AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:103AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:103AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:103AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:103AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:103AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:103B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:103B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:103B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:103B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:103B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:103B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:103B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:103B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:103B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:103B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:103BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:103BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:103BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:103BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:103BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:103BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:103C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:103C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:103C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:103C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:103C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:103C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:103C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:103C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:103C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:103C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:103CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:103CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:103CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:103CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:103CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:103CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:103D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:103D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:103D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:103D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:103D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:103D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:103D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:103D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:103D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:103D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:103DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:103DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:103DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:103DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:103DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:103DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:103E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:103E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:103E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:103E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:103E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:103E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:103E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:103E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:103E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:103E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:103EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:103EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:103EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:103ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:103EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:103EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:103F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:103F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:103F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:103F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:103F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:103F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:103F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:103F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:103F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:103F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:103FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:103FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:103FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:103FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:103FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:103FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10400000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10401000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10402000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10403000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10404000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10405000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10406000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10407000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10408000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10409000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1040A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1040B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1040C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1040D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1040E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1040F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10410000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10411000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10412000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10413000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10414000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10415000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10416000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10417000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10418000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10419000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1041A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1041B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1041C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1041D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1041E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1041F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10420000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10421000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10422000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10423000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10424000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10425000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10426000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10427000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10428000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10429000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1042A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1042B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1042C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1042D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1042E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1042F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10430000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10431000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10432000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10433000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10434000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10435000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10436000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10437000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10438000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10439000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1043A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1043B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1043C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1043D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1043E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1043F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10440000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10441000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10442000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10443000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10444000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10445000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10446000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10447000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10448000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10449000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1044A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1044B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1044C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1044D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1044E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1044F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10450000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10451000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10452000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10453000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10454000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10455000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10456000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10457000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10458000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10459000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1045A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1045B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1045C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1045D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1045E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1045F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10460000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10461000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10462000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10463000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10464000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10465000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10466000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10467000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10468000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10469000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1046A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1046B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1046C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1046D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1046E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1046F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10470000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10471000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10472000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10473000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10474000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10475000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10476000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10477000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10478000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10479000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1047A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1047B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1047C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1047D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1047E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1047F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10480000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10481000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10482000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10483000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10484000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10485000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10486000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10487000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10488000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10489000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1048A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1048B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1048C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1048D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1048E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1048F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10490000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10491000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10493000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10495000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10497000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10499000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1049A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1049B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1049C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1049D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1049E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1049F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:104A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:104A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:104A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:104A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:104A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:104A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:104A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:104A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:104A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:104A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:104AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:104AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:104AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:104AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:104AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:104AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:104B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:104B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:104B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:104B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:104B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:104B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:104B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:104B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:104B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:104BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:104BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:104BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:104C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:104C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:104C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:104C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:104C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:104C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:104C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:104C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:104C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:104C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:104CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:104CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:104CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:104CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:104CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:104CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:104D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:104D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:104D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:104D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:104D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:104D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:104D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:104D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:104D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:104D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:104DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:104DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:104DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:104DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:104DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:104DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:104E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:104E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:104E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:104E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:104E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:104E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:104E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:104E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:104E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:104ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:104EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:104F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:104F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:104F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:104F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:104F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:104F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:104F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:104F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:104F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:104F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:104FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:104FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:104FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:104FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:104FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:104FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10501000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10502000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10503000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10504000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10505000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10506000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10507000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10508000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10509000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1050A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1050B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1050C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1050D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1050E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1050F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10510000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10511000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10512000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10513000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10514000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10515000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10516000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10517000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10518000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10519000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1051A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1051B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1051C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1051D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1051E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1051F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10520000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10521000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10522000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10523000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10524000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10525000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10526000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10527000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10528000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10529000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1052A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1052B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1052C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1052D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1052E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1052F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10530000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10531000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10532000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10533000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10534000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10535000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10536000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10537000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10538000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10539000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1053A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1053B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1053C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1053D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10540000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10541000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10542000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10543000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10544000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10545000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10546000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10547000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10548000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10549000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1054A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1054B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1054C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1054D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1054E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1054F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10550000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10551000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10552000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10553000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10554000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10555000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10556000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10557000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10558000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10559000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1055A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1055B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1055C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1055D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1055E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1055F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10560000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10561000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10562000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10563000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10564000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10565000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10566000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10567000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10568000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10569000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1056A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1056B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1056C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1056D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1056E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1056F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10570000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10571000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10572000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10573000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10574000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10575000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10576000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10577000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10578000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10579000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1057A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1057B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1057C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1057D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1057E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1057F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10580000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10581000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10582000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10583000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10584000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10585000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10586000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10587000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10588000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10589000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1058A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1058B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1058C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1058D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1058E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1058F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10590000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10591000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10592000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10593000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10594000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10595000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10596000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10597000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10598000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10599000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1059A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1059B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1059C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1059D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1059E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1059F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:105A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:105A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:105A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:105A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:105A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:105A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:105A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:105A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:105A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:105A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:105AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:105AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:105AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:105AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:105AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:105AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:105B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:105B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:105B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:105B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:105B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:105B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:105B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:105B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:105B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:105B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:105BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:105BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:105BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:105BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:105BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:105BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:105C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:105C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:105C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:105C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:105C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:105C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:105C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:105C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:105C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:105C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:105CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:105CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:105CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:105CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:105CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:105CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:105D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:105D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:105D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:105D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:105D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:105D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:105D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:105D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:105D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:105D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:105DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:105DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:105DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:105DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:105DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:105DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:105E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:105E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:105E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:105E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:105E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:105E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:105E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:105E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:105E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:105E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:105EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:105EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:105EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:105ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:105EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:105EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:105F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:105F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:105F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:105F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:105F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:105F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:105F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:105F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:105F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:105F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:105FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:105FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:105FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:105FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:105FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:105FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10600000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10601000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10602000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10603000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10604000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10605000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10606000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10607000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10608000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10609000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1060A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1060B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1060C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1060D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1060E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1060F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10610000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10611000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10612000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10613000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10614000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10615000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10616000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10617000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10618000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10619000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1061A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1061B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1061C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1061D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1061E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10620000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10621000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10622000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10624000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10625000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10626000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10627000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10628000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10629000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1062A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1062B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1062C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1062D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1062E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1062F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10630000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10631000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10632000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10633000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10634000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10635000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10636000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10637000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10638000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10639000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1063A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1063B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1063C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10644000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10645000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10646000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10647000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10648000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10649000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1064A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1064B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1064C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1064D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1064E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1064F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10650000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10651000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10652000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10653000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10654000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10655000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10656000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10657000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10658000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10659000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1065A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1065B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1065C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1065D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1065E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1065F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10660000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10661000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10662000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10663000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10664000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10665000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10666000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10667000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10668000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10669000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1066A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1066B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1066C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1066D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1066E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1066F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10670000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10671000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10672000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10673000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10674000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10675000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10676000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10677000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10678000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10679000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1067A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1067B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1067C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1067D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1067E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1067F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10680000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10681000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10682000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10683000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10684000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10685000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10686000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10687000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10688000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10689000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1068A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1068B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1068C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1068D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1068E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10697000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:106A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:106A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:106A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:106A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:106A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:106A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:106A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:106A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:106A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:106A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:106AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:106AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:106AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:106AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:106AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:106AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:106B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:106B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:106B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:106B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:106B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:106B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:106B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:106B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:106B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:106B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:106BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:106BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:106BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:106BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:106BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:106BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:106C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:106C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:106C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:106C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:106C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:106C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:106C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:106C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:106C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:106C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:106CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:106CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:106CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:106CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:106CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:106CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:106D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:106D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:106D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:106D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:106D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:106D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:106D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:106D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:106D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:106D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:106DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:106DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:106DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:106DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:106DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:106DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:106E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:106E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:106E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:106E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:106E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:106E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:106E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:106E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:106E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:106E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:106EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:106EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:106EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:106ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:106EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:106EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:106F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:106F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:106F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:106F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:106F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:106F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:106F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:106F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:106F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:106F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:106FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:106FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:106FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:106FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:106FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:106FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10701000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10702000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10703000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10707000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10709000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1070B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1070C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1070D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1070E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1070F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10710000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10711000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10712000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10713000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10714000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10715000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10716000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10717000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10718000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10719000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1071A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1071B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1071C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1071D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1071E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1071F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10720000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10721000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10722000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10723000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10724000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10725000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10726000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10727000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10728000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10729000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1072A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1072B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1072C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1072D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1072E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1072F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10730000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10731000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10732000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10733000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10734000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10735000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10736000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10737000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10738000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10739000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1073A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1073B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1073C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1073D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1073E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1073F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10740000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10741000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10742000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10743000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10744000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10745000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10746000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10747000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10748000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10749000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1074A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1074B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1074C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1074D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1074E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1074F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10750000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10751000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10752000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10753000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10754000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10755000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10756000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10757000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10758000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10759000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1075A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1075B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1075C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1075D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1075E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1075F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10760000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10761000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10762000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10763000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10764000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10765000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10766000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10767000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10768000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10769000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1076A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1076B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1076C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1076D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1076E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1076F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10770000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10771000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10772000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10773000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10774000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10775000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10776000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10777000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10778000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10779000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1077A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1077B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1077C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1077D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1077E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1077F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10780000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10781000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10782000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10783000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10784000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10785000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10786000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10787000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10788000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10789000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1078A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1078B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1078C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1078D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1078E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1078F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10790000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10791000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10792000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10793000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10794000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10795000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10796000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10797000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10798000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10799000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1079A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1079B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1079C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1079D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1079E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1079F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:107A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:107A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:107A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:107A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:107A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:107A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:107A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:107A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:107A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:107A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:107AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:107AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:107AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:107AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:107AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:107AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:107B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:107B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:107B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:107B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:107B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:107B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:107B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:107B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:107B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:107B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:107BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:107BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:107BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:107BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:107BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:107BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:107C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:107C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:107C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:107C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:107C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:107C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:107C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:107C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:107C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:107C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:107CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:107CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:107CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:107CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:107CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:107CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:107D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:107D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:107D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:107D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:107D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:107D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:107D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:107D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:107D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:107D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:107DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:107DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:107DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:107DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:107DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:107DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:107E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:107E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:107E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:107E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:107E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:107E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:107E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:107E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:107E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:107E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:107EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:107EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:107EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:107ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:107EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:107EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:107F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:107F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:107F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:107F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:107F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:107F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:107F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:107F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:107F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:107F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:107FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:107FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:107FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:107FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:107FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:107FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10801000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10802000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10803000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10804000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10805000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10806000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10807000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10808000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10809000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1080A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1080B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1080C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1080D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1080E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:1080F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10810000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10811000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10812000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10813000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10814000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10815000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10816000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10817000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10818000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10819000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1081A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1081B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1081C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1081D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1081E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:1081F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10820000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10821000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10822000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10823000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10824000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10825000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10826000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10827000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10828000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10829000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1082A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1082B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1082C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1082D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1082E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:1082F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10830000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10831000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10832000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10833000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10834000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10835000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10836000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10837000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10838000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10839000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1083A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1083B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1083C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1083D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1083E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:1083F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10840000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10841000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10842000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10843000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10844000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10845000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10846000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10847000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10848000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10849000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1084A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1084B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1084C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1084D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1084E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:1084F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10850000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10851000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10852000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10853000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10854000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10855000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10856000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10857000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10858000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10859000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1085A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1085B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1085C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1085D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1085E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:1085F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10860000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10861000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10862000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10863000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10864000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10865000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10866000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10867000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10868000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10869000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1086A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1086B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1086C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1086D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1086E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:1086F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10870000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10871000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10872000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10873000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10874000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10875000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10876000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10877000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10878000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10879000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1087A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1087B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1087C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1087D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1087E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:1087F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10880000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10881000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10882000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10883000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10884000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10885000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10886000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10887000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10888000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10889000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1088A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1088B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1088C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1088D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1088E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:1088F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10890000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10891000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10892000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10893000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10894000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10895000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10896000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10897000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10898000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10899000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1089A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1089B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1089C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1089D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1089E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:1089F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:108A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:108A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:108A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:108A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:108A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:108A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:108A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:108A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:108A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:108A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:108AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:108AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:108AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:108AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:108AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:108AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:108B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:108B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:108B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:108B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:108B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:108B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:108B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:108B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:108B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:108B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:108BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:108BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:108BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:108BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:108BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:108BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:108C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:108C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:108C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:108C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:108C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:108C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:108C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:108C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:108C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:108C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:108CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:108CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:108CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:108CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:108CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:108CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:108D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:108D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:108D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:108D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:108D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:108D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:108D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:108D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:108D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:108D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:108DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:108DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:108DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:108DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:108DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:108DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:108E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:108E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:108E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:108E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:108E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:108E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:108E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:108E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:108E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:108E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:108EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:108EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:108EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:108ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:108EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:108EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:108F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:108F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:108F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:108F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:108F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:108F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:108F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:108F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:108F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:108F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:108FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:108FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:108FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:108FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:108FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:108FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10900000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10901000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10902000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10903000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10904000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10905000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10906000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10907000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10908000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10909000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1090A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1090B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1090C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1090D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:1090E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:1090F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10910000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10911000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10912000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10913000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10914000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10915000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10916000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10917000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10918000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10919000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1091A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1091B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1091C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1091D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:1091E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:1091F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10920000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10921000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10922000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10923000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10924000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10925000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10926000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10927000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10928000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10929000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1092A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1092B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1092C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1092D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:1092E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:1092F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10930000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10931000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10932000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10933000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10934000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10935000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10936000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10937000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10938000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10939000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1093A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1093B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1093C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1093D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:1093E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:1093F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10940000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10941000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10942000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10943000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10944000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10945000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10946000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10947000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10948000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10949000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1094A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1094B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1094C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1094D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:1094E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:1094F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10950000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10951000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10952000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10953000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10954000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10955000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10956000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10957000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10958000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10959000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1095A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1095B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1095C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1095D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:1095E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:1095F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10960000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10961000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10962000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10963000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10964000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10965000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10966000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10967000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10968000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10969000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1096A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1096B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1096C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1096D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:1096E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:1096F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10970000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10971000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10972000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10973000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10974000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10975000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10976000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10977000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10978000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10979000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1097A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1097B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1097C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1097D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:1097E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:1097F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10980000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10981000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10982000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10983000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10984000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10985000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10986000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10987000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10988000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10989000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1098A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1098B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1098C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1098D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:1098E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:1098F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10990000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10991000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10992000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10993000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10994000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10995000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10996000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10997000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10998000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10999000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1099A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1099B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1099C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1099D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:1099E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:1099F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:109A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:109A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:109A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:109A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:109A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:109A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:109A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:109A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:109A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:109A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:109AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:109AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:109AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:109AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:109AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:109AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:109B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:109B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:109B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:109B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:109B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:109B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:109B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:109B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:109B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:109B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:109BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:109BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:109BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:109BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:109BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:109BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:109C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:109C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:109C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:109C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:109C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:109C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:109C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:109C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:109C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:109C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:109CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:109CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:109CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:109CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:109CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:109CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:109D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:109D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:109D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:109D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:109D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:109D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:109D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:109D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:109D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:109D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:109DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:109DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:109DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:109DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:109DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:109DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:109E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:109E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:109E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:109E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:109E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:109E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:109E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:109E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:109E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:109E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:109EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:109EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:109EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:109ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:109EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:109EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:109F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:109F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:109F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:109F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:109F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:109F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:109F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:109F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:109F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:109F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:109FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:109FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:109FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:109FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:109FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:109FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10A00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10A01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10A02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10A03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10A04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10A05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10A06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10A07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10A08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10A09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10A0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10A0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10A0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10A0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10A0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10A0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10A10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10A11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10A12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10A13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10A14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10A15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10A16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10A17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10A18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10A19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10A1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10A1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10A1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10A1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10A1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10A1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10A20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10A21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10A22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10A23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10A24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10A25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10A26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10A27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10A28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10A29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10A2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10A2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10A2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10A2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10A2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10A2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10A30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10A31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10A32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10A33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10A34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10A35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10A36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10A37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10A38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10A39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10A3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10A3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10A3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10A3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10A3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10A3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10A40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10A41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10A42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10A43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10A44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10A45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10A46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10A47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10A48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10A49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10A4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10A4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10A4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10A4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10A4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10A4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10A50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10A51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10A52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10A53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10A54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10A55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10A56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10A57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10A58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10A59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10A5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10A5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10A5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10A5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10A5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10A5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10A60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10A61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10A62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10A63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10A64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10A65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10A66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10A67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10A68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10A69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10A6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10A6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10A6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10A6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10A6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10A6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10A70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10A71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10A72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10A73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10A74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10A75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10A76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10A77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10A78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10A79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10A7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10A7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10A7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10A7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10A7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10A7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10A80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10A81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10A82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10A83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10A84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10A85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10A86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10A87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10A88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10A89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10A8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10A8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10A8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10A8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10A8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10A8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10A90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10A91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10A92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10A93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10A94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10A95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10A96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10A97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10A98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10A99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10A9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10A9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10A9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10A9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10A9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10A9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10AA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10AA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10AA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10AA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10AA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10AA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10AA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10AA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10AA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10AA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10AAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10AAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10AAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10AAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10AAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10AAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10AB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10AB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10AB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10AB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10AB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10AB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10AB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10AB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10AB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10AB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10ABA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10ABB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10ABC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10ABD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10ABE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10ABF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10AC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10AC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10AC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10AC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10AC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10AC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10AC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10AC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10AC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10AC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10ACA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10ACB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10ACC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10ACD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10ACE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10ACF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10AD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10AD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10AD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10AD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10AD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10AD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10AD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10AD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10AD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10AD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10ADA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10ADB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10ADC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10ADD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10ADE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10ADF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10AE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10AE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10AE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10AE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10AE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10AE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10AE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10AE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10AE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10AE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10AEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10AEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10AEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10AED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10AEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10AEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10AF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10AF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10AF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10AF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10AF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10AF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10AF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10AF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10AF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10AF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10AFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10AFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10AFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10AFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10AFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10AFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10B00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10B01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10B02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10B03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10B04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10B05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10B06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10B07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10B08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10B09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10B0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10B0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10B0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10B0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10B0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10B0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10B10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10B11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10B12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10B13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10B14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10B15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10B16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10B17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10B18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10B19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10B1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10B1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10B1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10B1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10B1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10B1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10B20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10B21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10B22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10B23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10B24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10B25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10B26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10B27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10B28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10B29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10B2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10B2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10B2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10B2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10B2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10B2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10B30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10B31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10B32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10B33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10B34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10B35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10B36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10B37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10B38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10B39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10B3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10B3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10B3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10B3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10B3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10B3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10B40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10B41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10B42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10B43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10B44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10B45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10B46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10B47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10B48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10B49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10B4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10B4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10B4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10B4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10B4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10B4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10B50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10B51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10B52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10B53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10B54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10B55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10B56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10B57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10B58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10B59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10B5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10B5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10B5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10B5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10B5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10B5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10B60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10B61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10B62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10B63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10B64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10B65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10B66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10B67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10B68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10B69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10B6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10B6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10B6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10B6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10B6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10B6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10B70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10B71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10B72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10B73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10B74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10B75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10B76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10B77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10B78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10B79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10B7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10B7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10B7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10B7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10B7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10B7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10B80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10B81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10B82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10B83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10B84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10B85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10B86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10B87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10B88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10B89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10B8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10B8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10B8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10B8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10B8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10B8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10B90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10B91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10B92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10B93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10B94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10B95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10B96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10B97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10B98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10B99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10B9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10B9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10B9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10B9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10B9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10B9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10BA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10BA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10BA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10BA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10BA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10BA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10BA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10BA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10BA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10BA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10BAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10BAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10BAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10BAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10BAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10BAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10BB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10BB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10BB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10BB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10BB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10BB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10BB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10BB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10BB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10BB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10BBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10BBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10BBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10BBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10BBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10BBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10BC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10BC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10BC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10BC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10BC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10BC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10BC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10BC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10BC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10BC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10BCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10BCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10BCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10BCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10BCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10BCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10BD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10BD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10BD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10BD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10BD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10BD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10BD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10BD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10BD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10BD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10BDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10BDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10BDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10BDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10BDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10BDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10BE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10BE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10BE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10BE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10BE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10BE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10BE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10BE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10BE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10BE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10BEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10BEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10BEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10BED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10BEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10BEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10BF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10BF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10BF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10BF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10BF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10BF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10BF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10BF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10BF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10BF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10BFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10BFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10BFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10BFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10BFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10BFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10C00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10C01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10C02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10C03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10C04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10C05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10C06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10C07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10C08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10C09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10C0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10C0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10C0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10C0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10C0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10C0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10C10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10C11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10C12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10C13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10C14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10C15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10C16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10C17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10C18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10C19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10C1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10C1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10C1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10C1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10C1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10C1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10C20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10C21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10C22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10C23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10C24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10C25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10C26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10C27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10C28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10C29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10C2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10C2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10C2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10C2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10C2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10C2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10C30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10C31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10C32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10C33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10C34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10C35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10C36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10C37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10C38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10C39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10C3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10C3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10C3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10C3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10C3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10C3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10C40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10C41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10C42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10C43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10C44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10C45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10C46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10C47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10C48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10C49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10C4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10C4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10C4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10C4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10C4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10C4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10C50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10C51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10C52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10C53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10C54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10C55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10C56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10C57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10C58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10C59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10C5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10C5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10C5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10C5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10C5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10C5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10C60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10C61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10C62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10C63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10C64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10C65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10C66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10C67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10C68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10C69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10C6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10C6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10C6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10C6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10C6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10C6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10C70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10C71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10C72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10C73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10C74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10C75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10C76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10C77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10C78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10C79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10C7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10C7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10C7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10C7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10C7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10C7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10C80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10C81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10C82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10C83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10C84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10C85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10C86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10C87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10C88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10C89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10C8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10C8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10C8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10C8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10C8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10C8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10C90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10C91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10C92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10C93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10C94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10C95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10C96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10C97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10C98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10C99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10C9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10C9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10C9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10C9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10C9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10C9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10CA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10CA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10CA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10CA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10CA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10CA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10CA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10CA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10CA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10CA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10CAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10CAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10CAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10CAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10CAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10CAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10CB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10CB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10CB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10CB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10CB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10CB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10CB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10CB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10CB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10CB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10CBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10CBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10CBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10CBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10CBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10CBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10CC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10CC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10CC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10CC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10CC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10CC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10CC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10CC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10CC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10CC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10CCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10CCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10CCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10CCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10CCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10CCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10CD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10CD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10CD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10CD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10CD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10CD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10CD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10CD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10CD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10CD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10CDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10CDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10CDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10CDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10CDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10CDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10CE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10CE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10CE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10CE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10CE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10CE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10CE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10CE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10CE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10CE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10CEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10CEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10CEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10CED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10CEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10CEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10CF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10CF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10CF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10CF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10CF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10CF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10CF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10CF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10CF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10CF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10CFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10CFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10CFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10CFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10CFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10CFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10D00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10D01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10D02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10D03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10D04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10D05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10D06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10D07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10D08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10D09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10D0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10D0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10D0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10D0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10D0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10D0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10D10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10D11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10D12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10D13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10D14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10D15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10D16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10D17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10D18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10D19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10D1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10D1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10D1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10D1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10D1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10D1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10D20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10D21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10D22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10D23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10D24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10D25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10D26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10D27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10D28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10D29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10D2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10D2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10D2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10D2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10D2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10D2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10D30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10D31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10D32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10D33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10D34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10D35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10D36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10D37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10D38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10D39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10D3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10D3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10D3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10D3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10D3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10D3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10D40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10D41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10D42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10D43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10D44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10D45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10D46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10D47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10D48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10D49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10D4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10D4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10D4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10D4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10D4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10D4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10D50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10D51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10D52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10D53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10D54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10D55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10D56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10D57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10D58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10D59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10D5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10D5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10D5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10D5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10D5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10D5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10D60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10D61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10D62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10D63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10D64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10D65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10D66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10D67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10D68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10D69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10D6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10D6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10D6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10D6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10D6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10D6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10D70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10D71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10D72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10D73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10D74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10D75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10D76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10D77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10D78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10D79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10D7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10D7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10D7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10D7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10D7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10D7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10D80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10D81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10D82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10D83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10D84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10D85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10D86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10D87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10D88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10D89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10D8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10D8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10D8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10D8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10D8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10D8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10D90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10D91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10D92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10D93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10D94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10D95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10D96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10D97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10D98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10D99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10D9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10D9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10D9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10D9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10D9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10D9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10DA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10DA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10DA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10DA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10DA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10DA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10DA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10DA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10DA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10DA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10DAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10DAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10DAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10DAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10DAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10DAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10DB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10DB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10DB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10DB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10DB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10DB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10DB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10DB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10DB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10DB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10DBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10DBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10DBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10DBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10DBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10DBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10DC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10DC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10DC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10DC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10DC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10DC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10DC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10DC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10DC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10DC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10DCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10DCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10DCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10DCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10DCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10DCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10DD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10DD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10DD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10DD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10DD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10DD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10DD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10DD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10DD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10DD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10DDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10DDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10DDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10DDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10DDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10DDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10DE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10DE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10DE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10DE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10DE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10DE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10DE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10DE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10DE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10DE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10DEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10DEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10DEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10DED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10DEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10DEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10DF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10DF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10DF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10DF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10DF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10DF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10DF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10DF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10DF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10DF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10DFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10DFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10DFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10DFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10DFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10DFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10E00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10E01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10E02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10E03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10E04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10E05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10E06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10E07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10E08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10E09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10E0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10E0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10E0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10E0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10E0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10E0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10E10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10E11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10E12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10E13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10E14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10E15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10E16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10E17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10E18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10E19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10E1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10E1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10E1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10E1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10E1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10E1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10E20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10E21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10E22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10E23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10E24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10E25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10E26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10E27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10E28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10E29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10E2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10E2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10E2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10E2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10E2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10E2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10E30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10E31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10E32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10E33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10E34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10E35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10E36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10E37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10E38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10E39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10E3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10E3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10E3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10E3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10E3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10E3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10E40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10E41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10E42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10E43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10E44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10E45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10E46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10E47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10E48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10E49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10E4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10E4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10E4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10E4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10E4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10E4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10E50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10E51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10E52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10E53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10E54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10E55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10E56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10E57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10E58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10E59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10E5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10E5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10E5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10E5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10E5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10E5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10E60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10E61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10E62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10E63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10E64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10E65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10E66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10E67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10E68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10E69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10E6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10E6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10E6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10E6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10E6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10E6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10E70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10E71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10E72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10E73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10E74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10E75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10E76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10E77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10E78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10E79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10E7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10E7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10E7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10E7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10E7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10E7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10E80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10E81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10E82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10E83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10E84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10E85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10E86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10E87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10E88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10E89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10E8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10E8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10E8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10E8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10E8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10E8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10E90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10E91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10E92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10E93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10E94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10E95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10E96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10E97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10E98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10E99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10E9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10E9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10E9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10E9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10E9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10E9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10EA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10EA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10EA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10EA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10EA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10EA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10EA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10EA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10EA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10EA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10EAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10EAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10EAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10EAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10EAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10EAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10EB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10EB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10EB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10EB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10EB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10EB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10EB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10EB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10EB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10EB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10EBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10EBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10EBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10EBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10EBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10EBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10EC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10EC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10EC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10EC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10EC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10EC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10EC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10EC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10EC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10EC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10ECA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10ECB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10ECC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10ECD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10ECE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10ECF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10ED0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10ED1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10ED2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10ED3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10ED4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10ED5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10ED6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10ED7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10ED8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10ED9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10EDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10EDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10EDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10EDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10EDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10EDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10EE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10EE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10EE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10EE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10EE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10EE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10EE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10EE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10EE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10EE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10EEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10EEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10EEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10EED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10EEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10EEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10EF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10EF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10EF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10EF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10EF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10EF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10EF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10EF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10EF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10EF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10EFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10EFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10EFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10EFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10EFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10EFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10F00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10F01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10F02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10F03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10F04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10F05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10F06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10F07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10F08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10F09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10F0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10F0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10F0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10F0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10F0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10F0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10F10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10F11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10F12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10F13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10F14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10F15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10F16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10F17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10F18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10F19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10F1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10F1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10F1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10F1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10F1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10F1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10F20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10F21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10F22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10F23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10F24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10F25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10F26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10F27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10F28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10F29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10F2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10F2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10F2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10F2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10F2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10F2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10F30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10F31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10F32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10F33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10F34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10F35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10F36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10F37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10F38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10F39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10F3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10F3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10F3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10F3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10F3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10F3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10F40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10F41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10F42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10F43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10F44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10F45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10F46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10F47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10F48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10F49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10F4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10F4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10F4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10F4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10F4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10F4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10F50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10F51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10F52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10F53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10F54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10F55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10F56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10F57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10F58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10F59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10F5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10F5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10F5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10F5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10F5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10F5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10F60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10F61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10F62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10F63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10F64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10F65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10F66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10F67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10F68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10F69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10F6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10F6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10F6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10F6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10F6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10F6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10F70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10F71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10F72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10F73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10F74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10F75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10F76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10F77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10F78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10F79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10F7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10F7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10F7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10F7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10F7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10F7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10F80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10F81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10F82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10F83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10F84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10F85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10F86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10F87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10F88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10F89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10F8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10F8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10F8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10F8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10F8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10F8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10F90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10F91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10F92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10F93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10F94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10F95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10F96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10F97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10F98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10F99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10F9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10F9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10F9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10F9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10F9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10F9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10FA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10FA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10FA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10FA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10FA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10FA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10FA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10FA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10FA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10FA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10FAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10FAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10FAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10FAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10FAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10FAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10FB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10FB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10FB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10FB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10FB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10FB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10FB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10FB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10FB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10FB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10FBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10FBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10FBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10FBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10FBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10FBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10FC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10FC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10FC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10FC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10FC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10FC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10FC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10FC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10FC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10FC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10FCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10FCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10FCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10FCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10FCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10FCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10FD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10FD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10FD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10FD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10FD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10FD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10FD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10FD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10FD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10FD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10FDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10FDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10FDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10FDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10FDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10FDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10FE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10FE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10FE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10FE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10FE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10FE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10FE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10FE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10FE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10FE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10FEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10FEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10FEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10FED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10FEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10FEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10FF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10FF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10FF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10FF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10FF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10FF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10FF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10FF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10FF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10FFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10FFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10FFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10FFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10FFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10FFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:020000041D03DA
+:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10011000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10013000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10016000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10017000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10019000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:1001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:1001B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:1001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1001D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1001E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1001F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10021000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10023000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10025000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10027000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10029000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:1002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:1002B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:1002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1002D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1002E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1002F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10031000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10033000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10035000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10037000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10039000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:1003B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:1003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1003D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1003F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10040000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10041000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10042000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10043000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10044000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10045000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10046000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10047000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10048000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10049000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:1004A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:1004B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:1004C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1004D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1004E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1004F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10050000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10051000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10052000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10053000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10054000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10055000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10056000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10057000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10058000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10059000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:1005A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:1005B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:1005C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1005D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1005E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1005F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10060000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10061000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10062000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10063000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10064000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10065000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10066000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10067000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10068000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10069000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:1006A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:1006B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:1006C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1006D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1006E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1006F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10070000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10071000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10072000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10073000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10074000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10075000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10076000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10077000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10078000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10079000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:1007A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:1007B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:1007C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1007D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1007E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1007F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10080000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10081000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10082000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10083000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10084000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10085000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10086000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10087000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10088000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10089000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:1008A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:1008B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:1008C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1008D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1008E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1008F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10090000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10091000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10092000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10093000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10094000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10095000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10096000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10097000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10098000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10099000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:1009A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:1009B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:1009C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1009D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1009E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1009F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:100A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:100A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:100A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:100A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:100A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:100A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:100A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:100A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:100A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:100A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:100AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:100AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:100AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:100AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:100AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:100AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:100B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:100B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:100B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:100B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:100B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:100B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:100B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:100B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:100B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:100B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:100BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:100BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:100BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:100BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:100BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:100BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:100C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:100C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:100C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:100C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:100C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:100C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:100C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:100C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:100C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:100C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:100CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:100CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:100CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:100CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:100CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:100CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:100D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:100D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:100D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:100D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:100D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:100D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:100D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:100D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:100D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:100D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:100DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:100DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:100DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:100DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:100DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:100DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:100E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:100E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:100E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:100E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:100E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:100E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:100E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:100E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:100E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:100E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:100EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:100EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:100EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:100ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:100EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:100EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:100F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:100F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:100F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:100F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:100F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:100F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:100F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:100F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:100F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:100F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:100FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:100FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:100FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:100FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:100FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:100FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10100000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10101000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10102000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10103000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10104000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10105000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10106000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10107000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10108000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10109000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:1010A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:1010B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1010C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1010D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1010E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1010F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10110000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10111000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10112000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10113000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10114000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10115000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10116000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10117000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10118000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10119000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:1011A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:1011B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1011C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1011D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1011E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1011F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10120000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10121000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10122000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10123000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10124000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10125000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10126000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10127000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10128000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10129000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:1012A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:1012B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1012C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1012D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1012E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1012F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10130000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10131000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10133000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10134000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10135000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10136000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10137000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10138000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10139000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:1013A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:1013B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1013C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1013D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1013E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1013F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10140000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10141000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10142000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10143000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10144000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10145000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10146000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10147000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10148000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10149000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:1014A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:1014B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1014C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1014D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1014E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1014F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10150000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10151000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10152000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10153000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10154000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10155000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10156000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10157000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10158000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10159000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:1015A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:1015B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1015C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1015D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1015E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1015F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10160000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10161000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10162000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10163000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10164000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10165000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10166000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10167000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10168000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10169000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:1016A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:1016B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1016C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1016D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1016E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1016F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10170000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10171000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10172000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10173000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10174000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10175000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10176000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10177000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10178000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10179000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:1017A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:1017B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1017C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1017D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1017E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1017F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10180000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10181000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10182000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10183000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10184000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10185000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10186000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10187000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10188000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10189000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:1018A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:1018B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1018C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1018D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1018E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1018F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10190000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10191000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10192000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10193000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10194000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10195000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10196000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10197000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10198000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10199000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:1019A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:1019B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1019C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1019D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1019E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1019F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:101A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:101A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:101A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:101A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:101A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:101A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:101A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:101A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:101A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:101A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:101AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:101AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:101AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:101AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:101AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:101AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:101B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:101B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:101B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:101B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:101B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:101B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:101B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:101B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:101B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:101B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:101BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:101BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:101BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:101BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:101BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:101BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:101C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:101C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:101C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:101C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:101C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:101C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:101C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:101C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:101C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:101C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:101CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:101CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:101CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:101CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:101CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:101CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:101D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:101D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:101D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:101D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:101D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:101D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:101D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:101D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:101D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:101D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:101DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:101DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:101DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:101DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:101DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:101DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:101E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:101E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:101E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:101E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:101E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:101E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:101E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:101E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:101E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:101E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:101EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:101EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:101EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:101ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:101EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:101EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:101F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:101F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:101F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:101F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:101F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:101F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:101F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:101F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:101F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:101F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:101FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:101FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:101FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:101FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:101FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:101FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10200000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10201000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10202000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10203000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10204000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10205000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10206000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10207000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10208000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10209000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:1020A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1020B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1020C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1020D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1020E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1020F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10210000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10211000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10212000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10213000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10214000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10215000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10216000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10217000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10218000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10219000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:1021A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1021B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1021C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1021D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1021E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1021F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10220000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10221000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10222000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10223000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10224000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10225000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10226000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10227000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10228000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10229000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:1022A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1022B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1022C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1022D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1022E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1022F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10230000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10231000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10232000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10233000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10234000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10235000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10236000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10237000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10238000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10239000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:1023A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1023B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1023C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1023D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1023E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1023F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10240000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10241000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10242000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10243000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10244000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10245000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10246000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10247000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10248000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10249000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:1024A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1024B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1024C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1024D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1024E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1024F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10250000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10251000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10252000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10253000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10254000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10255000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10256000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10257000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10258000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10259000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:1025A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1025B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1025C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1025D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1025E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1025F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10260000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10261000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10263000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10264000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10265000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10266000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10267000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10268000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10269000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:1026A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1026B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1026C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1026D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1026E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1026F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10270000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10271000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10272000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10273000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10274000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10275000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10276000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10277000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10278000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10279000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:1027A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1027B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1027C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1027D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1027E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1027F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10280000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10281000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10282000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10283000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10284000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10285000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10286000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10287000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10288000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10289000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:1028A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1028B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1028C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1028D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1028E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1028F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10290000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10291000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10292000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10293000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10294000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10295000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10296000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10297000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10298000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10299000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:1029A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1029B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1029C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1029D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1029E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1029F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:102A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:102A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:102A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:102A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:102A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:102A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:102A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:102A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:102A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:102A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:102AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:102AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:102AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:102AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:102AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:102AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:102B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:102B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:102B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:102B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:102B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:102B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:102B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:102B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:102B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:102B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:102BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:102BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:102BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:102BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:102BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:102BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:102C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:102C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:102C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:102C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:102C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:102C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:102C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:102C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:102C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:102C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:102CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:102CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:102CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:102CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:102CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:102CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:102D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:102D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:102D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:102D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:102D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:102D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:102D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:102D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:102D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:102D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:102DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:102DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:102DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:102DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:102DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:102DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:102E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:102E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:102E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:102E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:102E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:102E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:102E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:102E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:102E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:102E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:102EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:102EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:102EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:102ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:102EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:102EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:102F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:102F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:102F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:102F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:102F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:102F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:102F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:102F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:102F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:102F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:102FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:102FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:102FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:102FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:102FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:102FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10300000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10301000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10302000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10303000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10304000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10305000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10306000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10307000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10308000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10309000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1030A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1030B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1030C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1030D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1030E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1030F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10310000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10311000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10312000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10313000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10314000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10315000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10316000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10317000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10318000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10319000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1031A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1031B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1031C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1031D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1031E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1031F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10320000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10321000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10322000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10323000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10324000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10325000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10326000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10327000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10328000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10329000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1032A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1032B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1032C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1032D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1032E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1032F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10330000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10331000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10332000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10333000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10334000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10335000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10336000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10337000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10338000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10339000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1033A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1033B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1033C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1033D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1033E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1033F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10340000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10341000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10342000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10343000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10344000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10345000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10346000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10347000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10348000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10349000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1034A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1034B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1034C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1034D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1034E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1034F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10350000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10351000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10352000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10353000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10354000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10355000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10356000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10357000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10358000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10359000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1035A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1035B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1035C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1035D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1035E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1035F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10360000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10361000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10362000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10363000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10364000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10365000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10366000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10367000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10368000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10369000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1036A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1036B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1036C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1036D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1036E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1036F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10370000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10371000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10372000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10373000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10374000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10375000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10376000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10377000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10378000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10379000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1037A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1037B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1037D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1037E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1037F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10380000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10381000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10382000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10383000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10384000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10385000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10388000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10389000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1038A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1038B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1038C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1038D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1038E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1038F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10390000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10391000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10392000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10393000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10394000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10395000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10396000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10397000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10398000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10399000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1039A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1039B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1039D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1039E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1039F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:103A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:103A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:103A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:103A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:103A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:103A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:103A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:103A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:103A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:103AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:103AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:103AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:103AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:103AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:103AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:103B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:103B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:103B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:103B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:103B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:103B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:103B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:103B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:103B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:103B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:103BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:103BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:103BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:103BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:103BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:103BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:103C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:103C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:103C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:103C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:103C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:103C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:103C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:103C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:103C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:103C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:103CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:103CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:103CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:103CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:103CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:103CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:103D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:103D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:103D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:103D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:103D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:103D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:103D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:103D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:103D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:103D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:103DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:103DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:103DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:103DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:103DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:103DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:103E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:103E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:103E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:103E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:103E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:103E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:103E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:103E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:103E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:103E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:103EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:103EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:103EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:103ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:103EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:103EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:103F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:103F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:103F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:103F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:103F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:103F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:103F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:103F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:103F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:103F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:103FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:103FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:103FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:103FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:103FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:103FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10400000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10401000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10402000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10403000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10404000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10405000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10406000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10407000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10408000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10409000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1040A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1040B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1040C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1040D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1040E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1040F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10410000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10411000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10412000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10413000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10414000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10415000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10416000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10417000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10418000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10419000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1041A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1041B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1041C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1041D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1041E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1041F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10420000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10421000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10422000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10423000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10424000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10425000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10426000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10427000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10428000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10429000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1042A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1042B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1042C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1042D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1042E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1042F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10430000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10431000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10432000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10433000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10434000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10435000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10436000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10437000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10438000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10439000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1043A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1043B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1043C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1043D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1043E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1043F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10440000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10441000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10442000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10443000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10444000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10445000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10446000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10447000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10448000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10449000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1044A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1044B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1044C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1044D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1044E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1044F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10450000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10451000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10452000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10453000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10454000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10455000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10456000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10457000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10458000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10459000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1045A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1045B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1045C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1045D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1045E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1045F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10460000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10461000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10462000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10463000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10464000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10465000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10466000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10467000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10468000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10469000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1046A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1046B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1046C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1046D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1046E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1046F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10470000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10471000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10472000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10473000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10474000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10475000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10476000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10477000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10478000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10479000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1047A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1047B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1047C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1047D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1047E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1047F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10480000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10481000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10482000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10483000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10484000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10485000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10486000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10487000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10488000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10489000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1048A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1048B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1048C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1048D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1048E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1048F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10490000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10491000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10493000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10495000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10497000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10499000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1049A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1049B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1049C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1049D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1049E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1049F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:104A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:104A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:104A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:104A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:104A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:104A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:104A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:104A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:104A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:104A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:104AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:104AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:104AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:104AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:104AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:104AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:104B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:104B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:104B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:104B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:104B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:104B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:104B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:104B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:104B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:104BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:104BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:104BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:104C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:104C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:104C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:104C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:104C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:104C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:104C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:104C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:104C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:104C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:104CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:104CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:104CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:104CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:104CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:104CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:104D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:104D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:104D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:104D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:104D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:104D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:104D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:104D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:104D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:104D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:104DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:104DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:104DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:104DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:104DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:104DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:104E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:104E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:104E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:104E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:104E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:104E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:104E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:104E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:104E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:104ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:104EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:104F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:104F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:104F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:104F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:104F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:104F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:104F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:104F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:104F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:104F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:104FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:104FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:104FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:104FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:104FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:104FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10501000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10502000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10503000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10504000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10505000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10506000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10507000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10508000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10509000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1050A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1050B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1050C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1050D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1050E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1050F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10510000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10511000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10512000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10513000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10514000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10515000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10516000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10517000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10518000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10519000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1051A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1051B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1051C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1051D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1051E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1051F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10520000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10521000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10522000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10523000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10524000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10525000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10526000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10527000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10528000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10529000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1052A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1052B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1052C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1052D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1052E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1052F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10530000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10531000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10532000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10533000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10534000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10535000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10536000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10537000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10538000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10539000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1053A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1053B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1053C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1053D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10540000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10541000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10542000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10543000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10544000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10545000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10546000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10547000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10548000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10549000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1054A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1054B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1054C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1054D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1054E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1054F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10550000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10551000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10552000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10553000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10554000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10555000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10556000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10557000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10558000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10559000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1055A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1055B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1055C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1055D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1055E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1055F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10560000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10561000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10562000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10563000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10564000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10565000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10566000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10567000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10568000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10569000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1056A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1056B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1056C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1056D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1056E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1056F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10570000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10571000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10572000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10573000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10574000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10575000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10576000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10577000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10578000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10579000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1057A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1057B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1057C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1057D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1057E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1057F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10580000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10581000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10582000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10583000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10584000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10585000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10586000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10587000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10588000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10589000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1058A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1058B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1058C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1058D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1058E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1058F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10590000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10591000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10592000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10593000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10594000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10595000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10596000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10597000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10598000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10599000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1059A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1059B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1059C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1059D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1059E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1059F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:105A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:105A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:105A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:105A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:105A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:105A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:105A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:105A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:105A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:105A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:105AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:105AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:105AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:105AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:105AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:105AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:105B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:105B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:105B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:105B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:105B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:105B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:105B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:105B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:105B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:105B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:105BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:105BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:105BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:105BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:105BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:105BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:105C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:105C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:105C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:105C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:105C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:105C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:105C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:105C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:105C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:105C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:105CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:105CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:105CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:105CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:105CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:105CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:105D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:105D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:105D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:105D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:105D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:105D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:105D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:105D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:105D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:105D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:105DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:105DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:105DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:105DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:105DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:105DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:105E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:105E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:105E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:105E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:105E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:105E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:105E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:105E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:105E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:105E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:105EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:105EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:105EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:105ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:105EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:105EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:105F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:105F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:105F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:105F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:105F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:105F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:105F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:105F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:105F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:105F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:105FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:105FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:105FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:105FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:105FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:105FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10600000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10601000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10602000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10603000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10604000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10605000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10606000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10607000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10608000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10609000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1060A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1060B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1060C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1060D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1060E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1060F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10610000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10611000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10612000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10613000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10614000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10615000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10616000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10617000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10618000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10619000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1061A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1061B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1061C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1061D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1061E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10620000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10621000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10622000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10624000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10625000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10626000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10627000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10628000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10629000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1062A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1062B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1062C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1062D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1062E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1062F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10630000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10631000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10632000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10633000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10634000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10635000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10636000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10637000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10638000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10639000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1063A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1063B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1063C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10644000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10645000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10646000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10647000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10648000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10649000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1064A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1064B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1064C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1064D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1064E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1064F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10650000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10651000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10652000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10653000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10654000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10655000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10656000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10657000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10658000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10659000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1065A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1065B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1065C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1065D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1065E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1065F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10660000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10661000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10662000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10663000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10664000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10665000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10666000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10667000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10668000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10669000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1066A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1066B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1066C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1066D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1066E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1066F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10670000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10671000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10672000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10673000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10674000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10675000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10676000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10677000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10678000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10679000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1067A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1067B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1067C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1067D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1067E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1067F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10680000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10681000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10682000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10683000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10684000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10685000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10686000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10687000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10688000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10689000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1068A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1068B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1068C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1068D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1068E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10697000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:106A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:106A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:106A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:106A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:106A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:106A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:106A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:106A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:106A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:106A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:106AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:106AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:106AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:106AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:106AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:106AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:106B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:106B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:106B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:106B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:106B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:106B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:106B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:106B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:106B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:106B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:106BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:106BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:106BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:106BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:106BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:106BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:106C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:106C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:106C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:106C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:106C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:106C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:106C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:106C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:106C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:106C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:106CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:106CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:106CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:106CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:106CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:106CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:106D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:106D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:106D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:106D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:106D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:106D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:106D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:106D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:106D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:106D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:106DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:106DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:106DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:106DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:106DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:106DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:106E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:106E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:106E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:106E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:106E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:106E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:106E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:106E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:106E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:106E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:106EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:106EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:106EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:106ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:106EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:106EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:106F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:106F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:106F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:106F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:106F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:106F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:106F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:106F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:106F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:106F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:106FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:106FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:106FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:106FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:106FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:106FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10701000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10702000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10703000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10707000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10709000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1070B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1070C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1070D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1070E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1070F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10710000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10711000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10712000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10713000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10714000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10715000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10716000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10717000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10718000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10719000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1071A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1071B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1071C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1071D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1071E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1071F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10720000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10721000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10722000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10723000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10724000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10725000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10726000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10727000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10728000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10729000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1072A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1072B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1072C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1072D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1072E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1072F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10730000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10731000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10732000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10733000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10734000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10735000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10736000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10737000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10738000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10739000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1073A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1073B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1073C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1073D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1073E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1073F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10740000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10741000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10742000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10743000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10744000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10745000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10746000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10747000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10748000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10749000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1074A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1074B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1074C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1074D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1074E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1074F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10750000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10751000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10752000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10753000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10754000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10755000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10756000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10757000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10758000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10759000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1075A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1075B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1075C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1075D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1075E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1075F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10760000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10761000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10762000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10763000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10764000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10765000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10766000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10767000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10768000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10769000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1076A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1076B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1076C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1076D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1076E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1076F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10770000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10771000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10772000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10773000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10774000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10775000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10776000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10777000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10778000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10779000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1077A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1077B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1077C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1077D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1077E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1077F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10780000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10781000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10782000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10783000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10784000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10785000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10786000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10787000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10788000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10789000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1078A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1078B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1078C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1078D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1078E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1078F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10790000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10791000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10792000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10793000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10794000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10795000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10796000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10797000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10798000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10799000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1079A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1079B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1079C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1079D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1079E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1079F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:107A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:107A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:107A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:107A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:107A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:107A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:107A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:107A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:107A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:107A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:107AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:107AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:107AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:107AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:107AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:107AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:107B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:107B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:107B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:107B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:107B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:107B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:107B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:107B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:107B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:107B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:107BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:107BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:107BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:107BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:107BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:107BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:107C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:107C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:107C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:107C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:107C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:107C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:107C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:107C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:107C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:107C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:107CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:107CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:107CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:107CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:107CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:107CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:107D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:107D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:107D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:107D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:107D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:107D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:107D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:107D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:107D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:107D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:107DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:107DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:107DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:107DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:107DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:107DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:107E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:107E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:107E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:107E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:107E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:107E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:107E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:107E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:107E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:107E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:107EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:107EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:107EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:107ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:107EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:107EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:107F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:107F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:107F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:107F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:107F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:107F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:107F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:107F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:107F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:107F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:107FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:107FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:107FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:107FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:107FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:107FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10801000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10802000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10803000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10804000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10805000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10806000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10807000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10808000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10809000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1080A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1080B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1080C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1080D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1080E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:1080F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10810000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10811000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10812000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10813000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10814000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10815000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10816000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10817000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10818000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10819000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1081A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1081B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1081C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1081D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1081E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:1081F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10820000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10821000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10822000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10823000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10824000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10825000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10826000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10827000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10828000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10829000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1082A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1082B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1082C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1082D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1082E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:1082F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10830000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10831000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10832000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10833000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10834000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10835000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10836000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10837000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10838000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10839000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1083A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1083B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1083C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1083D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1083E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:1083F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10840000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10841000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10842000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10843000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10844000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10845000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10846000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10847000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10848000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10849000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1084A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1084B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1084C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1084D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1084E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:1084F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10850000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10851000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10852000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10853000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10854000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10855000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10856000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10857000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10858000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10859000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1085A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1085B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1085C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1085D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1085E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:1085F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10860000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10861000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10862000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10863000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10864000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10865000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10866000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10867000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10868000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10869000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1086A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1086B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1086C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1086D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1086E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:1086F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10870000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10871000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10872000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10873000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10874000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10875000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10876000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10877000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10878000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10879000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1087A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1087B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1087C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1087D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1087E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:1087F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10880000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10881000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10882000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10883000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10884000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10885000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10886000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10887000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10888000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10889000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1088A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1088B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1088C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1088D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1088E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:1088F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10890000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10891000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10892000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10893000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10894000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10895000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10896000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10897000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10898000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10899000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1089A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1089B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1089C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1089D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1089E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:1089F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:108A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:108A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:108A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:108A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:108A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:108A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:108A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:108A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:108A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:108A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:108AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:108AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:108AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:108AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:108AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:108AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:108B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:108B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:108B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:108B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:108B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:108B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:108B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:108B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:108B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:108B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:108BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:108BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:108BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:108BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:108BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:108BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:108C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:108C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:108C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:108C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:108C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:108C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:108C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:108C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:108C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:108C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:108CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:108CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:108CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:108CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:108CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:108CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:108D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:108D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:108D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:108D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:108D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:108D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:108D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:108D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:108D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:108D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:108DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:108DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:108DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:108DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:108DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:108DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:108E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:108E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:108E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:108E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:108E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:108E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:108E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:108E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:108E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:108E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:108EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:108EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:108EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:108ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:108EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:108EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:108F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:108F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:108F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:108F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:108F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:108F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:108F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:108F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:108F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:108F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:108FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:108FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:108FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:108FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:108FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:108FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10900000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10901000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10902000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10903000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10904000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10905000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10906000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10907000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10908000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10909000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1090A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1090B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1090C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1090D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:1090E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:1090F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10910000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10911000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10912000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10913000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10914000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10915000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10916000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10917000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10918000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10919000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1091A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1091B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1091C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1091D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:1091E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:1091F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10920000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10921000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10922000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10923000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10924000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10925000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10926000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10927000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10928000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10929000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1092A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1092B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1092C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1092D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:1092E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:1092F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10930000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10931000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10932000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10933000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10934000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10935000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10936000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10937000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10938000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10939000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1093A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1093B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1093C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1093D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:1093E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:1093F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10940000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10941000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10942000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10943000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10944000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10945000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10946000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10947000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10948000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10949000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1094A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1094B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1094C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1094D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:1094E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:1094F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10950000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10951000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10952000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10953000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10954000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10955000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10956000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10957000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10958000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10959000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1095A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1095B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1095C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1095D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:1095E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:1095F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10960000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10961000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10962000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10963000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10964000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10965000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10966000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10967000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10968000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10969000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1096A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1096B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1096C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1096D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:1096E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:1096F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10970000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10971000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10972000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10973000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10974000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10975000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10976000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10977000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10978000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10979000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1097A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1097B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1097C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1097D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:1097E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:1097F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10980000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10981000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10982000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10983000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10984000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10985000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10986000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10987000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10988000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10989000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1098A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1098B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1098C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1098D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:1098E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:1098F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10990000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10991000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10992000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10993000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10994000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10995000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10996000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10997000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10998000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10999000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1099A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1099B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1099C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1099D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:1099E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:1099F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:109A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:109A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:109A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:109A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:109A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:109A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:109A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:109A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:109A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:109A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:109AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:109AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:109AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:109AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:109AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:109AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:109B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:109B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:109B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:109B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:109B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:109B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:109B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:109B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:109B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:109B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:109BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:109BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:109BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:109BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:109BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:109BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:109C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:109C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:109C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:109C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:109C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:109C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:109C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:109C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:109C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:109C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:109CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:109CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:109CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:109CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:109CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:109CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:109D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:109D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:109D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:109D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:109D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:109D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:109D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:109D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:109D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:109D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:109DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:109DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:109DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:109DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:109DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:109DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:109E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:109E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:109E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:109E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:109E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:109E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:109E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:109E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:109E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:109E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:109EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:109EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:109EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:109ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:109EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:109EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:109F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:109F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:109F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:109F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:109F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:109F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:109F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:109F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:109F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:109F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:109FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:109FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:109FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:109FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:109FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:109FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10A00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10A01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10A02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10A03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10A04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10A05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10A06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10A07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10A08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10A09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10A0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10A0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10A0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10A0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10A0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10A0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10A10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10A11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10A12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10A13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10A14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10A15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10A16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10A17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10A18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10A19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10A1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10A1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10A1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10A1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10A1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10A1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10A20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10A21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10A22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10A23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10A24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10A25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10A26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10A27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10A28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10A29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10A2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10A2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10A2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10A2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10A2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10A2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10A30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10A31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10A32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10A33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10A34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10A35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10A36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10A37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10A38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10A39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10A3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10A3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10A3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10A3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10A3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10A3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10A40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10A41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10A42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10A43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10A44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10A45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10A46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10A47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10A48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10A49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10A4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10A4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10A4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10A4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10A4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10A4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10A50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10A51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10A52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10A53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10A54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10A55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10A56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10A57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10A58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10A59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10A5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10A5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10A5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10A5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10A5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10A5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10A60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10A61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10A62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10A63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10A64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10A65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10A66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10A67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10A68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10A69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10A6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10A6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10A6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10A6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10A6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10A6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10A70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10A71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10A72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10A73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10A74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10A75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10A76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10A77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10A78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10A79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10A7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10A7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10A7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10A7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10A7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10A7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10A80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10A81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10A82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10A83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10A84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10A85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10A86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10A87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10A88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10A89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10A8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10A8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10A8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10A8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10A8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10A8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10A90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10A91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10A92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10A93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10A94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10A95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10A96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10A97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10A98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10A99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10A9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10A9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10A9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10A9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10A9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10A9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10AA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10AA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10AA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10AA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10AA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10AA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10AA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10AA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10AA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10AA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10AAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10AAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10AAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10AAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10AAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10AAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10AB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10AB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10AB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10AB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10AB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10AB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10AB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10AB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10AB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10AB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10ABA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10ABB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10ABC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10ABD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10ABE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10ABF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10AC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10AC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10AC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10AC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10AC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10AC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10AC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10AC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10AC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10AC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10ACA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10ACB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10ACC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10ACD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10ACE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10ACF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10AD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10AD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10AD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10AD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10AD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10AD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10AD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10AD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10AD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10AD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10ADA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10ADB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10ADC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10ADD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10ADE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10ADF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10AE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10AE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10AE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10AE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10AE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10AE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10AE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10AE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10AE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10AE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10AEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10AEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10AEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10AED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10AEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10AEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10AF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10AF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10AF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10AF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10AF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10AF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10AF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10AF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10AF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10AF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10AFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10AFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10AFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10AFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10AFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10AFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10B00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10B01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10B02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10B03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10B04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10B05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10B06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10B07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10B08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10B09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10B0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10B0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10B0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10B0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10B0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10B0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10B10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10B11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10B12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10B13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10B14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10B15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10B16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10B17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10B18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10B19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10B1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10B1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10B1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10B1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10B1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10B1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10B20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10B21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10B22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10B23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10B24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10B25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10B26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10B27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10B28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10B29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10B2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10B2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10B2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10B2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10B2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10B2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10B30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10B31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10B32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10B33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10B34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10B35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10B36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10B37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10B38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10B39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10B3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10B3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10B3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10B3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10B3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10B3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10B40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10B41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10B42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10B43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10B44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10B45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10B46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10B47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10B48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10B49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10B4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10B4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10B4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10B4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10B4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10B4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10B50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10B51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10B52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10B53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10B54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10B55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10B56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10B57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10B58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10B59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10B5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10B5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10B5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10B5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10B5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10B5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10B60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10B61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10B62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10B63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10B64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10B65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10B66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10B67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10B68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10B69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10B6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10B6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10B6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10B6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10B6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10B6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10B70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10B71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10B72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10B73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10B74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10B75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10B76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10B77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10B78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10B79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10B7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10B7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10B7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10B7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10B7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10B7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10B80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10B81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10B82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10B83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10B84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10B85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10B86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10B87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10B88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10B89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10B8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10B8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10B8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10B8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10B8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10B8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10B90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10B91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10B92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10B93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10B94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10B95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10B96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10B97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10B98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10B99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10B9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10B9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10B9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10B9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10B9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10B9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10BA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10BA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10BA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10BA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10BA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10BA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10BA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10BA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10BA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10BA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10BAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10BAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10BAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10BAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10BAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10BAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10BB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10BB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10BB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10BB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10BB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10BB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10BB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10BB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10BB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10BB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10BBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10BBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10BBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10BBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10BBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10BBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10BC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10BC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10BC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10BC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10BC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10BC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10BC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10BC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10BC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10BC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10BCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10BCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10BCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10BCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10BCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10BCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10BD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10BD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10BD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10BD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10BD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10BD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10BD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10BD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10BD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10BD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10BDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10BDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10BDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10BDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10BDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10BDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10BE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10BE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10BE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10BE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10BE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10BE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10BE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10BE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10BE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10BE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10BEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10BEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10BEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10BED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10BEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10BEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10BF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10BF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10BF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10BF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10BF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10BF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10BF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10BF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10BF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10BF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10BFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10BFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10BFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10BFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10BFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10BFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10C00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10C01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10C02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10C03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10C04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10C05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10C06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10C07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10C08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10C09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10C0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10C0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10C0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10C0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10C0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10C0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10C10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10C11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10C12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10C13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10C14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10C15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10C16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10C17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10C18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10C19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10C1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10C1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10C1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10C1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10C1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10C1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10C20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10C21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10C22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10C23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10C24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10C25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10C26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10C27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10C28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10C29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10C2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10C2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10C2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10C2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10C2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10C2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10C30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10C31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10C32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10C33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10C34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10C35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10C36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10C37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10C38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10C39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10C3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10C3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10C3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10C3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10C3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10C3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10C40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10C41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10C42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10C43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10C44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10C45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10C46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10C47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10C48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10C49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10C4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10C4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10C4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10C4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10C4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10C4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10C50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10C51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10C52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10C53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10C54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10C55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10C56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10C57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10C58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10C59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10C5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10C5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10C5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10C5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10C5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10C5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10C60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10C61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10C62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10C63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10C64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10C65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10C66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10C67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10C68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10C69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10C6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10C6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10C6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10C6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10C6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10C6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10C70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10C71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10C72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10C73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10C74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10C75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10C76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10C77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10C78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10C79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10C7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10C7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10C7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10C7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10C7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10C7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10C80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10C81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10C82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10C83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10C84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10C85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10C86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10C87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10C88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10C89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10C8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10C8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10C8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10C8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10C8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10C8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10C90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10C91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10C92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10C93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10C94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10C95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10C96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10C97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10C98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10C99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10C9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10C9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10C9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10C9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10C9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10C9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10CA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10CA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10CA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10CA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10CA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10CA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10CA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10CA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10CA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10CA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10CAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10CAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10CAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10CAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10CAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10CAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10CB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10CB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10CB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10CB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10CB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10CB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10CB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10CB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10CB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10CB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10CBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10CBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10CBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10CBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10CBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10CBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10CC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10CC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10CC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10CC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10CC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10CC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10CC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10CC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10CC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10CC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10CCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10CCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10CCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10CCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10CCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10CCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10CD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10CD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10CD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10CD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10CD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10CD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10CD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10CD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10CD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10CD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10CDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10CDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10CDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10CDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10CDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10CDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10CE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10CE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10CE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10CE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10CE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10CE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10CE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10CE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10CE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10CE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10CEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10CEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10CEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10CED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10CEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10CEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10CF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10CF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10CF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10CF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10CF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10CF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10CF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10CF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10CF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10CF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10CFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10CFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10CFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10CFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10CFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10CFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10D00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10D01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10D02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10D03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10D04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10D05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10D06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10D07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10D08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10D09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10D0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10D0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10D0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10D0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10D0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10D0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10D10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10D11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10D12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10D13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10D14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10D15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10D16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10D17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10D18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10D19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10D1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10D1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10D1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10D1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10D1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10D1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10D20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10D21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10D22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10D23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10D24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10D25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10D26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10D27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10D28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10D29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10D2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10D2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10D2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10D2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10D2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10D2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10D30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10D31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10D32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10D33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10D34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10D35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10D36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10D37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10D38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10D39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10D3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10D3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10D3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10D3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10D3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10D3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10D40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10D41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10D42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10D43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10D44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10D45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10D46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10D47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10D48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10D49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10D4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10D4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10D4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10D4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10D4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10D4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10D50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10D51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10D52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10D53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10D54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10D55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10D56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10D57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10D58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10D59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10D5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10D5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10D5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10D5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10D5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10D5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10D60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10D61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10D62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10D63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10D64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10D65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10D66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10D67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10D68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10D69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10D6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10D6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10D6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10D6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10D6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10D6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10D70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10D71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10D72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10D73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10D74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10D75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10D76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10D77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10D78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10D79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10D7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10D7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10D7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10D7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10D7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10D7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10D80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10D81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10D82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10D83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10D84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10D85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10D86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10D87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10D88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10D89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10D8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10D8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10D8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10D8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10D8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10D8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10D90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10D91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10D92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10D93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10D94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10D95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10D96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10D97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10D98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10D99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10D9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10D9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10D9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10D9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10D9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10D9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10DA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10DA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10DA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10DA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10DA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10DA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10DA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10DA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10DA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10DA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10DAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10DAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10DAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10DAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10DAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10DAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10DB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10DB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10DB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10DB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10DB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10DB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10DB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10DB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10DB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10DB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10DBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10DBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10DBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10DBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10DBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10DBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10DC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10DC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10DC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10DC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10DC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10DC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10DC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10DC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10DC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10DC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10DCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10DCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10DCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10DCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10DCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10DCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10DD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10DD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10DD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10DD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10DD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10DD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10DD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10DD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10DD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10DD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10DDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10DDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10DDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10DDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10DDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10DDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10DE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10DE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10DE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10DE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10DE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10DE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10DE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10DE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10DE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10DE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10DEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10DEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10DEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10DED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10DEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10DEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10DF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10DF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10DF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10DF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10DF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10DF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10DF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10DF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10DF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10DF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10DFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10DFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10DFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10DFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10DFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10DFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10E00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10E01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10E02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10E03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10E04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10E05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10E06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10E07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10E08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10E09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10E0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10E0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10E0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10E0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10E0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10E0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10E10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10E11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10E12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10E13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10E14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10E15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10E16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10E17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10E18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10E19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10E1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10E1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10E1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10E1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10E1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10E1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10E20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10E21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10E22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10E23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10E24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10E25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10E26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10E27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10E28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10E29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10E2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10E2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10E2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10E2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10E2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10E2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10E30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10E31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10E32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10E33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10E34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10E35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10E36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10E37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10E38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10E39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10E3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10E3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10E3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10E3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10E3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10E3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10E40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10E41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10E42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10E43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10E44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10E45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10E46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10E47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10E48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10E49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10E4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10E4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10E4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10E4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10E4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10E4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10E50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10E51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10E52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10E53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10E54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10E55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10E56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10E57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10E58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10E59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10E5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10E5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10E5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10E5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10E5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10E5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10E60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10E61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10E62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10E63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10E64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10E65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10E66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10E67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10E68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10E69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10E6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10E6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10E6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10E6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10E6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10E6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10E70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10E71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10E72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10E73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10E74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10E75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10E76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10E77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10E78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10E79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10E7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10E7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10E7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10E7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10E7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10E7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10E80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10E81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10E82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10E83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10E84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10E85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10E86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10E87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10E88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10E89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10E8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10E8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10E8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10E8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10E8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10E8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10E90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10E91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10E92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10E93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10E94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10E95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10E96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10E97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10E98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10E99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10E9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10E9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10E9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10E9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10E9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10E9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10EA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10EA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10EA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10EA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10EA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10EA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10EA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10EA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10EA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10EA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10EAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10EAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10EAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10EAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10EAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10EAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10EB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10EB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10EB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10EB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10EB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10EB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10EB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10EB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10EB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10EB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10EBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10EBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10EBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10EBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10EBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10EBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10EC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10EC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10EC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10EC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10EC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10EC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10EC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10EC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10EC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10EC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10ECA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10ECB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10ECC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10ECD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10ECE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10ECF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10ED0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10ED1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10ED2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10ED3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10ED4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10ED5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10ED6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10ED7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10ED8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10ED9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10EDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10EDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10EDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10EDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10EDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10EDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10EE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10EE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10EE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10EE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10EE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10EE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10EE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10EE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10EE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10EE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10EEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10EEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10EEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10EED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10EEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10EEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10EF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10EF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10EF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10EF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10EF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10EF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10EF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10EF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10EF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10EF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10EFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10EFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10EFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10EFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10EFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10EFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10F00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10F01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10F02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10F03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10F04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10F05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10F06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10F07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10F08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10F09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10F0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10F0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10F0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10F0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10F0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10F0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10F10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10F11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10F12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10F13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10F14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10F15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10F16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10F17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10F18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10F19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10F1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10F1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10F1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10F1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10F1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10F1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10F20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10F21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10F22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10F23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10F24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10F25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10F26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10F27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10F28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10F29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10F2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10F2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10F2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10F2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10F2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10F2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10F30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10F31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10F32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10F33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10F34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10F35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10F36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10F37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10F38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10F39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10F3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10F3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10F3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10F3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10F3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10F3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10F40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10F41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10F42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10F43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10F44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10F45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10F46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10F47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10F48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10F49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10F4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10F4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10F4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10F4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10F4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10F4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10F50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10F51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10F52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10F53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10F54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10F55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10F56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10F57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10F58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10F59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10F5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10F5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10F5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10F5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10F5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10F5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10F60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10F61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10F62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10F63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10F64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10F65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10F66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10F67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10F68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10F69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10F6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10F6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10F6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10F6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10F6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10F6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10F70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10F71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10F72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10F73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10F74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10F75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10F76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10F77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10F78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10F79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10F7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10F7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10F7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10F7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10F7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10F7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10F80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10F81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10F82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10F83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10F84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10F85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10F86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10F87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10F88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10F89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10F8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10F8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10F8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10F8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10F8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10F8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10F90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10F91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10F92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10F93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10F94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10F95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10F96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10F97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10F98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10F99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10F9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10F9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10F9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10F9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10F9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10F9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10FA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10FA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10FA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10FA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10FA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10FA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10FA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10FA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10FA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10FA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10FAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10FAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10FAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10FAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10FAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10FAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10FB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10FB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10FB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10FB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10FB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10FB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10FB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10FB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10FB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10FB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10FBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10FBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10FBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10FBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10FBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10FBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10FC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10FC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10FC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10FC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10FC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10FC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10FC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10FC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10FC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10FC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10FCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10FCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10FCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10FCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10FCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10FCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10FD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10FD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10FD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10FD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10FD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10FD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10FD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10FD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10FD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10FD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10FDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10FDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10FDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10FDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10FDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10FDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10FE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10FE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10FE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10FE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10FE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10FE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10FE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10FE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10FE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10FE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10FEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10FEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10FEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10FED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10FEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10FEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10FF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10FF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10FF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10FF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10FF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10FF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10FF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10FF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10FF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10FFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10FFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10FFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10FFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10FFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10FFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:00000001FF
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/SD-SPI.c b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/SD-SPI.c new file mode 100644 index 00000000..fa57e704 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/SD-SPI.c @@ -0,0 +1,1493 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: SD-SPI.c
+ * Dependencies: SD-SPI.h
+ * string.h
+ * FSIO.h
+ * FSDefs.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#include "FSIO.h"
+#include "FSDefs.h"
+#include "SD-SPI.h"
+#include "string.h"
+#include "FSConfig.h"
+#include "HardwareProfile.h"
+
+/******************************************************************************
+ * Global Variables
+ *****************************************************************************/
+
+// Description: Used for the mass-storage library to determine capacity
+DWORD MDD_SDSPI_finalLBA;
+
+
+#ifdef __18CXX
+ // Summary: Table of SD card commands and parameters
+ // Description: The sdmmc_cmdtable contains an array of SD card commands, the corresponding CRC code, the
+ // response type that the card will return, and a parameter indicating whether to expect
+ // additional data from the card.
+ const rom typMMC_CMD sdmmc_cmdtable[] =
+#else
+ const typMMC_CMD sdmmc_cmdtable[] =
+#endif
+{
+ // cmd crc response
+ {cmdGO_IDLE_STATE, 0x95, R1, NODATA},
+ {cmdSEND_OP_COND, 0xF9, R1, NODATA},
+ {cmdSEND_CSD, 0xAF, R1, MOREDATA},
+ {cmdSEND_CID, 0x1B, R1, MOREDATA},
+ {cmdSTOP_TRANSMISSION, 0xC3, R1, NODATA},
+ {cmdSEND_STATUS, 0xAF, R2, NODATA},
+ {cmdSET_BLOCKLEN, 0xFF, R1, NODATA},
+ {cmdREAD_SINGLE_BLOCK, 0xFF, R1, MOREDATA},
+ {cmdREAD_MULTI_BLOCK, 0xFF, R1, MOREDATA},
+ {cmdWRITE_SINGLE_BLOCK, 0xFF, R1, MOREDATA},
+ {cmdWRITE_MULTI_BLOCK, 0xFF, R1, MOREDATA},
+ {cmdTAG_SECTOR_START, 0xFF, R1, NODATA},
+ {cmdTAG_SECTOR_END, 0xFF, R1, NODATA},
+ {cmdERASE, 0xDF, R1b, NODATA},
+ {cmdAPP_CMD, 0x73, R1, NODATA},
+ {cmdREAD_OCR, 0x25, R3, NODATA},
+ {cmdCRC_ON_OFF, 0x25, R1, NODATA}
+};
+
+
+
+
+/******************************************************************************
+ * Prototypes
+ *****************************************************************************/
+
+extern void Delayms(BYTE milliseconds);
+BYTE MDD_SDSPI_ReadMedia(void);
+BYTE MDD_SDSPI_MediaInitialize(void);
+MMC_RESPONSE SendMMCCmd(BYTE cmd, DWORD address);
+
+#if defined __C30__ || defined __C32__
+ void OpenSPIM ( unsigned int sync_mode);
+ void CloseSPIM( void );
+ unsigned char WriteSPIM( unsigned char data_out );
+#elif defined __18CXX
+ void OpenSPIM ( unsigned char sync_mode);
+ void CloseSPIM( void );
+ unsigned char WriteSPIM( unsigned char data_out );
+
+ unsigned char WriteSPIManual(unsigned char data_out);
+ BYTE ReadMediaManual (void);
+ MMC_RESPONSE SendMMCCmdManual(BYTE cmd, DWORD address);
+#endif
+
+#ifdef __PIC32MX__
+
+/*********************************************************
+ Function:
+ static inline __attribute__((always_inline)) unsigned char SPICacutateBRG (unsigned int pb_clk, unsigned int spi_clk)
+ Summary:
+ Calculate the PIC32 SPI BRG value
+ Conditions:
+ None
+ Input:
+ pb_clk - The value of the PIC32 peripheral clock
+ spi_clk - The desired baud rate
+ Return:
+ The corresponding BRG register value.
+ Side Effects:
+ None.
+ Description:
+ The SPICalutateBRG function is used to determine an appropriate BRG register value for the PIC32 SPI module.
+ Remarks:
+ None
+ *********************************************************/
+
+static inline __attribute__((always_inline)) unsigned char SPICalutateBRG(unsigned int pb_clk, unsigned int spi_clk)
+{
+ unsigned int brg;
+
+ brg = pb_clk / (2 * spi_clk);
+
+ if(pb_clk % (2 * spi_clk))
+ brg++;
+
+ if(brg > 0x100)
+ brg = 0x100;
+
+ if(brg)
+ brg--;
+
+ return (unsigned char) brg;
+}
+#endif
+
+
+/*********************************************************
+ Function:
+ BYTE MDD_SDSPI_MediaDetect
+ Summary:
+ Determines whether an SD card is present
+ Conditions:
+ The MDD_MediaDetect function pointer must be configured
+ to point to this function in FSconfig.h
+ Input:
+ None
+ Return Values:
+ TRUE - Card detected
+ FALSE - No card detected
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_MediaDetect function will determine if an
+ SD card is connected to the microcontroller by polling
+ the SD card detect pin.
+ Remarks:
+ None
+ *********************************************************/
+
+BYTE MDD_SDSPI_MediaDetect (void)
+{
+ return(!SD_CD);
+}//end MediaDetect
+
+
+/*********************************************************
+ Function:
+ WORD MDD_SDSPI_ReadSectorSize (void)
+ Summary:
+ Determines the current sector size on the SD card
+ Conditions:
+ MDD_MediaInitialize() is complete
+ Input:
+ None
+ Return:
+ The size of the sectors for the physical media
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_ReadSectorSize function is used by the
+ USB mass storage class to return the card's sector
+ size to the PC on request.
+ Remarks:
+ None
+ *********************************************************/
+
+WORD MDD_SDSPI_ReadSectorSize(void)
+{
+ return MEDIA_SECTOR_SIZE;
+}
+
+
+/*********************************************************
+ Function:
+ DWORD MDD_SDSPI_ReadCapacity (void)
+ Summary:
+ Determines the current capacity of the SD card
+ Conditions:
+ MDD_MediaInitialize() is complete
+ Input:
+ None
+ Return:
+ The capacity of the device
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_ReadCapacity function is used by the
+ USB mass storage class to return the total number
+ of sectors on the card.
+ Remarks:
+ None
+ *********************************************************/
+DWORD MDD_SDSPI_ReadCapacity(void)
+{
+ return (MDD_SDSPI_finalLBA);
+}
+
+
+/*********************************************************
+ Function:
+ WORD MDD_SDSPI_InitIO (void)
+ Summary:
+ Initializes the I/O lines connected to the card
+ Conditions:
+ MDD_MediaInitialize() is complete. The MDD_InitIO
+ function pointer is pointing to this function.
+ Input:
+ None
+ Return:
+ None
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_InitIO function initializes the I/O
+ pins connected to the SD card.
+ Remarks:
+ None
+ *********************************************************/
+
+void MDD_SDSPI_InitIO (void)
+{
+ // Turn off the card
+ SD_CD_TRIS = INPUT; //Card Detect - input
+ SD_CS = 1; //Initialize Chip Select line
+ SD_CS_TRIS = OUTPUT; //Card Select - output
+ SD_WE_TRIS = INPUT; //Write Protect - input
+}
+
+
+
+/*********************************************************
+ Function:
+ BYTE MDD_SDSPI_ShutdownMedia (void)
+ Summary:
+ Disables the SD card
+ Conditions:
+ The MDD_ShutdownMedia function pointer is pointing
+ towards this function.
+ Input:
+ None
+ Return:
+ None
+ Side Effects:
+ None.
+ Description:
+ This function will disable the SPI port and deselect
+ the SD card.
+ Remarks:
+ None
+ *********************************************************/
+
+BYTE MDD_SDSPI_ShutdownMedia(void)
+{
+ // close the spi bus
+ CloseSPIM();
+
+ // deselect the device
+ SD_CS = 1;
+
+ return 0;
+}
+
+
+/*****************************************************************************
+ Function:
+ MMC_RESPONSE SendMMCCmd (BYTE cmd, DWORD address)
+ Summary:
+ Sends a command packet to the SD card.
+ Conditions:
+ None.
+ Input:
+ None.
+ Return Values:
+ MMC_RESPONSE - The response from the card
+ - Bit 0 - Idle state
+ - Bit 1 - Erase Reset
+ - Bit 2 - Illegal Command
+ - Bit 3 - Command CRC Error
+ - Bit 4 - Erase Sequence Error
+ - Bit 5 - Address Error
+ - Bit 6 - Parameter Error
+ - Bit 7 - Unused. Always 0.
+ Side Effects:
+ None.
+ Description:
+ SendMMCCmd prepares a command packet and sends it out over the SPI interface.
+ Response data of type 'R1' (as indicated by the SD/MMC product manual is returned.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+MMC_RESPONSE SendMMCCmd(BYTE cmd, DWORD address)
+{
+ WORD timeout = 0x8;
+ BYTE index;
+ MMC_RESPONSE response;
+ CMD_PACKET CmdPacket;
+
+ SD_CS = 0; //Card Select
+
+ // Copy over data
+ CmdPacket.cmd = sdmmc_cmdtable[cmd].CmdCode;
+ CmdPacket.address = address;
+ CmdPacket.crc = sdmmc_cmdtable[cmd].CRC; // Calc CRC here
+
+ CmdPacket.TRANSMIT_BIT = 1; //Set Tranmission bit
+
+ WriteSPIM(CmdPacket.cmd); //Send Command
+ WriteSPIM(CmdPacket.addr3); //Most Significant Byte
+ WriteSPIM(CmdPacket.addr2);
+ WriteSPIM(CmdPacket.addr1);
+ WriteSPIM(CmdPacket.addr0); //Least Significant Byte
+ WriteSPIM(CmdPacket.crc); //Send CRC
+
+ // see if we are going to get a response
+ if(sdmmc_cmdtable[cmd].responsetype == R1 || sdmmc_cmdtable[cmd].responsetype == R1b)
+ {
+ do
+ {
+ response.r1._byte = MDD_SDSPI_ReadMedia();
+ timeout--;
+ }while(response.r1._byte == MMC_FLOATING_BUS && timeout != 0);
+ }
+ else if(sdmmc_cmdtable[cmd].responsetype == R2)
+ {
+ MDD_SDSPI_ReadMedia();
+
+ response.r2._byte1 = MDD_SDSPI_ReadMedia();
+ response.r2._byte0 = MDD_SDSPI_ReadMedia();
+ }
+
+ if(sdmmc_cmdtable[cmd].responsetype == R1b)
+ {
+ response.r1._byte = 0x00;
+
+ for(index =0; index < 0xFF && response.r1._byte == 0x00; index++)
+ {
+ timeout = 0xFFFF;
+
+ do
+ {
+ response.r1._byte = MDD_SDSPI_ReadMedia();
+ timeout--;
+ }while(response.r1._byte == 0x00 && timeout != 0);
+ }
+ }
+
+ mSend8ClkCycles(); //Required clocking (see spec)
+
+ // see if we are expecting data or not
+ if(!(sdmmc_cmdtable[cmd].moredataexpected))
+ SD_CS = 1;
+
+ return(response);
+}
+
+#ifdef __18CXX
+#if (GetSystemClock() >= 25600000)
+
+/*****************************************************************************
+ Function:
+ MMC_RESPONSE SendMMCCmdManual (BYTE cmd, DWORD address)
+ Summary:
+ Sends a command packet to the SD card with bit-bang SPI.
+ Conditions:
+ None.
+ Input:
+ None.
+ Return Values:
+ MMC_RESPONSE - The response from the card
+ - Bit 0 - Idle state
+ - Bit 1 - Erase Reset
+ - Bit 2 - Illegal Command
+ - Bit 3 - Command CRC Error
+ - Bit 4 - Erase Sequence Error
+ - Bit 5 - Address Error
+ - Bit 6 - Parameter Error
+ - Bit 7 - Unused. Always 0.
+ Side Effects:
+ None.
+ Description:
+ SendMMCCmd prepares a command packet and sends it out over the SPI interface.
+ Response data of type 'R1' (as indicated by the SD/MMC product manual is returned.
+ This function is intended to be used when the clock speed of a PIC18 device is
+ so high that the maximum SPI divider can't reduce the clock below the maximum
+ SD card initialization sequence speed.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+MMC_RESPONSE SendMMCCmdManual(BYTE cmd, DWORD address)
+{
+ WORD timeout = 0x8;
+ BYTE index;
+ MMC_RESPONSE response;
+ CMD_PACKET CmdPacket;
+
+ SD_CS = 0; //Card Select
+
+ // Copy over data
+ CmdPacket.cmd = sdmmc_cmdtable[cmd].CmdCode;
+ CmdPacket.address = address;
+ CmdPacket.crc = sdmmc_cmdtable[cmd].CRC; // Calc CRC here
+
+ CmdPacket.TRANSMIT_BIT = 1; //Set Tranmission bit
+
+ WriteSPIManual(CmdPacket.cmd); //Send Command
+ WriteSPIManual(CmdPacket.addr3); //Most Significant Byte
+ WriteSPIManual(CmdPacket.addr2);
+ WriteSPIManual(CmdPacket.addr1);
+ WriteSPIManual(CmdPacket.addr0); //Least Significant Byte
+ WriteSPIManual(CmdPacket.crc); //Send CRC
+
+ // see if we are going to get a response
+ if(sdmmc_cmdtable[cmd].responsetype == R1 || sdmmc_cmdtable[cmd].responsetype == R1b)
+ {
+ do
+ {
+ response.r1._byte = ReadMediaManual();
+ timeout--;
+ }while(response.r1._byte == MMC_FLOATING_BUS && timeout != 0);
+ }
+ else if(sdmmc_cmdtable[cmd].responsetype == R2)
+ {
+ ReadMediaManual();
+
+ response.r2._byte1 = ReadMediaManual();
+ response.r2._byte0 = ReadMediaManual();
+ }
+
+ if(sdmmc_cmdtable[cmd].responsetype == R1b)
+ {
+ response.r1._byte = 0x00;
+
+ for(index =0; index < 0xFF && response.r1._byte == 0x00; index++)
+ {
+ timeout = 0xFFFF;
+
+ do
+ {
+ response.r1._byte = ReadMediaManual();
+ timeout--;
+ }while(response.r1._byte == 0x00 && timeout != 0);
+ }
+ }
+
+ WriteSPIManual(0xFF); //Required clocking (see spec)
+
+ // see if we are expecting data or not
+ if(!(sdmmc_cmdtable[cmd].moredataexpected))
+ SD_CS = 1;
+
+ return(response);
+}
+#endif
+#endif
+
+
+
+/*****************************************************************************
+ Function:
+ BYTE MDD_SDSPI_SectorRead (DWORD sector_addr, BYTE * buffer)
+ Summary:
+ Reads a sector of data from an SD card.
+ Conditions:
+ The MDD_SectorRead function pointer must be pointing towards this function.
+ Input:
+ sector_addr - The address of the sector on the card.
+ byffer - The buffer where the retrieved data will be stored. If
+ buffer is NULL, do not store the data anywhere.
+ Return Values:
+ TRUE - The sector was read successfully
+ FALSE - The sector could not be read
+ Side Effects:
+ None
+ Description:
+ The MDD_SDSPI_SectorRead function reads 512 bytes of data from the SD card
+ starting at the sector address and stores them in the location pointed to
+ by 'buffer.'
+ Remarks:
+ The card expects the address field in the command packet to be a byte address.
+ The sector_addr value is converted to a byte address by shifting it left nine
+ times (multiplying by 512).
+ ***************************************************************************************/
+
+BYTE MDD_SDSPI_SectorRead(DWORD sector_addr, BYTE* buffer)
+{
+ WORD index;
+ WORD delay;
+ MMC_RESPONSE response;
+ BYTE data_token;
+ BYTE status = TRUE;
+ DWORD new_addr;
+
+#ifdef USB_USE_MSD
+ DWORD firstSector;
+ DWORD numSectors;
+#endif
+
+ // send the cmd
+ new_addr = sector_addr << 9;
+ response = SendMMCCmd(READ_SINGLE_BLOCK,new_addr);
+
+ // Make sure the command was accepted
+ if(response.r1._byte != 0x00)
+ {
+ response = SendMMCCmd (READ_SINGLE_BLOCK,new_addr);
+ if(response.r1._byte != 0x00)
+ {
+ return FALSE;
+ }
+ }
+
+ index = 0x2FF;
+
+ // Timing delay- at least 8 clock cycles
+ delay = 0x40;
+ while (delay)
+ delay--;
+
+ //Now, must wait for the start token of data block
+ do
+ {
+ data_token = MDD_SDSPI_ReadMedia();
+ index--;
+
+ delay = 0x40;
+ while (delay)
+ delay--;
+
+ }while((data_token == MMC_FLOATING_BUS) && (index != 0));
+
+ // Hopefully that zero is the datatoken
+ if((index == 0) || (data_token != DATA_START_TOKEN))
+ {
+ status = FALSE;
+ }
+ else
+ {
+#ifdef USB_USE_MSD
+ if ((sector_addr == 0) && (buffer == NULL))
+ MDD_SDSPI_finalLBA = 0x00000000;
+#endif
+
+ for(index = 0; index < MEDIA_SECTOR_SIZE; index++) //Reads in 512-byte of data
+ {
+ if(buffer != NULL)
+ {
+#ifdef __18CXX
+ data_token = SPIBUF;
+ SPI_INTERRUPT_FLAG = 0;
+ SPIBUF = 0xFF;
+ while(!SPI_INTERRUPT_FLAG);
+ buffer[index] = SPIBUF;
+#else
+ SPIBUF = 0xFF;
+ while (!SPISTAT_RBF);
+ buffer[index] = SPIBUF;
+#endif
+ }
+ else
+ {
+#ifdef USB_USE_MSD
+ if (sector_addr == 0)
+ {
+ if ((index == 0x1C6) || (index == 0x1D6) || (index == 0x1E6) || (index == 0x1F6))
+ {
+ firstSector = MDD_SDSPI_ReadMedia();
+ firstSector |= (DWORD)MDD_SDSPI_ReadMedia() << 8;
+ firstSector |= (DWORD)MDD_SDSPI_ReadMedia() << 16;
+ firstSector |= (DWORD)MDD_SDSPI_ReadMedia() << 24;
+ numSectors = MDD_SDSPI_ReadMedia();
+ numSectors |= (DWORD)MDD_SDSPI_ReadMedia() << 8;
+ numSectors |= (DWORD)MDD_SDSPI_ReadMedia() << 16;
+ numSectors |= (DWORD)MDD_SDSPI_ReadMedia() << 24;
+ index += 8;
+ if ((firstSector + numSectors) > MDD_SDSPI_finalLBA)
+ {
+ MDD_SDSPI_finalLBA = firstSector + numSectors - 1;
+ }
+ }
+ else
+ {
+ MDD_SDSPI_ReadMedia();
+ }
+ }
+ else
+ MDD_SDSPI_ReadMedia();
+#else
+ MDD_SDSPI_ReadMedia();
+#endif
+ }
+ }
+ // Now ensure CRC
+ mReadCRC(); //Read 2 bytes of CRC
+ //status = mmcCardCRCError;
+ }
+
+ mSend8ClkCycles(); //Required clocking (see spec)
+
+ SD_CS = 1;
+
+ return(status);
+}//end SectorRead
+
+
+/*****************************************************************************
+ Function:
+ BYTE MDD_SDSPI_SectorWrite (DWORD sector_addr, BYTE * buffer, BYTE allowWriteToZero)
+ Summary:
+ Writes a sector of data to an SD card.
+ Conditions:
+ The MDD_SectorWrite function pointer must be pointing to this function.
+ Input:
+ sector_addr - The address of the sector on the card.
+ buffer - The buffer with the data to write.
+ allowWriteToZero -
+ - TRUE - Writes to the 0 sector (MBR) are allowed
+ - FALSE - Any write to the 0 sector will fail.
+ Return Values:
+ TRUE - The sector was written successfully.
+ FALSE - The sector could not be written.
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_SectorWrite function writes 512 bytes of data from the location
+ pointed to by 'buffer' to the specified sector of the SD card.
+ Remarks:
+ The card expects the address field in the command packet to be a byte address.
+ The sector_addr value is ocnverted to a byte address by shifting it left nine
+ times (multiplying by 512).
+ ***************************************************************************************/
+
+BYTE MDD_SDSPI_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero)
+{
+ WORD index;
+ BYTE data_response;
+#ifdef __18CXX
+ BYTE clear;
+#endif
+ MMC_RESPONSE response;
+ BYTE status = TRUE;
+
+ if (sector_addr == 0 && allowWriteToZero == FALSE)
+ status = FALSE;
+ else
+ {
+ // send the cmd
+ response = SendMMCCmd(WRITE_SINGLE_BLOCK,(sector_addr << 9));
+
+ // see if it was accepted
+ if(response.r1._byte != 0x00)
+ status = FALSE;
+ else
+ {
+ WriteSPIM(DATA_START_TOKEN); //Send data start token
+
+ for(index = 0; index < MEDIA_SECTOR_SIZE; index++) //Send 512 bytes of data
+ {
+#ifdef __18CXX
+ clear = SPIBUF;
+ SPI_INTERRUPT_FLAG = 0;
+ SPIBUF = buffer[index]; // write byte to SSP1BUF register
+ while( !SPI_INTERRUPT_FLAG ); // wait until bus cycle complete
+ data_response = SPIBUF; // Clear the SPIBUF
+#else
+ SPIBUF = buffer[index];
+ while (!SPISTAT_RBF);
+ data_response = SPIBUF;
+#endif
+ }
+
+ // calc crc
+ mSendCRC(); //Send 2 bytes of CRC
+
+ data_response = MDD_SDSPI_ReadMedia(); //Read response
+
+ if((data_response & 0x0F) != DATA_ACCEPTED)
+ {
+ status = FALSE;
+ }
+ else
+ {
+ index = 0; //using i as a timeout counter
+
+ do //Wait for write completion
+ {
+#ifdef __18CXX
+ clear = SPIBUF;
+ SPI_INTERRUPT_FLAG = 0;
+ SPIBUF = 0xFF;
+ while(!SPI_INTERRUPT_FLAG);
+ data_response = SPIBUF;
+#else
+ SPIBUF = 0xFF;
+ while(!SPISTAT_RBF);
+ data_response = SPIBUF;
+#endif
+ index++;
+ }while((data_response == 0x00) && (index != 0));
+
+ if(index == 0) //if timeout first
+ status = FALSE;
+ }
+
+ mSend8ClkCycles();
+ }
+
+ SD_CS = 1;
+
+ } // Not writing to 0 sector
+
+ return(status);
+} //end SectorWrite
+
+
+/*****************************************************************************
+ Function:
+ BYTE MDD_SDSPI_WriteProtectState
+ Summary:
+ Indicates whether the card is write-protected.
+ Conditions:
+ The MDD_WriteProtectState function pointer must be pointing to this function.
+ Input:
+ None.
+ Return Values:
+ TRUE - The card is write-protected
+ FALSE - The card is not write-protected
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_WriteProtectState function will determine if the SD card is
+ write protected by checking the electrical signal that corresponds to the
+ physical write-protect switch.
+ Remarks:
+ None
+ ***************************************************************************************/
+
+BYTE MDD_SDSPI_WriteProtectState(void)
+{
+ return(SD_WE);
+}
+
+
+/*****************************************************************************
+ Function:
+ void Delayms (BYTE milliseconds)
+ Summary:
+ Delay.
+ Conditions:
+ None.
+ Input:
+ BYTE milliseconds - Number of ms to delay
+ Return:
+ None.
+ Side Effects:
+ None.
+ Description:
+ The Delayms function will delay a specified number of milliseconds. Used for SPI
+ timing.
+ Remarks:
+ Depending on compiler revisions, this function may delay for the exact time
+ specified. This shouldn't create a significant problem.
+ ***************************************************************************************/
+
+void Delayms(BYTE milliseconds)
+{
+ BYTE ms;
+ DWORD count;
+
+ ms = milliseconds;
+ while (ms--)
+ {
+ count = MILLISECDELAY;
+ while (count--);
+ }
+ Nop();
+ return;
+}
+
+
+/*****************************************************************************
+ Function:
+ void CloseSPIM (void)
+ Summary:
+ Disables the SPI module.
+ Conditions:
+ None.
+ Input:
+ None.
+ Return:
+ None.
+ Side Effects:
+ None.
+ Description:
+ Disables the SPI module.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+void CloseSPIM (void)
+{
+#if defined __C30__ || defined __C32__
+
+ SPISTAT &= 0x7FFF;
+
+#elif defined __18CXX
+
+ SPICON1 &= 0xDF;
+
+#endif
+}
+
+
+
+/*****************************************************************************
+ Function:
+ unsigned char WriteSPIM (unsigned char data_out)
+ Summary:
+ Writes data to the SD card.
+ Conditions:
+ None.
+ Input:
+ data_out - The data to write.
+ Return:
+ 0.
+ Side Effects:
+ None.
+ Description:
+ The WriteSPIM function will write a byte of data from the microcontroller to the
+ SD card.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+unsigned char WriteSPIM( unsigned char data_out )
+{
+#ifdef __PIC32MX__
+ BYTE clear;
+ putcSPI((BYTE)data_out);
+ clear = getcSPI();
+ return ( 0 ); // return non-negative#
+#elif defined __18CXX
+ BYTE clear;
+ clear = SPIBUF;
+ SPI_INTERRUPT_FLAG = 0;
+ SPIBUF = data_out;
+ if (SPICON1 & 0x80)
+ return -1;
+ else
+ while (!SPI_INTERRUPT_FLAG);
+ return 0;
+#else
+ BYTE clear;
+ SPIBUF = data_out; // write byte to SSP1BUF register
+ while( !SPISTAT_RBF ); // wait until bus cycle complete
+ clear = SPIBUF;
+ return ( 0 ); // return non-negative#
+#endif
+}
+
+
+
+/*****************************************************************************
+ Function:
+ BYTE MDD_SDSPI_ReadMedia (void)
+ Summary:
+ Reads a byte of data from the SD card.
+ Conditions:
+ None.
+ Input:
+ None.
+ Return:
+ The byte read.
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_ReadMedia function will read one byte from the SPI port.
+ Remarks:
+ This function replaces ReadSPI, since some implementations of that function
+ will initialize SSPBUF/SPIBUF to 0x00 when reading. The card expects 0xFF.
+ ***************************************************************************************/
+BYTE MDD_SDSPI_ReadMedia(void)
+{
+
+#ifdef __C32__
+
+ putcSPI((BYTE)0xFF);
+ return (BYTE)getcSPI();
+
+#elif defined __18CXX
+
+ BYTE clear;
+ clear = SPIBUF;
+ SPI_INTERRUPT_FLAG = 0;
+ SPIBUF = 0xFF;
+ while (!SPI_INTERRUPT_FLAG);
+ return SPIBUF;
+
+#else
+ SPIBUF = 0xFF; //Data Out - Logic ones
+ while(!SPISTAT_RBF); //Wait until cycle complete
+ return(SPIBUF); //Return with byte read
+#endif
+}
+
+/*****************************************************************************
+ Function:
+ void OpenSPIM (unsigned int sync_mode)
+ Summary:
+ Initializes the SPI module
+ Conditions:
+ None.
+ Input:
+ sync_mode - Sets synchronization
+ Return:
+ None.
+ Side Effects:
+ None.
+ Description:
+ The OpenSPIM function will enable and configure the SPI module.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+#ifdef __18CXX
+void OpenSPIM (unsigned char sync_mode)
+#else
+void OpenSPIM( unsigned int sync_mode)
+#endif
+{
+ SPISTAT = 0x0000; // power on state
+
+#ifndef __PIC32MX__
+ SPICON1 = 0x0000; // power on state
+ SPICON1 |= sync_mode; // select serial mode
+#endif
+
+#ifdef __18CXX
+ SPICON1 |= 0x80;
+ SPISTATbits.CKE = 1;
+#else
+ SPICON1bits.CKP = 1;
+ SPICON1bits.CKE = 0;
+#endif
+
+ SPICLOCK = 0;
+ SPIOUT = 0; // define SDO1 as output (master or slave)
+ SPIIN = 1; // define SDI1 as input (master or slave)
+ SPIENABLE = 1; // enable synchronous serial port
+}
+
+
+
+
+
+#ifdef __18CXX
+#if (GetSystemClock() >= 25600000)
+
+// Description: Delay value for the manual SPI clock
+#define MANUAL_SPI_CLOCK_VALUE 1
+
+/*****************************************************************************
+ Function:
+ unsigned char WriteSPIManual (unsigned char data_out)
+ Summary:
+ Write a character to the SD card with bit-bang SPI.
+ Conditions:
+ None.
+ Input:
+ data_out - Data to send.
+ Return:
+ 0.
+ Side Effects:
+ None.
+ Description:
+ Writes a character to the SD card.
+ Remarks:
+ The WriteSPIManual function is for use on a PIC18 when the clock speed is so
+ high that the maximum SPI clock divider cannot reduce the SPI clock speed below
+ the maximum SD card initialization speed.
+ ***************************************************************************************/
+unsigned char WriteSPIManual(unsigned char data_out)
+{
+ char i = data_out;
+ unsigned char clock;
+
+ ADCON1 = 0xFF;
+ SPICLOCKLAT = 0;
+ SPIOUTLAT = 1;
+ SPICLOCK = OUTPUT;
+ SPIOUT = OUTPUT;
+
+ if ((SPIOUTPORT != SPIOUTLAT) || (SPICLOCKPORT != SPICLOCKLAT))
+ return (-1);
+
+ // Perform loop operation iteratively to reduce discrepancy
+ // Bit 7
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x80)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 6
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x40)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 5
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x20)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 4
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x10)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 3
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x08)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 2
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x04)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 1
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x02)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 0
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x01)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ SPICLOCKLAT = 0;
+
+ return 0;
+}
+
+
+/*****************************************************************************
+ Function:
+ BYTE ReadMediaManual (void)
+ Summary:
+ Reads a byte of data from the SD card.
+ Conditions:
+ None.
+ Input:
+ None.
+ Return:
+ The byte read.
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_ReadMedia function will read one byte from the SPI port.
+ Remarks:
+ This function replaces ReadSPI, since some implementations of that function
+ will initialize SSPBUF/SPIBUF to 0x00 when reading. The card expects 0xFF.
+ This function is for use on a PIC18 when the clock speed is so high that the
+ maximum SPI clock prescaler cannot reduce the SPI clock below the maximum SD card
+ initialization speed.
+ ***************************************************************************************/
+BYTE ReadMediaManual (void)
+{
+ char i, result = 0x00;
+ unsigned char clock;
+
+ SPICLOCKLAT = 0;
+ SPIOUTLAT = 1;
+ SPICLOCK = OUTPUT;
+ SPIOUT = OUTPUT;
+ SPIIN = INPUT;
+
+ if ((SPIOUTPORT != SPIOUTLAT) || (SPICLOCKPORT != SPICLOCKLAT))
+ return (-1);
+
+ // Perform loop operation iteratively to reduce discrepancy
+ // Bit 7
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x80;
+
+ // Bit 6
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x40;
+
+ // Bit 5
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x20;
+
+ // Bit 4
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x10;
+
+ // Bit 3
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x08;
+
+ // Bit 2
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x04;
+
+ // Bit 1
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x02;
+
+ // Bit 0
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x01;
+
+ SPICLOCKLAT = 0;
+
+ return result;
+}//end ReadMedia
+
+#endif // End >25600000
+#endif // End __18CXX
+
+
+/*****************************************************************************
+ Function:
+ BYTE MDD_SDSPI_MediaInitialize (void)
+ Summary:
+ Initializes the SD card.
+ Conditions:
+ The MDD_MediaInitialize function pointer must be pointing to this function.
+ Input:
+ None.
+ Return Values:
+ TRUE - The card was successfully initialized
+ FALSE - Communication could not be established.
+ Side Effects:
+ None.
+ Description:
+ This function will send initialization commands to and SD card.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+BYTE MDD_SDSPI_MediaInitialize(void)
+{
+ WORD timeout;
+ BYTE status = TRUE;
+ MMC_RESPONSE response;
+#if defined __C30__ || defined __C32__
+ WORD spiconvalue = 0x0003;
+#endif
+
+ SD_CS = 1; //Initialize Chip Select line
+
+ //Media powers up in the open-drain mode and cannot handle a clock faster
+ //than 400kHz. Initialize SPI port to slower than 400kHz
+#if defined __C30__ || defined __C32__
+#ifdef __PIC32MX__
+ OpenSPI(SPI_START_CFG_1, SPI_START_CFG_2);
+ SPIBRG = SPICalutateBRG(GetPeripheralClock(), 400000);
+#else
+ // Calculate the prescaler needed for the clock
+ timeout = GetSystemClock() / 400000;
+ // if timeout is less than 400k and greater than 100k use a 1:1 prescaler
+ if (timeout == 0)
+ {
+ OpenSPIM (MASTER_ENABLE_ON | PRI_PRESCAL_1_1 | SEC_PRESCAL_1_1);
+ }
+ else
+ {
+ while (timeout != 0)
+ {
+ if (timeout > 8)
+ {
+ spiconvalue--;
+ // round up
+ if ((timeout % 4) != 0)
+ timeout += 4;
+ timeout /= 4;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ timeout--;
+
+ OpenSPIM (MASTER_ENABLE_ON | spiconvalue | ((~(timeout << 2)) & 0x1C));
+ }
+#endif
+
+
+ // let the card power on and initialize
+ Delayms(1);
+
+ //Media requires 80 clock cycles to startup [8 clocks/BYTE * 10 us]
+ for(timeout=0; timeout<10; timeout++)
+ mSend8ClkCycles();
+
+ SD_CS = 0;
+
+ Delayms(1);
+
+ // Send CMD0 to reset the media
+ response = SendMMCCmd(GO_IDLE_STATE,0x0);
+
+ if((response.r1._byte == MMC_BAD_RESPONSE) || ((response.r1._byte & 0xF7) != 0x01))
+ {
+ status = FALSE; // we have not got anything back from the card
+ SD_CS = 1; // deselect the devices
+
+ return status;
+ }
+
+ // According to spec cmd1 must be repeated until the card is fully initialized
+ timeout = 0xFFF;
+
+ do
+ {
+ response = SendMMCCmd(SEND_OP_COND,0x0);
+ timeout--;
+ }while(response.r1._byte != 0x00 && timeout != 0);
+
+ // see if it failed
+ if(timeout == 0)
+ {
+ status = FALSE; // we have not got anything back from the card
+
+ SD_CS = 1; // deselect the devices
+ }
+ else
+ {
+
+#else
+
+ // let the card power on and initialize
+ Delayms(1);
+
+ #if (GetSystemClock() < 25600000)
+
+ #if (GetSystemClock() < 1600000)
+ OpenSPIM (SYNC_MODE_FAST, BUS_MODE, SMP_PHASE);
+ #elif (GetSystemClock() < 6400000)
+ OpenSPIM (SYNC_MODE_MED, BUS_MODE, SMP_PHASE);
+ #else
+ OpenSPIM (SYNC_MODE_SLOW, BUS_MODE, SMP_PHASE);
+ #endif
+
+ // let the card power on and initialize
+ Delayms(1);
+
+ //Media requires 80 clock cycles to startup [8 clocks/BYTE * 10 us]
+ for(timeout=0; timeout<10; timeout++)
+ mSend8ClkCycles();
+
+ SD_CS = 0;
+
+ Delayms(1);
+
+ // Send CMD0 to reset the media
+ response = SendMMCCmd(GO_IDLE_STATE,0x0);
+
+ if((response.r1._byte == MMC_BAD_RESPONSE) || ((response.r1._byte & 0xF7) != 0x01))
+ {
+ status = FALSE; // we have not got anything back from the card
+ SD_CS = 1; // deselect the devices
+
+ return status;
+ }
+
+ // According to spec cmd1 must be repeated until the card is fully initialized
+ timeout = 0xFFF;
+
+ do
+ {
+ response = SendMMCCmd(SEND_OP_COND,0x0);
+ timeout--;
+ }while(response.r1._byte != 0x00 && timeout != 0);
+
+ #else
+
+ // Make sure the SPI module doesn't control the bus
+ SPICON1 = 0x00;
+
+ //Media requires 80 clock cycles to startup [8 clocks/BYTE * 10 us]
+ for(timeout=0; timeout<10; timeout++)
+ WriteSPIManual(0xFF);
+
+ SD_CS = 0;
+
+ Delayms(1);
+
+ // Send CMD0 to reset the media
+ response = SendMMCCmdManual (GO_IDLE_STATE, 0x0);
+
+ if ((response.r1._byte == MMC_BAD_RESPONSE) || ((response.r1._byte & 0xF7) != 0x01))
+ {
+ status = FALSE; // we have not got anything back from the card
+ SD_CS = 1; // deselect the devices
+
+ return status;
+ }
+
+ // According to the spec cmd1 must be repeated until the card is fully initialized
+ timeout = 0xFFF;
+
+ do
+ {
+ response = SendMMCCmdManual (SEND_OP_COND, 0x0);
+ timeout--;
+ }while(response.r1._byte != 0x00 && timeout != 0);
+ #endif
+
+ // see if it failed
+ if (timeout == 0)
+ {
+ status = FALSE; // we have not got anything back from the card
+ SD_CS = 1; // deselect the devices
+ }
+ else
+ {
+#endif
+
+ Delayms (2);
+
+ #ifdef __PIC32MX__
+ #if (GetSystemClock() <= 20000000)
+ SPIBRG = SPICalutateBRG(GetPeripheralClock(), 10000);
+ #else
+ SPIBRG = SPICalutateBRG(GetPeripheralClock(), SPI_FREQUENCY);
+ #endif
+ #else
+ OpenSPIM(SYNC_MODE_FAST);
+ #endif
+
+ // Turn off CRC7 if we can, might be an invalid cmd on some cards (CMD59)
+ response = SendMMCCmd(CRC_ON_OFF,0x0);
+
+ // Now set the block length to media sector size. It should be already
+ response = SendMMCCmd(SET_BLOCKLEN,MEDIA_SECTOR_SIZE);
+
+ for(timeout = 0xFF; timeout > 0 && MDD_SDSPI_SectorRead(0x0,NULL) != TRUE; timeout--)
+ {;}
+
+ // see if we had an issue
+ if(timeout == 0)
+ {
+ status = FALSE;
+ SD_CS = 1; // deselect the devices
+ }
+ }
+
+ return(status);
+}//end MediaInitialize
+
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/SD-SPI.d b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/SD-SPI.d new file mode 100644 index 00000000..b22968c6 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/SD-SPI.d @@ -0,0 +1,58 @@ +SD-SPI.o: SD-SPI.c FSIO.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h FSconfig.h \
+ C:/Microchip\ Solutions/Microchip/Include/Compiler.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/string.h \
+ HardwareProfile.h FSDefs.h SD-SPI.h FSConfig.h
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/SD-SPI.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/SD-SPI.h new file mode 100644 index 00000000..0b4c7c4b --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/SD-SPI.h @@ -0,0 +1,443 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: SD-SPI.h
+ * Dependencies: GenericTypeDefs.h
+ * FSconfig.h
+ * FSDefs.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#ifndef SDMMC_H
+#define SDMMC_H
+
+#include "GenericTypeDefs.h"
+#include "FSconfig.h"
+#include "FSDefs.h"
+
+
+#ifdef __18CXX
+ // Description: This macro is used to initialize a PIC18 SPI module with a 4x prescale divider
+ #define SYNC_MODE_FAST 0x00
+ // Description: This macro is used to initialize a PIC18 SPI module with a 16x prescale divider
+ #define SYNC_MODE_MED 0x01
+ // Description: This macro is used to initialize a PIC18 SPI module with a 64x prescale divider
+ #define SYNC_MODE_SLOW 0x02
+#elif defined __PIC32MX__
+ // Description: This macro is used to initialize a PIC32 SPI module
+ #define SYNC_MODE_FAST 0x3E
+ // Description: This macro is used to initialize a PIC32 SPI module
+ #define SYNC_MODE_SLOW 0x3C
+#else
+ // Description: This macro indicates the SPI enable bit for 16-bit PICs
+ #ifndef MASTER_ENABLE_ON
+ #define MASTER_ENABLE_ON 0x0020
+ #endif
+
+ // Description: This macro is used to initialize a 16-bit PIC SPI module
+ #ifndef SYNC_MODE_FAST
+ #define SYNC_MODE_FAST 0x3E
+ #endif
+ // Description: This macro is used to initialize a 16-bit PIC SPI module
+ #ifndef SYNC_MODE_SLOW
+ #define SYNC_MODE_SLOW 0x3C
+ #endif
+
+ // Description: This macro is used to initialize a 16-bit PIC SPI module secondary prescaler
+ #ifndef SEC_PRESCAL_1_1
+ #define SEC_PRESCAL_1_1 0x001c
+ #endif
+ // Description: This macro is used to initialize a 16-bit PIC SPI module primary prescaler
+ #ifndef PRI_PRESCAL_1_1
+ #define PRI_PRESCAL_1_1 0x0003
+ #endif
+#endif
+
+
+
+/*****************************************************************/
+/* Strcutures and defines */
+/*****************************************************************/
+
+
+// Description: This macro represents an SD card start token
+#define DATA_START_TOKEN 0xFE
+
+// Description: This macro represents an SD card data accepted token
+#define DATA_ACCEPTED 0x05
+
+// Description: This macro indicates that the SD card expects to transmit or receive more data
+#define MOREDATA !0
+
+// Description: This macro indicates that the SD card does not expect to transmit or receive more data
+#define NODATA 0
+
+// Description: This macro represents a floating SPI bus condition
+#define MMC_FLOATING_BUS 0xFF
+
+// Description: This macro represents a bad SD card response byte
+#define MMC_BAD_RESPONSE MMC_FLOATING_BUS
+
+// The SDMMC Commands
+
+// Description: This macro defines the command code to reset the SD card
+#define cmdGO_IDLE_STATE 0
+// Description: This macro defines the command code to initialize the SD card
+#define cmdSEND_OP_COND 1
+// Description: This macro defines the command code to get the Card Specific Data
+#define cmdSEND_CSD 9
+// Description: This macro defines the command code to get the Card Information
+#define cmdSEND_CID 10
+// Description: This macro defines the command code to stop transmission during a multi-block read
+#define cmdSTOP_TRANSMISSION 12
+// Description: This macro defines the command code to get the card status information
+#define cmdSEND_STATUS 13
+// Description: This macro defines the command code to set the block length of the card
+#define cmdSET_BLOCKLEN 16
+// Description: This macro defines the command code to read one block from the card
+#define cmdREAD_SINGLE_BLOCK 17
+// Description: This macro defines the command code to read multiple blocks from the card
+#define cmdREAD_MULTI_BLOCK 18
+// Description: This macro defines the command code to write one block to the card
+#define cmdWRITE_SINGLE_BLOCK 24
+// Description: This macro defines the command code to write multiple blocks to the card
+#define cmdWRITE_MULTI_BLOCK 25
+// Description: This macro defines the command code to set the address of the start of an erase operation
+#define cmdTAG_SECTOR_START 32
+// Description: This macro defines the command code to set the address of the end of an erase operation
+#define cmdTAG_SECTOR_END 33
+// Description: This macro defines the command code to erase all previously selected blocks
+#define cmdERASE 38
+// Description: This macro defines the command code to begin application specific command inputs
+#define cmdAPP_CMD 55
+// Description: This macro defines the command code to get the OCR register information from the card
+#define cmdREAD_OCR 58
+// Description: This macro defines the command code to disable CRC checking
+#define cmdCRC_ON_OFF 59
+
+
+// Description: Enumeration of different SD response types
+typedef enum
+{
+ R1, // R1 type response
+ R1b, // R1b type response
+ R2, // R2 type response
+ R3 // R3 type response
+}RESP;
+
+// Summary: SD card command data structure
+// Description: The typMMC_CMD structure is used to create a command table of information needed for each relevant SD command
+typedef struct
+{
+ BYTE CmdCode; // The command code
+ BYTE CRC; // The CRC value for that command
+ RESP responsetype; // The response type
+ BYTE moredataexpected; // Set to MOREDATA or NODATA, depending on whether more data is expected or not
+} typMMC_CMD;
+
+
+// Summary: An SD command packet
+// Description: This union represents different ways to access an SD card command packet
+typedef union
+{
+ // This structure allows array-style access of command bytes
+ struct
+ {
+ #ifdef __18CXX
+ BYTE field[6]; // BYTE array
+ #else
+ BYTE field[7];
+ #endif
+ };
+ // This structure allows byte-wise access of packet command bytes
+ struct
+ {
+ BYTE crc; // The CRC byte
+ #if defined __C30__
+ BYTE c30filler; // Filler space (since bitwise declarations can't cross a WORD boundary)
+ #elif defined __C32__
+ BYTE c32filler[3]; // Filler space (since bitwise declarations can't cross a DWORD boundary)
+ #endif
+
+ BYTE addr0; // Address byte 0
+ BYTE addr1; // Address byte 1
+ BYTE addr2; // Address byte 2
+ BYTE addr3; // Address byte 3
+ BYTE cmd; // Command code byte
+ };
+ // This structure allows bitwise access to elements of the command bytes
+ struct
+ {
+ BYTE END_BIT:1; // Packet end bit
+ BYTE CRC7:7; // CRC value
+ DWORD address; // Address
+ BYTE CMD_INDEX:6; // Command code
+ BYTE TRANSMIT_BIT:1; // Transmit bit
+ BYTE START_BIT:1; // Packet start bit
+ };
+} CMD_PACKET;
+
+
+// Summary: The format of an R1 type response
+// Description: This union represents different ways to access an SD card R1 type response packet.
+typedef union
+{
+ BYTE _byte; // Byte-wise access
+ // This structure allows bitwise access of the response
+ struct
+ {
+ unsigned IN_IDLE_STATE:1; // Card is in idle state
+ unsigned ERASE_RESET:1; // Erase reset flag
+ unsigned ILLEGAL_CMD:1; // Illegal command flag
+ unsigned CRC_ERR:1; // CRC error flag
+ unsigned ERASE_SEQ_ERR:1; // Erase sequence error flag
+ unsigned ADDRESS_ERR:1; // Address error flag
+ unsigned PARAM_ERR:1; // Parameter flag
+ unsigned B7:1; // Unused bit 7
+ };
+} RESPONSE_1;
+
+// Summary: The format of an R2 type response
+// Description: This union represents different ways to access an SD card R2 type response packet
+typedef union
+{
+ WORD _word;
+ struct
+ {
+ BYTE _byte0;
+ BYTE _byte1;
+ };
+ struct
+ {
+ unsigned IN_IDLE_STATE:1;
+ unsigned ERASE_RESET:1;
+ unsigned ILLEGAL_CMD:1;
+ unsigned CRC_ERR:1;
+ unsigned ERASE_SEQ_ERR:1;
+ unsigned ADDRESS_ERR:1;
+ unsigned PARAM_ERR:1;
+ unsigned B7:1;
+ unsigned CARD_IS_LOCKED:1;
+ unsigned WP_ERASE_SKIP_LK_FAIL:1;
+ unsigned ERROR:1;
+ unsigned CC_ERROR:1;
+ unsigned CARD_ECC_FAIL:1;
+ unsigned WP_VIOLATION:1;
+ unsigned ERASE_PARAM:1;
+ unsigned OUTRANGE_CSD_OVERWRITE:1;
+ };
+} RESPONSE_2;
+
+// Summary: A union of responses from an SD card
+// Description: The MMC_RESPONSE union represents any of the possible responses that an SD card can return after
+// being issued a command.
+typedef union
+{
+ RESPONSE_1 r1;
+ RESPONSE_2 r2;
+}MMC_RESPONSE;
+
+
+// Summary: A description of the card specific data register
+// Description: This union represents different ways to access information in a packet with SD card CSD informaiton. For more
+// information on the CSD register, consult an SD card user's manual.
+typedef union
+{
+ struct
+ {
+ DWORD _u320;
+ DWORD _u321;
+ DWORD _u322;
+ DWORD _u323;
+ };
+ struct
+ {
+ BYTE _byte[16];
+ };
+ struct
+ {
+ unsigned NOT_USED :1;
+ unsigned CRC :7;
+ unsigned ECC :2;
+ unsigned FILE_FORMAT :2;
+ unsigned TMP_WRITE_PROTECT :1;
+ unsigned PERM_WRITE_PROTECT :1;
+ unsigned COPY :1;
+ unsigned FILE_FORMAT_GRP :1;
+ unsigned RESERVED_1 :5;
+ unsigned WRITE_BL_PARTIAL :1;
+ unsigned WRITE_BL_LEN_L :2;
+ unsigned WRITE_BL_LEN_H :2;
+ unsigned R2W_FACTOR :3;
+ unsigned DEFAULT_ECC :2;
+ unsigned WP_GRP_ENABLE :1;
+ unsigned WP_GRP_SIZE :5;
+ unsigned ERASE_GRP_SIZE_L :3;
+ unsigned ERASE_GRP_SIZE_H :2;
+ unsigned SECTOR_SIZE :5;
+ unsigned C_SIZE_MULT_L :1;
+ unsigned C_SIZE_MULT_H :2;
+ unsigned VDD_W_CURR_MAX :3;
+ unsigned VDD_W_CUR_MIN :3;
+ unsigned VDD_R_CURR_MAX :3;
+ unsigned VDD_R_CURR_MIN :3;
+ unsigned C_SIZE_L :2;
+ unsigned C_SIZE_H :8;
+ unsigned C_SIZE_U :2;
+ unsigned RESERVED_2 :2;
+ unsigned DSR_IMP :1;
+ unsigned READ_BLK_MISALIGN :1;
+ unsigned WRITE_BLK_MISALIGN :1;
+ unsigned READ_BL_PARTIAL :1;
+ unsigned READ_BL_LEN :4;
+ unsigned CCC_L :4;
+ unsigned CCC_H :8;
+ unsigned TRAN_SPEED :8;
+ unsigned NSAC :8;
+ unsigned TAAC :8;
+ unsigned RESERVED_3 :2;
+ unsigned SPEC_VERS :4;
+ unsigned CSD_STRUCTURE :2;
+ };
+} CSD;
+
+
+// Summary: A description of the card information register
+// Description: This union represents different ways to access information in a packet with SD card CID register informaiton. For more
+// information on the CID register, consult an SD card user's manual.
+typedef union
+{
+ struct
+ {
+ DWORD _u320;
+ DWORD _u321;
+ DWORD _u322;
+ DWORD _u323;
+ };
+ struct
+ {
+ BYTE _byte[16];
+ };
+ struct
+ {
+ unsigned NOT_USED :1;
+ unsigned CRC :7;
+ unsigned MDT :8;
+ DWORD PSN;
+ unsigned PRV :8;
+ char PNM[6];
+ WORD OID;
+ unsigned MID :8;
+ };
+} CID;
+
+#ifndef FALSE
+ #define FALSE 0
+#endif
+#ifndef TRUE
+ #define TRUE !FALSE
+#endif
+
+#define INPUT 1
+#define OUTPUT 0
+
+
+// Description: A delay prescaler
+#define DELAY_PRESCALER (BYTE) 8
+
+// Description: An approximation of the number of cycles per delay loop of overhead
+#define DELAY_OVERHEAD (BYTE) 5
+
+// Description: An approximate calculation of how many times to loop to delay 1 ms in the Delayms function
+#define MILLISECDELAY (WORD) ((GetInstructionClock()/DELAY_PRESCALER/(WORD)1000) - DELAY_OVERHEAD)
+
+
+// Summary: An enumeration of SD commands
+// Description: This enumeration corresponds to the position of each command in the sdmmc_cmdtable array
+// These macros indicate to the SendMMCCmd function which element of the sdmmc_cmdtable array
+// to retrieve command code information from.
+typedef enum
+{
+ GO_IDLE_STATE,
+ SEND_OP_COND,
+ SEND_CSD,
+ SEND_CID,
+ STOP_TRANSMISSION,
+ SEND_STATUS,
+ SET_BLOCKLEN,
+ READ_SINGLE_BLOCK,
+ READ_MULTI_BLOCK,
+ WRITE_SINGLE_BLOCK,
+ WRITE_MULTI_BLOCK,
+ TAG_SECTOR_START,
+ TAG_SECTOR_END,
+ ERASE,
+ APP_CMD,
+ READ_OCR,
+ CRC_ON_OFF
+}sdmmc_cmd;
+
+
+
+/***************************************************************************/
+/* Macros */
+/***************************************************************************/
+
+// Description: A macro to send clock cycles to dummy-read the CRC
+#define mReadCRC() WriteSPIM(0xFF);WriteSPIM(0xFF);
+
+// Description: A macro to send clock cycles to dummy-write the CRC
+#define mSendCRC() WriteSPIM(0xFF);WriteSPIM(0xFF);
+
+// Description: A macro to send 8 clock cycles for SD timing requirements
+#define mSend8ClkCycles() WriteSPIM(0xFF);
+
+/*****************************************************************************/
+/* Prototypes */
+/*****************************************************************************/
+
+DWORD MDD_SDSPI_ReadCapacity(void);
+WORD MDD_SDSPI_ReadSectorSize(void);
+void MDD_SDSPI_InitIO(void);
+
+BYTE MDD_SDSPI_MediaDetect(void);
+BYTE MDD_SDSPI_MediaInitialize(void);
+BYTE MDD_SDSPI_SectorRead(DWORD sector_addr, BYTE* buffer);
+BYTE MDD_SDSPI_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero);
+
+BYTE MDD_SDSPI_WriteProtectState(void);
+BYTE MDD_SDSPI_ShutdownMedia(void);
+
+#if defined __C30__ || defined __C32__
+ extern BYTE ReadByte( BYTE* pBuffer, WORD index );
+ extern WORD ReadWord( BYTE* pBuffer, WORD index );
+ extern DWORD ReadDWord( BYTE* pBuffer, WORD index );
+#endif
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Screens.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Screens.h new file mode 100644 index 00000000..a5322eed --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Screens.h @@ -0,0 +1,183 @@ +/**********************************************************************
+ *************************** Screens.h ******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+/***********************************************************/
+// Variable Declaration
+/***********************************************************/
+
+//RapMan logo
+const unsigned char RAPMAN_LOGO[1024] = {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0xFF,0xFF,0x63,0x63,0xE3,0xE3,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC7,0xC7,0xC6,0xC6,0xFF,0xFF,0x06,0x06,0x06,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x40,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x71,0x71,0xF1,0xF1,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x00,0x00,0x00,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF0,0x00,0x00,0x04,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0x1C,0x1C,0x1C,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF0,0x00,0x00,0xFF,0xFF,0xFF,0x0F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,0xE0,0x00,0xE0,0xFC,0x3F,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF0,0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0x1C,0x1C,0x1C,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF0,0x00,0x00,
+0x00,0x00,0x00,0x40,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,0x00,0x07,0x3F,0x7F,0x7F,0x7F,0x7F,0x7C,0x70,0x40,0x00,0x3F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x71,0x71,0x71,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x70,0x70,0x70,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F,0x00,0x40,0x7F,0x7F,0x7F,0x00,0x00,0x03,0x1F,0x7F,0x7F,0x7F,0x7F,0x7F,0x0F,0x01,0x00,0x40,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,0x00,0x3F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x71,0x71,0x71,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,0x40,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,0x40,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+//Bits From Bytes logo with globe
+const unsigned char BfB_LOGO[1024] = {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x60,0x30,0x10,0x88,0xE4,0x54,0x6E,0x6E,0x26,0xF3,0x2F,0x27,0x23,0x23,0x27,0x2F,0xF3,0x26,0x6E,0x56,0x64,0xCC,0x98,0x30,0x20,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFC,0x47,0x26,0x32,0xF9,0x3F,0x10,0x08,0x08,0x08,0xF8,0x0F,0x09,0x08,0x08,0x08,0x08,0x08,0x08,0x09,0xFF,0x08,0x08,0x08,0x10,0x17,0x3D,0xF3,0x26,0x65,0x5F,0xFC,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x74,0xC8,0x88,0x10,0x7F,0xD0,0x30,0x20,0x60,0x60,0x7F,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x60,0x60,0x20,0x30,0x10,0xF0,0x1F,0x90,0xD8,0xE8,0x7C,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0D,0x3B,0x27,0x6E,0x5C,0xA8,0xC8,0x88,0x97,0x7C,0xD0,0x90,0x10,0x10,0x90,0xD0,0x3C,0x97,0xD8,0xE8,0xB8,0xCC,0x67,0x37,0x1B,0x0D,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x40,0x40,0x40,0xC0,0xC0,0x80,0x00,0xC0,0x00,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0xC0,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x80,0xC0,0xC0,0xC1,0xC1,0xC1,0x81,0x03,0x03,0xC3,0x83,0x03,0x01,0x01,0x01,0x00,0x00,0x80,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x40,0x40,0x40,0xC0,0xC0,0x80,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x80,0xC0,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0xC0,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x26,0x22,0x26,0x36,0x1F,0x0F,0x00,0x3F,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x33,0x33,0x34,0x34,0x34,0x3C,0x18,0x00,0x00,0x00,0x00,0x3F,0x3D,0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x3F,0x3F,0x06,0x0E,0x1E,0x1E,0x36,0x27,0x00,0x06,0x1F,0x30,0x30,0x30,0x30,0x30,0x1F,0x06,0x00,0x3F,0x03,0x0F,0x1C,0x38,0x38,0x1C,0x0F,0x03,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x26,0x22,0x26,0x36,0x1F,0x0F,0x00,0x00,0x00,0x01,0x03,0x3E,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x1F,0x1F,0x34,0x34,0x34,0x34,0x34,0x34,0x00,0x33,0x33,0x34,0x34,0x34,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0xE0,0xF0,0xF8,0x18,0x18,0xB0,0xA0,0x00,0xE0,0xF0,0xF8,0x18,0xF8,0xF0,0xE0,0x00,0xF8,0xF8,0xF8,0x10,0xF8,0xF8,0xF0,0x18,0xF8,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x00,0x00,0x01,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x01,0x00,0x00,0x03,0x03,0x03,0x00,0x03,0x03,0x03,0x00,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+//Extruder Screen
+const unsigned char EXTRUDER_SCREEN[1024] = {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xFC,0x03,0x00,0xC0,0xC0,0xC0,0xC0,0x00,0x03,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x05,0x02,0x00,0x3C,0x42,0x81,0x81,0x81,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x0E,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x04,0x04,0x00,0x00,0x32,0x4A,0x4A,0x7C,0x00,0x7E,0x04,0x02,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x63,0x1C,0x33,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0x08,0xF0,0x00,0x01,0x0E,0x30,0x40,0x88,0x04,0x04,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x30,0x0E,0x01,0xE0,0x10,0x90,0x20,0x00,0xE0,0x10,0x10,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,
+0x80,0xC0,0xFF,0xF0,0xF8,0xFF,0xFF,0xFF,0xFF,0xF8,0xF0,0xFF,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x04,0x04,0x04,0x04,0x04,0x02,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x07,0x09,0x08,0x07,0x00,0x07,0x08,0x08,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x05,0x02,0x00,0x3C,0x42,0x81,0x81,0x81,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x09,0x19,0x29,0x46,0x80,0xFF,0x11,0x11,0x11,0x0E,0x00,0xFF,0x06,0x78,0x80,0x78,0x06,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+//TextFont5x7
+//Font def for characters 5x7
+const unsigned char TEXT[51][5] ={0x00, 0x00, 0x00, 0x00, 0x00, // SPACE
+ 0x00, 0x00, 0x5F, 0x00, 0x00, // !
+ 0x00, 0x03, 0x00, 0x03, 0x00, // "
+ 0x14, 0x3E, 0x14, 0x3E, 0x14, // #
+ 0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
+ 0x43, 0x33, 0x08, 0x66, 0x61, // %
+ 0x36, 0x49, 0x55, 0x22, 0x50, // &
+ 0x00, 0x05, 0x03, 0x00, 0x00, // '
+ 0x00, 0x1C, 0x22, 0x41, 0x00, // (
+ 0x00, 0x41, 0x22, 0x1C, 0x00, // )
+ 0x14, 0x08, 0x3E, 0x08, 0x14, // *
+ 0x08, 0x08, 0x3E, 0x08, 0x08, // +
+ 0x00, 0x50, 0x30, 0x00, 0x00, // ,
+ 0x08, 0x08, 0x08, 0x08, 0x08, // -
+ 0x00, 0x60, 0x60, 0x00, 0x00, // .
+ 0x20, 0x10, 0x08, 0x04, 0x02, // /
+ 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
+ 0x04, 0x02, 0x7F, 0x00, 0x00, // 1
+ 0x42, 0x61, 0x51, 0x49, 0x46, // 2
+ 0x22, 0x41, 0x49, 0x49, 0x36, // 3
+ 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
+ 0x27, 0x45, 0x45, 0x45, 0x39, // 5
+ 0x3E, 0x49, 0x49, 0x49, 0x32, // 6
+ 0x01, 0x01, 0x71, 0x09, 0x07, // 7
+ 0x36, 0x49, 0x49, 0x49, 0x36, // 8
+ 0x26, 0x49, 0x49, 0x49, 0x3E, // 9
+ 0x00, 0x36, 0x36, 0x00, 0x00, // :
+ 0x00, 0x56, 0x36, 0x00, 0x00, // ;
+ 0x08, 0x14, 0x22, 0x41, 0x00, // <
+ 0x14, 0x14, 0x14, 0x14, 0x14, // =
+ 0x00, 0x41, 0x22, 0x14, 0x08, // >
+ 0x02, 0x01, 0x51, 0x09, 0x06, // ?
+ 0x3E, 0x41, 0x59, 0x55, 0x5E, // @
+ 0x7E, 0x09, 0x09, 0x09, 0x7E, // A
+ 0x7F, 0x49, 0x49, 0x49, 0x36, // B
+ 0x3E, 0x41, 0x41, 0x41, 0x22, // C
+ 0x7F, 0x41, 0x41, 0x41, 0x3E, // D
+ 0x7F, 0x49, 0x49, 0x49, 0x41, // E
+ 0x7F, 0x09, 0x09, 0x09, 0x01, // F
+ 0x3E, 0x41, 0x41, 0x49, 0x3A, // G
+ 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
+ 0x00, 0x41, 0x7F, 0x41, 0x00, // I
+ 0x30, 0x40, 0x40, 0x40, 0x3F, // J
+ 0x7F, 0x08, 0x14, 0x22, 0x41, // K
+ 0x7F, 0x40, 0x40, 0x40, 0x40, // L
+ 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
+ 0x7F, 0x02, 0x04, 0x08, 0x7F, // N
+ 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
+ 0x7F, 0x09, 0x09, 0x09, 0x06, // P
+ 0x1E, 0x21, 0x21, 0x21, 0x5E, // Q
+ 0x7F, 0x09, 0x09, 0x09, 0x76};// R
+
+const unsigned char TEXT2[44][5]={ 0x26, 0x49, 0x49, 0x49, 0x32, // S
+ 0x01, 0x01, 0x7F, 0x01, 0x01, // T
+ 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
+ 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
+ 0x7F, 0x20, 0x10, 0x20, 0x7F, // W
+ 0x41, 0x22, 0x1C, 0x22, 0x41, // X
+ 0x07, 0x08, 0x70, 0x08, 0x07, // Y
+ 0x61, 0x51, 0x49, 0x45, 0x43, // Z
+ 0x00, 0x7F, 0x41, 0x00, 0x00, // [
+ 0x02, 0x04, 0x08, 0x10, 0x20, // \
+ 0x00, 0x00, 0x41, 0x7F, 0x00, // ]
+ 0x04, 0x02, 0x01, 0x02, 0x04, // ^
+ 0x40, 0x40, 0x40, 0x40, 0x40, // _
+ 0x00, 0x01, 0x02, 0x04, 0x00, // `
+ 0x20, 0x54, 0x54, 0x54, 0x78, // a
+ 0x7F, 0x44, 0x44, 0x44, 0x38, // b
+ 0x38, 0x44, 0x44, 0x44, 0x44, // c
+ 0x38, 0x44, 0x44, 0x44, 0x7F, // d
+ 0x38, 0x54, 0x54, 0x54, 0x18, // e
+ 0x04, 0x04, 0x7E, 0x05, 0x05, // f
+ 0x08, 0x54, 0x54, 0x54, 0x3C, // g
+ 0x7F, 0x08, 0x04, 0x04, 0x78, // h
+ 0x00, 0x44, 0x7D, 0x40, 0x00, // i
+ 0x20, 0x40, 0x44, 0x3D, 0x00, // j
+ 0x7F, 0x10, 0x28, 0x44, 0x00, // k
+ 0x00, 0x41, 0x7F, 0x40, 0x00, // l
+ 0x7C, 0x04, 0x78, 0x04, 0x78, // m
+ 0x7C, 0x08, 0x04, 0x04, 0x78, // n
+ 0x38, 0x44, 0x44, 0x44, 0x38, // o
+ 0x7C, 0x14, 0x14, 0x14, 0x08, // p
+ 0x08, 0x14, 0x14, 0x14, 0x7C, // q
+ 0x00, 0x7C, 0x08, 0x04, 0x04, // r
+ 0x48, 0x54, 0x54, 0x54, 0x20, // s
+ 0x04, 0x04, 0x3F, 0x44, 0x44, // t
+ 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
+ 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
+ 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
+ 0x44, 0x28, 0x10, 0x28, 0x44, // x
+ 0x0C, 0x50, 0x50, 0x50, 0x3C, // y
+ 0x44, 0x64, 0x54, 0x4C, 0x44, // z
+ 0x00, 0x08, 0x36, 0x41, 0x41, // {
+ 0x00, 0x00, 0x7F, 0x00, 0x00, // |
+ 0x41, 0x41, 0x36, 0x08, 0x00, // }
+ 0x02, 0x01, 0x02, 0x04, 0x02 // ~
+ };
+
+
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Stepper.c b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Stepper.c new file mode 100644 index 00000000..7e1f5d74 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Stepper.c @@ -0,0 +1,1033 @@ +/**********************************************************************
+ *************************** Stepper.c ******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+#include <plib.h> //required for interrupt handlers
+#include <stdio.h>
+#include <stdlib.h>
+#include <p32xxxx.h>
+#include <math.h>
+#include <inttypes.h>
+#include "Stepper.h"
+#include "Enviroment.h" //to import button defs
+#include "Extruder.h"
+#include "OLED.h"
+
+#define X_LEFT 1
+#define X_RIGHT 0
+#define Z_DOWN 1
+#define Z_UP 0
+#define Y_FORWARD 1
+#define Y_BACK 0
+
+#define VERY_SLOW_MOVE 60000 //Sets the speed of the start speed in manual move mode
+#define HOME_SPEED_X_Y 1000
+#define HOME_SPEED_X_Y_SET 60000
+#define HOME_SPEED_Z 500
+#define HOME_SPEED_Z_SET 5000
+
+#define PRESSED 0
+#define NOT_PRESSED 1
+
+#define X_HOME_MM -135
+#define Y_HOME_MM 100
+#define Z_HOME_MM 0
+
+//Internal Functions
+int f_to_ul(float fNumber); //float to unsigned long
+signed int f_to_sl(float fNumber); //float to signed long
+void Bresenham_3D_Line(signed int x1, signed int y1, signed int z1,signed int x2, signed int y2, signed int z2);
+void AddToStepBuffer(unsigned char SData, char xs, char ys);
+void Stepper_SaveValues(void);
+
+//Module Globals
+
+int S_M_Code; //Stepper M code
+
+int xyrate = 0; //Used when x and y steps occur together
+int ZFeed_Rate = 0; //always do rapid z move
+
+float Delta_X; //Used to hold movement data
+float Delta_Y;
+float Delta_Z;
+
+float Save_X = 0; //Last used coordinate saved here.
+float Save_Y = 0;
+float Save_Z = 0;
+float Save2_X = 0; //2nd to Last used coordinate saved here.
+float Save2_Y = 0;
+float Save2_Z = 0;
+float Save3_X = 0; //3nd to Last used coordinate saved here.
+float Save3_Y = 0;
+float Save3_Z = 0;
+
+//Step value coordinates
+float X_Steps,Y_Steps,Z_Steps; //Float value of steps
+signed long lX_Steps,lY_Steps,lZ_Steps; //Long integer values of steps
+signed long lSaveSteps_X, lSaveSteps_Y, lSaveSteps_Z;
+signed long lHomeStepsX, lHomeStepsY, lHomeStepsZ; //Stores the machine home coordinates
+PRIVATE signed int OffsetSteps_X;//Stores the number of steps offset from absolute coordinate
+PRIVATE signed int OffsetSteps_Y;
+PRIVATE signed int OffsetSteps_Z;
+
+//Globals for the step circular buffer
+unsigned char SBuf; //Step buffer Flag
+int SBR, SBW; //Buffer pointers
+// circular buffer
+int SCB[ SB_SIZE]; //Step circular buffer
+// Buffer status
+volatile int SBReady;
+int SBCode; //Byte from buffer Only used in stepper Interrupt
+unsigned char BufferEmpty = 1; //Flags Buffer empty = 1
+
+int StepRPM_Setting = 30, PR4_Setting = 65535, StepperInt_Cycle = 0, ManualStepperInt_Cycle = 0;//, Direction = CCW;
+
+int Set_X_Dir, Set_Y_Dir, Set_Z_Dir;
+char moveX = 0, moveY = 0, moveZ = 0;
+int Manual_Mode_Set = !TRUE;
+int FirstPass = TRUE;
+
+//Functions
+/******************************************************************/
+void Manual_Mode(char ShowPos)
+{
+//ShowPos show position on OLED = 1 or not = 0
+unsigned char AsciiString[9];
+float Xmm=0,Ymm=0,Zmm=0;
+
+ while (SBR!=SBW); //wait for step buffer to empty
+ mT4IntEnable(!TRUE); //Disable T4 step buffer interrput
+ Feed_Rate = VERY_SLOW_MOVE; //Set speed to slow
+ moveX = !TRUE; //Turn off all steppers
+ moveY = !TRUE;
+ moveZ = !TRUE;
+ Axis_Stepper_Motors(On);
+ OLED_Manual_Screen();
+
+ while(!XPlusRight_Btn); //Wait for menu selection key to be released
+ while(Manual_Select == NOT_PRESSED){
+ Manual_Mode_Set = TRUE;
+
+ if(Feed_Rate>1000)Feed_Rate -=75; //Ramping of the move speed
+ if(Feed_Rate>100)Feed_Rate -=5; //the longer the button is
+ if(Feed_Rate<400) Feed_Rate = 400; //pressed
+
+ //Set direction & move
+ if (!XPlusRight_Btn) { Set_X_Dir = X_RIGHT; moveX =TRUE;}
+ if (!XMinusLeft_Btn) { Set_X_Dir = X_LEFT; moveX =TRUE;}
+ if (XPlusRight_Btn && XMinusLeft_Btn) moveX = !TRUE;
+ if (!YPlusTop_Btn) { Set_Y_Dir = Y_BACK; moveY =TRUE;}
+ if (!YMinusBot_Btn) { Set_Y_Dir = Y_FORWARD; moveY =TRUE;}
+ if (YPlusTop_Btn && YMinusBot_Btn) moveY = !TRUE;
+ if (!ZPlus_up_Btn) { Set_Z_Dir = Z_UP; moveZ =TRUE;}
+ if (!ZMinus_down_Btn){ Set_Z_Dir = Z_DOWN; moveZ =TRUE;}
+ if (ZPlus_up_Btn && ZMinus_down_Btn) moveZ = !TRUE;
+ if (!moveX && !moveY && !moveZ) Feed_Rate = VERY_SLOW_MOVE; //Re-set move speed
+
+ //Report current position to OLED.
+ if(ShowPos){
+ Xmm = (float)lSaveSteps_X / StepsPer_mm;
+ sprintf(AsciiString, "%6.2f",Xmm); // Converts number to text
+ OLED_FastText57(4, 64, AsciiString,0); // Write the new number
+ Ymm = (float)lSaveSteps_Y / StepsPer_mm;
+ sprintf(AsciiString, "%6.2f",Ymm); // Converts number to text
+ OLED_FastText57(5, 64, AsciiString,0); // Write the new number
+ Zmm = (float)lSaveSteps_Z / ZStepsPer_mm;
+ sprintf(AsciiString, "%6.2f",Zmm); // Converts number to text
+ OLED_FastText57(6, 64, AsciiString,0); // Write the new number
+ }
+ }
+ Manual_Mode_Set = !TRUE;
+ mT4IntEnable(!TRUE); //Disable T4 step buffer interrput
+}//ManualMode
+
+/******************************************************************/
+void Axis_Stepper_Motors(int on_off)
+{
+ if(on_off == On){
+ X_Disable = !TRUE; //to enable X axis
+ Y_Disable = !TRUE; //to enable Y axis
+ Z_Disable = !TRUE; //to enable Z axis
+ mT4IntEnable(TRUE); //Turn on interrupts
+ }
+ else{
+ X_Disable = TRUE; //to disable X axis
+ Y_Disable = TRUE; //to disable Y axis
+ Z_Disable = TRUE; //to disable Z axis
+ mT4IntEnable(!TRUE); //Turn off interrupts
+ }
+}
+/******************************************************************/
+int RapMan_Home(void)
+{
+int i;
+ OLED_Home_Screen();
+
+ moveX = !TRUE; //Turn off all steppers
+ moveY = !TRUE;
+ moveZ = !TRUE;
+ Stepper_InitIO();
+ Axis_Stepper_Motors(On);
+ Manual_Mode_Set = TRUE;
+
+ Feed_Rate = HOME_SPEED_Z; //Move tool down to prevent crash
+ OLED_FastText57(3, 0, "Z DOWN ",0);
+ Set_Z_Dir = Z_DOWN;
+ moveZ = TRUE;
+ for(i=0;i<200000;i++);
+ moveZ = !TRUE;
+
+ OLED_FastText57(3, 0, "Y FORWARD ",0);
+ Feed_Rate = HOME_SPEED_X_Y; //Move tool forward to prevent crash
+ Set_Y_Dir = Y_FORWARD;
+ moveY = TRUE;
+ for(i=0;i<60000;i++);
+ moveY = !TRUE;
+
+ OLED_FastText57(3, 0, "HOME X ",0); //Display operation
+ Feed_Rate = HOME_SPEED_X_Y; //Set homing speed
+ while(!X_HomeSwitch && Manual_Select){ //Keep homing until the switch is pressed
+ Set_X_Dir = X_LEFT; //Direction of home
+ while(!X_HomeSwitch && Manual_Select)moveX = TRUE;
+ moveX = !TRUE;
+ for(i=0;i<20000;i++); //Wait to allow de-bounce of switch/ noise
+ }
+ moveX=TRUE; //Move a little more to ensure full switch
+ for(i=0;i<10000;i++);
+ moveX = !TRUE;
+
+ Feed_Rate = HOME_SPEED_X_Y_SET; //At slow speed pull away from switch
+ while(X_HomeSwitch && Manual_Select){ //to get accurate switch point
+ Set_X_Dir = X_RIGHT;
+ while(X_HomeSwitch && Manual_Select)moveX = TRUE;
+ moveX = !TRUE;
+ for(i=0;i<2000;i++); //Wait to allow de-bounce of switch/ noise
+ lSaveSteps_X = X_HOME_MM * StepsPer_mm; //*************HOME X
+ lHomeStepsX = lSaveSteps_X;
+ }
+
+ OLED_FastText57(3, 0, "HOME Y ",0);
+ Feed_Rate = HOME_SPEED_X_Y;
+ while(!Y_HomeSwitch && Manual_Select){
+ Set_Y_Dir = Y_BACK;
+ while(!Y_HomeSwitch && Manual_Select)moveY = TRUE;
+ moveY = !TRUE;
+ for(i=0;i<20000;i++);
+ }
+ moveY=TRUE;
+ for(i=0;i<10000;i++);
+ moveY = !TRUE;
+
+ Feed_Rate = HOME_SPEED_X_Y_SET;
+ while(Y_HomeSwitch && Manual_Select){
+ Set_Y_Dir = Y_FORWARD;
+ while(Y_HomeSwitch && Manual_Select)moveY = TRUE;
+ moveY = !TRUE;
+ for(i=0;i<2000;i++);
+ lSaveSteps_Y = Y_HOME_MM * StepsPer_mm;//*************HOME Y
+ lHomeStepsY = lSaveSteps_Y;
+ }
+
+ OLED_FastText57(3, 0, "HOME Z ",0);
+ Feed_Rate = HOME_SPEED_Z;
+ while(!Z_HomeSwitch && Manual_Select){
+ Set_Z_Dir = Z_UP;
+ while(!Z_HomeSwitch && Manual_Select)moveZ = TRUE;
+ moveZ = !TRUE;
+ for(i=0;i<2000;i++);
+ }
+ moveZ=TRUE;
+ for(i=0;i<10000;i++);
+ moveZ = !TRUE;
+
+ Feed_Rate = HOME_SPEED_Z_SET;
+ while(Z_HomeSwitch && Manual_Select){
+ Set_Z_Dir = Z_DOWN;
+ while(Z_HomeSwitch && Manual_Select)moveZ = TRUE;
+ moveZ = !TRUE;
+ for(i=0;i<2000;i++);
+ lSaveSteps_Z = Z_HOME_MM;//*************HOME Z
+ lHomeStepsZ = lSaveSteps_Z;
+ }
+ Manual_Mode_Set = !TRUE;
+ mT4IntEnable(!TRUE);
+ if(!Manual_Select)
+ {
+ OLED_FastText57(3, 0, "HOME ABORTED",0);
+ for(i=0;i<2000000;i++);
+ return !TRUE;
+ }
+ else
+ {
+ OLED_FastText57(3, 0, "HOME COMPLETE",0);
+ for(i=0;i<2000000;i++);
+ return TRUE;
+ }
+}//Home
+
+//******************************************************************
+void GoToRest(void)
+{
+//Variables required for Run3DLine
+//Values set from last move: lSaveSteps_X,lSaveSteps_Y,lSaveSteps_Z
+//Values set here: lX_Steps,lY_Steps,lZ_Steps
+
+extern float X_Rest_mm,Y_Rest_mm,Z_Rest_mm;
+
+ GX_On=1; //Enable axis for move
+ GY_On=1;
+ GZ_On=0; //To stop any Z move
+ Feed_Rate = GO_TO_REST_RATE; //set speed
+
+ X_Steps = X_Rest_mm * StepsPer_mm;//Convert mm coordinate to steps
+ Y_Steps = Y_Rest_mm * StepsPer_mm;
+ //Z_Steps = Z_Rest_mm * ZStepsPer_mm;//Uncomment for Z move
+
+ lX_Steps= f_to_sl(X_Steps); //Convert to integer steps
+ lY_Steps= f_to_sl(Y_Steps); //float to signed long.
+ //lZ_Steps= f_to_sl(Z_Steps);//Uncomment for Z move
+
+ mT4IntEnable(TRUE);
+
+ Stepper_Run3DLine();//Run line and reset all values
+
+ GX_On=0;
+ GY_On=0;
+ //GZ_On=0;//Uncomment for Z move
+ Delayms(250);
+
+}//GoToRest
+
+//******************************************************************
+// STEPPER INTERRUPT
+//******************************************************************
+void __ISR( _TIMER_4_VECTOR, ipl2) T4Interrupt( void)
+{
+//XYZ-Axis step timer
+//SBCode is 32bit containing step and direction for xyz and speed data
+//SBCode Bits 7 XDir, 6 X, 5 YDir, 4 Y, 3 ZDir, 2 Z, 1 & 0 Not used
+int mask;
+unsigned char bit_pos = 0;
+unsigned char xs,ys;
+
+if(Manual_Mode_Set){
+ switch(ManualStepperInt_Cycle)
+ {
+ case 0: //set Direction
+ {
+ X_Dir = Set_X_Dir;
+ Y_Dir = Set_Y_Dir;
+ Z_Dir = Set_Z_Dir;
+ PR4 = 5;
+ ManualStepperInt_Cycle = 1;
+ break;
+ }
+
+ case 1:
+ {
+ if(moveX){
+ X_Step = 1;
+ if(!Set_X_Dir) lSaveSteps_X += 1;
+ else lSaveSteps_X -= 1;
+ }
+ else X_Step = 0;
+ if(moveY){
+ Y_Step = 1;
+ if(!Set_Y_Dir) lSaveSteps_Y += 1;
+ else lSaveSteps_Y -= 1;
+ }
+ else Y_Step = 0;
+ if(moveZ){
+ Z_Step = 1;
+ if(! Set_Z_Dir) lSaveSteps_Z += 1;
+ else lSaveSteps_Z -= 1;
+ }
+ else Z_Step = 0;
+
+ PR4 = 10; //Set the on Time
+ ManualStepperInt_Cycle = 2;
+ break;
+ }
+
+ case 2:
+ {
+ PR4 = Feed_Rate;
+ X_Step = 0; Y_Step = 0; Z_Step = 0;
+ ManualStepperInt_Cycle = 0;
+ break;
+ }
+ }
+ TMR4 = 0;
+ mT4ClearIntFlag();
+}
+else
+{
+ switch(StepperInt_Cycle)
+ {
+ case 0: //Read in new code and set Direction
+ if(!SBReady&&(SBR!=SBW))
+ { //ready and the buffer is not empty
+ SBCode = SCB[ SBR]; //Read buffer
+ SCB[ SBR] = 0x00; //once read, set to zero
+ SBR++;
+ SBR %= SB_SIZE;
+ SBReady = 1; //Step byte consumed - ready to take another byte
+
+ mask = 0x08000000;
+ bit_pos = 3;
+ do // Unpack the code into axis Step and Dir
+ {
+ if ( SBCode & mask )
+ {
+ switch(bit_pos)
+ {
+ //set 1's in code
+ case 3: Z_Dir = 1; break;
+ case 5: Y_Dir = 1; break;
+ case 7: X_Dir = 1; break;
+ }
+ }
+ else
+ {
+ switch(bit_pos)
+ {
+ //set 0's in code
+ case 3: Z_Dir = 0; break;
+ case 5: Y_Dir = 0; break;
+ case 7: X_Dir = 0; break;
+ }
+ }
+ bit_pos += 2;
+ mask <<= 2;
+ }
+ while (mask !=0);
+ }
+ PR4 = 5;
+ StepperInt_Cycle = 1;
+ break;
+
+ case 1:
+ if (SBReady)
+ {
+ mask = 0x04000000;
+ bit_pos = 2;
+ do // Unpack the code into axis Step and Dir
+ {
+ if ( SBCode & mask )
+ {
+ switch(bit_pos)
+ {
+ //set 1's in code
+ case 2: Z_Step = 1; break;
+ case 4: Y_Step = 1; ys = 1; break;
+ case 6: X_Step = 1; xs = 1; break;
+ }
+ }
+ else
+ {
+ switch(bit_pos)
+ {
+ //set 0's in code
+ case 2: Z_Step = 0; break;
+ case 4: Y_Step = 0; ys=0; break;
+ case 6: X_Step = 0; xs=0; break;
+ }
+ }
+ bit_pos += 2;
+ mask <<= 2;
+ }
+ while (mask !=0);
+ }
+ PR4 = 10; //Set the on Time
+ StepperInt_Cycle = 2;
+ break;
+
+ case 2:
+ if (SBReady)
+ {
+ mask = 0xFFFF; //to return the bottom two bytes
+ PR4_Setting = SBCode & mask;
+ PR4 = PR4_Setting; //Set the off time
+ }
+ else
+ PR4 = 5000;
+
+ X_Step = 0; Y_Step = 0; Z_Step = 0; //turn off step pulse
+ StepperInt_Cycle = 0;
+ SBReady = 0;//code taken from buffer
+ SBCode = 0;
+ break;
+ }
+
+ TMR4 = 0;
+ mT4ClearIntFlag();
+ }
+}//T4Interrupt
+//******************************************************************
+void Stepper_InitIO (void)
+{
+ // Setup timers
+ //Timer 1
+ T1CON = 0x8030; //Set up timer 1 Fosc/2, prescaled 1:256
+
+ DDPCONbits.JTAGEN = 0; //To release port A pins from use by JTAG port
+
+ //Set Tris for Stepper
+ //X
+ AD1PCFGbits.PCFG8 = 1; //AtoD port cfg AN8/B8
+ TRISBbits.TRISB8 = OUTPUT; //Step
+ AD1PCFGbits.PCFG9 = 1; //AtoD port cfg AN9/B9
+ TRISBbits.TRISB9 = OUTPUT; //Dir
+ AD1PCFGbits.PCFG13 = 1; //AtoD port cfg AN13/B13
+ TRISBbits.TRISB13 = OUTPUT; //Enable
+ TRISDbits.TRISD4 = INPUT; //X_HomeSwitch
+ //Y
+ TRISDbits.TRISD8 = OUTPUT; //Step
+ TRISDbits.TRISD9 = OUTPUT; //Dir
+ TRISDbits.TRISD10 = OUTPUT; //Enable
+ TRISCbits.TRISC13 = INPUT; //Y_HomeSwitch
+
+ //Z
+ TRISDbits.TRISD2 = OUTPUT; //Step
+ TRISDbits.TRISD7 = OUTPUT; //Dir
+ TRISDbits.TRISD3 = OUTPUT; //Enable
+ TRISCbits.TRISC14 = INPUT; //Z_HomeSwitch
+
+ X_Disable = TRUE;
+ Y_Disable = TRUE;
+ Z_Disable = TRUE;
+
+ //Timer 4 is used to time the stepper motor steps
+ //PB clk = 8MHz Post scaler = 2 to 1 tick every 25nS
+ T4CON = 0x0; //Clear timer setting register
+ T4CONSET = 0x0010; //Set PS to 2
+ TMR4 = 0; //Reset clock
+ PR4 = 500; //Initialise PR4 value (when T4 matches PR4 it interrupts)
+ mT4SetIntPriority(7); //Set T4 interrupt to top priority
+ INTEnableSystemMultiVectoredInt();//Set T4 to vectored i.e. Fast
+ mT4ClearIntFlag(); //Clear interrupt flag
+ T4CONSET = 0x8000; //Turn on T4
+ mT4IntEnable(!TRUE); //Disable T4 interrputs
+
+ // init the circular buffer pointers
+ SBR = 0;
+ SBW = 0;
+ // Init Rapid moves
+ G_CodeRapidXYMove=0;
+ G_CodeRapidZMove=0;
+
+}//InitStepper
+//****************************************************************
+void Stepper_LoadNewValues(int Feed_Code, int Machine_Code)
+{
+int PBspeed;
+extern int GoToRestSpeed;
+extern char FastMoveMotorEnable;//Flag to switch motor on/off during fast move
+
+ S_F_Code = Feed_Code;
+ S_M_Code = Machine_Code;
+
+ //Set the feed Rate
+ //From Enrique's code Feed rate comes in as mm/s
+ //Old code may come in as mm/min
+ //if (Feed_Code > 50)
+ //{ //assume its mm/min
+ Feed_Code /= 60; //to give mm/sec
+ //}
+
+ //PB clk = 80/8 = 10MHz PS is 2:1
+ //Timer is 5MHz
+ //defined above FeedFactor 57094 = 5000000 / 87.575 StepsPer_mm
+
+ if (Feed_Code !=0)
+ {
+ Feed_Rate = (int)FeedFactor / Feed_Code;
+ }
+ else Feed_Rate = SAFE_FEED_RATE;
+
+ if (G_CodeRapidZMove > 0) ZFeed_Rate = G_CodeRapidZMove; // if it gets a value from G_Code use it
+ else ZFeed_Rate = Z_FEED_RATE; //always do rapid z move
+
+ xyrate = Feed_Rate * 1.414; //Multiply by root2 for 45Degree step
+
+
+ //Extruder OFF Feed Rate
+ //Realistic range for Extruder off 250(Very fast) - 7136{Slow)
+ if (ExtruderStatus == 0)
+ {
+ if (G_CodeRapidXYMove > 0) Feed_Rate = G_CodeRapidXYMove;
+ else Feed_Rate = RAPID_MOVE_FEED_RATE; //extruder off fast speed
+
+ if (FastMoveMotorEnable == FALSE) //flag set by G-Code
+ //default is motor On ie TRUE
+ {
+ if (FirstPass == TRUE)Extruder_Reverse();
+
+ EXTRUDER_DISABLE = TRUE; //Turn off motor
+ FirstPass = FALSE;
+ }
+ }
+ else
+ {
+ if (FirstPass == FALSE)Extruder_Prime();
+ FirstPass = TRUE;
+ }
+
+ if (GoToRestSpeed)//Flag set and reset in the RapMan_Rest function
+ {
+ if (G_CodeRapidXYMove > 0)
+ {//if it gets a value from the G_Code
+ Feed_Rate = G_CodeRapidXYMove;
+ xyrate = G_CodeRapidXYMove;
+ }
+ else
+ {// Use default
+ Feed_Rate = RAPID_MOVE_FEED_RATE;
+ xyrate = RAPID_MOVE_FEED_RATE;
+ }
+ EXTRUDER_DISABLE = TRUE; //Turn off motor
+ }
+
+}//Stepper_LoadNewValues
+//****************************************************************
+void Stepper_CalcSteps(int Units, char G2_G3)
+{
+//Number of steps on each Axis
+ switch (Units)
+ {
+ case 20: //Inches
+ X_Steps = GX * StepsPer_Inch;//numbers here are not rounded
+ Y_Steps = GY * StepsPer_Inch;//up or down!
+ Z_Steps = GZ * StepsPer_Inch;
+
+ lX_Steps= f_to_sl(X_Steps); //Float to long function at bottom of this
+ lY_Steps= f_to_sl(Y_Steps); //section.
+ lZ_Steps= f_to_sl(Z_Steps);
+ break;
+
+ case 21: //Metric
+ default: //Default metric
+ X_Steps = GX * StepsPer_mm;
+ Y_Steps = GY * StepsPer_mm;
+ Z_Steps = GZ * ZStepsPer_mm;
+
+ lX_Steps= f_to_sl(X_Steps); //Float to long function at bottom of this
+ lY_Steps= f_to_sl(Y_Steps); //section.
+ lZ_Steps= f_to_sl(Z_Steps);
+ break;
+ }//switch
+}
+//****************************************************************
+void OriginOffset(void)
+{
+extern float X_Rest_mm,Y_Rest_mm,Z_Rest_mm;
+float OffsetX_mm,OffsetY_mm,OffsetZ_mm;
+
+ OffsetSteps_X = lHomeStepsX - lSaveSteps_X;
+ OffsetSteps_Y = lHomeStepsY - lSaveSteps_Y;
+ OffsetSteps_Z = lHomeStepsZ - lSaveSteps_Z;
+
+ //SAVE offset to EEPROM here?
+
+ //reset saved values to new origin
+ lSaveSteps_X = 0; //zero only if the machine is at new 0,0
+ lSaveSteps_Y = 0;
+ lSaveSteps_Z = 0;
+
+ OffsetX_mm = OffsetSteps_X / StepsPer_mm;
+ OffsetY_mm = OffsetSteps_Y / StepsPer_mm;
+ OffsetZ_mm = OffsetSteps_Z / ZStepsPer_mm;
+
+ X_Rest_mm = X_REST_ABS_MM - X_HOME_MM + OffsetX_mm;
+ Y_Rest_mm = Y_REST_ABS_MM - Y_HOME_MM + OffsetY_mm;
+ Z_Rest_mm = Z_REST_ABS_MM - Z_HOME_MM + OffsetZ_mm;
+
+}//OriginOffset
+//****************************************************************
+void ResetOrigin(void)
+{
+extern float X_Rest_mm,Y_Rest_mm,Z_Rest_mm;
+
+ //restore offset from EEPROM?
+
+ if (lSaveSteps_X != lHomeStepsX) lSaveSteps_X = lHomeStepsX - OffsetSteps_X + lSaveSteps_X;
+ if (lSaveSteps_Y != lHomeStepsY) lSaveSteps_Y = lHomeStepsY - OffsetSteps_Y + lSaveSteps_Y;
+ if (lSaveSteps_Z != lHomeStepsZ) lSaveSteps_Z = lHomeStepsZ - OffsetSteps_Z + lSaveSteps_Z;
+
+ X_Rest_mm = X_REST_ABS_MM;
+ Y_Rest_mm = Y_REST_ABS_MM;
+ Z_Rest_mm = Z_REST_ABS_MM;
+
+}//ResetOrigin
+
+//****************************************************************
+void Stepper_Run3DLine()
+{
+//all the variables in the following are available a global or local
+ Bresenham_3D_Line(lX_Steps,lY_Steps,lZ_Steps,lSaveSteps_X,lSaveSteps_Y,lSaveSteps_Z);
+ Stepper_SaveValues();
+
+}//Stepper_Run3DLine
+
+//****************************************************************
+void Bresenham_3D_Line(signed int x1, signed int y1, signed int z1,
+ signed int x2, signed int y2, signed int z2)
+{
+
+int MajorAxis = 0;
+signed int incX = 1, incY = 1, incZ = 1;
+signed long DeltaX = x2-x1;
+signed long DeltaY = y2-y1;
+signed long DeltaZ = z2-z1;
+signed long TwoDeltaX = DeltaX + DeltaX;
+signed long TwoDeltaY = DeltaY + DeltaY;
+signed long TwoDeltaZ = DeltaZ + DeltaZ;
+int currentX = x1;
+int currentY = y1;
+int currentZ = z1;
+int ErrorX = 0, ErrorY = 0, ErrorZ = 0;
+int moveX = 0, moveY = 0, moveZ = 0;
+
+//StepData Bits 7 XDir, 6 X, 5 YDir, 4 Y, 3 ZDir, 2 Z, 1 & 0 Not used
+unsigned char StepData = 0;
+
+ if (!GX_On)
+ { //checks to see if the code mentions X
+ DeltaX = 0; //if not mentioned then no change
+ TwoDeltaX=0;
+ }
+ if (!GY_On)
+ {
+ DeltaY = 0;
+ TwoDeltaY=0;
+ }
+ if (!GZ_On)
+ {
+ DeltaZ = 0;
+ TwoDeltaZ=0;
+ }
+
+ //if there is no delta, current step coord is same as saved value
+ if (DeltaX == 0)
+ {
+ x1=x2;
+ lX_Steps=lSaveSteps_X;
+ GX = Save_X;
+ }
+ if (DeltaY == 0)
+ {
+ y1=y2;
+ lY_Steps=lSaveSteps_Y;
+ GY = Save_Y;
+ }
+ if (DeltaZ == 0)
+ {
+ z1=z2;
+ lZ_Steps=lSaveSteps_Z;
+ GZ = Save_Z;
+ }
+
+ if (DeltaX < 0)
+ {
+ X_Dir = 0; //Set X Direction based on sign of Delta value
+ StepData = StepData & ~0x80; //set bit 7 off
+ incX = -1;
+ DeltaX = -DeltaX;
+ TwoDeltaX = -TwoDeltaX;
+ }
+ else
+ {
+ X_Dir = 1;
+ StepData |= 0x80; //set bit 7 on
+ }
+
+ if (DeltaY < 0)
+ {
+ Y_Dir = 0; //Set Y Direction based on sign of Delta value
+ StepData = StepData & ~0x20; //set bit 5 off
+ incY = -1;
+ DeltaY = -DeltaY;
+ TwoDeltaY = -TwoDeltaY;
+ }
+ else
+ {
+ Y_Dir = 1;
+ StepData |= 0x20; //set bit 5 on
+ }
+
+ if (DeltaZ < 0)
+ {
+ Z_Dir = 1; //Set Z Direction based on sign of Delta value
+ StepData |= 0x08; //set bit 3 on
+ incZ = -1;
+ DeltaZ = -DeltaZ;
+ TwoDeltaZ = -TwoDeltaZ;
+ }
+ else
+ {
+ Z_Dir = 0;
+ StepData = StepData & ~0x08; //set bit 3 off
+ }
+
+ if ((DeltaX == 0)&(DeltaY == 0))
+ {
+ // if its only a z change then go fast
+ if (DeltaZ != 0) Feed_Rate = ZFeed_Rate;
+ }
+
+ if ((DeltaZ >= DeltaX)&(DeltaZ >= DeltaY))(MajorAxis = 1);
+ if ((DeltaX >= DeltaZ)&(DeltaX >= DeltaY))(MajorAxis = 2);
+ if ((DeltaY >= DeltaX)&(DeltaY >= DeltaZ))(MajorAxis = 3);
+
+ if ((DeltaX ==0)&(DeltaY==0)&(DeltaZ==0)) MajorAxis = 0;
+
+ //if (MajorAxis == 0)
+ //{
+ //error trap if required
+ //if MajorAxis is 0 then it drops out of this code with no action
+ //}
+
+//case 1
+ if (MajorAxis == 1)// = Z
+ {
+ do
+ {
+ currentZ += incZ;
+ ErrorX += TwoDeltaX;
+ ErrorY += TwoDeltaY;
+
+ if (ErrorX > DeltaZ)
+ {
+ currentX += incX;
+ ErrorX -= TwoDeltaZ;
+ moveX = 1;
+ StepData |= 0x40; //x set bit 6 on
+ }
+ if (ErrorY > DeltaZ)
+ {
+ currentY += incY;
+ ErrorY -= TwoDeltaZ;
+ moveY = 1;
+ StepData |= 0x10; //y set bit 5 on
+ }
+
+ StepData |= 0x04; //z set bit 2 on
+ AddToStepBuffer(StepData,moveX,moveY); //add step data to cuircular buffer
+ moveX = 0, moveY = 0, moveZ = 0;
+ StepData = StepData & ~0x54; //set bit 6,4,2 (x,y,z) off
+
+ }
+ while(currentZ != z2);
+
+ }//if
+
+//case 2
+ if (MajorAxis == 2)// = X
+ {
+ do
+ {
+ currentX += incX;
+ ErrorZ += TwoDeltaZ;
+ ErrorY += TwoDeltaY;
+
+ if (ErrorZ > DeltaX)
+ {
+ currentZ += incZ;
+ ErrorZ -= TwoDeltaX;
+ moveZ = 1;
+ StepData |= 0x04; //z set bit 2 on
+ }
+ if (ErrorY > DeltaX)
+ {
+ currentY += incY;
+ ErrorY -= TwoDeltaX;
+ moveY = 1;
+ StepData |= 0x10; //y set bit 5 on
+ }
+
+ StepData |= 0x40; //x set bit 6 on
+ AddToStepBuffer(StepData,moveX,moveY); //add step data to cuircular buffer
+ moveX = 0, moveY = 0, moveZ = 0;
+ StepData = StepData & ~0x54; //set bit 6,4,2 (x,y,z) off
+
+ }
+ while(currentX != x2);
+ }//if
+
+//case 3
+ if (MajorAxis == 3)// = Y
+ {
+ if (currentY != y2)
+ {
+ do
+ {
+ currentY += incY;
+ ErrorX += TwoDeltaX;
+ ErrorZ += TwoDeltaZ;
+
+ if (ErrorX > DeltaY)
+ {
+ currentX += incX;
+ ErrorX -= TwoDeltaY;
+ moveX = 1;
+ StepData |= 0x40; //x set bit 6 on
+ }
+ if (ErrorZ > DeltaY)
+ {
+ currentZ += incZ;
+ ErrorZ -= TwoDeltaY;
+ moveZ = 1;
+ StepData |= 0x04; //z set bit 2 on
+ }
+
+ StepData |= 0x10; //y set bit 5 on
+ AddToStepBuffer(StepData,moveX,moveY); //add step data to circular buffer
+ moveX = 0, moveY = 0; moveZ = 0;
+ StepData = StepData & ~0x54; //set bit 6,4,2 (x,y,z) off
+
+ }
+ while(currentY != y2);
+ }//if
+ }//if
+}//Bresenham_3D_Line
+
+//*************************************************************
+void Stepper_SaveValues()
+{
+//Tidy up after Gcode instruction.
+//Save current dimension and step coordinates
+
+ lSaveSteps_X = lX_Steps;
+ lSaveSteps_Y = lY_Steps;
+ lSaveSteps_Z = lZ_Steps;
+
+ Save3_X = Save2_X;
+ Save3_Y = Save2_Y;
+ Save3_Z = Save2_Z;
+
+ Save2_X = Save_X;
+ Save2_Y = Save_Y;
+ Save2_Z = Save_Z;
+
+ Save_X = GX;
+ Save_Y = GY;
+ Save_Z = GZ;
+
+//Reset globals
+ Delta_X=0; Delta_Y=0; Delta_Z=0;
+ X_Steps=0; Y_Steps=0; Z_Steps=0;
+ lX_Steps=0;lY_Steps=0;lZ_Steps=0;
+
+}//Stepper_SaveValues
+
+//*************************************************************
+int f_to_ul(float fNumber)
+{
+//Function returns a rounded unsigned long value for fNumber
+
+double IntNumber, Fraction;
+int TempNum;
+
+ Fraction = modf(fNumber, &IntNumber);//split float into Int and fraction
+ TempNum = (int)IntNumber;
+
+ if (Fraction >= 0.5)
+ {
+ TempNum += 1;
+ return TempNum;
+ }
+ else
+ return TempNum;
+
+}//f_to_ul
+
+//****************************************************************
+signed int f_to_sl(float fNumber)
+{
+//Function returns a rounded signed long value for fNumber
+
+double IntNumber, Fraction;
+signed int TempNum;
+
+ Fraction=modf(fNumber,&IntNumber);//split float into Int and fraction
+ TempNum = (signed int)IntNumber;
+
+ if (Fraction >= 0.5)
+ {
+ TempNum += 1;
+ }
+ if (Fraction <= -0.5)
+ {
+ TempNum -= 1;
+ }
+
+ return TempNum;
+
+}//f_to_sl
+
+//****************************************************************
+void AddToStepBuffer(unsigned char SData, char xs, char ys)
+{
+int BufferCode = 0;
+int addmask;
+
+ BufferCode = SData; //shift in 8Bit step data
+ BufferCode <<= 24;
+
+ if (xs && ys) //if we have a step in x and y
+ { //at the same time, the move is at 45deg
+ addmask = xyrate; //therefore swap in the slower feed rate
+ }
+ else
+ {
+ addmask = Feed_Rate;
+ }
+ BufferCode |= addmask; //add in the feed rate
+
+ //ready to add new data so now wait if buffer is full
+ while ( (SBW+1)%SB_SIZE == SBR);
+
+ SCB[ SBW] = BufferCode; //write in the buffer
+ SBW++; //increment ptr
+ SBW %= SB_SIZE; //wrap around if required
+
+}//AddToStepBuffer
+/*****************************************************************/
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Stepper.d b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Stepper.d new file mode 100644 index 00000000..7fd16a94 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Stepper.d @@ -0,0 +1,63 @@ +Stepper.o: Stepper.c \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/math.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/inttypes.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdint.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_mwgwtypes.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_const.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_fmtio.h \
+ Stepper.h Enviroment.h Extruder.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h OLED.h
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Stepper.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Stepper.h new file mode 100644 index 00000000..47b3c18d --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/Stepper.h @@ -0,0 +1,123 @@ +/**********************************************************************
+ *************************** Stepper.h ******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ * Erik de Bruijn 11/03/2010 Local changes for Eriks Darwin cartesian bot
+ ***********************************************************************/
+
+#define SHOW_POSITIONS 1
+#define HIDE_POSITIONS 0
+
+//General Defines
+
+extern int GX_On;
+extern int GY_On;
+extern int GZ_On;
+extern int GI_On;
+extern int GJ_On;
+
+extern float GX;
+extern float GY;
+extern float GZ;
+extern float GI_Val;
+extern float GJ_Val;
+extern int F_Code;
+extern int M_Code;
+
+extern char ExtruderStatus;
+int Feed_Rate;
+
+#define INPUT 1
+#define OUTPUT 0
+
+//18T MXL Pulley 1/16 Stepping for X & Y Axis
+#define StepsPer_mm 61.302// Changed by ERIK. This was: 87.575 // 1/16 Stepping
+#define StepsPer_Inch 100 // 1/16 Stepping
+#define FeedFactor 57094
+
+//M8 x 1.25 thread
+//200 steps per rev 3200 at 1/16 stepping x 1/1.25 = 2560
+#define ZStepsPer_mm 2560
+
+// Axis definitions
+#define X_Step PORTDbits.RD2 //Digital
+#define X_Dir PORTDbits.RD7 //Digital
+#define X_Disable PORTDbits.RD3 //Digital
+
+#define Y_Step PORTDbits.RD8 //Digital
+#define Y_Dir PORTDbits.RD9 //Digital
+#define Y_Disable PORTDbits.RD10 //Digital
+
+#define Z_Step PORTBbits.RB8 //Analog
+#define Z_Dir PORTBbits.RB9 //Analog
+#define Z_Disable PORTBbits.RB13 //Analog
+
+#define SB_SIZE 512 // Step buffer size
+
+//Flag setup for interrupts
+#define _T4IE IEC0bits.T4IE
+#define _T4IF IFS0bits.T4IF
+
+#define SAFE_FEED_RATE 2000
+#define RAPID_MOVE_FEED_RATE 950 //ERIK was: 750 //was500
+#define Z_FEED_RATE 1200 //ERIK was: 750
+#define GO_TO_REST_RATE 800
+
+#define X_REST_ABS_MM 130 // ERIK: have a look at this!!
+#define Y_REST_ABS_MM -100
+#define Z_REST_ABS_MM 0
+
+int G_CodeRapidXYMove;
+int G_CodeRapidZMove;
+int S_F_Code; //Stepper F code
+
+/****************************************************************/
+/* Functions */
+/****************************************************************/
+//External Functions
+extern void Stepper_InitIO(void);
+extern void Stepper_LoadNewValues(int Feed_Code, int Machine_Code);
+extern void Stepper_CalcSteps(int Units, char G2_G3);
+extern void OriginOffset(void);
+extern void ResetOrigin(void);
+extern void Manual_Mode(char ShowPos);
+extern int RapMan_Home(void);
+extern void GoToRest();
+extern void Stepper_Run3DLine(void);
+extern void Axis_Stepper_Motors(int on_off);
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.elf b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.elf Binary files differnew file mode 100644 index 00000000..81e9ec9d --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.elf diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.hex b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.hex new file mode 100644 index 00000000..a1d870aa --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.hex @@ -0,0 +1,7073 @@ +:020000040000fa
+:020000041fc01b
+:042ff400d9fff8ff0a
+:020000040000fa
+:020000041fc01b
+:042ff800dbfd7fff7f
+:020000040000fa
+:020000041fc01b
+:042ffc00ffffff7f55
+:020000040000fa
+:020000041d00dd
+:10600000009d1a3c90645a270800400300000000dd
+:020000040000fa
+:020000041d00dd
+:10638000029d1a3c30ba5a27080040030000000062
+:020000040000fa
+:020000041d00dd
+:10518000029d1a3cd4af5a270800400300000000db
+:020000040000fa
+:020000041d00dd
+:08530000861a400b00000000ba
+:020000040000fa
+:020000041d00dd
+:085380004b1b400b0000000074
+:020000040000fa
+:020000041d00dd
+:08540000ea63400b000000000c
+:020000040000fa
+:020000041d00dd
+:1064900000601a40c0045a7f05004013000000004d
+:1064a000029d1a3c48ba5a27080040030000000029
+:1064b00001a01d3c0080bd2701a01c3cf0809c2752
+:1064c0000260094020582001801e2a7d8449497db0
+:1064d0000260894000e0dc4102608b40029d083c84
+:1064e00038ba082509f800010000000000a0083ca7
+:1064f0002001082500a0093c801229250600001073
+:1065000000000000000000ad040000ad080000ad78
+:106510000c0000ad100008252b080901f9ff20141c
+:1065200000000000029d083c601e082500a0093cf8
+:106530000000292500a00a3c20014a250500001082
+:106540000000000000000b8d00002bad04000825aa
+:10655000040029252b082a01faff2014000000005e
+:106560000000093c000029251d002011000000004a
+:10657000029d083c801f082500a0093c0018292521
+:1065800000a00a3c00184a2500000b8d00002bad2e
+:1065900004000825040029252b082a01faff2014ed
+:1065a000000000000000093c0018292588bf0a3cb3
+:1065b00010204a25000049ad0100093c0080292532
+:1065c00088bf0a3c20204a25000049ad0100093c53
+:1065d0000080292588bf0a3c30204a25000049adab
+:1065e00000488040ffff0a2400588a40009d093c73
+:1065f00000502925017889400000093c0100292527
+:1066000000000a2444492a7d01608a408000093c38
+:1066100000688940008008408005097d404c0900e1
+:10662000006008405800013c244001012540280139
+:1066300000608840029d083c40ba082509f8000126
+:106640000000000000600840bfff013cffff213454
+:106650002440010100608840000084300000a53023
+:10666000009d083c006a08250800000100000000a9
+:020000040000fa
+:020000041d00dd
+:106a0000e257400f00000000816c400f00000000c2
+:106a1000ffff00100000000000e85d4100681a4020
+:106a200000701b4088ffbd277400bbaf00601b4097
+:106a300082d21a007000bbaf847a5b7f12d0000054
+:106a40006c00baaf10d000006800baaf44201b7cc5
+:106a500000609b406000bfaf5c00beaf5800b9afa4
+:106a60005400b8af5000afaf4c00aeaf4800adaf70
+:106a70004400acaf4000abaf3c00aaaf3800a9afb8
+:106a80003400a8af3000a7af2c00a6af2800a5aff8
+:106a90002400a4af2000a3af1c00a2af1800a1af38
+:106aa00021f0a0036080828f1000c2af0100022499
+:106ab0001000c38f34006210000000001000c38f6c
+:106ac0000200622806004010000000001000c28f83
+:106ad00009004010000000006f00001000000000de
+:106ae000020002241000c38f2f006210000000007b
+:106af00069000010000000000b0004241e1d400f60
+:106b000000000000348082af3480828f1b00401868
+:106b1000000000003c80838f3480828f211062004f
+:106b20003c8082af3880828f01004224388082af5f
+:106b30003880828f0a0042281000401400000000b4
+:106b40003c80848f6666023c67664234180082008f
+:106b50001010000083180200c31704002310620005
+:106b6000648182af388080af3c8080af0100022416
+:106b7000608082af4800001000000000608080af9d
+:106b800045000010000000006481848fac1c400fa1
+:106b900000000000248182af02000224608082afe6
+:106ba0003d00001000000000ed1b400f0000000041
+:106bb000608080af88bf023c5061428c0000427c04
+:106bc00006004010000000003080828f0100422447
+:106bd000308082af0200001000000000308080afe3
+:106be00049818283150040140000000088bf023ce8
+:106bf0005060428cc000427c06004014000000003f
+:106c000001000224498182a30480828f0100422472
+:106c1000048082af88bf023c5060428c8000427c7e
+:106c2000060040140000000001000224498182a3f4
+:106c30000480828fffff4224048082af6c818283b4
+:106c4000150040140000000088bf023c5060428cd8
+:106c5000c003427c06004014000000000100022432
+:106c60006c8182a34c80828f010042244c8082afd1
+:106c700088bf023c5060428c0001427c06004014f8
+:106c800000000000010002246c8182a34c80828fee
+:106c9000ffff42244c8082af80bf023c100840ac12
+:106ca00088bf033c00010224341062ac21e8c00319
+:106cb0006000bf8f5c00be8f5800b98f5400b88f42
+:106cc0005000af8f4c00ae8f4800ad8f4400ac8faa
+:106cd0004000ab8f3c00aa8f3800a98f3400a88fea
+:106ce0003000a78f2c00a68f2800a58f2400a48f2a
+:106cf0002000a38f1c00a28f1800a18f00606041ac
+:106d0000c00000006c00ba8f130040036800ba8f07
+:106d1000110040037400ba8f00709a407000ba8f5f
+:106d20007800bd2700609a401800004200e85d41ed
+:106d3000f4ffbd2700601b400800bbaf04201b7c94
+:106d4000001c7b3700609b4021f0a0035080828fa5
+:106d50000000c2af010002240000c38f2d006210aa
+:106d6000000000000000c38f0200622806004010ef
+:106d7000000000000000c28f090040100000000069
+:106d80003f00001000000000020002240000c38f3a
+:106d90002e0062100000000039000010000000000a
+:106da0003081828f0f004014000000005881828fd4
+:106db00004004018000000005881828fffff422429
+:106dc000588182af7081828f04004018000000005b
+:106dd0007081828fffff4224708182af0100022404
+:106de000308182af88bf043c1061828c0c80838f1d
+:106df0008410627c106182ac80bf033c05000224d9
+:106e0000200a62ac01000224508082af1c000010f6
+:106e1000000000003081828f05004010000000005b
+:106e200088bf023c1061439002006334106143a0ac
+:106e300080bf023c0a000324200a43ac0200022463
+:106e4000508082af0e000010000000003081828f61
+:106e5000060040100000000088bf043c10618390d1
+:106e6000fdff022424106200106182a080bf033c59
+:106e70000880828f200a62ac508080af308180af62
+:106e800080bf023c100a40ac88bf033c00100224c3
+:106e9000341062ac21e8c0030800ba8f00609a4049
+:106ea00018000042e8ffbd271400bfaf1000beafbe
+:106eb00021f0a0030480828f548082af0480828fef
+:106ec00002004228030040100000000002000224db
+:106ed000048082af0480828fd107422803004014cf
+:106ee00000000000d0070224048082af0480848f59
+:106ef000d079400f000000002130400021386000b0
+:106f0000029d023c2006448c2406458ca378400f49
+:106f100000000000029d063c212040002128600066
+:106f20002c06c78c2806c68cce76400f00000000c9
+:106f30002120400021286000687a400f00000000f6
+:106f4000088082af4480828f100040100000000053
+:106f500088bf043c10618390feff0224241062006d
+:106f6000106182a00480828f100042280b00401024
+:106f70000000000088bf023c1061439001006334b0
+:106f8000106143a0050000100000000088bf023c13
+:106f90001061439001006334106143a021e8c003f5
+:106fa0001400bf8f1000be8f1800bd270800e0033b
+:106fb00000000000e8ffbd271400bfaf1000beaf07
+:106fc00021f0a0034c80828f0200410400000000e9
+:106fd0004c8080af4c80828f2d01422803004014ea
+:106fe000000000002c0102244c8082af20828283aa
+:106ff00019004014000000004c80848fae7c400fcc
+:10700000000000002481848f21284000137d400f60
+:107010000000000003004004000000000700001012
+:107020000000000088bf023c5061439001006334bf
+:10703000506143a00d0000100000000088bf043c18
+:1070400050618390feff022424106200506182a0f0
+:10705000060000100000000088bf043c50618390cf
+:10706000feff022424106200506182a048818283c6
+:1070700026004014000000004c80828ff6ff42245e
+:1070800021204000ae7c400f000000002481848f4e
+:1070900021284000137d400f000000001200400432
+:1070a000000000004c80828f0a0042242120400012
+:1070b000ae7c400f00000000212040002481858f1d
+:1070c000137d400f00000000070040040000000096
+:1070d0004c80828f640042280300401400000000ae
+:1070e0000800001000000000448080af88bf023c10
+:1070f0001061439001006334106143a0030000104d
+:107100000000000001000224448082af4881838394
+:10711000010002242c006214000000004c80828fc9
+:10712000ffff422421204000ae7c400f0000000001
+:107130002481848f21284000137d400f000000002f
+:1071400018004004000000004c80828f010042249f
+:1071500021204000ae7c400f0000000021204000b4
+:107160002481858f137d400f000000000d00400436
+:10717000000000004c80828f640042280900401407
+:10718000000000002481848f21280000137d400f1f
+:107190000000000003004010000000000800001084
+:1071a00000000000448080af88bf023c1061439023
+:1071b00001006334106143a00300001000000000d0
+:1071c00001000224448082af3c81838301000224b9
+:1071d00019006214000000004c80828ffbff4224e3
+:1071e00021204000ae7c400f000000002481848fed
+:1071f00021284000137d400f0000000003004004e0
+:1072000000000000080000100000000088bf043cdf
+:1072100010618390dfff022424106200106182a0bd
+:10722000050000100000000088bf023c1061439080
+:1072300020006334106143a0029d023c2481848fae
+:107240003006458c137d400f000000000300401005
+:1072500000000000040000100000000021200000d9
+:10726000481d400f00000000029d023c2481848fd5
+:107270003406458c137d400f0000000003004010d1
+:1072800000000000040000100000000021200000a9
+:10729000481d400f0000000021e8c0031400bf8f0c
+:1072a0001000be8f1800bd270800e003000000009a
+:1072b000d0ffbd272800bfaf2400beaf2000b0af75
+:1072c00021f0a0033000c4af3000c28f1c00422860
+:1072d0000800401000000000029d023c3806428c6d
+:1072e0001000c2af1000c28f1800c2af5a000010c9
+:1072f000000000003000c28fff0342280c00401441
+:10730000000000003080828f3300422808004014c3
+:1073100000000000029d023c3c06428c1000c2afff
+:107320001000c28f1800c2af4b0000100000000018
+:107330001400c0af1400c28f1f0042284600401046
+:1073400000000000029d043c1400c28f801802005f
+:10735000a0058224211062000000428c688182af67
+:107360003000c38f6881828f2a104300350040109f
+:10737000000000006881828f1c8182af029d043c66
+:107380001400c28f80180200a00582242110620020
+:10739000fcff428c608182af6081838f1c81828f71
+:1073a00023106200508182af3000c38f1c81828f16
+:1073b000231062005c8182af5c81848fae7c400fc1
+:1073c00000000000218040005081848fae7c400f7f
+:1073d000000000002120000221284000237c400ff3
+:1073e00000000000208182af029d023c2081848f3a
+:1073f0004006458cb57b400f00000000208182af25
+:107400001400c38f2110600080100200211043007f
+:107410004010020021204000ae7c400f0000000020
+:10742000212040002081858f187b400f0000000044
+:107430001000c2af1000c28f1800c2af06000010cb
+:10744000000000001400c28f010042241400c2afeb
+:10745000b8ff0010000000001800c28f21e8c00330
+:107460002800bf8f2400be8f2000b08f3000bd27c2
+:107470000800e00300000000f0ffbd270800beafd9
+:1074800021f0a0031000c4af81bf043c4090828c67
+:107490001000c38f049c627c409082ac81bf033c8f
+:1074a0000090629002004234009062a00000c0afe1
+:1074b0000000c28fc80042280600401000000000f3
+:1074c0000000c28f010042240000c2aff8ff00108c
+:1074d0000000000081bf043c00908390fdff022467
+:1074e00024106200009082a081bf023c0090428c78
+:1074f0000000427c0300401400000000faff00106e
+:107500000000000081bf023c7090428c21e8c00363
+:107510000800be8f1000bd270800e0030000000037
+:10752000f0ffbd270800beaf21f0a0031000c4afdc
+:107530001000c28f010042380100422c0000c2af8f
+:10754000010002240000c38f100062100000000040
+:107550000000c38f020062280600401000000000f7
+:107560000000c28f1d004010000000003900001014
+:1075700000000000020002240000c38f2c006210f3
+:1075800000000000330000100000000088bf043c31
+:1075900010618390feff022424106200106182a01b
+:1075a00088bf033c00010224641062ac88bf033c26
+:1075b00000010224681062ac88bf033c0010022462
+:1075c000641062ac88bf033c00100224681062acf7
+:1075d000308080af1f0000100000000088bf043c16
+:1075e00050618390feff022424106200506182a04b
+:1075f00088bf033c1061629001004234106162a0b8
+:1076000088bf033c00010224641062ac88bf023cc6
+:10761000681040ac88bf033c00100224641062acc8
+:1076200088bf023c681040ac0a0000100000000057
+:1076300088bf033c1061629001004234106162a077
+:1076400088bf033c00100224641062ac88bf023c77
+:10765000681040ac21e8c0030800be8f1000bd27b1
+:107660000800e00300000000d0ffbd272c00bfafe2
+:107670002800beaf21f0a00388bf043c00618390c6
+:10768000fdff022424106200006182a088bf043c38
+:1076900000618390fbff022424106200006182a03d
+:1076a00088bf043c00618390feff02242410620026
+:1076b000006182a00e7f400f000000001000c2afea
+:1076c00088bf023c0030428c0003427c1c00c2afe9
+:1076d0000b0040140000000088bf033c001002248f
+:1076e000083062ac88bf023c0030428c0003427c10
+:1076f0000300401400000000faff0010000000002a
+:107700001c00c28f1800c2af1800c28f1400c2af95
+:1077100081bf023c30f240ac81bf033c99aa023cdd
+:107720005566423430f262ac81bf033c6655023c80
+:10773000aa99423430f262ac81bf033c1800023c8b
+:1077400008f062ac81bf023c04f040ac81bf033c56
+:107750003333023c3333423430f262ac1400c28f14
+:107760001c00c2af1c00c28f1500401000000000ba
+:1077700088bf023c0030428c0003427c2000c2af34
+:107780000b0040140000000088bf033c00100224de
+:10779000083062ac88bf023c0030428c0003427c5f
+:1077a0000300401400000000faff00100000000079
+:1077b0002000c28f1800c2af0400001000000000bb
+:1077c00088bf033c00100224043062ac1000c48f58
+:1077d0001d7f400f0000000080bf023c000840ac4d
+:1077e00080bf033c70000224080862ac80bf023cea
+:1077f000100840ac80bf033cf4010224200862acb6
+:1078000088bf033c1c000224b41062ac88bf033c58
+:1078100010000224b81062ac88bf033c00010224af
+:10782000341062ac80bf033c00800234080862acb4
+:1078300088bf033c00010224641062ac88bf023c94
+:10784000681040ac80bf023c000a40ac80bf033ce3
+:1078500010000224080a62ac80bf023c100a40ac4f
+:1078600080bf033c88130224200a62ac88bf033c1b
+:107870001c000224c41062ac88bf033c1c0002241c
+:10788000c81062ac107f400f0000000088bf033cae
+:1078900000100224341062ac80bf033c008002342c
+:1078a000080a62ac88bf033c00100224641062ac7a
+:1078b00088bf023c681040ac88bf033c10616290f6
+:1078c00001004234106162a03c8180a3348180a316
+:1078d00021e8c0032c00bf8f2800be8f3000bd27d9
+:1078e0000800e00300000000e0ffbd271c00bfaf60
+:1078f0001800beaf21f0a0031000c0af212000008f
+:107900005f52400f0000000088bf023c5060428c74
+:10791000c000427c0300401400000000faff001089
+:1079200000000000048080af4c8080af4f51400fba
+:107930000000000001000424481d400f000000006a
+:1079400088bf023c9061428c4002437c01000224cb
+:107950002f00621400000000a91b400f000000006f
+:107960001000c28f010042241000c2af1000c28f6d
+:10797000e9034228f2ff4014000000004f51400f7d
+:107980000000000088bf023c5060428cc000427c76
+:1079900004004014000000000480828f0100422493
+:1079a000048082af88bf023c5060428c8000427ce1
+:1079b00004004014000000000480828fffff422476
+:1079c000048082af88bf023c5060428cc003427c7e
+:1079d00004004014000000004c80828f010042240b
+:1079e0004c8082af88bf023c5060428c0001427cd8
+:1079f00004004014000000004c80828fffff4224ee
+:107a00004c8082af1000c0afcdff0010000000001e
+:107a100021200000481d400f0000000021e8c003a5
+:107a20001c00bf8f1800be8f2000bd270800e00398
+:107a300000000000f0ffbd270800beaf21f0a0034a
+:107a40001000c4af0000c0af1000c28f8018020049
+:107a50000000c28f2a1043000c00401000000000fc
+:107a60000000000000000000000000000000000016
+:107a70000000000000000000000000000000c28fb5
+:107a800001004224f0ff00100000c2af21e8c00353
+:107a90000800be8f0800e0031000bd27e8ffbd27e7
+:107aa0001400bfaf1000beaf21f0a0031800c4af98
+:107ab0001800c28fe8030324021043702120400005
+:107ac0008d1e400f0000000021e8c0031400bf8f8e
+:107ad0001000be8f1800bd270800e0030000000062
+:107ae000f8ffbd270000beaf21f0a0034481828fc4
+:107af0001c0040100000000088bf023c1061428c56
+:107b00000000427c17004014000000000c8080af91
+:107b10005881828f0a004014000000002881828f63
+:107b20000500401400000000e8030224588182afe1
+:107b300003000010000000002881828f588182af6e
+:107b400090030224088082af5881828f030040187e
+:107b500000000000fcff00100000000001000224f3
+:107b60000c8082af21e8c0030000be8f0800bd2753
+:107b70000800e00300000000e8ffbd271400bfafcd
+:107b80001000beaf21f0a0034481828f310040106d
+:107b90000000000088bf023c1061428c0000427c63
+:107ba0002c00401400000000010002240c8082af71
+:107bb0007081828f0a004014000000005481828f7f
+:107bc0000500401400000000e8030224708182af29
+:107bd00003000010000000005481828f708182af8a
+:107be00090030224088082af7081828f03004018c6
+:107bf00000000000fcff0010000000000480848fe3
+:107c0000d079400f00000000213040002138600092
+:107c1000029d023c4806448c4c06458ca378400fdc
+:107c200000000000029d063c212040002128600049
+:107c30005406c78c5006c68cce76400f000000005c
+:107c40002120400021286000687a400f00000000d9
+:107c5000088082af21e8c0031400bf8f1000be8fe0
+:107c60001800bd270800e00300000000e0ffbd276a
+:107c70001c00bfaf1800beaf21f0a0031000c0afc2
+:107c80001000c28f030042280b00401000000000cb
+:107c90001000c38f74818227211862000100022422
+:107ca000000062a01000c28f010042241000c2af89
+:107cb000f3ff0010000000006e8080a3e748400f33
+:107cc0000000000000a0023cd80944247c21400fa1
+:107cd0000000000030004014000000001880838f76
+:107ce00000a0023cd8094224000062ac1880828fb8
+:107cf0000c0040a41880828f0e0040a41880828f50
+:107d0000100040ac1880828f140040ac1880838f24
+:107d10005c000224200062a0010002241000c2af17
+:107d20001000c28f0b0042280b0040100000000022
+:107d30001880838f1000c28f211862002000022457
+:107d4000200062a01000c28f010042241000c2afc8
+:107d5000f3ff0010000000001880828f2c0040a468
+:107d60001880838f10000224300062a41880838f53
+:107d70007c81828f340062ac1880838f7c81828ffb
+:107d8000380062ac8c8180a3010002241400c2afd1
+:107d900002000010000000001400c0af1400c28fe9
+:107da00021e8c0031c00bf8f1800be8f2000bd2734
+:107db0000800e00300000000c8ffbd273000bfaf8f
+:107dc0002c00beaf2800b0af21f0a0033800c4af34
+:107dd0003c00c5af2110c0002118e0004000c2a344
+:107de0004400c3a33800c28f2c0042941400c2a7e1
+:107df0000b0002241800c2af3800c38f3800c28fb6
+:107e00003400428c380062ac3c00c28f3000429497
+:107e1000271002001200c2a71400c2970d004014e0
+:107e2000000000001400c2273800c48f2128400041
+:107e300001000624182a400f00000000130040141f
+:107e4000000000001b0002241800c2af0f00001049
+:107e5000000000001400c2970f0042300b004010d9
+:107e6000000000001400c2273800c48f2128400001
+:107e700001000624182a400f0000000003004014ef
+:107e8000000000001b0002241800c2af1800c38fbe
+:107e90001b000224cc006210000000001800c28ffa
+:107ea000c9004010000000001400c2273800c48f31
+:107eb00021284000012e400f000000001600c2a340
+:107ec0001600c393020002240300621400000000a5
+:107ed000bd000010000000001600c293b100401465
+:107ee000000000003800c28f300042941000c2a78a
+:107ef0001000c2973f0042301000c2a74400c29356
+:107f00002000c2af2000c38f0700601000000000f7
+:107f1000010002242000c38f2d0062100000000029
+:107f2000a4000010000000001000c3970800022405
+:107f3000a0006210000000001800c0af6d00022415
+:107f40001c00c2a31700c0a31700c2930b00422c51
+:107f500098004010000000003800c38f1700c29343
+:107f600021106200200042901c00c2a33c00c38f7d
+:107f70001700c29321106200200042901d00c2a38e
+:107f80001c00c29321204000a86c400f000000009c
+:107f9000218040001d00c29321204000a86c400faa
+:107fa0000000000005000212000000000b00022487
+:107fb0001800c2af7f000010000000001700c2933d
+:107fc000010042241700c2a3dfff001000000000e0
+:107fd0001000c3971200c29724106200ffff4230c6
+:107fe00074004014000000001000c3970f0002242a
+:107ff00070006210000000001800c0af6d00022485
+:108000001c00c2a33c00c28f200043802a0002242f
+:108010002e006210000000001700c0a31700c293da
+:108020000800422c29004010000000003800c38fd7
+:108030001700c29321106200200042901c00c2a3ce
+:108040003c00c38f1700c2932110620020004290b1
+:108050001d00c2a31d00c3932a0002240300621462
+:108060000000000019000010000000001d00c39374
+:108070003f00022410006210000000001c00c293a8
+:1080800021204000a86c400f00000000218040002b
+:108090001d00c29321204000a86c400f000000008a
+:1080a00005000212000000000b0002241800c2affd
+:1080b00006000010000000001700c29301004224d7
+:1080c0001700c2a3d5ff0010000000003c00c28fc3
+:1080d000280043802a0002243600621000000000bd
+:1080e0001800c28f33004014000000000800022472
+:1080f0001700c2a31700c2930b00422c2d004010a2
+:10810000000000003800c38f1700c29321106200e6
+:10811000200042901c00c2a33c00c38f1700c293f2
+:1081200021106200200042901d00c2a31d00c393d5
+:108130002a00022403006214000000001d00001049
+:10814000000000001d00c3933f00022410006210d5
+:10815000000000001c00c29321204000a86c400fca
+:1081600000000000218040001d00c293212040003b
+:10817000a86c400f00000000050002120000000083
+:108180000b0002241800c2af0a000010000000001b
+:108190001700c293010042241700c2a3d5ff0010ac
+:1081a000000000004000c2930200401400000000e4
+:1081b0001800c0af1400c297010042241400c2a7e7
+:1081c00036ff0010000000001800c28f21e8c00335
+:1081d0003000bf8f2c00be8f2800b08f3800bd2725
+:1081e0000800e00300000000d0ffbd272c00bfaf57
+:1081f0002800beaf21f0a0033000c4af3400c5afeb
+:108200002110c0003800c2a31c00c0af3000c28fd4
+:108210000000428c1000c2af1000c28f1f004290bd
+:108220000500401400000000070002241c00c2af3b
+:1082300089000010000000003000c38f3000c28fa2
+:108240003400428c380062ac3400c28f000042948b
+:108250000c004014000000003000c48f3400c58fb3
+:1082600001000624182a400f0000000013004014eb
+:10827000000000001b0002241c00c2af0f00001011
+:10828000000000003400c28f000042940f00423012
+:108290000a004010000000003000c48f3400c58f79
+:1082a00001000624182a400f0000000003004014bb
+:1082b000000000001b0002241c00c2af3000c48f6d
+:1082c0003400c58f012e400f000000001400c2a32f
+:1082d0001400c29305004010000000000b000224af
+:1082e0001c00c2af5c000010000000003000c28f14
+:1082f000100040ac3000c38f3000c28f0400428cad
+:10830000080062ac3000c28f0c0040a43000c28f65
+:108310000e0040a41400c39301000224050062145f
+:10832000000000000b0002241c00c2af2700001058
+:10833000000000003000c28f1000c48f0800458c80
+:10834000cd33400f000000001800c2af6c80829354
+:1083500009004010000000009235400f00000000ae
+:108360000500401000000000090002242000c2aff8
+:108370003b000010000000003000c28f688082af18
+:108380001480838f1800c28f10006210000000005c
+:108390006e8080a31000c28f0300438800004398c2
+:1083a000211060001800c48f21284000d349400fdd
+:1083b0000000000003004014000000000800022438
+:1083c0001c00c2af1800c28f148082af3000c48f6f
+:1083d0001800838cfbff022424106200180082ac7a
+:1083e0003800c383770002240700621000000000f9
+:1083f0003800c38361000224030062100000000003
+:108400000c000010000000003000c38f1800628cc8
+:1084100001004234180062ac3000c48f1800838c15
+:10842000fdff022424106200180082ac0a00001034
+:10843000000000003000c48f1800838cfeff02246f
+:1084400024106200180082ac3000c38f1800628cc8
+:1084500002004234180062ac1c00c28f2000c2af80
+:108460002000c28f21e8c0032c00bf8f2800be8fe0
+:108470003000bd270800e00300000000c8ffbd2752
+:108480003400bfaf3000beaf21f0a0033800c4af4e
+:108490003c00c5af2000c0a33800c28f0000428c52
+:1084a0002400c2af2400c28f1e0042902800c2af39
+:1084b000010002242800c38f0f006210000000009a
+:1084c000030002242800c38f030062100000000094
+:1084d0000f00001000000000ff0f023cf8ff4234c4
+:1084e0001c00c2afff0f023cffff42341800c2afb6
+:1084f0000b00001000000000f80f02241c00c2afa7
+:10850000ffff02341800c2af050000100000000099
+:10851000f8ff02341c00c2afffff02341800c2afe4
+:108520003800c28f0800428c1400c2af2400c48ff0
+:108530001400c58f8c39400f000000001000c2af3e
+:108540001000c38f1800c28f0500621400000000e5
+:10855000080002242000c2a3110000100000000047
+:108560002400c28f19004388160043981000c28f60
+:108570002b10430003004014000000000a000224f6
+:108580002000c2a31000c28f1c00c38f2b10430019
+:1085900003004014000000003c0002242000c2a39d
+:1085a0003800c38f1000c28f080062ac3c00c28f3d
+:1085b000ffff42243c00c2af060040100000000054
+:1085c0002000c2930300401400000000d4ff0010fc
+:1085d000000000002000c29321e8c0033400bf8fd8
+:1085e0003000be8f3800bd270800e0030000000007
+:1085f000e0ffbd271c00bfaf1800beaf21f0a003f5
+:108600002000c4af1000c0a32000c28f1f0040a0f4
+:108610002000c28f00a0033c9c046324030043a8f5
+:10862000000043b8654b400f0000000021184000d7
+:10863000010002240700621000000000060002246e
+:108640001000c2a3060002248c8182a31200001035
+:10865000000000002000c48fad21400f000000008a
+:108660001000c2a31000c2930b00401400000000d1
+:108670002000c48fb322400f000000001000c2a3ee
+:108680001000c29304004014000000002000c38fbb
+:10869000010002241f0062a01000c29321e8c00361
+:1086a0001c00bf8f1800be8f2000bd270800e0030c
+:1086b00000000000d0ffbd272c00bfaf2800beafd8
+:1086c00021f0a0033000c4af1400c0a33000c28f5b
+:1086d000030043880000439821106000212000001f
+:1086e00021284000d349400f00000000211840001d
+:1086f00001000224070062100000000008000224ac
+:108700001400c2a3080002248c8182a3e60000109a
+:10871000000000003000c28f03004388000043982f
+:10872000211060001800c2af1800c28ffe014390f4
+:108730005500022490006214000000001800c28f4f
+:10874000ff014390aa0002248b0062140000000085
+:108750003000c28f0300438800004398211060005e
+:1087600021204000360005247a33400f000000002d
+:1087700021184000460002243a0062140000000064
+:108780003000c28f0300438800004398211060002e
+:1087900021204000370005247a33400f00000000fc
+:1087a00021184000410002242e0062140000000045
+:1087b0003000c28f030043880000439821106000fe
+:1087c00021204000380005247a33400f00000000cb
+:1087d000211840005400022422006214000000000e
+:1087e0003000c28f030043880000439821106000ce
+:1087f00021204000390005247a33400f000000009a
+:10880000211840003100022416006214000000000c
+:108810003000c28f0300438800004398211060009d
+:1088200021204000260005247a33400f000000007c
+:1088300021184000290002240a00621400000000f0
+:108840003000c28f070040a8040040b83000c38f3a
+:10885000020002241e0062a01c00c0af94000010a1
+:10886000000000003000c28f0300438800004398de
+:108870002110600021204000520005247a33400f6f
+:108880000000000021184000460002243a00621453
+:10889000000000003000c28f0300438800004398ae
+:1088a0002110600021204000530005247a33400f3e
+:1088b0000000000021184000410002242e00621434
+:1088c000000000003000c28f03004388000043987e
+:1088d0002110600021204000540005247a33400f0d
+:1088e00000000000211840005400022422006214fd
+:1088f000000000003000c28f03004388000043984e
+:108900002110600021204000550005247a33400fdb
+:1089100000000000211840003300022416006214f9
+:10892000000000003000c28f03004388000043981d
+:108930002110600021204000420005247a33400fbe
+:108940000000000021184000290002240a006214df
+:10895000000000003000c28f070040a8040040b8ab
+:108960003000c38f030002241e0062a01c00c0afb1
+:108970004f000010000000003000c28f0300438849
+:1089800000004398211060001000c2af1000c28f99
+:10899000fe0143905500022408006214000000000c
+:1089a0001000c28fff014390aa000224030062144a
+:1089b0000000000007000010000000000400022476
+:1089c0008c8182a3040002241400c2a3360000108c
+:1089d000000000003000c38f1000c28fc90144881e
+:1089e000c601449821108000070062a8040062b804
+:1089f0001000c28fc20142901500c2a31500c2939d
+:108a00002000c2af2000c38f0f00622c2200401054
+:108a100000000000010002242000c38f0410620047
+:108a20002400c2af2400c38f5040623010004014b5
+:108a3000000000002400c38f0018623011004014b1
+:108a4000000000002400c38f0200623003004014c5
+:108a50000000000010000010000000003000c38f74
+:108a6000010002241e0062a00f00001000000000a0
+:108a70003000c38f020002241e0062a00a00001012
+:108a8000000000003000c38f030002241e0062a01b
+:108a90000500001000000000050002248c8182a364
+:108aa000050002241400c2a31400c2931c00c2af2c
+:108ab0001c00c28f21e8c0032c00bf8f2800be8f8e
+:108ac0003000bd270800e00300000000c0ffbd2704
+:108ad0003800bfaf3400beaf3000b0af21f0a0030c
+:108ae0004000c4af1c00c0a34000c28f07004388f1
+:108af00021206000040044984000c28f0300438896
+:108b0000000043982110600021284000d349400f05
+:108b1000000000002118400001000224070062103c
+:108b200000000000080002248c8182a308000224b7
+:108b30001c00c2a344010010000000004000c28fce
+:108b40000300438800004398211060002000c2af5a
+:108b50002000c28ffe0143905500022408006214d9
+:108b6000000000002000c28fff014390aa000224f1
+:108b70000300621400000000070000100000000065
+:108b8000030002248c8182a3030002241c00c2a3e0
+:108b90002d010010000000004000c28f0300438838
+:108ba0000000439821106000212040000e000524a1
+:108bb0008933400f000000002600c2a74000d08f7c
+:108bc0004000c28f030043880000439821106000da
+:108bd000212040000d0005247a33400f00000000e2
+:108be0001d0002a24000c48f4000c28f07004388ce
+:108bf000040043982600c297211062000b0082a84f
+:108c0000080082b84000d08f4000c28f0300438824
+:108c1000000043982110600021204000100005242e
+:108c20007a33400f000000001c0002a24000d08fe9
+:108c30004000c28f03004388000043982110600069
+:108c400021204000160005248933400f0000000059
+:108c500021284000ff00a4301a0002920000423098
+:108c60002118400021108000251062001a0002a285
+:108c700002120500ffff44301b0002920000423048
+:108c80002118400021108000251062001b0002a264
+:108c90004000c28f1a0043901b0042900012020055
+:108ca00025104300ffff42301c004014000000006c
+:108cb0004000d08f4000c28f0300438800004398db
+:108cc000211060002120400024000524a833400f1b
+:108cd0000000000021284000ffffa230ff004430c8
+:108ce0001a0002920000423021184000211080003a
+:108cf000251062001a0002a2ffffa2300212020039
+:108d0000ffff44301b000292000042302118400057
+:108d100021108000251062001b0002a24000c48fb9
+:108d20004000c28f0b00438821286000080045984e
+:108d30004000c28f1c0046904000c28f1a00439032
+:108d40001b0042900012020025104300ffff42303a
+:108d50000210c2702110a2000f0082a80c0082b87d
+:108d60004000d08f4000c28f03004388000043982a
+:108d70002110600021204000110005248933400f9c
+:108d80000000000021284000ff00a43014000292df
+:108d900000004230211840002110800025106200a0
+:108da000140002a202120500ffff443015000292d7
+:108db0000000423021184000211080002510620080
+:108dc000150002a24000c28f0300438800004398b0
+:108dd0002110600021204000130005248933400f3a
+:108de000000000001400c2af1400c28f0a0040143b
+:108df000000000004000c28f030043880000439839
+:108e0000211060002120400020000524a833400fdd
+:108e1000000000001400c2af4000c28f030043886e
+:108e20000000439821106000212040000b00052421
+:108e30008933400f000000002400c2a72400c2971d
+:108e400007004010000000002400c29701004230db
+:108e500003004014000000000700001000000000a4
+:108e6000030002248c8182a3030002242800c2afe5
+:108e700077000010000000004000c28f14004390f3
+:108e8000150042900012020025104300ffff4230ff
+:108e9000401902002400c29721106200ffff432402
+:108ea0002400c2971a006200f40140001210000072
+:108eb0001000c2af2600c4974000c28f1c0045902e
+:108ec0004000c28f1a0043901b0042900012020023
+:108ed00025104300ffff42300210a27021188200cb
+:108ee0001000c28f211862001400c28f23104300ab
+:108ef0001800c2af4000c38f4000c28f1d004490d5
+:108f00001800c28f1b004400f40180001210000002
+:108f1000190062a8160062b84000c28f1900438889
+:108f20001600439821106000f50f422c06004010f7
+:108f3000000000004000c38f010002241e0062a058
+:108f400010000010000000004000c28f190043888c
+:108f500016004398f4ff02342b104300060040141f
+:108f6000000000004000c38f020002241e0062a027
+:108f700004000010000000004000c38f0300022422
+:108f80001e0062a04000c28f1e0043900300022416
+:108f900014006214000000004000c28f03004388e8
+:108fa0000000439821106000212040002c0005247f
+:108fb000a833400f000000007c8182af4000c48fc6
+:108fc0004000c28f0f0043880c0043981000c28fee
+:108fd00021106200130082a8100082b81200001055
+:108fe000000000007c8180af4000c48f4000c28f31
+:108ff0000f004388212860000c0045984000c28f74
+:109000001400439015004290001202002510430006
+:10901000ffff423002110200ffff42302110a20088
+:10902000130082a8100082b82400c3970002022413
+:109030000500621000000000030002241c00c2a30f
+:10904000030002248c8182a31c00c2932800c2afbb
+:109050002800c28f21e8c0033800bf8f3400be8fc4
+:109060003000b08f4000bd270800e0030000000082
+:10907000f0ffbd270800beaf21f0a0031000c4af71
+:109080000000c0af1000c28f140042940000c2afb5
+:109090000000c28f001402000000c2af1000c28f97
+:1090a0001a0043940000c28f251043000000c2af95
+:1090b0000000c28f21e8c0030800be8f1000bd274a
+:1090c0000800e00300000000d8ffbd272400bfaf68
+:1090d0002000beaf21f0a0032800c4af2c00c5af14
+:1090e0001400c0af2800c28f07004010000000002d
+:1090f0002c00c28f0200422c03004014000000002c
+:109100000500001000000000ffff02241c00c2af99
+:10911000f6000010000000002c00c28fffff432467
+:109120002800c28f2b1062000500401000000000d4
+:10913000ffff02241c00c2afec0000100000000082
+:109140006c80829309004010000000009235400faf
+:10915000000000000500401000000000ffff022496
+:109160001c00c2afe10000100000000000a0023ca3
+:109170009c0444242128000000020624096b400faf
+:109180000000000000a0023c9c0442241000c2af7a
+:109190002800c28f1800c2af1800c48f1505023c0a
+:1091a0005b5642341900820010180000231083001f
+:1091b00042100200211062004213020080130200dc
+:1091c0001400c2af1800c58f1505023c5b5642342f
+:1091d0001900a200101800002310a3004210020082
+:1091e0002110620042230200211080008019020039
+:1091f0002318640000120300231043002310a20070
+:109200001800c2af1800c48f1004023c054142345c
+:109210001900820010180000231083004210020081
+:109220002110620042110200801902001400c28f56
+:10923000251043001400c2af1800c48f1004023c74
+:1092400005414234190082001018000023108300e9
+:109250004210020021106200421902002110600039
+:109260008011020023104300231082001800c2afb7
+:109270001800c28f010043241400c28f2510430040
+:109280001400c2af00a0023c9c0443241400c28f0f
+:1092900002140200bf0162a000a0023c9c0443240f
+:1092a0001400c28f02120200c00162a000a0023ca2
+:1092b0009c0443241400c28fc10162a01000c28f1d
+:1092c0002c00c48f2800c38f23188300cd0143a82e
+:1092d000ca0143b81000c28fcd014388ca01439828
+:1092e000211060003910422c0600401000000000e0
+:1092f0001000c38f01000224c20162a012000010fe
+:10930000000000001000c28fcd014388ca014398bd
+:109310003f00023c5ffd42342b1043000600401426
+:10932000000000001000c38f06000224c20162a0ea
+:109330000500001000000000ffff02241c00c2af67
+:109340006a000010000000001000c28f2800c38fc8
+:10935000c90143a8c60143b82800c38f2c00c28f9f
+:1093600021106200ffff42241800c2af1800c48f12
+:109370001505023c5b5642341900820010180000ab
+:1093800023108300421002002110620042130200e9
+:10939000801302001400c2af1800c58f1505023cef
+:1093a0005b5642341900a200101800002310a300dd
+:1093b00042100200211062004223020021108000ae
+:1093c00080190200231864000012030023104300d8
+:1093d0002310a2001800c2af1800c48f1004023c72
+:1093e0000541423419008200101800002310830048
+:1093f0004210020021106200421102008019020096
+:109400001400c28f251043001400c2af1800c48f8f
+:109410001004023c0541423419008200101800007b
+:109420002310830042100200211062004219020042
+:1094300021106000801102002310430023108200dd
+:109440001800c2af1800c28f010043241400c28f5d
+:10945000251043001400c2af00a0023c9c0443242a
+:109460001400c28f02140200c30162a000a0023cdb
+:109470009c0443241400c28f02120200c40162a0a3
+:1094800000a0023c9c0443241400c28fc50162a0ca
+:109490001000c28fbe0140a01000c38f55000224ef
+:1094a000fe0162a01000c38faaff0224ff0162a088
+:1094b0002120000000a0023c9c0445240100062459
+:1094c0005b4a400f00000000211840000100022408
+:1094d0000500621000000000ffff02241c00c2af64
+:1094e00002000010000000001c00c0af1c00c28f72
+:1094f00021e8c0032400bf8f2000be8f2800bd27b5
+:109500000800e0030000000070ffbd278c00bfaf23
+:109510008800beaf21f0a003211080009400c5afe9
+:109520009800c6af9000c2a32800c2274800c2af6f
+:109530008c8180a34800c28f00a0033c9c0463245c
+:10954000030043a8000043b8e748400f00000000b4
+:10955000654b400f0000000021184000010002246c
+:109560000700621000000000060002248c8182a324
+:10957000ffff02245c00c2afd8030010000000000f
+:109580002120000000a0023c9c044524d349400f48
+:109590000000000007004014000000001b0002242f
+:1095a0008c8182a3ffff03245c00c3afcb030010b8
+:1095b000000000004800c28f030043880000439869
+:1095c000211060002000c2af2000c28ffe01439036
+:1095d000550002246b006214000000002000c28fbe
+:1095e000ff014390aa0002246600621400000000fc
+:1095f0004800c28f03004388000043982110600098
+:1096000021204000360005247a33400f000000007e
+:10961000211840004600022450006214000000009f
+:109620004800c28f03004388000043982110600067
+:1096300021204000370005247a33400f000000004d
+:109640002118400041000224440062140000000080
+:109650004800c28f03004388000043982110600037
+:1096600021204000380005247a33400f000000001c
+:109670002118400054000224380062140000000049
+:109680004800c28f03004388000043982110600007
+:1096900021204000390005247a33400f00000000eb
+:1096a00021184000310002242c0062140000000048
+:1096b0004800c28f030043880000439821106000d7
+:1096c00021204000260005247a33400f00000000ce
+:1096d000211840002900022420006214000000002c
+:1096e0009000c2836000c2af6000c38f0d006010a5
+:1096f00000000000010002246000c38f030062101c
+:10970000000000001f000010000000001f000224e5
+:109710008c8182a3ffff02245c00c2af6f030010a4
+:10972000000000004800c28f070040a8040040b8b5
+:109730004800c48fb322400f000000001100401009
+:10974000000000001b0002248c8182a3ffff032481
+:109750005c00c3af610300100000000000a0023ce9
+:109760009c0442241000c2af4800c38f1000c28f77
+:10977000c9014488c601449821108000070062a8ee
+:10978000040062b89000c2837c00c2af7c00c38f2b
+:109790003302601000000000010002247c00c38f2f
+:1097a00003006210000000003802001000000000fa
+:1097b0001000c28fcd014388ca0143982110600078
+:1097c0001400c2af1400c28f3910422c2d0040107b
+:1097d000000000004800c38f010002241e0062a0a8
+:1097e0001000c38f01000224c20162a021200000ea
+:1097f00000a0023c9c044524010006245b4a400f63
+:1098000000000000070040140000000009000224ce
+:109810008c8182a3ffff02245c00c2af2f030010e3
+:10982000000000001400c28f2810422c06004014d3
+:10983000000000004800c38f020002241d0062a047
+:1098400004000010000000004800c38f0100022443
+:109850001d0062a000a0023c9c04442421280000ba
+:1098600000020624096b400f0000000000a0023c2b
+:109870009c044324320002243a0062a04d000010f0
+:10988000000000001400c38f3f00023c5ffd423423
+:109890002b10430041004014000000004800c38f1b
+:1098a000020002241e0062a01000c38f06000224e2
+:1098b000c20162a02120000000a0023c9c044524bb
+:1098c000010006245b4a400f00000000070040141e
+:1098d00000000000090002248c8182a3ffff032402
+:1098e0005c00c3affd020010000000001400c28f36
+:1098f000e8fd42241800c2af4800c38f01000224d3
+:109900001d0062a01800c28fedff03342b1062000f
+:109910000b004010000000004800c38f4800c28fb9
+:109920001d004290401002001d0062a01800c28f6e
+:10993000421002001800c2aff2ff00100000000049
+:109940004800c28f1d0042908100422c0700401445
+:1099500000000000040002248c8182a3ffff022487
+:109960005c00c2afdd0200100000000000a0023c5d
+:109970009c0444242128000000020624096b400fa7
+:109980000000000000a0023c9c0443243600022496
+:109990003a0062a007000010000000001700022437
+:1099a0008c8182a3ffff03245c00c3afcb020010b5
+:1099b000000000004800c28f1d00429040180200c5
+:1099c0001400c28f21106200dfff42245000c2af9a
+:1099d0004800c28f1e004390010002240900621457
+:1099e000000000004800c28f1d0043905501022472
+:1099f00002106270020042245400c2af0600001040
+:109a0000000000004800c28f1d00429000120200ba
+:109a1000020042245400c2af5400c38f5000c28fd2
+:109a200021106200ffff43245400c28f1b0062001c
+:109a3000f4014000121000005000c2af00a0033c2f
+:109a4000ebff02249c0462a000a0023c9c0443247f
+:109a50003c000224010062a000a0023c9c044324bc
+:109a600090ff0224020062a000a0023c9c04432458
+:109a70004d000224030062a000a0023c9c04432489
+:109a800043000224040062a000a0023c9c04432482
+:109a900048000224050062a000a0023c9c0443246c
+:109aa00050000224060062a000a0023c9c04432453
+:109ab00020000224070062a000a0023c9c04432472
+:109ac00046000224080062a000a0023c9c0443243b
+:109ad00041000224090062a000a0023c9c0443242f
+:109ae000540002240a0062a000a0023c9c0442240c
+:109af0000b0040a000a0023c9c044324020002246e
+:109b00000c0062a000a0023c9c0443244800c28fc9
+:109b10001d0042900d0062a000a0023c9c04432462
+:109b2000080002240e0062a000a0023c9c04422413
+:109b30000f0040a04800c38f4800c28f0700448830
+:109b40000400449821108000080042240b0062a801
+:109b5000080062b800a0023c9c04432402000224d6
+:109b6000100062a04800c38f020002241c0062a003
+:109b700000a0023c9c044224110040a000a0023c32
+:109b80009c04432402000224120062a04800c38ff8
+:109b90001400629000004230140062a01500629030
+:109ba0000000423002004234150062a000a0023cd6
+:109bb0009c044224130040a000a0023c9c044224c8
+:109bc000140040a000a0023c9c044324f8ff02249f
+:109bd000150062a000a0023c9c0443245000c28fe8
+:109be000160062a000a0023c9c0443245000c28fd7
+:109bf00002120200170062a04800c48f5000c68ff6
+:109c0000ffffc230ff0045301a0082900000423052
+:109c1000211840002110a000251062001a0082a027
+:109c2000ffffc23002120200ffff45301b0082908e
+:109c300000004230211840002110a00025106200d1
+:109c40001b0082a000a0023c9c0443243f0002248d
+:109c5000180062a000a0023c9c044224190040a00d
+:109c600000a0023c9c044324ffff02241a0062a0cf
+:109c700000a0023c9c0442241b0040a000a0023c27
+:109c80009c0444244800c28f070043880400439882
+:109c9000211060001c0082a000a0023c9c0444240f
+:109ca0004800c28f070043880400439821106000d9
+:109cb000021202001d0082a000a0023c9c04442469
+:109cc0004800c28f070043880400439821106000b9
+:109cd000021402001e0082a000a0023c9c04442446
+:109ce0004800c28f07004388040043982110600099
+:109cf000021602001f0082a000a0023c9c04432424
+:109d00001400c28f200062a000a0023c9c044324e7
+:109d10001400c28f02120200210062a000a0023cc7
+:109d20009c0443241400c28f02140200220062a08b
+:109d300000a0023c9c0443241400c28f02160200bf
+:109d4000230062a000a0023c9c044224240040a006
+:109d500000a0023c9c044224250040a000a0023c3c
+:109d60009c04432429000224260062a000a0023c97
+:109d70009c0444249400c28fffff0324241043005a
+:109d8000270082a000a0023c9c0442246400c2afd1
+:109d90009400c28f6800c2af6800c28f0400410403
+:109da000000000006800c38fff0063246800c3af99
+:109db0006800c38f03120300ffff03242410430035
+:109dc0006400c38f280062a000a0023c9c044224cf
+:109dd0006c00c2af9400c28f7000c2af7000c28f1f
+:109de0000500410400000000ffff02347000c38f33
+:109df000211862007000c3af7000c38f031403000a
+:109e0000ffff0324241043006c00c38f290062a0cd
+:109e100000a0023c9c0442247400c2af9400c28f94
+:109e20007800c2af7800c28f060041040000000035
+:109e3000ff00023cffff42347800c38f211862000c
+:109e40007800c3af7800c38f03160300ffff03241d
+:109e5000241043007400c38f2a0062a09800c28fb0
+:109e600029004010000000005800c0a35800c39310
+:109e70009800c28f21106200000042801300401041
+:109e8000000000005800c2930b00422c0f0040104d
+:109e90000000000000a0023c5800c3939c04422430
+:109ea000212062005800c3939800c28f21106200e5
+:109eb000000042902b0082a05800c293010042246f
+:109ec0005800c2a3e9ff0010000000005800c29330
+:109ed0000b00422c1b0040100000000000a0043cbe
+:109ee0005800c393010062245800c2a3ff006330ee
+:109ef0009c04822421186200200002242b0062a00e
+:109f0000f2ff0010000000005800c0a35800c293e8
+:109f10000b00422c0b0040100000000000a0023c8f
+:109f20005800c3939c044224211062002b0040a0df
+:109f30005800c293010042245800c2a3f3ff00104e
+:109f40000000000000a0023c9c04432446000224c0
+:109f5000360062a000a0023c9c044324410002247d
+:109f6000370062a000a0023c9c0443245400022459
+:109f7000380062a000a0023c9c044324310002246b
+:109f8000390062a000a0023c9c044324200002246b
+:109f90003b0062a000a0023c9c0443242000022459
+:109fa0003c0062a000a0023c9c0443242000022448
+:109fb0003d0062a000a0023c9c0443245500022402
+:109fc000fe0162a000a0023c9c044324aaff0224dc
+:109fd000ff0162a04800c48f4800c28f0b00438875
+:109fe00021286000080045984800c28f1c00469058
+:109ff0004800c28f1a0043901b00429000120200da
+:10a0000025104300ffff42300210c2702110a20051
+:10a010000f0082a80c0082b84800c28f0700438856
+:10a0200004004398211060002120400000a0023c61
+:10a030009c044524213000005b4a400f00000000d2
+:10a040001800401400000000090002248c8182a343
+:10a05000ffff02245c00c2af2001001000000000de
+:10a060004800c48fb322400f000000000d004010d4
+:10a07000000000001b0002248c8182a3ffff032448
+:10a080005c00c3af15010010000000001f00022497
+:10a090008c8182a3ffff02245c00c2af0f0100107d
+:10a0a0000000000000a0023c9c0444242128000081
+:10a0b00000020624096b400f0000000000a0033cd2
+:10a0c000f8ff02249c0462a000a0023c9c044324ec
+:10a0d000ffff0224010062a000a0023c9c04432474
+:10a0e000ffff0224020062a04800c28f1e004390be
+:10a0f00002000224050062140000000000a0023cdf
+:10a100009c044324ffff0224030062a04800c28f86
+:10a110001c004290ffff42244c00c2a74c00c39792
+:10a12000ffff02341f006210000000004800c28fd1
+:10a130000b00438821206000080044984c00c5971c
+:10a140004800c28f1a0043901b0042900012020088
+:10a1500025104300ffff42300210a2702110820040
+:10a160002120400000a0023c9c0445242130000036
+:10a170005b4a400f00000000050040140000000092
+:10a18000ffff02245c00c2afd400001000000000fa
+:10a190004c00c297ffff42244c00c2a7dfff001013
+:10a1a0000000000000a0023c9c0444242128000080
+:10a1b00004000624096b400f000000004800c28f15
+:10a1c0000b004388080043982110600001004224de
+:10a1d0005800c2a35800c5934800c28f0b004388a3
+:10a1e00021206000080044984800c28f1a00439064
+:10a1f0001b0042900012020025104300ffff423076
+:10a20000211082002b10a200290040100000000045
+:10a210004800c28f1c004290ffff42244c00c2a79e
+:10a220004c00c397ffff02341c00621000000000c6
+:10a230005800c4934c00c5974800c28f1a00439041
+:10a240001b0042900012020025104300ffff423025
+:10a250000210a270211082002120400000a0023cc8
+:10a260009c044524213000005b4a400f00000000a0
+:10a270000500401400000000ffff02245c00c2af94
+:10a2800096000010000000004c00c297ffff42241f
+:10a290004c00c2a7e2ff0010000000005800c2936b
+:10a2a000010042245800c2a3caff001000000000b1
+:10a2b0004800c28f14004390150042900012020023
+:10a2c00025104300ffff423040110200ff014224ed
+:10a2d0008000c2af8000c38f040061040000000052
+:10a2e0008000c28fff0142248000c2af8000c38f74
+:10a2f000431203001c00c2af010002245800c2a395
+:10a300005800c2931c00c38f2b104300170040104d
+:10a31000000000004800c28f0f0043880c004398e3
+:10a320005800c293211062002120400000a0023c8e
+:10a330009c044524213000005b4a400f00000000cf
+:10a340000500401400000000ffff02245c00c2afc3
+:10a3500062000010000000005800c2930100422477
+:10a360005800c2a3e6ff0010000000009800c28f52
+:10a3700049004010000000005800c0a35800c393db
+:10a380009800c28f2110620000004280130040102c
+:10a39000000000005800c2930b00422c0f00401038
+:10a3a0000000000000a0023c5800c3939c0442241b
+:10a3b000212062005800c3939800c28f21106200d0
+:10a3c00000004290000082a05800c2930100422485
+:10a3d0005800c2a3e9ff0010000000005800c2931b
+:10a3e0000b00422c0c0040100000000000a0043cb8
+:10a3f0005800c393010062245800c2a3ff006330d9
+:10a400009c0482242118620020000224000062a023
+:10a41000f2ff00100000000000a0023c9c04432456
+:10a42000080002240b0062a000a0023c9c0443240c
+:10a4300011000224110062a000a0023c9c044324ed
+:10a4400011000224130062a000a0023c9c044324db
+:10a4500011000224170062a04800c28f0f00438839
+:10a460000c004398211060002120400000a0023c15
+:10a470009c044524213000005b4a400f000000008e
+:10a480001500401400000000ffff03245c00c3af70
+:10a4900012000010000000004800c28f0f00438827
+:10a4a0000c004398211060002120400000a0023cd5
+:10a4b0009c044524213000005b4a400f000000004e
+:10a4c0000500401400000000ffff02245c00c2af42
+:10a4d00002000010000000005c00c0af5c00c28ff2
+:10a4e00021e8c0038c00bf8f8800be8f9000bd277d
+:10a4f0000800e00300000000d0ffbd272c00bfaf24
+:10a500002800beaf21f0a0033000c4af3400c5afb7
+:10a510003000c28f0000428c1000c2af3000c28fea
+:10a520003800428c1c00c2af3400c28f000042943d
+:10a53000021102001500c2a31000c28f1e0042903b
+:10a540002000c2af2000c38f010062281f0040140a
+:10a55000000000002000c38f030062281000401498
+:10a5600000000000030002242000c38f03006210db
+:10a570000000000015000010000000001000c28f55
+:10a580001500c3931d0042901b006200f4014000bf
+:10a59000101000001500c2a30c0000100000000005
+:10a5a0001c00c38f7c81828f0800621000000000b5
+:10a5b0001000c28f1500c3931d0042901b00620063
+:10a5c000f4014000101000001500c2a31000c48f59
+:10a5d0001c00c58fcd33400f000000001800c2af33
+:10a5e0001500c3931800c28f212062001000c28f93
+:10a5f0000300438800004398211060002128400098
+:10a60000213000005b4a400f0000000004004014ad
+:10a61000000000001400c0a30300001000000000b0
+:10a62000010002241400c2a31400c29321e8c00355
+:10a630002c00bf8f2800be8f3000bd270800e0032c
+:10a6400000000000d0ffbd272c00bfaf2800beaf28
+:10a6500021f0a0033000c4af3400c5af1c00c0af70
+:10a660003400c28f1e0042902400c2af02000224b8
+:10a670002400c38f19006210000000002400c38f63
+:10a6800003006228070040100000000001000224bf
+:10a690002400c38f17006210000000001900001092
+:10a6a00000000000030002242400c38f0300621096
+:10a6b000000000001300001000000000ff0f023c2b
+:10a6c000ffff42341800c2afff0f023cf8ff4234d4
+:10a6d0001400c2af0b00001000000000ffff0234a6
+:10a6e0001800c2aff8ff02341400c2af050000101a
+:10a6f00000000000ffff02341800c2aff80f022470
+:10a700001400c2af3000c28f0700401000000000ec
+:10a710003000c38f0100022403006210000000001b
+:10a720000500001000000000020002241c00c2af5f
+:10a7300035000010000000001c00c28f32004014e1
+:10a74000000000003400c48f3000c58f8c39400fea
+:10a75000000000001000c2af1000c38f1800c28fad
+:10a760000500621400000000010002241c00c2afba
+:10a77000f1ff0010000000001000c28f0700401021
+:10a78000000000001000c38f0100022403006210cb
+:10a79000000000000500001000000000020002247c
+:10a7a0001c00c2afe4ff0010000000001000c28fc8
+:10a7b0001400c38f2b10430003004014000000005e
+:10a7c000020002241c00c2af3400c48f3000c58fc9
+:10a7d0002130000021380000af3a400f0000000097
+:10a7e000211840001800c28f03006214000000000e
+:10a7f000010002241c00c2af1000c28f3000c2afa3
+:10a80000cdff0010000000003400c48f212800009c
+:10a810002130000001000724af3a400f0000000083
+:10a820001c00c38f02000224050062140000000017
+:10a83000010002242000c2af02000010000000004e
+:10a840002000c0af2000c28f21e8c0032c00bf8fc2
+:10a850002800be8f3000bd270800e0030000000084
+:10a86000c0ffbd273c00bfaf3800beaf21f0a00342
+:10a870004000c4af4400c5af2110c0004800c2a3cf
+:10a880004000c28f0000428c1400c2af4000c28f53
+:10a890003400428c1c00c2af4000c28f3800428c92
+:10a8a0002400c2af4400c28f000042940211020093
+:10a8b0002800c2a31400c28f1e0042903000c2af15
+:10a8c0003000c38f01006228230040140000000004
+:10a8d0003000c38f03006228130040140000000002
+:10a8e000030002243000c38f030062100000000048
+:10a8f00019000010000000001400c28f2800c3934c
+:10a900001d0042901b006200f40140001010000086
+:10a910002800c2a3ff0f023cf8ff42342000c2af60
+:10a920000d000010000000001c00c28f0800401045
+:10a93000000000001400c28f2800c3931d00429045
+:10a940001b006200f4014000101000002800c2a3a8
+:10a95000f8ff02342000c2af4800c2930600401442
+:10a96000000000004400c28f000042940f004230fb
+:10a9700096004014000000002800c2930600401416
+:10a98000000000004400c28f000042941000422cde
+:10a9900006004010000000004800c293030040146d
+:10a9a000000000002c000010000000001c00c28ffe
+:10a9b00004004014000000002400c0af2600001076
+:10a9c000000000004800c2930d004010000000008d
+:10a9d0004400c38f1400c28f1d004290001102007a
+:10a9e00000006394ffff42301b006200f40140004e
+:10a9f000121000002900c2a3030000100000000094
+:10aa0000010002242900c2a32900c29312004010b1
+:10aa1000000000001400c48f2400c58f8c39400f43
+:10aa2000000000002400c2af2400c38f2000c28faa
+:10aa30002b1062000300401400000000060000100c
+:10aa4000000000002900c293ffff42242900c2a396
+:10aa5000edff0010000000002400c28f2000c38f13
+:10aa60002b10430054004010000000004000c38f32
+:10aa70002400c28f380062ac1400c48f2400c58f3c
+:10aa8000cd33400f000000001800c2af2400c38f78
+:10aa90007c81828f13006214000000002800c393a1
+:10aaa0001800c28f212062001400c28f1300438857
+:10aab00010004398211060002b1082000900401400
+:10aac000000000001400c28f1e0043900300022407
+:10aad00004006210000000001000c0af450000102c
+:10aae000000000006c80829308004010000000000d
+:10aaf0009235400f000000000400401000000000ec
+:10ab00002c00c0af3d00001000000000688080af46
+:10ab10006e8080a32800c3931800c28f212062009a
+:10ab20001400c28f03004388000043982110600086
+:10ab300021284000d349400f0000000021184000a8
+:10ab40000100022404006210000000001000c0afe9
+:10ab500015000010000000004800c2930d004010d6
+:10ab6000000000001400c28f0300438800004398d7
+:10ab70004400c28f000042940f004230ffff423079
+:10ab800040110200211062001000c2af0600001048
+:10ab9000000000001400c28f0300438800004398a7
+:10aba000211060001000c2afffff0224148082afaa
+:10abb0001000001000000000010002246d8082a33c
+:10abc0001000c0af0b000010000000001400c28f86
+:10abd00003004388000043984400c28f0000429461
+:10abe0000f004230ffff423040110200211062008e
+:10abf0001000c2af1000c28f2c00c2af2c00c28f59
+:10ac000021e8c0033c00bf8f3800be8f4000bd2745
+:10ac10000800e00300000000d0ffbd272c00bfaffc
+:10ac20002800beaf21f0a0033000c4af3400c5af90
+:10ac30002110c0003800c2a31400c0af8c8180a3d3
+:10ac40001000c0a31000c2930b00422c0e00401055
+:10ac5000000000001000c3931000c22721206200f2
+:10ac60003000c38f1000c293211062002000429078
+:10ac7000080082a01000c293010042241000c2a369
+:10ac8000f0ff0010000000003400c28f000040a45c
+:10ac90003000c48f3400c58f7d2b400f00000000b2
+:10aca00013004010000000001800c2273800c393b2
+:10acb0003000c48f212840003400c68f2138600046
+:10acc000182c400f000000001400c2af1400c28f07
+:10acd00009004014000000003000c48f472b400fd3
+:10ace000000000001400c2af0300001000000000cc
+:10acf000140002241400c2af1400c28f8c8182a3fe
+:10ad00001400c28f21e8c0032c00bf8f2800be8f23
+:10ad10003000bd270800e00300000000d0ffbd2781
+:10ad20002c00bfaf2800beaf21f0a0033000c4af9d
+:10ad30003000c28f2c0042941c00c2a71400c2270e
+:10ad40003000c48f21284000ca32400f00000000ac
+:10ad50001000c2af1000c28f1f004014000000009e
+:10ad60001c00c2273000c48f21284000b72e400f9e
+:10ad7000000000002000c2af2000c38f1400c28f6b
+:10ad80001a0062a41400c38fff0f023c241062005b
+:10ad90001800c2af1800c28f021402001800c2af20
+:10ada0002000c38f1800c28f140062a41c00c227a9
+:10adb0003000c48f212840003e29400f00000000d1
+:10adc000211840000100022403006210000000006e
+:10add000090002241000c2af1000c28f21e8c00396
+:10ade0002c00bf8f2800be8f3000bd270800e00375
+:10adf00000000000d0ffbd272c00bfaf2800beaf71
+:10ae000021f0a0033000c4af3400c5af010002241c
+:10ae10001000c2a33000c38f3000c28f3400428cb8
+:10ae2000380062ac3000c48f3400c58f01000624a6
+:10ae3000182a400f000000001c00c2af1c00c28f87
+:10ae400005004014000000001b0002241000c2a3f3
+:10ae500074000010000000001000c39301000224e1
+:10ae60006d006214000000001100c0a33400c28f06
+:10ae7000000042941400c2a73000c48f3400c58f74
+:10ae800021300000182a400f000000001c00c2af53
+:10ae90001c00c28f000042901200c2a33400c38f76
+:10aea0003400c28f0000429401004224000062a4da
+:10aeb0001200c393e50002240400621000000000a9
+:10aec0001200c2930c004014000000001c00c28f4e
+:10aed00009004010000000001100c293010042244c
+:10aee0001100c2a3ff004230030040140000000024
+:10aef000e1ff0010000000001c00c28f3c00401465
+:10af0000000000003000c28f3800428c1800c2af31
+:10af10001800c38f7c81828f200062140000000023
+:10af20003000c28f0000428c1e00439003000224b8
+:10af30000500621000000000020002241000c2a3fd
+:10af4000c5ff0010000000003000c38f1800c28f42
+:10af5000080062ac3000c48f01000524be2c400ff5
+:10af600000000000211840001500022405006214b2
+:10af700000000000020002241000c2a3b6ff00106f
+:10af8000000000003400c38f1400c297000062a4c8
+:10af90001000c0a3b0ff0010000000003000c38ffd
+:10afa0001800c28f080062ac3000c48f0100052475
+:10afb000be2c400f000000002118400015000224a4
+:10afc0000500621400000000020002241000c2a369
+:10afd000a1ff0010000000003400c38f1400c297ce
+:10afe000000062a41000c0a39bff0010000000003e
+:10aff0001100c3930100022497ff621400000000b7
+:10b000001000c0a33400c38f1400c297000062a4d4
+:10b0100091ff0010000000003400c38f1400c2979d
+:10b02000000062a41000c29305004014000000005c
+:10b03000010002242000c2af020000100000000046
+:10b040002000c0af2000c28f21e8c0032c00bf8fba
+:10b050002800be8f3000bd270800e003000000007c
+:10b06000d8ffbd272400bfaf2000beaf21f0a00352
+:10b070002800c4af2c00c5af3000c6af2110e000df
+:10b080003400c2a31000c0a32800c38f2800c28fc1
+:10b090003400428c380062ac2800c48f3000c58f69
+:10b0a00001000624182a400f000000001400c2af5f
+:10b0b0001400c28f05004014000000001b00022491
+:10b0c0001800c2af5a000010000000001400c48f26
+:10b0d0002c00c58f0b000624296c400f00000000d7
+:10b0e0003400c39312000224060062140000000022
+:10b0f0001400c38f100002240b0062a00400001093
+:10b10000000000001400c38f200002240b0062a086
+:10b110001400c28f0c0040a01400c28f140040a481
+:10b120001400c28f1a0040a41400c28f1c0040ac4f
+:10b13000932c400f000000001400c38f778182938e
+:10b140000d0062a01400c38f788182970e0062a464
+:10b150001400c38f82818297100062a43400c393cd
+:10b16000120002240c006210000000001400c38fc3
+:10b170008a818297120062a41400c38f8e81829705
+:10b18000160062a41400c38f80818297180062a405
+:10b1900007000010000000001400c28f120040a43d
+:10b1a0001400c28f160040a41400c28f180040a4df
+:10b1b0002800c38f1400c28f1c00428c140062aca4
+:10b1c0002800c38f1400c28f0e0042941c0062a49a
+:10b1d0002800c38f1400c28f100042941e0062a486
+:10b1e0002800c38f1400c28f0b004290300062a46d
+:10b1f0002800c38f3000c28f000042942c0062a44c
+:10b200002800c48f3000c58f3e29400f0000000089
+:10b210002118400001000224030062100000000019
+:10b22000090002241000c2a31000c2931800c2af8c
+:10b230001800c28f21e8c0032400bf8f2000be8ffa
+:10b240002800bd270800e00300000000e0ffbd2744
+:10b250001800beaf21f0a0030800deaf0400c22733
+:10b260000c00c2af80bf023c3002428c1400c2af5f
+:10b2700080bf023c2002428c1000c2af0800c38f86
+:10b2800080bf023c2002428c000062ac0c00c38fe5
+:10b2900080bf023c3002428c000062ac0c00c28fc6
+:10b2a0001400c38f0000428ceeff62140000000007
+:10b2b0000800c28f1000c38f0000428ce9ff6214a7
+:10b2c000000000000200c3970000c2972510620032
+:10b2d000788182a70600c3970000c29725106200fc
+:10b2e000808182a721e8c0031800be8f2000bd27ff
+:10b2f0000800e00300000000d8ffbd272400bfaf16
+:10b300002000beaf21f0a0032800c4af2110a00090
+:10b310002c00c2a32800c28f0000428c1000c2afd4
+:10b320002800c28f0800428c1400c2af2800c48fce
+:10b33000162d400f000000001400c2af1400c28f91
+:10b340000500401400000000150002241c00c2afdc
+:10b350003a000010000000001000c28f1e00439051
+:10b360000100022409006214000000001000c48fd4
+:10b370001400c58ff80f062421380000af3a400fa3
+:10b380000000000015000010000000001000c28f37
+:10b390001e00439002000224090062140000000015
+:10b3a0001000c48f1400c58ff8ff06342138000048
+:10b3b000af3a400f0000000008000010000000003d
+:10b3c0001000c48f1400c58fff0f023cf8ff4634f5
+:10b3d00021380000af3a400f000000002800c28f63
+:10b3e0000800428c1800c2af1000c48f1800c58f2f
+:10b3f0001400c68f21380000af3a400f0000000053
+:10b400002800c38f1400c28f080062ac2c00c393c5
+:10b410000100022408006214000000001000c48f24
+:10b420001400c58f2933400f000000001c00c2af7c
+:10b4300002000010000000001c00c0af1c00c28f02
+:10b4400021e8c0032400bf8f2000be8f2800bd2745
+:10b450000800e00300000000c8ffbd273400bfafb4
+:10b460003000beaf21f0a0033800c4af1400c0af5d
+:10b470003800c28f0000428c1000c2af3800c28f6b
+:10b480000800428c1800c2af1000c28f1e0042900c
+:10b490002800c2af020002242800c38f19006210e6
+:10b4a000000000002800c38f03006228070040103e
+:10b4b00000000000010002242800c38f1700621062
+:10b4c000000000001900001000000000030002242a
+:10b4d0002800c38f0300621000000000130000105a
+:10b4e00000000000ff0f023cf7ff42342000c2af13
+:10b4f000ff0f023cffff42342400c2af0b000010dc
+:10b5000000000000f7ff02342000c2afffff02344a
+:10b510002400c2af0500001000000000f70f022455
+:10b520002000c2afffff02342400c2af1800c28f58
+:10b530000200422c03004010000000000200022420
+:10b540001800c2af1800c28f1c00c2af1000c48f19
+:10b550001800c58f8c39400f000000001800c28f02
+:10b5600029004010000000001000c48f1800c58f93
+:10b570008c39400f000000001400c2af1400c38fcc
+:10b580002400c28f04006214000000001800c0af45
+:10b590001d000010000000001400c28f03004014c2
+:10b5a0000000000018000010000000001800c28f0a
+:10b5b000010042241800c2af1400c38f2000c28fc4
+:10b5c0000a006210000000001000c28f19004388ba
+:10b5d000160043981800c28f2b1043000300401040
+:10b5e0000000000003000010000000000200022420
+:10b5f0001800c2af1800c38f1c00c28fd7ff62149f
+:10b60000000000001800c0af1800c28f21e8c0037e
+:10b610003400bf8f3000be8f3800bd270800e00324
+:10b6200000000000d8ffbd272400bfaf2000beaf40
+:10b6300021f0a0032800c4af480002241400c2afc8
+:10b640008c8180a32800c28f2c0042941000c2a7d6
+:10b650002800c28f1800428c0000427c420040103b
+:10b66000000000006c8082930a004010000000007f
+:10b670009235400f0000000006004010000000005e
+:10b68000090002248c8182a3ffff022457000010ce
+:10b690001c00c2af2800c28f0000448c212800008b
+:10b6a00021300000af3a400f010007242800c48f6a
+:10b6b000b72e400f1000c5271800c2af1800c28f68
+:10b6c00008004014000000001b0002248c8182a3ab
+:10b6d000ffff02241400c2af1400c28f4300001009
+:10b6e0001c00c2af932c400f000000001800c38f55
+:10b6f0008e818297160062a41800c38f8081829782
+:10b70000180062a4000000001800c38f2800c28f38
+:10b710001400428c1c0062ac1800c38f2800c28f3a
+:10b72000300042940b0062a02800c48f3e29400fd5
+:10b730001000c527030040100000000005000010a5
+:10b740001400c0af090002248c8182a3ffff0224f1
+:10b750001400c2af2800c48f1800838cfeff02249f
+:10b7600024106200180082ac1200c0a71200c29719
+:10b770000300422c16004010000000001200c39786
+:10b780002110600000110200231043008018020005
+:10b7900000a0023c24094224211862002800c28f24
+:10b7a00007006214000000001200c3977481822712
+:10b7b000211862000100022405000010000062a0b0
+:10b7c0001200c29701004224e8ff00101200c2a735
+:10b7d0001400c38f4800022402006214000000001d
+:10b7e0001400c0af1400c28f1c00c2af1c00c28f77
+:10b7f00021e8c0032400bf8f2000be8f0800e003b3
+:10b800002800bd27d0ffbd272800bfaf2400beaf52
+:10b810002000b0af21f0a0033000c4af3400c5afaa
+:10b820001800c0a33400c28f000042940f004230c1
+:10b8300011004014000000003400c28f0000429448
+:10b840000d004010000000003000c38f3000c28f98
+:10b850003400428c380062ac3000c48f3400c58f95
+:10b8600001000624182a400f000000001000c2af9b
+:10b8700007000010000000003000c48f3400c58fa6
+:10b8800021300000182a400f000000001000c2af55
+:10b890001000c28f000042901500c2a31000c28f9a
+:10b8a00004004010000000001500c2930500401481
+:10b8b00000000000020002241700c2a37f00001055
+:10b8c000000000001500c393e50002240500621487
+:10b8d00000000000010002241700c2a3770000103e
+:10b8e000000000001000c28f0b0042901500c2a3a0
+:10b8f0001400c0a31400c2930800422c180040108a
+:10b90000000000001000c38f1400c29321104300f8
+:10b91000000042901600c2a31600c29321204000ee
+:10b92000b06c400f000000001600c2a33000c48fae
+:10b930001800c393010062241800c2a3ff00623004
+:10b94000211882001600c293200062a01400c29346
+:10b95000010042241400c2a3e6ff00100000000012
+:10b960001000c28f0b0042901500c2a31000c28fbe
+:10b97000080042901600c2a31400c0a31400c29392
+:10b980000300422c18004010000000001000c38f7c
+:10b990001400c29321106200080042901600c2a356
+:10b9a0001600c29321204000b06c400f0000000040
+:10b9b0001600c2a33000c48f1800c3930100622494
+:10b9c0001800c2a3ff006230211882001600c29343
+:10b9d000200062a01400c293010042241400c2a3fc
+:10b9e000e6ff0010000000003000c38f3400c28f5b
+:10b9f000000042942c0062a41000c28f000042900c
+:10ba00001500c2a31500c393e500022405006214cb
+:10ba100000000000010002241700c2a30200001071
+:10ba2000000000001700c0a33000c38f1000c28fb9
+:10ba30001c00428c140062ac3000d08f1000c48f08
+:10ba40001c24400f00000000040002ae1000c28f52
+:10ba50000b0042901500c2a33000c38f1500c293a3
+:10ba6000300062a41500c293100042300b00401059
+:10ba7000000000003000c38f1000c28f0e004294ff
+:10ba80001c0062a43000c38f1000c28f10004294cb
+:10ba90001e0062a409000010000000003000c38fe7
+:10baa0001000c28f160042941c0062a43000c38fa5
+:10bab0001000c28f180042941e0062a41700c293a7
+:10bac00021e8c0032800bf8f2400be8f2000b08f64
+:10bad0003000bd270800e00300000000d8ffbd27ac
+:10bae0002400bfaf2000beaf21f0a0032800c4afe8
+:10baf0002c00c5af2800c38f2800c28f3400428cb1
+:10bb0000380062ac2800c48f2c00c58f01000624c9
+:10bb1000182a400f000000001000c2af1000c28fb2
+:10bb200004004014000000001800c0af31000010f5
+:10bb3000000000001000c28f000042901400c2a359
+:10bb40001400c29302004014000000001000c0afb7
+:10bb50001000c28f25004010000000001400c393a5
+:10bb6000e500022404006214000000001000c0afd1
+:10bb70001e000010000000001000c28f0b00429059
+:10bb80001400c2a31400c3930f0002241700621410
+:10bb9000000000002c00c38f2c00c28f00004294d4
+:10bba00001004224000062a42800c48f2c00c58f2d
+:10bbb00021300000182a400f000000001000c2af22
+:10bbc0001000c28f04004014000000001800c0af35
+:10bbd00008000010000000001000c28f0b0042900f
+:10bbe0001400c2a3e7ff0010000000001000c28f85
+:10bbf0001800c2af1800c28f21e8c0032400bf8f15
+:10bc00002000be8f2800bd270800e00300000000d0
+:10bc1000d0ffbd272c00bfaf2800beaf21f0a0038e
+:10bc20003000c4af3400c5af2110c0003800c2a33b
+:10bc30001800c0af3000c28f0000428c2000c2af9d
+:10bc40003000c28f3400428c1c00c2af3000c38f62
+:10bc50001c00c28f380062ac3000c48f3400c58f26
+:10bc600001000624182a400f000000001000c2af97
+:10bc70001000c28f070040140000000001000224e1
+:10bc80008c8182a31b0002242400c2af4500001057
+:10bc9000000000001000c28f000042901400c2a3f8
+:10bca0001000c28f04004010000000001400c29376
+:10bcb00005004014000000000b0002241800c2af71
+:10bcc0002e000010000000001400c393e5000224c1
+:10bcd00005006214000000000b0002241800c2af2f
+:10bce00026000010000000001000c28f0b004290e0
+:10bcf0001400c2a31000c38fe5ff0224000062a05d
+:10bd00001000c48f1c24400f000000001c00c2afb4
+:10bd10001800c28f07004014000000003000c48fdc
+:10bd20003400c58f3e29400f00000000050040147c
+:10bd300000000000010002241800c2af0f00001034
+:10bd4000000000001c00c38f7c81828f0b006210fa
+:10bd5000000000003800c2930800401000000000fe
+:10bd60001c00c48f2000c58f9129400f00000000e7
+:10bd7000000042380100422c1800c2af1800c28fe8
+:10bd800004004014000000008c8180a30300001018
+:10bd900000000000010002248c8182a31800c28fe1
+:10bda0002400c2af2400c28f21e8c0032c00bf8f43
+:10bdb0002800be8f3000bd270800e003000000000f
+:10bdc000c0ffbd273c00bfaf3800beaf21f0a003cd
+:10bdd0004000c4af4400c5af1100c0a3010002245d
+:10bde0002800c2a78c8180a34400c28f07004014a2
+:10bdf00000000000190002248c8182a3ffff0224ae
+:10be00003000c2afd1000010000000004400c28f1b
+:10be1000200042244000c48f21284000213000002f
+:10be2000a136400f00000000070040140000000091
+:10be3000120002248c8182a3ffff02243000c2afd3
+:10be4000c2000010000000001000c0a31000c29348
+:10be50000b00422c0e004010000000001000c393a5
+:10be60001000c227212062004400c38f1000c2933b
+:10be70002110620020004290080082a01000c293ae
+:10be8000010042241000c2a3f0ff001000000000d7
+:10be90004400c28f2c0042942a00c2a72800c0a7e9
+:10bea0004400c38f4400c28f3400428c380062ac1f
+:10beb0002800c2274400c48f212840000100062426
+:10bec000182a400f000000002c00c2af2c00c28fc7
+:10bed00007004014000000001b0002248c8182a394
+:10bee000ffff02243000c2af9800001000000000e5
+:10bef0001000c0a31000c2930b00422c120040108f
+:10bf0000000000002c00c38f1000c29321204300ca
+:10bf10001000c3931000c22721106200000083802c
+:10bf200008004280030062100000000001000224ab
+:10bf30001100c2a31000c293010042241000c2a34a
+:10bf4000ecff0010000000001100c2930700401435
+:10bf500000000000110002248c8182a3ffff022454
+:10bf60003000c2af79000010000000001100c0a333
+:10bf70006d8080a32800c2274400c48f2128400080
+:10bf800021300000182a400f000000002c00c2af32
+:10bf90002c00c28f0d004014000000006d808393c0
+:10bfa00001000224030062140000000032000010af
+:10bfb000000000001b0002248c8182a3ffff0224ea
+:10bfc0003000c2af61000010000000002c00c28fe2
+:10bfd0000000428003004014000000002600001012
+:10bfe000000000001000c0a31000c2930b00422c00
+:10bff00012004010000000002c00c38f1000c293fc
+:10c00000212043001000c3931000c22721106200ba
+:10c0100000008380080042800300621000000000de
+:10c02000010002241100c2a31000c29301004224a7
+:10c030001000c2a3ecff0010000000001100c2932a
+:10c040000700401400000000110002248c8182a32c
+:10c05000ffff02243000c2af3c00001000000000cf
+:10c060001100c0a32800c297010042242800c2a7e3
+:10c07000c0ff0010000000002a00c2972800c2a7dd
+:10c080004400c38f4400c28f3400428c380062ac3d
+:10c090002800c2274400c48f21284000b72e400f3b
+:10c0a000000000002c00c2af2c00c28f070040141b
+:10c0b000000000001b0002248c8182a3ffff0224e9
+:10c0c0003000c2af21000010000000001000c0a32b
+:10c0d0001000c2930b00422c0e0040100000000024
+:10c0e0002c00c38f1000c293212043004400c38f53
+:10c0f0001000c2932110620020004290000082a034
+:10c100001000c293010042241000c2a3f0ff0010ef
+:10c11000000000002800c2274400c48f21284000ee
+:10c120003e29400f000000000700401400000000fe
+:10c13000090002248c8182a3ffff02243000c2afd9
+:10c1400002000010000000003000c0af3000c28fbd
+:10c1500021e8c0033c00bf8f3800be8f4000bd27e0
+:10c160000800e00300000000d0ffbd272c00bfaf97
+:10c170002800beaf21f0a0033000c4af3400c5af2b
+:10c180001000c0af1400c0af1400c28f03004228db
+:10c190001b004010000000001400c38f7481822730
+:10c1a00021106200000042901000401000000000ca
+:10c1b0001400c38f7481822721106200000040a008
+:10c1c0001400c38f211060000011020023104300ef
+:10c1d0008018020000a0023c2409422421106200c1
+:10c1e0001000c2af06000010000000001400c28f53
+:10c1f000010042241400c2afe3ff00100000000061
+:10c200001000c28f0600401400000000200002242d
+:10c210008c8182a32000c0af7801001000000000d4
+:10c220001000c28f200042243000c48f212840001b
+:10c2300021300000a136400f000000000b00401428
+:10c24000000000001400c38f74818227211862004f
+:10c2500001000224000062a0120002248c8182a34b
+:10c260002000c0af65010010000000003400c28f44
+:10c27000000042901800c2a31000c38f00a0023c2f
+:10c28000d8094224000062ac1000c28f040040ac08
+:10c290001000c28f080040ac1000c28f2c0040a4d8
+:10c2a0001000c38f20000224300062a41000c38f4e
+:10c2b0001880828f3400428c340062ac1000c38f2f
+:10c2c0001880828f3800428c380062ac00a0023c9b
+:10c2d000f80944241000c58fa732400f0000000069
+:10c2e0001000c48f00a0023cf80945240100062478
+:10c2f000213800006e1f400f00000000db004014da
+:10c30000000000001800c293bfff42242400c2af07
+:10c310002400c38f3700622cce00401000000000c4
+:10c320002400c28f80180200029d023c580642245d
+:10c33000211062000000428c080040000000000054
+:10c340001000c28f2c0042941a00c2a71a00c22704
+:10c350001000c48f2128400001000624042f400f44
+:10c36000000000001c00c2af1c00c28f0c01401472
+:10c37000000000001a00c2271000c48f21284000ce
+:10c3800021300000062b400f000000001c00c2af4f
+:10c390001c00c28f02014014000000001a00c227d6
+:10c3a0001000c48f21284000770006247a20400f17
+:10c3b000000000001c00c2af1000c28f3000429489
+:10c3c0001000423005004010000000001f00022451
+:10c3d0008c8182a3ff0002241c00c2af1c00c28f0c
+:10c3e000ef004014000000001000c48f212800005e
+:10c3f000020006249e38400f000000001c00c2af5f
+:10c400003400c28f010043802b000224e400621438
+:10c41000000000001000c28f1800438c020063343b
+:10c42000180043acde000010000000001000c28fb6
+:10c430001400428c2d004010000000001000c28f3c
+:10c440002c0042941a00c2a71a00c2271000c48f01
+:10c4500021284000770006247a20400f00000000c9
+:10c460001c00c2af1000c28f300042941000423056
+:10c4700005004010000000001f0002248c8182a3f0
+:10c48000ff0002241c00c2af1c00c28fc400401475
+:10c49000000000001000c48f2128000002000624c4
+:10c4a0009e38400f000000001c00c2af1c00c28f6d
+:10c4b00003004010000000001a0002248c8182a3b7
+:10c4c0003400c28f010043802b000224b4006214a8
+:10c4d000000000001000c28f1800438c020063347b
+:10c4e000180043acae000010000000001000c28f26
+:10c4f0002c0042941a00c2a71a00c2271000c48f51
+:10c500002128400001000624042f400f00000000f5
+:10c510001c00c2af1c00c28fa1004014000000002c
+:10c520001a00c2271000c48f2128400021300000cb
+:10c53000062b400f000000001c00c2af1c00c28f81
+:10c5400097004014000000001a00c2271000c48f9a
+:10c5500021284000770006247a20400f00000000c8
+:10c560001c00c2af1000c28f300042941000423055
+:10c5700005004010000000001f0002248c8182a3ef
+:10c58000ff0002241c00c2af1c00c28f84004014b4
+:10c59000000000001000c48f2128000002000624c3
+:10c5a0009e38400f000000001c00c2af1c00c28f6c
+:10c5b00003004010000000001a0002248c8182a3b6
+:10c5c0003400c28f010043802b00022474006214e7
+:10c5d000000000001000c28f1800438c020063347a
+:10c5e000180043ac6e000010000000001000c28f65
+:10c5f0002c0042941a00c2a71a00c2271000c48f50
+:10c6000021284000720006247a20400f000000001c
+:10c610001c00c2af3400c28f010043802b000224f3
+:10c620005f006214000000001000c28f30004294ce
+:10c63000100042305a004014000000001000c28f69
+:10c640001800438c01006334180043ac5400001000
+:10c65000000000001f0002248c8182a3ff0002243e
+:10c660001c00c2af4e000010000000001000c48f7c
+:10c6700000a0023cf8094524a732400f000000004a
+:10c680001800c393770002240f006210000000001e
+:10c690001800c393570002240b0062100000000032
+:10c6a0001800c3936100022407006210000000001c
+:10c6b0001800c39341000224030062100000000030
+:10c6c00035000010000000001a00c0a71a00c227a1
+:10c6d0001000c48f2128400021300000062b400f9d
+:10c6e000000000001c00c2af1c00c28f2c004014d0
+:10c6f000000000001a00c2271000c48f212840004b
+:10c70000770006247a20400f000000001c00c2af12
+:10c710001000c28f300042941000423005004010db
+:10c72000000000001f0002248c8182a3ff0002246d
+:10c730001c00c2af1c00c28f190040140000000092
+:10c740001000c48f21280000020006249e38400fec
+:10c75000000000001c00c2af1c00c28f030040108c
+:10c76000000000001a0002248c8182a33400c28fd2
+:10c77000010043802b000224090062140000000025
+:10c780001000c28f1800438c02006334180043acc1
+:10c7900003000010000000000b0002241c00c2afc8
+:10c7a000d54a400f000000000600401000000000c5
+:10c7b0001000c48f1800838cfeff02242410620036
+:10c7c000180082ac1c00c28f09004010000000005d
+:10c7d0001400c38f74818227211862000100022493
+:10c7e000000062a01000c0af0200001000000000b6
+:10c7f0008c8180a31000c28f2000c2af2000c28fa6
+:10c8000021e8c0032c00bf8f2800be8f3000bd2759
+:10c810000800e00300000000f8ffbd270000beafe5
+:10c8200021f0a0030800c4af8c8180a30800c28f50
+:10c830001000428c21e8c0030000be8f0800bd2715
+:10c840000800e00300000000d8ffbd272400bfafb0
+:10c850002000beaf21f0a0032800c4af00a0023c1e
+:10c86000e80642241000c2af8c8180a3d54a400f55
+:10c870000000000007004010000000001800022423
+:10c880008c8182a3ffff02241800c2af5800001061
+:10c89000000000001000c28f200042242800c48f36
+:10c8a0002128400021300000a136400f0000000088
+:10c8b0000700401400000000120002248c8182a3b3
+:10c8c000ffff02241800c2af490000100000000062
+:10c8d0001000c38f00a0023cd8094224000062acc3
+:10c8e0001000c28f040040ac1000c28f080040aca2
+:10c8f0001000c28f2c0040a41000c38f200002241f
+:10c90000300062a41000c38f1880828f3400428ce4
+:10c91000340062ac1000c38f1880828f3800428cc4
+:10c92000380062ac00a0023cf80944241000c58f16
+:10c93000a732400f000000001000c48f00a0023c8e
+:10c94000f809452401000624213800006e1f400f1d
+:10c95000000000001400c2af1400c28f0700401096
+:10c96000000000000b0002248c8182a3ffff022440
+:10c970001800c2af1e000010000000001000c28f9f
+:10c9800030004294100042300700401000000000c8
+:10c99000130002248c8182a3ffff02241800c2af7f
+:10c9a00013000010000000001000c28f2c00422471
+:10c9b0001000c48f2128400001000624042f400fde
+:10c9c000000000001400c2af1400c28f0400401425
+:10c9d000000000001800c0af0500001000000000bb
+:10c9e000010002248c8182a3ffff02241800c2af41
+:10c9f0001800c28f21e8c0032400bf8f2000be8f23
+:10ca00002800bd270800e00300000000e8ffbd2764
+:10ca10001400bfaf1000beaf21f0a0031800c4afd8
+:10ca20006c80829303004010000000009235400f9c
+:10ca3000000000001800c28f100040ac1800c28f28
+:10ca40000e0040a41800c28f0c0040a41800c38f31
+:10ca50001800c28f0400428c080062ac688080af6e
+:10ca600021e8c0031400bf8f1000be8f1800bd273f
+:10ca70000800e00300000000f8ffbd270000beaf83
+:10ca800021f0a0038c81829321e8c0030000be8fb7
+:10ca90000800bd270800e00300000000e8ffbd27f4
+:10caa0001000beaf21f0a0031800c4af1c00c5af3a
+:10cab0001800c28f0400c2af1c00c28f0800c2afb2
+:10cac0003c0002240000c2a30c00c0a30c00c293cf
+:10cad0000000c3932b1043000e0040100000000024
+:10cae0000c00c3930400c28f212062000c00c3938a
+:10caf0000800c28f2110620000004290000082a056
+:10cb00000c00c293010042240c00c2a3efff0010ee
+:10cb10000000000021e8c0031000be8f1800bd27f0
+:10cb20000800e00300000000e0ffbd271c00bfafcd
+:10cb30001800beaf21f0a0032000c4af2400c5af91
+:10cb40001400c0af2000c28f0000428c1000c2afa2
+:10cb50002000c48f162d400f000000002118400057
+:10cb60002400c28f000043ac2400c28f0000428c1e
+:10cb70000500401400000000150002241400c2af9c
+:10cb800041000010000000001000c28f1e00439002
+:10cb90000100022410006214000000002400c28f73
+:10cba0001000c48f0000458cf80f062421380000c7
+:10cbb000af3a400f0000000021184000ffff023490
+:10cbc0002800621400000000090002241400c2af13
+:10cbd00024000010000000001000c28f1e004390cf
+:10cbe0000200022410006214000000002400c28f22
+:10cbf0001000c48f0000458cf8ff06342138000077
+:10cc0000af3a400f0000000021184000ffff02343f
+:10cc10001400621400000000090002241400c2afd6
+:10cc200010000010000000002400c28f1000c48f0c
+:10cc30000000458cff0f023cf8ff4634213800000d
+:10cc4000af3a400f0000000021184000ff0f023ce7
+:10cc5000ffff4234030062140000000009000224b8
+:10cc60001400c2af1400c28f07004014000000007f
+:10cc70002400c28f1000c48f0000458c2933400f60
+:10cc8000000000001400c2af1400c28f21e8c003ee
+:10cc90001c00bf8f1800be8f2000bd270800e003d6
+:10cca00000000000d8ffbd272400bfaf2000beafaa
+:10ccb00021f0a0032800c4af2c00c5af1800c0a30a
+:10ccc0002800c48f2c00c58fcd33400f000000001a
+:10ccd0001400c2af6c808293090040100000000075
+:10cce0009235400f000000000500401000000000d9
+:10ccf000090002241c00c2af340000100000000034
+:10cd0000688080af6e8082930c00401400000000a9
+:10cd10002800c28f03004388000043982110600060
+:10cd2000212040002128000000020624096b400f4a
+:10cd300000000000010002246e8082a31000c0a346
+:10cd40002800c28f1d0043901000c2932b10430097
+:10cd50001c004010000000001800c293190040148d
+:10cd6000000000001400c3270000628c2120400056
+:10cd700001004224000062ac2800c28f03004388f7
+:10cd8000000043982110600021284000213000005d
+:10cd90005b4a400f000000002118400001000224ff
+:10cda0000300621000000000090002241800c2a362
+:10cdb0001000c293010042241000c2a3e0ff001043
+:10cdc000000000001800c2931c00c2af1c00c28ffc
+:10cdd00021e8c0032400bf8f2000be8f2800bd279c
+:10cde0000800e00300000000f8ffbd270000beaf10
+:10cdf00021f0a0030800c4af2110a0000c00c2a7be
+:10ce00000c00c3970800c28f2110620000004290fe
+:10ce100021e8c0030000be8f0800bd270800e00322
+:10ce200000000000f0ffbd270800beaf21f0a00306
+:10ce30001000c4af2110a0001400c2a71400c397b3
+:10ce40001000c28f21106200000042900000c2a3b7
+:10ce50001400c3971000c28f21106200010042909d
+:10ce60000100c2a30100c2930200c2a70200c29740
+:10ce7000001202000200c2a70000c3930200c29782
+:10ce8000251043000200c2a70200c29721e8c00398
+:10ce90000800be8f1000bd270800e003000000005e
+:10cea000e0ffbd271c00bfaf1800beaf21f0a003fc
+:10ceb0002000c4af2110a0002400c2a72400c29704
+:10cec0002000c48f212840008933400f000000005b
+:10ced0001000c2a72400c29702004224ffff423084
+:10cee0002000c48f212840008933400f000000003b
+:10cef0001200c2a71200c2971400c2af1400c28f62
+:10cf0000001402001400c2af1000c3971400c28fb7
+:10cf1000251043001400c2af1400c28f21e8c003e3
+:10cf20001c00bf8f1800be8f2000bd270800e00343
+:10cf300000000000f0ffbd270800beaf21f0a003f5
+:10cf40001000c4af1400c5af1000c28f1e00429085
+:10cf50000400c2af0400c38f0100622834004014f3
+:10cf6000000000000400c38f030062281400401476
+:10cf700000000000030002240400c38f03006210bd
+:10cf8000000000002a000010000000001400c28f02
+:10cf9000feff43241000c28f1d00429002206270e9
+:10cfa0001000c28f130043881000439821106000c6
+:10cfb000211082000000c2af1d0000100000000020
+:10cfc0001400c28f07004010000000001400c38f3f
+:10cfd000010002240300621000000000090000109c
+:10cfe000000000001000c28f0f0043880c0043981f
+:10cff0001400c28f211062000000c2af0c000010ac
+:10d00000000000001400c28ffeff43241000c28ff6
+:10d010001d004290022062701000c28f13004388ee
+:10d020001000439821106000211082000000c2af60
+:10d030000000c28f21e8c0030800be8f1000bd278a
+:10d040000800e00300000000d8ffbd272400bfafa8
+:10d050002000beaf21f0a0032800c4af2110a00023
+:10d060002c00c2a38c8180a32c00c393d8ff022480
+:10d070002410620007004010000000001f0002247e
+:10d080008c8182a3ffff02241800c2af3c00001075
+:10d09000000000002800c28f2c0042941000c2a79c
+:10d0a0002800c38f2800c28f3400428c380062ac45
+:10d0b0002800c48f1000c527b72e400f00000000c5
+:10d0c0001400c2af1400c28f07004014000000001b
+:10d0d0001b0002248c8182a3ffff02241800c2af30
+:10d0e00027000010000000001400c28f0b004290c7
+:10d0f0000800423007004010000000001f0002241a
+:10d100008c8182a3ffff02241800c2af1c00001014
+:10d11000000000002800c28f30004294100042300e
+:10d1200007004010000000001400c28f2c00c393c1
+:10d13000100063340b0043a0040000100000000046
+:10d140001400c38f2c00c2930b0062a02800c48f70
+:10d150001000c5273e29400f0000000007004014c2
+:10d1600000000000090002248c8182a3ffff02243a
+:10d170001800c2af02000010000000001800c0af8d
+:10d180001800c28f21e8c0032400bf8f2000be8f8b
+:10d190002800bd270800e00300000000c0ffbd27f5
+:10d1a0003c00bfaf3800beaf21f0a0034000c4afc9
+:10d1b0004400c5af4800c6af4c00c7af4400c38fa2
+:10d1c0004800c28f021062701000c2af4000c28fd0
+:10d1d0001400c2af1c00c0af3000c0a74c00c28f0b
+:10d1e0001800428c0000427c08004014000000003f
+:10d1f0001d0002248c8182a3090002241c00c2affe
+:10d200003400c0af09010010000000001000c28f00
+:10d2100004004014000000003400c0af03010010ff
+:10d2200000000000d54a400f000000000800401038
+:10d2300000000000180002248c8182a31800022440
+:10d240001c00c2af3400c0aff800001000000000a6
+:10d250006e8080a34c00c28f0000428c1800c2afc9
+:10d260004c00c28f0e0042942000c2a74c00c28f17
+:10d270001000428c2800c2af4c00c28f1800c48f2f
+:10d280000800458ccd33400f000000002400c2afe1
+:10d290004c00c28f0c0043942400c28f2110430025
+:10d2a0002400c2af6880838f4c00c28f0f006210d1
+:10d2b000000000006c8082930a0040100000000013
+:10d2c0009235400f000000000600401000000000f2
+:10d2d000090002248c8182a33400c0afd300001067
+:10d2e000000000004c00c28f688082af1480838fe2
+:10d2f0002400c28f1e006210000000006c80829328
+:10d300000a004010000000009235400f00000000ad
+:10d310000600401000000000090002248c8182a356
+:10d320003400c0afc1000010000000006e8080a378
+:10d330001800c28f0300438800004398211060004a
+:10d340002400c48f21284000d349400f0000000072
+:10d3500005004014000000001b0002248c8182a301
+:10d36000080002241c00c2af2400c28f148082afc8
+:10d370004c00c28f1400428c2c00c2af1c00c28f24
+:10d380009b004014000000001000c28f9800401065
+:10d39000000000002800c38f2c00c28f050062141b
+:10d3a000000000004c00c28f1800438c040063345e
+:10d3b000180043ac2000c3970002022465006214e9
+:10d3c00000000000010002243200c2a36c8082939e
+:10d3d0000a004010000000009235400f00000000dd
+:10d3e0000600401000000000090002248c8182a386
+:10d3f0003400c0af8d000010000000002000c0a766
+:10d400004c00c38f4c00c28f0c0042940100422498
+:10d410000c0062a44c00c38f1800c28f1d00429004
+:10d420000c006394ffff42301500621400000000fe
+:10d430004c00c28f0c0040a44c00c28f1800428cdc
+:10d440008000427c09004010000000004c00c48fa6
+:10d4500021280000be2c400f000000001c00c2afbd
+:10d460003200c0a306000010000000004c00c48f72
+:10d47000010005241f21400f000000001c00c2af66
+:10d480001c00c38f15000224060062140000000077
+:10d49000150002248c8182a33400c0af6300001009
+:10d4a000000000001c00c28f2a0040140000000091
+:10d4b0004c00c28f1800c48f0800458ccd33400f3c
+:10d4c000000000002400c2af4c00c28f0c00439447
+:10d4d0002400c28f211043002400c2af4c00c28f31
+:10d4e000688082af3200c293180040100000000034
+:10d4f0001800c28f03004388000043982110600089
+:10d500002400c48f21284000d349400f00000000b0
+:10d510000a004014000000001b0002248c8182a33a
+:10d52000080002241c00c2afffff0224148082af57
+:10d530003400c0af3d000010000000002400c28f86
+:10d54000148082af03000010000000002400c28f8e
+:10d55000148082af1c00c28f88ff401400000000be
+:10d560001800c28f03004388212060000000449807
+:10d570002000c397010062242000c2a7ffff623091
+:10d58000211844001400c28f00004290000062a0e5
+:10d590001400c28f010042241400c2af2800c28fc1
+:10d5a000010042242800c2af1000c28fffff4224b6
+:10d5b0001000c2af3000c297010042243000c2a761
+:10d5c0004c00c28f1800428c8000427c0400401046
+:10d5d000000000002c00c28f010042242c00c2afca
+:10d5e000010002246c8082a364ff00100000000090
+:10d5f0004c00c38f2000c2970e0062a44c00c38f62
+:10d600002800c28f100062ac4c00c38f2c00c28f68
+:10d61000140062ac3000c3974400c28f1b0062004c
+:10d62000f4014000121000003400c2af3400c28f79
+:10d6300021e8c0033c00bf8f3800be8f4000bd27eb
+:10d640000800e00300000000d8ffbd272400bfafa2
+:10d650002000beaf21f0a0036880828f1800c2af07
+:10d660001800c28f0000428c1400c2af1800c28f95
+:10d670001400c48f0800458ccd33400f000000001b
+:10d680001000c2af1800c28f0c0043941000c28f6c
+:10d69000211043001000c2af1400c28f0300438862
+:10d6a00000004398211060001000c48f2128400022
+:10d6b000213000005b4a400f0000000005004014cc
+:10d6c00000000000090002241c00c2af030000108b
+:10d6d000000000006c8080a31c00c0af1c00c28f43
+:10d6e00021e8c0032400bf8f2000be8f2800bd2783
+:10d6f0000800e00300000000f8ffbd270000beaff7
+:10d7000021f0a0030800c4af8c8180a30800c28f61
+:10d710000800c38f1000448c1400628c2610820015
+:10d720000100422c21e8c0030000be8f0800bd2785
+:10d730000800e00300000000c0ffbd273c00bfafb1
+:10d740003800beaf21f0a0034000c4af4400c5af15
+:10d750004800c6af4c00c7af4400c38f4800c28f1b
+:10d76000021062701000c2af4000c28f1400c2af3e
+:10d770002800c0af2c00c0a78c8180a34c00c28fb2
+:10d780000000428c1800c2af4c00c28f0e004294c1
+:10d790002400c2a74c00c28f1000428c1c00c2aff4
+:10d7a0004c00c28f1800428c4000427c060040149e
+:10d7b000000000001e0002248c8182a33000c0af54
+:10d7c000a9000010000000006c8082930a00401045
+:10d7d000000000009235400f0000000006004010dd
+:10d7e00000000000090002248c8182a33000c0af39
+:10d7f0009d000010000000006880838f4c00c28fe5
+:10d8000026006210000000002400c39700020224da
+:10d8100022006210000000004c00c28f688082afbe
+:10d820004c00c28f1800c48f0800458ccd33400fc8
+:10d83000000000002000c2af4c00c28f0c004394d7
+:10d840002000c28f211043002000c2af6e8080a351
+:10d850001800c28f03004388000043982110600025
+:10d860002000c48f21284000d349400f0000000051
+:10d870000800401400000000080002248c8182a3ec
+:10d88000080002242800c2af3000c0af76000010ac
+:10d89000000000002000c28f148082af1000c28ff1
+:10d8a00065004010000000004c00c28f1400438c43
+:10d8b0001c00c28f07006214000000003d0002241b
+:10d8c0008c8182a33d0002242800c2af5a000010c0
+:10d8d000000000002400c397000202243c006214f0
+:10d8e000000000002400c0a74c00c38f4c00c28f72
+:10d8f0000c004294010042240c0062a44c00c38f2f
+:10d900001800c28f1d0042900c006394ffff42304c
+:10d910000f006214000000004c00c28f0c0040a4f5
+:10d920004c00c48f010005241f21400f000000009f
+:10d930002800c2af2800c28f050040100000000080
+:10d940000f0002248c8182a33b0000100000000025
+:10d950004c00c28f1800c48f0800458ccd33400f97
+:10d96000000000002000c2af4c00c28f0c004394a6
+:10d970002000c28f211043002000c2af4c00c28f94
+:10d98000688082af6e8080a31800c28f0300438836
+:10d9900000004398211060002000c48f212840001f
+:10d9a000d349400f000000000700401400000000b1
+:10d9b000080002248c8182a3080002242800c2af40
+:10d9c0001d000010000000002000c28f148082aff4
+:10d9d0001400c58f1800c28f030043882120600007
+:10d9e000000044982400c397010062242400c2a7c9
+:10d9f000ffff623021104400000042900000a2a00e
+:10da00001400c28f010042241400c2af1c00c28f58
+:10da1000010042241c00c2af2c00c2970100422426
+:10da20002c00c2a71000c28fffff42241000c2af1b
+:10da30009aff0010000000004c00c38f2400c29722
+:10da40000e0062a44c00c38f1c00c28f100062ac99
+:10da50002c00c3974400c28f1b006200f4014000f9
+:10da6000121000003000c2af3000c28f21e8c003a6
+:10da70003c00bf8f3800be8f4000bd270800e00388
+:10da800000000000c0ffbd273800bfaf3400beafac
+:10da90003000b0af21f0a0034000c4af4400c5afd8
+:10daa0002110c0004800c2a32800c0a32800c293d0
+:10dab0000b00422c0b004010000000002800c39314
+:10dac0004400c28f2118620020000224000062a0de
+:10dad0002800c293010042242800c2a3f3ff0010d3
+:10dae000000000004000c28f000043802e0002248e
+:10daf00005006210000000004000c28f000042805c
+:10db000004004014000000002c00c0af730000109f
+:10db1000000000004000c48f9b6b400f000000001d
+:10db20001400c2a71400c2970d00422c0800401038
+:10db3000000000001800c227212040004000c58fcf
+:10db4000336b400f000000000400001000000000d4
+:10db50002c00c0af61000010000000001800c227b8
+:10db60004800c3932120400021286000cf37400f98
+:10db70000000000004004014000000002c00c0afb2
+:10db800056000010000000001800c22721204000ad
+:10db90002e0005245d6c400f000000001000c2af95
+:10dba0001000c28f0f004010000000001000c28f54
+:10dbb000000040a01000c28f010042241000c2af3c
+:10dbc0001000c48f9b6b400f000000000400422c2b
+:10dbd00004004014000000002c00c0af3f00001003
+:10dbe000000000001800c227212040009b6b400f5e
+:10dbf000000000000900422c040040140000000056
+:10dc00002c00c0af35000010000000002800c0a3a9
+:10dc10002800d0931800c227212040009b6b400fa2
+:10dc2000000000002b1002020e0040100000000057
+:10dc30002800c3934400c28f212062002800c393b0
+:10dc40001000c2272110620008004290000082a04c
+:10dc50002800c293010042242800c2a3ecff001058
+:10dc6000000000001000c28f1a00401000000000e9
+:10dc70001000c28f0000428016004010000000001b
+:10dc80002800c0a32800d0931000c48f9b6b400fc6
+:10dc9000000000002b1002020e00401000000000e7
+:10dca0002800c3934400c28f212062002800c39340
+:10dcb0001000c28f2110620000004290080082a074
+:10dcc0002800c293010042242800c2a3edff0010e7
+:10dcd00000000000010002242c00c2af2c00c28f03
+:10dce00021e8c0033800bf8f3400be8f3000b08ff2
+:10dcf0004000bd270800e00300000000c8ffbd276a
+:10dd00003400bfaf3000beaf21f0a0033800c4af75
+:10dd10002110a0003c00c2a33c00c2933800c48f75
+:10dd200021284000cf37400f0000000004004014bd
+:10dd3000000000002800c0af7900001000000000c3
+:10dd40001000c0a31000c2930800422c1b0040101a
+:10dd5000000000001000c3933800c28f2110620041
+:10dd6000000043802e000224140062100000000016
+:10dd70001000c3933800c28f21106200000042805f
+:10dd80000e004010000000001000c3931000c227d6
+:10dd9000212062001000c3933800c28f211062005e
+:10dda00000004290080082a01000c29301004224ab
+:10ddb0001000c2a3e3ff0010000000001000c29397
+:10ddc0001100c2a31000c2930800422c0b004010a7
+:10ddd000000000001000c393010062241000c2a3e1
+:10dde000ff0063301000c2272118620020000224c7
+:10ddf000080062a0f3ff0010000000001100c393b0
+:10de00003800c28f21106200000043802e000224df
+:10de10001a006214000000001100c29301004224a5
+:10de20001100c2a31100c3933800c28f21106200f9
+:10de30000000428011004010000000001000c39359
+:10de4000010062241000c2a3ff0063301000c2274b
+:10de5000212062001100c393010062241100c2a3bb
+:10de6000ff0063303800c28f211062000000429032
+:10de7000080082a0ebff0010000000001000c29319
+:10de80000b00422c0b004010000000001000c39358
+:10de9000010062241000c2a3ff0063301000c227fb
+:10dea0002118620020000224080062a0f3ff001085
+:10deb000000000002300c0a31800c3832000022438
+:10dec00003006214000000005f0002241800c2a3d7
+:10ded0001000c0a31000c2930c00422c0e00401092
+:10dee000000000001000c3933800c28f21206200a0
+:10def0001000c3931000c227211062000800429056
+:10df0000000082a01000c293010042241000c2a3ae
+:10df1000f0ff001000000000010002242800c2af42
+:10df20002800c28f21e8c0033400bf8f3000be8fad
+:10df30003800bd270800e00300000000d8ffbd271f
+:10df40002400bfaf2000beaf21f0a0032800c4af63
+:10df50002110a0002c00c2a31800c0a32800c48f69
+:10df60009b6b400f000000001000c2af1400c0af58
+:10df70001400c28f1000c38f2a104300b500401058
+:10df8000000000001400c38f2800c28f211062001f
+:10df900000004280210042280800401000000000dc
+:10dfa0001400c38f2800c28f21106200000043803c
+:10dfb0000500022469006214000000001400c38ff1
+:10dfc0002800c28f2110620000004380220002243a
+:10dfd00062006210000000001400c38f2800c28f8e
+:10dfe00021106200000043802b0002245b006210bd
+:10dff000000000001400c38f2800c28f21106200af
+:10e00000000043802c000224540062100000000035
+:10e010001400c38f2800c28f2110620000004380cb
+:10e020002f0002244d006210000000001400c38f76
+:10e030002800c28f21106200000043803a000224b1
+:10e0400046006210000000001400c38f2800c28f39
+:10e0500021106200000043803b0002243f00621058
+:10e06000000000001400c38f2800c28f211062003e
+:10e07000000043803c0002243800621000000000d1
+:10e080001400c38f2800c28f21106200000043805b
+:10e090003d00022431006210000000001400c38f14
+:10e0a0002800c28f21106200000043803e0002243d
+:10e0b0002a006210000000001400c38f2800c28fe5
+:10e0c00021106200000043805b00022423006210e4
+:10e0d000000000001400c38f2800c28f21106200ce
+:10e0e000000043805c0002241c006210000000005d
+:10e0f0001400c38f2800c28f2110620000004380eb
+:10e100005d00022415006210000000001400c38f9f
+:10e110002800c28f21106200000043807c0002248e
+:10e120000e006210000000001400c38f2800c28f90
+:10e1300021106200000043802e0002240a006214b5
+:10e14000000000001800c3930100022403006210c5
+:10e150000000000004000010000000001c00c0af20
+:10e160003e000010000000002c00c2931400401478
+:10e17000000000001400c38f2800c28f211062002d
+:10e18000000043802a0002240a0062100000000000
+:10e190001400c38f2800c28f21106200000043804a
+:10e1a0003f00022403006210000000000400001081
+:10e1b000000000001c00c0af28000010000000009c
+:10e1c0001400c38f2800c28f21106200000043801a
+:10e1d0002e0002240300621400000000010002244b
+:10e1e0001800c2a31400c38f2800c28f2110620040
+:10e1f000000042806100422811004014000000002d
+:10e200001400c38f2800c28f2110620000004280da
+:10e210007b0042280a004010000000001400c38f59
+:10e220002800c28f212062001400c38f2800c28ff3
+:10e230002110620000004290e0ff4224000082a012
+:10e240001400c28f010042241400c2af48ff001026
+:10e2500000000000010002241c00c2af1c00c28f9d
+:10e2600021e8c0032400bf8f2000be8f2800bd27f7
+:10e270000800e00300000000c8ffbd273400bfaf66
+:10e280003000beaf21f0a0033800c4af3c00c5afe2
+:10e290004000c6af3c00c28f2000c2af3800c28f22
+:10e2a0000000428c1800c2af4000c28f2800c2afed
+:10e2b000010002242800c38f070062100000000044
+:10e2c000020002242800c38f0a0062100000000030
+:10e2d0000d000010000000003800c28f2000c38f26
+:10e2e0001000428c211062002000c2af0600001016
+:10e2f000000000003800c28f1400438c2000c28f41
+:10e30000231062002000c2af6c8082930b0040108b
+:10e31000000000009235400f000000000700401090
+:10e3200000000000090002248c8182a3ffff022468
+:10e330002400c2afb7000010000000003800c28ff8
+:10e340000400428c1400c2af3800c38f1400c28f87
+:10e35000080062ac3800c28f1400428c1400c2afb7
+:10e360002000c38f1400c28f2b1043000700401001
+:10e37000000000001f0002248c8182a3ffff032401
+:10e380002400c3afa3000010000000003800c48fb9
+:10e390001800838cfbff022424106200180082ac5a
+:10e3a0003800c38f2000c28f100062ac2000c28fe3
+:10e3b0002c00c2af2c00c28f0400410400000000fa
+:10e3c0002c00c38fff0163242c00c3af2c00c38f2c
+:10e3d000431203001000c2af1000c28f401a0200a7
+:10e3e0002000c28f231043002000c2af3800c38f2b
+:10e3f0002000c28f0e0062a41800c28f1d0043903f
+:10e400001000c28f1b004300f401600012100000d6
+:10e410001400c2af1800c28f1d0043901400c28fb9
+:10e42000021862701000c28f231043001000c2afa8
+:10e430003800c38f1000c28f0c0062a41400c28f7a
+:10e4400051004010000000003800c48f1400c58f38
+:10e450001f21400f000000001c00c2a31c00c2933b
+:10e4600049004010000000001c00c3933c0002243f
+:10e470003f006214000000003800c28f1800428c78
+:10e480000000427c1c004010000000003800c38fd8
+:10e490003800c28f0400428c080062ac1400c38fa5
+:10e4a0000100022408006210000000001400c28f66
+:10e4b000ffff42243800c48f212840001f21400f55
+:10e4c000000000001c00c2a33800c48f21280000f7
+:10e4d000be2c400f000000002b0040100000000088
+:10e4e0000f0002248c8182a3ffff02242400c2af0c
+:10e4f00048000010000000003800c38f3800c28fb1
+:10e500000400428c080062ac1400c28fffff42245a
+:10e510003800c48f212840001f21400f0000000058
+:10e520001c00c2a31c00c2930700401000000000a2
+:10e530000f0002248c8182a3ffff03242400c3afb9
+:10e5400034000010000000003800c38f00020224d5
+:10e550000e0062a43800c38f1800c28f1d004290c5
+:10e56000ffff42240c0062a407000010000000001e
+:10e570000f0002248c8182a3ffff02242400c2af7b
+:10e5800024000010000000003800c28f1800c48f63
+:10e590000800458ccd33400f000000001400c2afce
+:10e5a0003800c28f0c0042941000c2af1400c38f19
+:10e5b0001000c28f211062001400c2af688080afcb
+:10e5c0006e8080a31800c28f030043880000439828
+:10e5d000211060001400c48f21284000d349400f4f
+:10e5e0000000000007004014000000001b0002248f
+:10e5f0008c8182a3ffff03242400c3af0500001019
+:10e60000000000001400c28f148082af8c8180a3b0
+:10e610002400c0af2400c28f21e8c0033400bf8fa4
+:10e620003000be8f3800bd270800e0030000000066
+:10e63000c0ffbd273c00bfaf3800beaf21f0a00334
+:10e640004000c4af4400c5af6e8080a34000c28fbd
+:10e650001e0042903000c2af010002243000c38f80
+:10e660001200621000000000030002243000c38f7b
+:10e6700003006210000000001d00001000000000f8
+:10e680004400c28f801002001400c2afff0f023c92
+:10e69000ffff42342400c2afff0f023cf8ff4234b8
+:10e6a0002800c2af19000010000000004400c38f12
+:10e6b0002110600040100200211043001400c2af7e
+:10e6c0001400c28f010042301000c2a31400c28f98
+:10e6d000421002001400c2afffff02342400c2af98
+:10e6e000f80f02242800c2af08000010000000004c
+:10e6f0004400c28f401002001400c2afffff02347a
+:10e700002400c2aff8ff02342800c2af4000c28f1d
+:10e710000b004388080043981400c28f4212020085
+:10e72000211062001800c2af1400c28fff014230f6
+:10e730001400c2af1080838f1800c28f6c00621467
+:10e74000000000004000c28f1e004390030002241e
+:10e7500009006214000000001400c38f00a0023cf6
+:10e7600024074224211062000000428c1c00c2af2a
+:10e77000c2000010000000004000c28f1e00439045
+:10e780000200022409006214000000001400c38f7c
+:10e7900000a0023c240742242110620000004294a1
+:10e7a0001c00c2afb5000010000000004000c28f86
+:10e7b0001e00439001000224b0006214000000001b
+:10e7c0001400c38f00a0023c2407422421106200e1
+:10e7d000000042901c00c2af1000c2930400401021
+:10e7e000000000001c00c28f021102001c00c2af1a
+:10e7f0001400c28f01004224ff0142301400c2af56
+:10e800001400c28f22004014000000006480829334
+:10e810000d004010000000004000c48f21280000bf
+:10e820002130000001000724af3a400f0000000033
+:10e8300005004010000000002400c28f2c00c2af71
+:10e8400097000010000000001800c28f0100422451
+:10e850002120400000a0023c24074524d349400f5a
+:10e86000000000000700401400000000ffff023419
+:10e87000108082af2400c28f2c00c2af880000102d
+:10e88000000000001800c28f01004224108082aff7
+:10e890001400c38f00a0023c240742242110620010
+:10e8a000000042902000c2af1000c2930800401048
+:10e8b000000000002000c28f001902001c00c28f5f
+:10e8c000211043001c00c2af6c00001000000000cb
+:10e8d0002000c28f0f004230001a02001c00c28fbd
+:10e8e000211043001c00c2af6400001000000000b3
+:10e8f000648082930d004010000000004000c48f2f
+:10e90000212800002130000001000724af3a400f09
+:10e910000000000005004010000000002400c28f2d
+:10e920002c00c2af5e000010000000001800c48f71
+:10e9300000a0023c24074524d349400f00000000fa
+:10e940000700401400000000ffff0234108082af77
+:10e950002400c28f2c00c2af510000100000000044
+:10e960001800c28f108082af4000c28f1e004390fb
+:10e970000300022409006214000000001400c38f89
+:10e9800000a0023c24074224211062000000428cb7
+:10e990001c00c2af39000010000000004000c28f10
+:10e9a0001e004390020002240900621400000000cf
+:10e9b0001400c38f00a0023c2407422421106200ef
+:10e9c000000042941c00c2af2c00001000000000a8
+:10e9d0004000c28f1e0043900100022427006214f1
+:10e9e000000000001400c38f00a0023c2407422452
+:10e9f00021106200000042901c00c2af1000c293c0
+:10ea000004004010000000001c00c28f0211020030
+:10ea10001c00c2af1400c28f01004224ff0142302b
+:10ea20001400c2af1400c38f00a0023c240742248c
+:10ea300021106200000042902000c2af1000c2937b
+:10ea400008004010000000002000c28f00190200e2
+:10ea50001c00c28f211043001c00c2af0700001031
+:10ea6000000000002000c28f0f004230001a020098
+:10ea70001c00c28f211043001c00c2af1c00c28fbb
+:10ea80002800c38f2b104300030040140000000037
+:10ea90002800c28f1c00c2af1c00c28f2c00c2af66
+:10eaa0002c00c28f21e8c0033c00bf8f3800be8f0e
+:10eab0004000bd270800e00300000000c8ffbd279c
+:10eac0003400bfaf3000beaf21f0a0033800c4afa8
+:10ead0003c00c5af4000c6af2110e0004400c2a317
+:10eae0003800c28f1e004390030002241000621001
+:10eaf000000000003800c28f1e0043900200022474
+:10eb00000b006210000000003800c28f1e0043900e
+:10eb1000010002240600621000000000ff0f023c0a
+:10eb2000ffff42342400c2af4a0100100000000081
+:10eb30003800c28f1e0042902800c2af2800c38f49
+:10eb40000100622812004014000000002800c38f5a
+:10eb5000030062280c00401400000000030002249f
+:10eb60002800c38f0300621000000000080000109e
+:10eb700000000000ff0f023cffff42342000c2af44
+:10eb80000300001000000000ffff02342000c2afad
+:10eb90006e8080a34400c293280040100000000053
+:10eba0001000c0a31080828f1800c2af3800c28f3f
+:10ebb0001c0043901000c2932b1043001b00401018
+:10ebc000000000001080848f00a0023c2407452430
+:10ebd000213000005b4a400f000000000500401497
+:10ebe000000000002000c28f2400c2af19010010f5
+:10ebf000000000001000c293010042241000c2a3d4
+:10ec00003800c28f1a0043901b004290001202008d
+:10ec100025104300ffff43301800c28f211043002e
+:10ec20001800c2afe1ff001000000000648080a364
+:10ec30002400c0af07010010000000003800c28fa0
+:10ec40001e0042902c00c2af010002242c00c38f92
+:10ec50000c00621000000000030002242c00c38f8f
+:10ec6000030062100000000013000010000000000c
+:10ec70003c00c28f801002001400c2af11000010cf
+:10ec8000000000003c00c38f211060004010020013
+:10ec9000211043001400c2af1400c28f01004230a3
+:10eca0001100c2a31400c28f421002001400c2afb0
+:10ecb00004000010000000003c00c28f4010020061
+:10ecc0001400c2af3800c28f0b004388080043987d
+:10ecd0001400c28f42120200211062001c00c2af59
+:10ece0001400c28fff0142301400c2af1080838f26
+:10ecf0001c00c28f37006210000000006480829305
+:10ed000025004010000000001000c0a31080828f7a
+:10ed10001800c2af3800c28f1c0043901000c2938d
+:10ed20002b1043001b004010000000001080848f57
+:10ed300000a0023c24074524213000005b4a400f1c
+:10ed40000000000005004014000000002000c28ff9
+:10ed50002400c2afbf000010000000001000c293ea
+:10ed6000010042241000c2a33800c28f1a00439051
+:10ed70001b0042900012020025104300ffff4330a9
+:10ed80001800c28f211043001800c2afe1ff00102d
+:10ed900000000000648080a31c00c48f00a0023c1f
+:10eda00024074524d349400f000000000700401409
+:10edb00000000000ffff0234108082af2000c28fed
+:10edc0002400c2afa3000010000000001c00c28f8e
+:10edd000108082af3800c28f1e00439003000224cf
+:10ede00023006214000000001400c38f00a0023c46
+:10edf00024074224211862004000c28f000062a054
+:10ee00001400c38f00a0023c250742242118620091
+:10ee10004000c28f00ff423002120200000062a0d8
+:10ee20001400c38f00a0023c260742242120620068
+:10ee30004000c38fff00023c241062000214020055
+:10ee4000000082a01400c38f00a0023c27074224c8
+:10ee5000212062004000c38f000f023c241062009a
+:10ee600002160200000082a07700001000000000df
+:10ee70003800c28f1e004390020002241100621469
+:10ee8000000000001400c38f00a0023c24074224ad
+:10ee9000211862004000c28f000062a01400c38fde
+:10eea00000a0023c25074224211862004000c28fc6
+:10eeb00000ff423002120200000062a06200001057
+:10eec000000000003800c28f1e00439001000224a1
+:10eed0005d006214000000001400c38f00a0023c1b
+:10eee0002407422421106200000042901200c2a3b5
+:10eef0001100c2930a004010000000004000c28fc1
+:10ef00000f004230001902001200c2930f0042307d
+:10ef1000251062001200c2a30300001000000000d0
+:10ef20004000c28f1200c2a31400c38f00a0023c95
+:10ef300024074224211862001200c293000062a03c
+:10ef40001400c28f01004224ff0142301400c2affe
+:10ef50001400c28f1f004014000000003800c48f4e
+:10ef6000212800002130000001000724af3a400fa3
+:10ef70000000000005004010000000002000c28fcb
+:10ef80002400c2af33000010000000001c00c28f3c
+:10ef9000010042242120400000a0023c2407452417
+:10efa000d349400f0000000007004014000000009b
+:10efb000ffff0234108082af2000c28f2400c2af56
+:10efc00024000010000000001c00c28f0100422439
+:10efd000108082af1400c38f00a0023c240742249b
+:10efe00021106200000042901200c2a31100c293df
+:10eff00006004010000000004000c28f0211020015
+:10f000001200c2a30a000010000000004000c28fde
+:10f01000021202000f0044301200c393f0ff0224da
+:10f020002410620021188000251062001200c2a383
+:10f030001400c38f00a0023c240742242118620060
+:10f040001200c293000062a001000224648082a327
+:10f050002400c0af2400c28f21e8c0033400bf8f5a
+:10f060003000be8f3800bd270800e003000000001c
+:10f07000e8ffbd271400bfaf1000beaf21f0a00312
+:10f080001800c4af212000001800c58f21300000f7
+:10f090002c3c400f0000000021e8c0031400bf8f8b
+:10f0a0001000be8f1800bd270800e003000000001c
+:10f0b00070ffbd278800bfaf8400beaf8000b0af37
+:10f0c00021f0a003211080009400c5af9800c6afc6
+:10f0d0009000c2a3010002241200c2a79400c28fb4
+:10f0e0001800c2af2000c2277000c2af7000c48fea
+:10f0f0001880858fa732400f000000008c8180a30c
+:10f100001800c28f000042901000c2a31000c293ea
+:10f1100007004014000000001f0002248c8182a31d
+:10f12000ffff02247400c2afc40100100000000001
+:10f130001000c3937800c3af2e0002247800c38f61
+:10f1400007006210000000005c0002247800c38ffa
+:10f15000c100621000000000070100100000000064
+:10f160001800c28f010042241800c2af1800c28fdd
+:10f17000000042901000c2a31000c3932e0002248e
+:10f180008b006214000000001800c28f01004224ae
+:10f190001800c2af1800c28f000042901000c2a336
+:10f1a0007000c28f3400438c7c81828f0700621410
+:10f1b000000000001f0002248c8182a3ffff0224b4
+:10f1c0007400c2af9d010010000000007000c38fea
+:10f1d0007000c28f3400428c380062ac01000224ff
+:10f1e0001200c2a71200c2277000c48f212840005d
+:10f1f00001000624182a400f000000001400c2afce
+:10f200001400c28f07004014000000001b000224fd
+:10f210008c8182a3ffff03247400c3af8701001019
+:10f22000000000007000d08f1400c48f1c24400f19
+:10f2300000000000340002ae7000c38f7000c28f67
+:10f240003400428c380062ac7000c28f3400428cb3
+:10f250001c004014000000007000c28f5c000324fa
+:10f26000200043a0010002241100c2a31100c29398
+:10f270000b00422c0b004010000000007000c38ff8
+:10f280001100c2932118620020000224200062a015
+:10f290001100c293010042241100c2a3f3ff001029
+:10f2a000000000007000c38f7c81828f380062ac48
+:10f2b0007000c38f7c81828f340062ac1700001015
+:10f2c000000000007000c38f2e000224200062a006
+:10f2d0007000c38f2e000224210062a002000224cd
+:10f2e0001100c2a31100c2930b00422c0b0040106e
+:10f2f000000000007000c38f1100c293211862004b
+:10f3000020000224200062a01100c29301004224c8
+:10f310001100c2a3f3ff0010000000001200c0a7fc
+:10f320001200c2277000c48f21284000010006246b
+:10f33000182a400f000000000700401400000000e1
+:10f340001b0002248c8182a3ffff02247400c2af41
+:10f350003a010010000000001000c3935c0002247a
+:10f3600009006214000000001800c28f010042244e
+:10f370001800c2af1800c28f000042901000c2a354
+:10f38000f5ff0010000000001000c29368ff401459
+:10f39000000000001880848f7000c58fa732400fd6
+:10f3a000000000007400c0af240100100000000045
+:10f3b0001000c29308004014000000001880848fe1
+:10f3c0007000c58fa732400f000000007400c0af6e
+:10f3d0001a010010000000001000c3935c0002241a
+:10f3e00017006214000000001000c3935c000224a8
+:10f3f00009006214000000001800c28f01004224be
+:10f400001800c2af1800c28f000042901000c2a3c3
+:10f41000f5ff0010000000001000c29344ff4014ec
+:10f42000000000001880848f7000c58fa732400f45
+:10f43000000000007400c0af0001001000000000d8
+:10f440001f0002248c8182a3ffff03247400c3af3a
+:10f45000fa000010000000001800c28f01004224d2
+:10f460001800c2af1800c28f000042901000c2a363
+:10f470001000c3935c000224070062140000000027
+:10f480001f0002248c8182a3ffff02247400c2affc
+:10f49000ea000010000000001000c2931d0040149c
+:10f4a000000000001880838f7c81828f340062ac62
+:10f4b0001880838f7c81828f380062ac1880838fa4
+:10f4c0005c000224200062a0010002241100c2a3fb
+:10f4d0001100c2930b00422c0b00401000000000f2
+:10f4e0001880838f1100c29321186200200002242b
+:10f4f000200062a01100c293010042241100c2a3a7
+:10f50000f3ff0010000000007400c0afcb0000103b
+:10f51000000000007000c38f7c81828f340062acd9
+:10f520007000c38f7c81828f380062ac7000c38f03
+:10f530005c000224200062a0010002241100c2a38a
+:10f540001100c2930b00422cf9fe40100000000095
+:10f550007000c38f1100c2932118620020000224a2
+:10f56000200062a01100c293010042241100c2a336
+:10f57000f3ff0010000000001100c0a31000c293b0
+:10f5800019004010000000001000c3935c0002242a
+:10f5900015006210000000001100c2930c00422c04
+:10f5a000110040100000000000a0043c1100c393b3
+:10f5b000010062241100c2a3ff006330d806822438
+:10f5c000211862001000c293000062a01800c28fd0
+:10f5d000010042241800c2af000042901000c2a3f4
+:10f5e000e6ff0010000000001100c3930c0002248d
+:10f5f0000f006214000000001000c2930c004010c5
+:10f60000000000001000c3935c0002240800621098
+:10f61000000000001800c28f010042241800c2af91
+:10f62000000042901000c2a3f3ff00100000000091
+:10f6300000a0023c1100c393d806422421106200ae
+:10f64000000040a000a0023cd8064424212800006d
+:10f650003f37400f0000000005004014000000008c
+:10f66000ffff03247400c3af74000010000000000b
+:10f670001100c0a31100c2930b00422c17004010d0
+:10f68000000000001100c3931000c2272120620077
+:10f690007000c38f1100c2932110620020004290bd
+:10f6a000500082a07000c38f1100c293212062001d
+:10f6b00000a0023c1100c393d8064224211062002e
+:10f6c00000004290200082a01100c2930100422459
+:10f6d0001100c2a3e7ff00100000000000a0023ce0
+:10f6e000f80944247000c58fa732400f00000000c5
+:10f6f00000a0023cf80944247000c58f01000624d4
+:10f70000213800006e1f400f00000000070040106d
+:10f71000000000000c0002248c8182a3ffff022461
+:10f720007400c2af450000100000000000a0023cc1
+:10f73000f8094224300043941000022407006210ac
+:10f74000000000001f0002248c8182a3ffff03241d
+:10f750007400c3af39000010000000001100c0a306
+:10f760001100c2930b00422c0f004010000000005b
+:10f770007000c38f1100c2932120620000a0023ce0
+:10f780001100c393f8094224211062002000429026
+:10f79000200082a01100c293010042241100c2a3e4
+:10f7a000efff0010000000007000c38f00a0023cbb
+:10f7b000f80942240400428c340062ac7000c38f0c
+:10f7c0007000c28f3400428c380062ac1000c293cb
+:10f7d00008004014000000001880848f7000c58f5e
+:10f7e000a732400f000000007400c0af13000010eb
+:10f7f000000000001000c3935c0002244cfe621461
+:10f80000000000001800c28f010042241800c2af9f
+:10f810001800c28f000042901000c2a31000c293d3
+:10f82000f4ff4014000000001880848f7000c58f22
+:10f83000a732400f000000007400c0af7400c28ff8
+:10f8400021e8c0038800bf8f8400be8f8000b08f86
+:10f850009000bd270800e00300000000b0ffbd27b6
+:10f860004c00bfaf4800beaf21f0a0035000c4afb2
+:10f870005400c5af5000c28f0500401000000000ca
+:10f880005400c28f4000c2a303000010000000001b
+:10f890000a0002244000c2a34000c2931000c2a389
+:10f8a00000a0023cf80942241c00c2af2000c0a303
+:10f8b0003000c0af8c8180a35000c28f060040147e
+:10f8c0000000000000a0023c340a42241400c2af31
+:10f8d0000b000010000000005000c28f1400c2afe7
+:10f8e0005400c28f06004014000000001f000224d4
+:10f8f0008c8182a33c00c0afb30100100000000067
+:10f900001000c3831400c28f21106200ffff422445
+:10f910001800c2af1c00c48f1880858fa732400f1b
+:10f92000000000001c00c28f200043802e00022433
+:10f9300096006214000000001c00c28f210043806a
+:10f940002e00022491006214000000001c00c28fef
+:10f950003400428c2400c2af010002242800c2a758
+:10f960001c00c38f1c00c28f3400428c380062ac74
+:10f970002800c2271c00c48f212840000100062453
+:10f98000182a400f000000003800c2af3800c28fb4
+:10f9900006004014000000001b0002248c8182a39a
+:10f9a0003c00c0af88010010000000003800c48f88
+:10f9b0001c24400f00000000848182af8481828f6c
+:10f9c00006004014000000001c00c38f7c81828f61
+:10f9d000340062ac04000010000000001c00c38f63
+:10f9e0008481828f340062ac1c00c38f1c00c28fe4
+:10f9f0003400428c380062ac2800c0a72800c2271f
+:10fa00001c00c48f2128400001000624182a400f42
+:10fa1000000000003800c2af3800c28f060040145a
+:10fa2000000000001b0002248c8182a33c00c0afb8
+:10fa300065010010000000003800c48f1c24400f36
+:10fa400000000000848182af8481838f2400c28ff4
+:10fa500016006214000000008481838f2400c28f8e
+:10fa60002a006214000000003800c28f000043909a
+:10fa7000e50002240d006210000000003800c28f73
+:10fa80000b004390080002240800621000000000f0
+:10fa90003800c28f0b0043900f0002240300621055
+:10faa0000000000019000010000000002800c297ac
+:10fab000010042242800c2a72800c2271c00c48fce
+:10fac0002128400021300000182a400f00000000cb
+:10fad0003800c2af3800c28f06004014000000009a
+:10fae0001b0002248c8182a33c00c0af36010010b1
+:10faf000000000003800c48f1c24400f00000000ec
+:10fb0000848182afd0ff0010000000002c00c0af45
+:10fb10002c00c28f0b00422816004010000000008d
+:10fb20001c00c38f2c00c28f212062003800c38fbd
+:10fb30002c00c28f2110620000004290200082a0a1
+:10fb40001880838f2c00c28f212062003800c38f61
+:10fb50002c00c28f2110620000004290200082a081
+:10fb60002c00c28f010042242c00c2afe8ff00101d
+:10fb7000000000001c00c38f2400c28f340062ac60
+:10fb80001c00c38f2400c28f380062ac1c00c28fdf
+:10fb9000200043805c0002240a0062140000000080
+:10fba0001400c38f5c000224000062a01400c28f06
+:10fbb000010040a01400c28f3c00c2af020100103f
+:10fbc000000000001c00c28f3400438c7c81828fb7
+:10fbd00084006210000000000a0002242100c2a379
+:10fbe0001c00c38f2100c2832110620020004380cb
+:10fbf0002000022406006214000000002100c293cd
+:10fc0000ffff42242100c2a3f5ff00100000000006
+:10fc10002100c283080042282d004014000000008b
+:10fc20002100c2830800422819004014000000008f
+:10fc30003000c6270000c48c211880001400c28f39
+:10fc4000213862001c00c58f2100c393ffff62248e
+:10fc50002100c2a32014037c2110a20020004290a6
+:10fc60000000e2a0010084240000c4ac1000c383a3
+:10fc70003000c28feaff6214000000003000c0af05
+:10fc8000010002242000c2a3e5ff001000000000d4
+:10fc90003000c5270000a38c212060001400c28f13
+:10fca000212082002e000224000082a00100632493
+:10fcb0000000a3ac1000c3833000c28f04006214a4
+:10fcc000000000003000c0af010002242000c2a3e9
+:10fcd0001c00c38f2100c2832110620020004380da
+:10fce0002000022406006214000000002100c293dc
+:10fcf000ffff42242100c2a3f5ff00100000000016
+:10fd00002100c28319004004000000003000c62713
+:10fd10000000c48c211880001400c28f21386200ba
+:10fd20001c00c58f2100c393ffff62242100c2a3e2
+:10fd30002014037c2110a200200042900000e2a0c9
+:10fd4000010084240000c4ac1000c3833000c28fc3
+:10fd5000ebff6214000000003000c0af010002247d
+:10fd60002000c2a3e6ff0010000000003000c527fd
+:10fd70000000a38c212060001400c28f212082008b
+:10fd80005c000224000082a0010063240000a3acf8
+:10fd90001000c3833000c28f040062140000000012
+:10fda0003000c0af010002242000c2a31c00c38f9a
+:10fdb0001c00c28f3400428c380062ac1c00c48f1f
+:10fdc000f93f400f000000007eff401000000000df
+:10fdd000080002248c8182a33c00c0af7a0000108e
+:10fde000000000003000c28fffff42243000c2af8d
+:10fdf0002c00c0af2000c2934c0040100000000057
+:10fe00003000c28f2a00c2a73000c28f2c00c38fdf
+:10fe1000231043001b004018000000002c00c38f7b
+:10fe20001400c28f21106200000042903400c2a36f
+:10fe30002c00c38f1400c28f212062003000c38fba
+:10fe40001400c28f2110620000004290000082a0c6
+:10fe50003000c38f1400c28f211862003400c29397
+:10fe6000000062a03000c28fffff42243000c2af0a
+:10fe70002c00c28f010042242c00c2afe2ff001010
+:10fe8000000000002a00c297010042242c00c2afeb
+:10fe90001800c38f1400c28f231062003000c2af5d
+:10fea0003000c28f2c00c38f231043001b0040186a
+:10feb000000000002c00c38f1400c28f21106200cc
+:10fec000000042903400c2a32c00c38f1400c28fe4
+:10fed000212062003000c38f1400c28f2110620005
+:10fee00000004290000082a03000c38f1400c28f37
+:10fef000211862003400c293000062a03000c28f5b
+:10ff0000ffff42243000c2af2c00c28f0100422408
+:10ff10002c00c2afe2ff0010000000001800c28fea
+:10ff2000000040a026000010000000003000c28f3a
+:10ff30002a00c2a73000c28f2c00c38f23104300b9
+:10ff40001b004018000000002c00c38f1400c28f5b
+:10ff500021106200000042903400c2a32c00c38f25
+:10ff60001400c28f212062003000c38f1400c28fa2
+:10ff70002110620000004290000082a03000c38f78
+:10ff80001400c28f211862003400c293000062a0e6
+:10ff90003000c28fffff42243000c2af2c00c28f5e
+:10ffa000010042242c00c2afe2ff0010000000005c
+:10ffb0002a00c2971400c38f21104300010040a003
+:10ffc0001400c28f3c00c2af3c00c28f21e8c003c6
+:10ffd0004c00bf8f4800be8f5000bd270800e003d3
+:10ffe00000000000d8ffbd272400bfaf2000beaf37
+:10fff00021f0a0032800c4af010002241200c2a710
+:020000041d01dc
+:100000001200c2272800c48f2128400001000624c6
+:10001000182a400f000000001800c2af1800c28f5d
+:100020000500401400000000ff0002241c00c2afc5
+:10003000a7000010000000001800c48f1c24400f0f
+:1000400000000000848182af8481828f1b004014f5
+:10005000000000002800c38f5c000224200062a082
+:100060001000c0a31000c2930b00422c0b004010e4
+:10007000000000002800c38f1000c2932118620006
+:1000800020000224200062a01000c293010042243c
+:100090001000c2a3f3ff0010000000002800c38f6f
+:1000a0007c81828f340062ac2800c38f7c81828f78
+:1000b000380062ac85000010000000008481828f4f
+:1000c0001400c2af2800c38f8481828f340062acd9
+:1000d0002800c38f8481828f380062ac1200c2274f
+:1000e0002800c48f2128400001000624182a400f50
+:1000f000000000001800c2af1800c28f05004014b5
+:1001000000000000ff0002241c00c2af70000010bd
+:10011000000000001800c48f1c24400f00000000e5
+:10012000848182af8481828f060040140000000029
+:100130002800c38f7c81828f340062ac04000010e1
+:10014000000000002800c38f8481828f340062acdd
+:100150002800c38f2800c28f3400428c380062ac64
+:100160001200c0a71200c2272800c48f2128400017
+:1001700001000624182a400f000000001800c2af3a
+:100180001800c28f0500401400000000ff00022488
+:100190001c00c2af4e000010000000001800c48f09
+:1001a0001c24400f00000000848182af8481838f73
+:1001b0001400c28f16006214000000008481838f37
+:1001c0001400c28f29006214000000001800c28fc2
+:1001d00000004390e50002240d00621000000000c2
+:1001e0001800c28f0b004390080002240800621020
+:1001f000000000001800c28f0b0043900f00022483
+:100200000300621000000000180000100000000051
+:100210001200c2272800c48f21284000213000008e
+:10022000182a400f000000001800c2af1800c28f4b
+:100230000500401400000000ff0002241c00c2afb3
+:1002400023000010000000001200c29701004224a9
+:100250001200c2a71800c48f1c24400f0000000029
+:10026000848182afd1ff0010000000001000c0a305
+:100270001000c2930b00422c0e0040100000000042
+:100280002800c38f1000c293212062001800c38f82
+:100290001000c2932110430000004290200082a071
+:1002a0001000c293010042241000c2a3f0ff00100e
+:1002b000000000002800c38f1400c28f340062ac1d
+:1002c0002800c38f1400c28f380062ac1c00c0af7e
+:1002d0001c00c28f21e8c0032400bf8f2000be8f06
+:1002e0002800bd270800e00300000000e8ffbd274c
+:1002f0001400bfaf1000beaf21f0a0031800c4afc0
+:10030000212000001800c58f21300000cb40400f95
+:100310000000000021e8c0031400bf8f1000be8f52
+:100320001800bd270800e00300000000c8ffbd273b
+:100330003400bfaf3000beaf21f0a0032110800019
+:100340003c00c5af4000c6af3800c2a33c00c28f1e
+:100350001400c2af00a0023ce80642242800c2af4d
+:100360008c8180a3d54a400f000000000700401098
+:1003700000000000180002248c8182a3ffff0224e9
+:100380002c00c2af90010010000000001000c0a3bc
+:100390001400c28f000042801300401000000000d3
+:1003a0001400c28f000043802e0002240e00621051
+:1003b000000000001400c28f000043805c00022493
+:1003c00009006210000000001400c28f01004224e6
+:1003d0001400c2af1000c293010042241000c2a357
+:1003e000ebff0010000000001000c2930900422c37
+:1003f00007004014000000001f0002248c8182a32b
+:10040000ffff02242c00c2af6f01001000000000ab
+:100410001400c28f000043802e00022420006214ca
+:10042000000000001400c28f010042241400c2af7b
+:100430001000c0a31400c28f000042800e004010c4
+:10044000000000001400c28f000043805c00022402
+:1004500009006210000000001400c28f0100422455
+:100460001400c2af1000c293010042241000c2a3c6
+:10047000f0ff0010000000001000c2930400422ca6
+:1004800007004014000000001f0002248c8182a39a
+:10049000ffff02242c00c2af4b010010000000003f
+:1004a0001400c28f000043805c0002240600621426
+:1004b000000000001400c28f010042241400c2afeb
+:1004c000f7ff0010000000001400c28f00004280ff
+:1004d000aeff4014000000003c00c28f1400c2af09
+:1004e0002800c48f1880858fa732400f00000000bd
+:1004f0001400c28f000042901000c2a31000c393ea
+:100500002e00022457006214000000001400c28f65
+:10051000010042241400c2af1400c28f00004290b8
+:100520001000c2a31000c3932e0002240e0062101c
+:10053000000000001000c2930b00401000000000fb
+:100540001000c3935c00022407006210000000004a
+:100550001f0002248c8182a3ffff02242c00c2af63
+:1005600019010010000000001000c3932e000224a7
+:1005700023006214000000001880828f3400438c36
+:100580007c81828f07006214000000001f0002249b
+:100590008c8182a3ffff02242c00c2af0a0100104d
+:1005a000000000001400c28f010042241400c2affa
+:1005b0001400c28f000042901000c2a31000c39329
+:1005c0005c0002240a006210000000001000c293c8
+:1005d00007004010000000001f0002248c8182a34d
+:1005e000ffff02242c00c2aff70000100000000043
+:1005f000029d023c340744241c3c400f00000000d4
+:100600001000c3935c000224090062140000000083
+:100610001400c28f010042241400c2af1400c28f24
+:10062000000042901000c2a3f5ff0010000000007f
+:100630001000c293aeff4014000000001880848fa9
+:100640002800c58fa732400f000000001f000224c1
+:100650008c8182a3ffff02242c00c2afda000010bd
+:10066000000000001000c3935c0002243b006214f1
+:10067000000000001880838f7c81828f340062ac80
+:100680001880838f7c81828f380062ac1880838fc2
+:100690005c000224200062a0010002241000c2a31a
+:1006a0001000c2930b00422c0b0040100000000011
+:1006b0001880838f1000c29321186200200002244a
+:1006c000200062a01000c293010042241000c2a3c7
+:1006d000f3ff0010000000001400c28f010042244c
+:1006e0001400c2af1400c28f000042901000c2a3d9
+:1006f0001000c3935c0002240b0062140000000091
+:100700001880848f2800c58fa732400f000000009a
+:100710001f0002248c8182a3ffff02242c00c2afa1
+:10072000a9000010000000001000c29370ff4014e8
+:10073000000000001880848f2800c58fa732400f6a
+:10074000000000001f0002248c8182a3ffff02240e
+:100750002c00c2af9c000010000000002400c0a3c9
+:100760001400c28f000042901000c2a31100c0a369
+:100770001000c29319004010000000001000c39345
+:100780005c00022415006210000000001100c293fa
+:100790000c00422c11004010000000001100c39317
+:1007a000010062241100c2a3ff0063301000c227c1
+:1007b000211862001000c293080062a01400c28fca
+:1007c000010042241400c2af1400c28f0000429006
+:1007d0001000c2a3e6ff0010000000001100c39348
+:1007e0001000c22721106200080040a01800c38337
+:1007f0002e00022423006214000000001900c283ae
+:100800000f004010000000001900c3832e000224d6
+:100810000b006210000000001880848f2800c58f34
+:10082000a732400f000000001f0002248c8182a329
+:10083000ffff02242c00c2af630000100000000084
+:100840001900c3832e0002240e0062140000000071
+:100850001a00c2830b004010000000001880848f33
+:100860002800c58fa732400f000000001f0002249f
+:100870008c8182a3ffff02242c00c2af5200001023
+:10088000000000001800c227212040001c3c400f3f
+:1008900000000000030040100000000017000010de
+:1008a000000000001000c3935c00022409006214e1
+:1008b000000000001400c28f010042241400c2afe7
+:1008c0001400c28f000042901000c2a3f5ff001078
+:1008d000000000001000c293a1ff401400000000bf
+:1008e0001880848f2800c58fa732400f00000000b9
+:1008f0002c00c0af34000010000000001800c22718
+:10090000212040007942400f0000000009004014ff
+:10091000000000001880848f2800c58fa732400f88
+:1009200000000000ffff02242c00c2af26000010d0
+:10093000000000001800c227212040001c3c400f8e
+:10094000000000000b004010000000001880848fa1
+:100950002800c58fa732400f000000001b000224b2
+:100960008c8182a3ffff02242c00c2af160000106e
+:10097000000000001400c28f000043805c000224cd
+:1009800009006214000000001400c28f010042241c
+:100990001400c2af1400c28f000042901000c2a326
+:1009a000f4ff0010000000001000c2936cff401420
+:1009b000000000001880848f2800c58fa732400fe8
+:1009c000000000002c00c0af2c00c28f21e8c00343
+:1009d0003400bf8f3000be8f3800bd270800e00311
+:1009e00000000000c8ffbd273400bfaf3000beaf1d
+:1009f00021f0a0033800c4af00a0023cf809422453
+:100a00001000c2af1800c0a72400c0a32400c293e6
+:100a10000c00422c0f0040100000000000a0023c1f
+:100a20002400c393d8064224212062002400c393eb
+:100a30003800c28f2110620000004290000082a0a6
+:100a40002400c293010042242400c2a3efff00103f
+:100a50000000000000a0023cd80644242128000029
+:100a60003f37400f00000000060040140000000067
+:100a7000120002248c8182a32800c0af6f000010f6
+:100a8000000000002400c0a32400c2930b00422ced
+:100a90000f004010000000001000c38f2400c2931c
+:100aa0002120620000a0023c2400c393d806422407
+:100ab0002110620000004290200082a02400c29316
+:100ac000010042242400c2a3efff00100000000038
+:100ad0001000c38f1880828f3400428c340062acc7
+:100ae0001000c38f1880828f3800428c380062acaf
+:100af0001000c28f040040ac1000c28f080040ac50
+:100b00001000c38f1880828f0000428c000062acfe
+:100b10001800c2271000c48f2128400012000624ac
+:100b2000062b400f000000000400401000000000f1
+:100b30002800c0af410000100000000064808293d4
+:100b40000f004010000000001000c28f0000448c15
+:100b5000212800002130000001000724af3a400f97
+:100b60000000000006004010000000000900022400
+:100b70008c8182a32800c0af30000010000000006c
+:100b80001000c28f3400438c7c81828f0400621479
+:100b9000000000002000c0af0400001000000000b2
+:100ba0001000c28f3400428c2000c2af1000c38fef
+:100bb0001000c28f3400428c380062ac1800c2278b
+:100bc0001000c48f2128400001000624182a400f7d
+:100bd000000000001400c2af1400c28f06004014d1
+:100be000000000001b0002248c8182a32800c0affb
+:100bf00012000010000000001400c48f1c24400fdd
+:100c0000000000001c00c2af1000c28f0000448c26
+:100c10001c00c58f2000c68f1643400f0000000047
+:100c20000500401000000000010002242800c2afaf
+:100c300002000010000000002800c0af2800c28f92
+:100c400021e8c0033400bf8f3000be8f3800bd27bd
+:100c50000800e00300000000b0ffbd274c00bfaf5c
+:100c60004800beaf21f0a0035000c4af5400c5af90
+:100c70005800c6af1800c2273800c2af688080afe6
+:100c8000200002241200c2a75000c28f0300438834
+:100c9000000043982110600021204000212800001e
+:100ca00000020624096b400f000000002e00022401
+:100cb0001800c2a3010002241000c2a71000c297ae
+:100cc0000b00422c0b004010000000001000c397e6
+:100cd0001000c2272118620020000224080062a030
+:100ce0001000c297010042241000c2a7f3ff0010b9
+:100cf00000000000100002242300c2a32400c0a3af
+:100d00005400c28f3200c2a75400c38fff0f023cb1
+:100d100024106200021402002c00c2a73400c0afed
+:100d2000778182932500c2a3788182972600c2a78b
+:100d3000828182972800c2a72a00c0a72e00c0a7e0
+:100d40003000c0a71000c0a71000c2971200c397c0
+:100d50002b10430010004010000000005000c28f14
+:100d600003004388000043981000c29721204300ed
+:100d70001000c3973800c28f21106200000042901b
+:100d8000000082a01000c297010042241000c2a7f8
+:100d9000edff0010000000002e0002241900c2a385
+:100da0005800c28f3200c2a75800c38fff0f023c09
+:100db00024106200021402002c00c2a71000c0a779
+:100dc0001000c2971200c3972b104300120040106e
+:100dd000000000005000c28f0300438800004398c9
+:100de0001000c4971200c297211043002120440034
+:100df0001000c3973800c28f21106200000042909b
+:100e0000000082a01000c297010042241000c2a777
+:100e1000ebff0010000000005000c48f5400c58f8d
+:100e2000cd33400f000000003c00c2af5000c28f25
+:100e30000300438800004398211060003c00c48fe9
+:100e400021284000213000005b4a400f00000000d4
+:100e50000600401400000000090002248c8182a3d7
+:100e60004000c0af03000010000000000100022499
+:100e70004000c2af4000c28f21e8c0034c00bf8fca
+:100e80004800be8f5000bd270800e00300000000ae
+:100e9000e8ffbd271400bfaf1000beaf21f0a003d4
+:100ea0001800c4af2110a0001c00c2a31c00c293f4
+:100eb000212000001800c58f21300000213840009b
+:100ec000b843400f0000000021e8c0031400bf8faa
+:100ed0001000be8f1800bd270800e00300000000ce
+:100ee000b8ffbd274400bfaf4000beaf21f0a00354
+:100ef000211880004c00c5af5000c6af2110e000a3
+:100f00004800c3a35400c2a300a0023ce806422448
+:100f10001000c2af00a0023cf80942241400c2af86
+:100f20001c00c0a7029d023c3807448c38074324ac
+:100f30000400638c380742240800428c2800c4afa8
+:100f40002c00c3af3000c2af3400c0a38c8180a39b
+:100f50001000c48f1880858fa732400f000000005a
+:100f60004c00c48f1c3c400f0000000007004010e4
+:100f7000000000000c0002248c8182a3ffff0224e9
+:100f80003800c2af80020010000000001880828f7d
+:100f90003400438c7c81828f0900621000000000c5
+:100fa0001880828f1000c38f3400448c3400628c10
+:100fb00003008210000000000b0000100000000081
+:100fc0001880848f1000c58fa732400f00000000ea
+:100fd0001f0002248c8182a3ffff02243800c2afcd
+:100fe00069020010000000001c00c29701004224aa
+:100ff0001c00c2a71c00c2271880848f2128400033
+:1010000001000624182a400f000000001800c2af9b
+:101010001800c28f0b004014000000001880848f5d
+:101020001000c58fa732400f000000001b000224f3
+:101030008c8182a3ffff02243800c2af520200104d
+:10104000000000001c00c297010042241c00c2a73f
+:101050001c00c2271880848f212840002130000006
+:10106000182a400f000000001800c2af1800c28ffd
+:101070000b004014000000001880848f1000c58f02
+:10108000a732400f000000001b0002248c8182a3c5
+:10109000ffff02243800c2af3b0200100000000036
+:1010a0005400c2932b004014000000001800c28faf
+:1010b00000004280e8014010000000001800c28fcc
+:1010c00000004390e50002240b00621000000000c5
+:1010d0001880848f1000c58fa732400f00000000d9
+:1010e000160002248c8182a3ffff02243800c2afc5
+:1010f00025020010000000001c00c29701004224dd
+:101100001c00c2a71c00c2271880848f2128400021
+:1011100021300000182a400f000000001800c2af64
+:101120001800c28fe1ff4014000000001880848f77
+:101130001000c58fa732400f000000001b000224e2
+:101140008c8182a3ffff02243800c2af0e02001080
+:1011500000000000888180a32000c0a788818293be
+:10116000bd014014000000001800c28f0000428042
+:10117000ee004010000000001800c28f00004390f5
+:10118000e5000224c1006210000000001800c28fb8
+:101190000b00439008000224bc0062100000000015
+:1011a0001800c28f0b0043900f000224b70062109a
+:1011b000000000001800c28f0b0042901000423067
+:1011c00070004010000000002000c297010042247f
+:1011d0002000c2a72200c0a32200c2930800422c14
+:1011e00015004010000000001800c38f2200c293b9
+:1011f0002110430000004380200002240e006210f2
+:10120000000000002200c3931000c22721206200ca
+:101210001800c38f2200c2932110430000004290a7
+:10122000180082a02200c293010042242200c2a31f
+:10123000e9ff0010000000001800c28f0800438082
+:101240002000022425006210000000002200c39349
+:10125000010062242200c2a3ff0063301000c227f5
+:10126000211862002e000224180062a02300c0a3ef
+:101270002300c2930300422c18004010000000001d
+:101280001800c38f2300c29321106200080043801e
+:101290002000022411006210000000002200c3930d
+:1012a000010062242200c2a3ff0063301000c227a5
+:1012b000212062001800c38f2300c2932110620016
+:1012c00008004290180082a02300c293010042242b
+:1012d0002300c2a3e6ff0010000000002200c39319
+:1012e0001000c22721106200180040a02800c22769
+:1012f000212040001c3c400f000000000b0040106b
+:10130000000000001880848f1000c58fa732400fa6
+:10131000000000000c0002248c8182a3ffff022445
+:101320003800c2af98010010000000001880828fc2
+:101330001000c38f3400448c3400628c0b00821484
+:10134000000000001880848f1000c58fa732400f66
+:10135000000000001f0002248c8182a3ffff0224f2
+:101360003800c2af88010010000000000200022413
+:101370001c00c2a7010002246f8082a34600001057
+:10138000000000002800c227212040002128000082
+:101390000c000624096b400f000000002200c0a3cf
+:1013a0002200c2930b00422c0e00401000000000ef
+:1013b0001400c38f2200c293212062001800c38f43
+:1013c0002200c2932110430000004290200082a01e
+:1013d0002200c293010042242200c2a3f0ff0010a9
+:1013e000000000001400c38f00a0023cd809422472
+:1013f000000062ac1400c38f1c00c2972c0062a4d2
+:101400001400c38f1880828f3400428c340062ac89
+:101410001400c38f1880828f3800428c380062ac71
+:101420001400c28f040040ac1400c28f080040ac0e
+:101430001c00c2271400c48f21284000010006248c
+:10144000042f400f000000000b00401000000000bf
+:101450001880848f1000c58fa732400f0000000055
+:10146000010002248c8182a3ffff02243800c2af56
+:1014700045010010000000001c00c297010042243a
+:101480001c00c2a704000010000000001c00c2974e
+:10149000010042241c00c2a76f8082930f004010fd
+:1014a000000000006f8080a31880838f1880828fd7
+:1014b0003400428c380062ac1c00c2271880848f34
+:1014c0002128400001000624182a400f00000000d7
+:1014d0001800c2af08000010000000001c00c22766
+:1014e0001880848f2128400021300000182a400fe6
+:1014f000000000001800c2af1800c28f17ff401490
+:10150000000000001880848f1000c58fa732400fa4
+:10151000000000001b0002248c8182a3ffff022434
+:101520003800c2af18010010000000002000c29770
+:10153000c5004010000000001e00c0a71880838f67
+:101540001880828f3400428c380062ac1e00c227a3
+:101550001880848f2128400001000624182a400f9b
+:10156000000000001800c2af1800c28f0b0040142a
+:10157000000000001880848f1000c58fa732400f34
+:10158000000000001b0002248c8182a3ffff0224c4
+:101590003800c2affc000010000000001800c48f2b
+:1015a0001c24400f000000001e00c2a7029d023c48
+:1015b000340744241c3c400f000000000b00401086
+:1015c000000000001880848f1000c58fa732400fe4
+:1015d000000000000c0002248c8182a3ffff022483
+:1015e0003800c2afe8000010000000000200022432
+:1015f0001c00c2a71880838f1880828f3400428c11
+:10160000380062ac1c00c2271880848f212840005b
+:1016100001000624182a400f000000001800c2af85
+:101620001800c28f0b004014000000001880848f47
+:101630001000c58fa732400f000000001b000224dd
+:101640008c8182a3ffff02243800c2afce000010bd
+:10165000000000001800c48f1c24400f0000000090
+:10166000848182af1e00c3978481828f110062142f
+:10167000000000001e00c3978481828f2a0062143c
+:10168000000000001800c28f00004390e500022413
+:1016900008006210000000001800c28f0b00439089
+:1016a0000800022403006210000000001e00001069
+:1016b000000000001c00c297010042241c00c2a7c9
+:1016c0001c00c2271880848f212840002130000090
+:1016d000182a400f000000001800c2af1800c28f87
+:1016e0000b004014000000001880848f1000c58f8c
+:1016f000a732400f000000001b0002248c8182a34f
+:10170000ffff02243800c2af9f000010000000005d
+:101710001800c48f1c24400f00000000848182af99
+:10172000d0ff0010000000002800c2272120400048
+:10173000212800000c000624096b400f0000000067
+:101740002200c0a32200c2930b00422c0e004010c6
+:10175000000000002200c3931000c2272120620075
+:101760001800c38f2200c293211043000000429052
+:10177000180082a02200c293010042242200c2a3ca
+:10178000f0ff0010000000002800c22721204000c8
+:101790006946400f000000000b00401000000000f0
+:1017a0001880848f1000c58fa732400f0000000002
+:1017b000010002248c8182a3ffff02243800c2af03
+:1017c00071000010000000001c00c29701004224bc
+:1017d0001c00c2a71880838f1880828f3400428c2f
+:1017e000380062ac1c00c2271880848f212840007a
+:1017f00001000624182a400f000000001800c2afa4
+:101800001800c28f0b004014000000001880848f65
+:101810001000c58fa732400f000000001b000224fb
+:101820008c8182a3ffff02243800c2af5600001053
+:10183000000000002000c297ffff42242000c2a742
+:1018400046fe00100000000001000224888182a3ef
+:1018500042fe0010000000002800c22721204000a6
+:101860000c000524173e400f000000000900401442
+:10187000000000001880848f1000c58fa732400f31
+:1018800000000000ffff02243800c2af3e0000103d
+:10189000000000002800c22721204000212800006d
+:1018a0000c000624096b400f000000002200c0a3ba
+:1018b0002200c2930b00422c0e00401000000000da
+:1018c0002200c3931000c227212062001880838f5a
+:1018d0002200c2932110620020004290180082a0d2
+:1018e0002200c293010042242200c2a3f0ff001094
+:1018f00000000000029d023c340744241c3c400fc1
+:10190000000000000b004010000000001880848fd1
+:101910001000c58fa732400f000000000c00022409
+:101920008c8182a3ffff02243800c2af1600001092
+:10193000000000002800c227212040006946400f17
+:10194000000000000b004010000000001880848f91
+:101950001000c58fa732400f0000000001000224d4
+:101960008c8182a3ffff02243800c2af0600001062
+:10197000000000001880848f1000c58fa732400f30
+:10198000000000003800c0af3800c28f21e8c0035b
+:101990004400bf8f4000be8f4800bd270800e00311
+:1019a0000000000098ffbd276400bfaf6000beaf1d
+:1019b00021f0a0036800c4afd54a400f000000002a
+:1019c0000500401000000000ffff02245800c2afd5
+:1019d0004b000010000000001800c227212040002a
+:1019e0001880858fa732400f000000001400c0a3ac
+:1019f0001400c2930b00422c0e00401000000000a7
+:101a00001880838f1400c293212062001400c393b6
+:101a10006800c28f2110620000004290200082a066
+:101a20001400c293010042241400c2a3f0ff00106e
+:101a30000000000000a0023cf80944241880858fb3
+:101a4000a732400f000000001880848f00a0023ce5
+:101a5000f809452401000624213800006e1f400fbc
+:101a6000000000001000c2af1000c28f0a0040103a
+:101a7000000000001800c2271880848f2128400031
+:101a8000a732400f00000000ffff02245800c2af41
+:101a90001b000010000000001880828f2c004224e0
+:101aa0001880848f2128400001000624042f400f55
+:101ab000000000001000c2af1000c28f09004014e7
+:101ac000000000001800c2271880848f21284000e1
+:101ad000a732400f000000005800c0af08000010ff
+:101ae000000000001800c2271880848f21284000c1
+:101af000a732400f00000000ffff02245800c2afd1
+:101b00005800c28f21e8c0036400bf8f6000be8f01
+:101b10006800bd270800e0030000000098ffbd2713
+:101b20006400bfaf6000beaf21f0a0036800c4af87
+:101b30006c00c5af7000c6af1000c2275000c2af26
+:101b40008c8180a35000c28f200042246800c48f83
+:101b50002128400001000624a136400f00000000ab
+:101b60000700401400000000120002248c8182a3b0
+:101b7000ffff02245c00c2aff00000100000000074
+:101b80007000c28f300040a05b00c0a35b00c29316
+:101b90000c00422c14004010000000005b00c393b6
+:101ba0006800c28f21106200000042800e004010c9
+:101bb000000000007000c38f5b00c2932120620010
+:101bc0005b00c3936800c28f211062000000429046
+:101bd0001c0082a05b00c293010042245b00c2a3f0
+:101be000eaff0010000000007000c38f5b00c2938a
+:101bf000211062001c0040a07000c38f6c00c28fd7
+:101c0000290062a07000c38f1880828f3400428c3c
+:101c10002c0062ac5000c38f00a0023cd8094224c3
+:101c2000000062ac5000c28f040040ac5000c28f74
+:101c3000080040ac5000c28f2c0040a45000c38f5d
+:101c40006c00c28f300062a45000c38f1880828f56
+:101c50003400428c340062ac5000c38f1880828ff5
+:101c60003800428c380062ac00a0023cf8094424e1
+:101c70005000c58fa732400f000000005000c48ff5
+:101c800000a0023cf80945240100062401000724b5
+:101c90006e1f400f000000005400c2af5400c28ffe
+:101ca00007004010000000000b0002248c8182a37a
+:101cb000ffff02245c00c2afa00000100000000083
+:101cc0005000c28f2c0042945800c2a75800c2276f
+:101cd0005000c48f21284000720006247a20400f53
+:101ce000000000005400c2af5400c28f8f004014a7
+:101cf000000000005000c28f30004394080002240e
+:101d00005a006210000000005b00c0a35a00c0a38c
+:101d10005a00c2930800422c180040100000000036
+:101d20005000c38f5a00c2932110620020004380ec
+:101d30002000022411006210000000007000c38f18
+:101d40005b00c293212043005000c38f5a00c2930e
+:101d50002110620020004290000082a05b00c2932c
+:101d6000010042245b00c2a35a00c2930100422436
+:101d70005a00c2a3e6ff0010000000005000c28f0e
+:101d800028004380200002240d006214000000009f
+:101d90005000c28f290043802000022408006214f2
+:101da000000000005000c28f2a004380200002245f
+:101db0000300621400000000090000100000000091
+:101dc0007000c48f5b00c393010062245b00c2a358
+:101dd000ff006230211844002e000224000062a09f
+:101de000080002245a00c2a35a00c2930b00422cde
+:101df00018004010000000005000c38f5a00c2932a
+:101e00002110620020004380200002241100621093
+:101e1000000000007000c38f5b00c29321204300cc
+:101e20005000c38f5a00c2932110620020004290dc
+:101e3000000082a05b00c293010042245b00c2a3a9
+:101e40005a00c293010042245a00c2a3e6ff0010c8
+:101e5000000000007000c28f5b00c393211062007d
+:101e6000000040a017000010000000005b00c0a3ad
+:101e70005b00c2930b00422c0e00401000000000db
+:101e80007000c38f5b00c293212043005000c38fba
+:101e90005b00c2932110620020004290000082a0eb
+:101ea0005b00c293010042245b00c2a3f0ff00105c
+:101eb000000000007000c28f5b00c393211062001d
+:101ec000000040a07000c38f5000c28f30004294c9
+:101ed0000d0062a07000c38f5000c28f1400428cae
+:101ee000100062ac7000c48f5000c28f1e0042947c
+:101ef000001c02005000c28f1c004294211062009e
+:101f0000140082ac7000c38f5000c28f2c0042942a
+:101f1000180062ac7000c38f01000224300062a080
+:101f20005c00c0af05000010000000001b00022490
+:101f30008c8182a3ffff02245c00c2af5c00c28fd1
+:101f400021e8c0036400bf8f6000be8f6800bd271a
+:101f50000800e0030000000098ffbd276400bfaf49
+:101f60006000beaf21f0a0036800c4af1000c2271c
+:101f70005000c2af8c8180a36800c28f30004290b5
+:101f80000700401400000000070002248c8182a397
+:101f9000ffff02245c00c2afd6000010000000006a
+:101fa0006800c28f1880838f2c00448c3400628cb0
+:101fb00007008210000000001f0002248c8182a311
+:101fc000ffff02245c00c2afca0000100000000046
+:101fd0006800c28f1c0043245000c28f200042249e
+:101fe000212060002128400001000624a136400f76
+:101ff000000000000700401400000000120002244e
+:102000008c8182a3ffff02245c00c2afb9000010e4
+:10201000000000005000c38f00a0023cd8094224f9
+:10202000000062ac5000c28f040040ac5000c28f70
+:10203000080040ac5000c38f6800c28f1800428c6b
+:10204000010042242c0062a45000c38f6800c28f9c
+:1020500029004290300062a45000c38f1880828f04
+:102060003400428c340062ac5000c38f1880828fe1
+:102070003800428c380062ac00a0023cf8094424cd
+:102080005000c58fa732400f000000005000c48fe1
+:1020900000a0023cf80945240100062401000724a1
+:1020a0006e1f400f000000005400c2af5400c28fea
+:1020b00007004010000000000b0002248c8182a366
+:1020c000ffff02245c00c2af8a0000100000000085
+:1020d0005000c28f30004394080002245a0062105e
+:1020e000000000005800c0a35900c0a35900c293cb
+:1020f0000800422c18004010000000005000c38f60
+:102100005900c29321106200200043802000022465
+:1021100011006210000000006800c38f5800c293d5
+:10212000212043005000c38f5900c2932110620048
+:1021300020004290000082a05800c2930100422477
+:102140005800c2a35900c293010042245900c2a3ff
+:10215000e6ff0010000000005000c28f28004380fe
+:10216000200002240d006214000000005000c28f05
+:1021700029004380200002240800621400000000af
+:102180005000c28f2a004380200002240300621402
+:102190000000000009000010000000006800c48f6b
+:1021a0005800c393010062245800c2a3ff006230ac
+:1021b000211844002e000224000062a0080002241e
+:1021c0005900c2a35900c2930b00422c18004010c2
+:1021d000000000005000c38f5900c293211062001c
+:1021e0002000438020000224110062100000000043
+:1021f0006800c38f5800c293212043005000c38f52
+:102200005900c2932110620020004290000082a079
+:102210005800c293010042245800c2a35900c2933f
+:10222000010042245900c2a3e6ff00100000000094
+:102230006800c28f5800c39321106200000040a0c4
+:1022400017000010000000005800c0a35800c293ff
+:102250000b00422c0e004010000000006800c38fed
+:102260005800c293212043005000c38f5800c293ee
+:102270002110620020004290000082a05800c2930a
+:10228000010042245800c2a3f0ff0010000000002b
+:102290006800c28f5800c39321106200000040a064
+:1022a0006800c38f5000c28f300042940d0062a0be
+:1022b0006800c38f5000c28f1400428c100062acc3
+:1022c0006800c48f5000c28f1e004294001c0200a0
+:1022d0005000c28f1c00429421106200140082ac96
+:1022e0006800c38f5000c28f2c004294180062ac6b
+:1022f0005c00c0af5c00c28f21e8c0036400bf8fe8
+:102300006000be8f6800bd270800e00300000000e9
+:10231000f0ffbd270800beaf21f0a00388bf023c3c
+:102320001061428c0001427c0000c2af0000c38fec
+:10233000000062380100422c0000c2af0000c28fd2
+:1023400021e8c0030800be8f1000bd270800e0038d
+:1023500000000000f8ffbd270000beaf21f0a00381
+:102360000002022421e8c0030000be8f0800bd2740
+:102370000800e00300000000f8ffbd270000beaf2a
+:1023800021f0a0039081828f21e8c0030000be8f5e
+:102390000800bd270800e00300000000f8ffbd278b
+:1023a0000000beaf21f0a00388bf033c0061629033
+:1023b00010004234006162a088bf033c506062900c
+:1023c00002004234506062a088bf043c40608390a9
+:1023d000fdff022424106200406082a088bf033cfd
+:1023e0000061629008004234006162a021e8c003ed
+:1023f0000000be8f0800bd270800e00300000000b9
+:10240000e8ffbd271400bfaf1000beaf21f0a0034e
+:10241000ff4a400f0000000088bf033c50606290fc
+:1024200002004234506062a02110000021e8c00385
+:102430001400bf8f1000be8f1800bd270800e003f6
+:1024400000000000d0ffbd272c00bfaf2800beafaa
+:1024500021f0a0033000c4af2110a0003800c6afa7
+:102460003400c2a3080002241000c2a788bf043ca5
+:1024700050608390fdff022424106200506082a00f
+:10248000029d043c3400c393211060004010020000
+:1024900021104300801802004807822421106200a6
+:1024a000000042902000c2a33800c28f1c00c2afbf
+:1024b000029d043c3400c3932110600040100200d0
+:1024c0002110430080180200480782242110620076
+:1024d000010042901800c2a32000c28f4000423485
+:1024e0002000c2af2000c293212040000c4b400fbf
+:1024f000000000001f00c293212040000c4b400f41
+:10250000000000001e00c293212040000c4b400f31
+:10251000000000001d00c293212040000c4b400f22
+:10252000000000001c00c293212040000c4b400f13
+:10253000000000001800c293212040000c4b400f07
+:1025400000000000029d023c3400c393480744246d
+:102550002110600040100200211043008010020092
+:10256000211044000400428c0f00401000000000c5
+:10257000029d023c3400c3934807442421106000ac
+:10258000401002002110430080100200211044007e
+:102590000400438c010002240300621000000000cc
+:1025a0001000001000000000264b400f000000004b
+:1025b0001400c2a31000c297ffff42241000c2a75c
+:1025c0001400c393ff0002241a00621400000000ec
+:1025d0001000c2971700401000000000f2ff00102a
+:1025e00000000000029d023c3400c39348074424cd
+:1025f00021106000401002002110430080100200f2
+:10260000211044000400438c0200022409006214db
+:1026100000000000264b400f00000000264b400f3a
+:10262000000000001500c2a3264b400f0000000070
+:102630001400c2a3029d023c3400c3934807442403
+:1026400021106000401002002110430080100200a1
+:10265000211044000400438c010002241f00621476
+:10266000000000001400c0a31200c0a31200c39316
+:10267000ff00022419006210000000001400c29341
+:102680001600401400000000ffff02241000c2a743
+:10269000264b400f000000001400c2a31000c29798
+:1026a000ffff42241000c2a71400c293060040148a
+:1026b000000000001000c29703004010000000005e
+:1026c000f3ff0010000000001200c293010042243a
+:1026d0001200c2a3e5ff001000000000ff00042468
+:1026e0000c4b400f00000000029d043c3400c393db
+:1026f00021106000401002002110430080180200e9
+:10270000480782242110620008004290050040140e
+:102710000000000088bf023c506043900200633418
+:10272000506043a01400c28f3000c38f000062ac21
+:102730003000c28f21e8c0032c00bf8f2800be8f5d
+:102740003000bd270800e00300000000d0ffbd27d7
+:102750002c00bfaf2800beaf21f0a0033000c4aff3
+:102760003400c5af010002241900c2a33000c28f9b
+:10277000401202001c00c2af1400c22721204000fa
+:10278000070005241c00c68f1149400f00000000ff
+:102790001400c2930d004010000000001400c22776
+:1027a00021204000070005241c00c68f1149400f5e
+:1027b000000000001400c29304004010000000005c
+:1027c0002000c0af6200001000000000ff020224e1
+:1027d0001000c2a7400002241200c2a71200c29734
+:1027e00006004010000000001200c297ffff4224c4
+:1027f0001200c2a7f9ff001000000000264b400f96
+:10280000000000001800c2a31000c297ffff42247e
+:102810001000c2a7400002241200c2a71200c297f3
+:1028200006004010000000001200c297ffff422483
+:102830001200c2a7f9ff0010000000001800c393a7
+:10284000ff00022406006214000000001000c2977e
+:102850000300401000000000e8ff0010000000002e
+:102860001000c29707004010000000001800c3933a
+:10287000fe000224030062140000000004000010a7
+:10288000000000001900c0a3280000100000000094
+:102890001000c0a71000c2970002422c1d0040107b
+:1028a000000000003400c28f130040100000000040
+:1028b00080bf033cff000224205a62ac80bf023c70
+:1028c000105a428c0000427c0300401400000000bb
+:1028d000faff0010000000001000c3973400c28f00
+:1028e0002118620080bf023c205a428c000062a086
+:1028f0000300001000000000264b400f0000000005
+:102900001000c297010042241000c2a7e1ff00108e
+:1029100000000000ff0004240c4b400f00000000ea
+:10292000ff0004240c4b400f00000000ff000424b3
+:102930000c4b400f0000000088bf033c50606290c9
+:1029400002004234506062a01900c2932000c2af5e
+:102950002000c28f21e8c0032c00bf8f2800be8f4b
+:102960003000bd270800e00300000000d8ffbd27ad
+:102970002400bfaf2000beaf21f0a0032800c4afe9
+:102980002c00c5af2110c0003000c2a301000224fa
+:102990001800c2a32800c28f0700401400000000e6
+:1029a0003000c29304004014000000001800c0a3cf
+:1029b00061000010000000001400c3272800c28f2f
+:1029c000401202002120600009000524213040004f
+:1029d0001149400f000000001400c2930400401091
+:1029e000000000001800c0a34f000010000000000d
+:1029f000fe0004240c4b400f000000001000c0a794
+:102a00001000c2970002422c160040100000000087
+:102a100080bf043c1000c3972c00c28f21106200bd
+:102a200000004290205a82ac80bf023c105a428c77
+:102a30000000427c0300401400000000faff001078
+:102a40000000000080bf023c205a428c1200c2a34a
+:102a50001000c297010042241000c2a7e8ff001036
+:102a600000000000ff0004240c4b400f0000000099
+:102a7000ff0004240c4b400f00000000264b400fc9
+:102a8000000000001200c2a31200c2930f004330e6
+:102a90000500022404006210000000001800c0a31a
+:102aa0001e000010000000001000c0a780bf033c03
+:102ab000ff000224205a62ac80bf023c105a428cb4
+:102ac0000000427c0300401400000000faff0010e8
+:102ad0000000000080bf023c205a428c1200c2a3ba
+:102ae0001000c297010042241000c2a71200c29336
+:102af00006004014000000001000c29703004010c0
+:102b000000000000e9ff0010000000001000c29764
+:102b100002004014000000001800c0a3ff000424bd
+:102b20000c4b400f0000000088bf023c50604390f7
+:102b300002006334506043a01800c29321e8c00330
+:102b40002400bf8f2000be8f2800bd270800e003af
+:102b500000000000f8ffbd270000beaf21f0a00379
+:102b600088bf023c1061428cc000427cff004230b2
+:102b700021e8c0030000be8f0800bd270800e00365
+:102b800000000000f0ffbd270800beaf21f0a00349
+:102b9000211080001000c2a31000c2930000c2a345
+:102ba0000000c293ffff42240000c2a3ff00433095
+:102bb000ff0002240c006210000000000b2702241a
+:102bc0000400c2af0400c28fffff4224211840005e
+:102bd0000400c3afffff0224f1ff621000000000f9
+:102be000f8ff0010000000000000000021e8c00312
+:102bf0000800be8f0800e0031000bd27f8ffbd27c6
+:102c00000000beaf21f0a00380bf033c80bf023ca8
+:102c1000105a428cff7f4230105a62ac21e8c00348
+:102c20000000be8f0800bd270800e0030000000080
+:102c3000e0ffbd271c00bfaf1800beaf21f0a0030e
+:102c4000211080002000c2a380bf023c105a428c99
+:102c5000c000427c0300401400000000faff001096
+:102c60000000000080bf033c2000c293205a62ace9
+:102c7000ec7e400f000000001000c2a321100000f5
+:102c800021e8c0031c00bf8f1800be8f2000bd27a5
+:102c90000800e00300000000e8ffbd271400bfaffc
+:102ca0001000beaf21f0a00380bf023c105a428c3e
+:102cb000c000427c0300401400000000faff001036
+:102cc0000000000080bf033cff000224205a62acd9
+:102cd000ec7e400f00000000ff00423021e8c003fe
+:102ce0001400bf8f1000be8f1800bd270800e0033e
+:102cf00000000000f8ffbd270000beaf21f0a003d8
+:102d00000800c4af80bf023c105a40ac80bf033cf7
+:102d1000005a629040004234005a62a080bf043cd6
+:102d2000015a8390feff022424106200015a82a0ff
+:102d300088bf043c80618390bfff0224241062009e
+:102d4000806182a088bf043c81618390feff0224e1
+:102d500024106200816182a088bf043c806183905e
+:102d600080ff022425106200806182a080bf043ca5
+:102d7000015a839080ff022425106200015a82a02c
+:102d800021e8c0030000be8f0800bd270800e00353
+:102d900000000000c0ffbd273c00bfaf3800beaf41
+:102da00021f0a003010002241200c2a303000224a8
+:102db0001800c2a788bf033c5060629002004234f2
+:102dc000506062a02003042400800534f57e400f8b
+:102dd0000000000080bf023c3000c2af6202023c33
+:102de000005a42341c00c2af0600023c801a423432
+:102df0002000c2af2000c28f401802001c00c28f0a
+:102e00001b004300f4016000121000002800c2af54
+:102e10002000c28f401802001c00c28f1b0043001c
+:102e2000f4016000101000000400401000000000d9
+:102e30002800c28f010042242800c2af2800c28fa0
+:102e40000101422c03004014000000000001022494
+:102e50002800c2af2800c28f04004010000000000c
+:102e60002800c28fffff42242800c2af2800c28f73
+:102e7000ff0042302400c2af2400c28fff00423066
+:102e80003000c38f305a62ac01000424e14a400f85
+:102e9000000000001000c0a71000c2970a00422cda
+:102ea0000900401000000000ff0004240c4b400ffc
+:102eb000000000001000c297010042241000c2a7c9
+:102ec000f5ff00100000000088bf043c50608390b4
+:102ed000fdff022424106200506082a0010004243f
+:102ee000e14a400f000000001400c22721204000ea
+:102ef00021280000213000001149400f000000008f
+:102f00001400c393ff0002240800621000000000b8
+:102f10001400c293f700433001000224030062143e
+:102f2000000000000a000010000000001200c0a312
+:102f300088bf033c5060629002004234506062a03f
+:102f40001200c2932c00c2af7600001000000000f7
+:102f5000ff0f02241000c2a71400c2272120400046
+:102f600001000524213000001149400f000000003d
+:102f70001000c297ffff42241000c2a71400c293a2
+:102f800006004010000000001000c297030040102f
+:102f900000000000f0ff0010000000001000c297c9
+:102fa00008004014000000001200c0a388bf023ccb
+:102fb0005060439002006334506043a057000010fb
+:102fc0000000000002000424e14a400f000000005d
+:102fd00080bf023c3400c2af6202023c005a42345d
+:102fe0002800c2af3101023c002d42342400c2afa0
+:102ff0002400c28f401802002800c28f1b0043002b
+:10300000f4016000121000001c00c2af2400c28f47
+:10301000401802002800c28f1b004300f40160002a
+:103020001010000004004010000000001c00c28fbf
+:10303000010042241c00c2af1c00c28f0101422cbf
+:103040000300401400000000000102241c00c2af75
+:103050001c00c28f04004010000000001c00c28f42
+:10306000ffff42241c00c2af1c00c28fff00423091
+:103070002000c2af2000c28fff0042303400c38f57
+:10308000305a62ac1400c2272120400010000524f1
+:10309000213000001149400f000000001400c22739
+:1030a0002120400006000524000206241149400f9b
+:1030b00000000000ff0002241000c2a71000c29709
+:1030c0000e00401000000000212000002128000018
+:1030d000d349400f000000002118400001000224e5
+:1030e00006006210000000001000c297ffff42249b
+:1030f0001000c2a7f1ff0010000000001000c297ee
+:1031000006004014000000001200c0a388bf023c6b
+:103110005060439002006334506043a01200c29399
+:103120002c00c2af2c00c28f21e8c0033c00bf8f2f
+:103130003800be8f4000bd270800e00300000000fb
+:10314000e0ffbd271c00bfaf1800beaf21f0a003f9
+:10315000214080002400c5af2128c0002c00c7af4b
+:103160003000c28f3800c38f4000c48f2000c8a336
+:103170002800c5a31000c2a31100c3a31200c4a35a
+:103180004882838f6c82828f0e00621000000000e4
+:103190009880838301000224f9ff6214000000007c
+:1031a0006c82828f010043244882828ff4ff621474
+:1031b000000000004882828f6c8282aff0ff001016
+:1031c0000000000021100000b48182af2800c383fa
+:1031d0005800022403006214000000002c00c28f7b
+:1031e000b48182af1000c38358000224030062142c
+:1031f000000000003400c28fb48182af1100c3838d
+:103200005800022403006214000000003c00c28f3a
+:10321000b48182af1200c3835800022403006214f9
+:10322000000000004400c28fb48182af2800c28336
+:10323000580042380100432c1000c2835800423825
+:103240000100422c251862001100c2835800423848
+:103250000100422c251862001200c2835800423837
+:103260000100422c25106200050040100000000003
+:1032700001000224788082af0200001000000000ec
+:10328000788080af211800009c8183af2800c38321
+:103290005900022403006214000000002c00c28fb9
+:1032a0009c8182af1000c383590002240300621482
+:1032b000000000003400c28f9c8182af1100c383e4
+:1032c0005900022403006214000000003c00c28f79
+:1032d0009c8182af1200c383590002240300621450
+:1032e000000000004400c28f9c8182af2800c2838e
+:1032f000590042380100432c1000c2835900423863
+:103300000100422c251862001100c2835900423886
+:103310000100422c251862001200c2835900423875
+:103320000100422c25106200050040100000000042
+:10333000010002247c8082af020000100000000027
+:103340007c8080af21100000a88182af2800c38359
+:103350005a00022403006214000000002c00c28ff7
+:10336000a88182af1000c3835a00022403006214b4
+:10337000000000003400c28fa88182af1100c38317
+:103380005a00022403006214000000003c00c28fb7
+:10339000a88182af1200c3835a0002240300621482
+:1033a000000000004400c28fa88182af2800c283c1
+:1033b0005a0042380100432c1000c2835a004238a0
+:1033c0000100422c251862001100c2835a004238c5
+:1033d0000100422c251862001200c2835a004238b4
+:1033e0000100422c25106200050040100000000082
+:1033f00001000224808082af020000100000000063
+:10340000808080af21180000a08183af2800c38393
+:103410004900022403006214000000002c00c28f47
+:10342000a08182af1000c38349000224030062140c
+:10343000000000003400c28fa08182af1100c3835e
+:103440004900022403006214000000003c00c28f07
+:10345000a08182af1200c3834900022403006214da
+:10346000000000004400c28fa08182af2800c28308
+:10347000490042380100432c1000c2834900423801
+:103480000100422c251862001100c2834900423815
+:103490000100422c251862001200c2834900423804
+:1034a0000100422c251062000500401000000000c1
+:1034b00001000224848082af02000010000000009e
+:1034c000848080af21100000a48182af2800c383d4
+:1034d0004a00022403006214000000002c00c28f86
+:1034e000a48182af1000c3834a0002240300621447
+:1034f000000000003400c28fa48182af1100c3839a
+:103500004a00022403006214000000003c00c28f45
+:10351000a48182af1200c3834a0002240300621414
+:10352000000000004400c28fa48182af2800c28343
+:103530004a0042380100432c1000c2834a0042383e
+:103540000100422c251862001100c2834a00423853
+:103550000100422c251862001200c2834a00423842
+:103560000100422c25106200050040100000000000
+:1035700001000224888082af0200001000000000d9
+:10358000888080af2800c3834600022405006214af
+:10359000000000002c00c48fd87c400f0000000009
+:1035a000708082af1000c3834600022405006214bd
+:1035b000000000003400c48fd87c400f00000000e1
+:1035c000708082af1100c38346000224050062149c
+:1035d000000000003c00c48fd87c400f00000000b9
+:1035e000708082af1200c38346000224050062147b
+:1035f000000000004400c48fd87c400f0000000091
+:10360000708082af21180000ac8183af2800c38393
+:103610005000022403006214000000002c00c28f3e
+:10362000ac8182af1000c3835000022403006214f7
+:10363000000000003400c28fac8182af1100c38350
+:103640005000022403006214000000003c00c28ffe
+:10365000ac8182af1200c3835000022403006214c5
+:10366000000000004400c28fac8182af2110000036
+:10367000b08182af2800c383530002240300621488
+:10368000000000002c00c28fb08182af1000c38305
+:103690005300022403006214000000003400c28fb3
+:1036a000b08182af1100c38353000224030062146f
+:1036b000000000003c00c28fb08182af1200c383c3
+:1036c0005300022403006214000000004400c28f73
+:1036d000b08182af2000c3831400c3af470002242f
+:1036e0001400c38f07006210000000004d00022488
+:1036f0001400c38f4800621000000000a4000010f6
+:10370000000000002400c28f988182af9881828fd0
+:1037100003004014000000006a4e400f000000004b
+:103720009881838f010002240300621400000000ce
+:10373000894e400f000000009881838f0200022410
+:103740000300621400000000af4e400f00000000b4
+:103750009881838f0300022403006214000000009c
+:10376000c64e400f000000009881838f04000224a1
+:103770000300621400000000dd4e400f0000000056
+:103780009881838f1400022403006214000000005b
+:10379000f94e400f000000009881838f150002242d
+:1037a0000300621400000000034f400f00000000ff
+:1037b0009881838f1c000224030062140000000023
+:1037c0000d4f400f000000009881838f5a000224a3
+:1037d0000300621400000000154f400f00000000bd
+:1037e0009881838f5b0002240300621400000000b4
+:1037f000214f400f000000009881838f5c0002245d
+:103800006300621400000000294f400f0000000018
+:103810005f000010000000002400c28f948182af7e
+:10382000988180af708080af9481838f650002247f
+:103830000300621400000000374f400f000000003a
+:103840009481838f6700022403006214000000004b
+:10385000454f400f000000009481838f68000224d0
+:103860000300621400000000524f400f00000000ef
+:103870009481838f6a000224030062140000000018
+:10388000964f400f000000009481838f6b0002244c
+:103890000300621400000000a44f400f000000006d
+:1038a0009481838f6c0002240300621400000000e6
+:1038b000b24f400f000000009481838fdc0002248f
+:1038c0000300621400000000d04f400f0000000011
+:1038d0009481838fdd000224030062140000000045
+:1038e000dd4f400f000000009481838fde00022432
+:1038f0000300621400000000e94f400f00000000c8
+:103900009481838fdf000224030062140000000012
+:103910000350400f000000009481838fe0000224d8
+:1039200003006214000000001d50400f0000000062
+:103930009481838fe10002240300621400000000e0
+:103940002750400f000000009481838fe200022482
+:1039500003006214000000003050400f000000001f
+:103960009481838fe30002240300621400000000ae
+:103970006850400f000000009481838fe40002240f
+:103980000300621400000000a050400f000000007f
+:1039900021e8c0031c00bf8f1800be8f2000bd2788
+:1039a0000800e00300000000e8ffbd271400bfafdf
+:1039b0001000beaf21f0a0037080828f030040147e
+:1039c00000000000c0030224708082af7080848fea
+:1039d0009481858f6c66400f00000000b080838367
+:1039e0000100022403006214000000000100022410
+:1039f000098282a37480848f21280000e266400f30
+:103a000000000000c767400f0000000021e8c0036d
+:103a10001400bf8f1000be8f1800bd270800e00300
+:103a200000000000e8ffbd271400bfaf1000beafcc
+:103a300021f0a0037080828f03004014000000007a
+:103a4000f0000224708082af2c8182830500401038
+:103a5000000000007080828ffc81838f2110430062
+:103a6000708082af7080848f9481858f6c66400fe8
+:103a700000000000b0808383010002240300621470
+:103a80000000000001000224098282a37480848f58
+:103a900021280000e266400f00000000c767400fc9
+:103aa0000000000021e8c0031400bf8f1000be8f8b
+:103ab0001800bd270800e00300000000e8ffbd2754
+:103ac0001400bfaf1000beaf21f0a0037080828f42
+:103ad0000300401400000000f0000224708082af58
+:103ae0007080848f9481858f6c66400f0000000089
+:103af0007480848f01000524e266400f00000000fe
+:103b000021e8c0031400bf8f1000be8f1800bd272e
+:103b10000800e00300000000e8ffbd271400bfaf6d
+:103b20001000beaf21f0a0037080828f030040140c
+:103b300000000000f0000224708082af7080848f4b
+:103b40009481858f6c66400f000000007480848f24
+:103b500001000524e266400f0000000021e8c003d8
+:103b60001400bf8f1000be8f1800bd270800e003af
+:103b700000000000e0ffbd271c00bfaf1800beaf73
+:103b800021f0a0031000c0afac81848f2128000079
+:103b9000137d400f000000000300401400000000ef
+:103ba0000a00001000000000ac81848fd87c400f18
+:103bb00000000000c8000324021043701000c2afd0
+:103bc0001000c48fa71e400f0000000021e8c003b2
+:103bd0001c00bf8f1800be8f2000bd270800e00327
+:103be00000000000f8ffbd270000beaf21f0a003d9
+:103bf00014000224748082af21e8c0030000be8f4d
+:103c00000800bd270800e00300000000f8ffbd2702
+:103c10000000beaf21f0a00315000224748082af23
+:103c200021e8c0030000be8f0800bd270800e003a4
+:103c300000000000f8ffbd270000beaf21f0a00388
+:103c400021e8c0030000be8f0800bd270800e00384
+:103c500000000000e8ffbd271400bfaf1000beaf9a
+:103c600021f0a0039967400f0000000021e8c00385
+:103c70001400bf8f1000be8f1800bd270800e0039e
+:103c800000000000f8ffbd270000beaf21f0a00338
+:103c900021e8c0030000be8f0800bd270800e00334
+:103ca00000000000e8ffbd271400bfaf1000beaf4a
+:103cb00021f0a0036a4e400f000000004567400f4e
+:103cc0000000000021e8c0031400bf8f1000be8f69
+:103cd0001800bd270800e00300000000f8ffbd2722
+:103ce0000000beaf21f0a003b08083830200022455
+:103cf000030062140000000001000224098282a374
+:103d000021e8c0030000be8f0800bd270800e003c3
+:103d100000000000f8ffbd270000beaf21f0a003a7
+:103d2000b0808383020002240200621400000000bd
+:103d3000098280a321e8c0030000be8f0800bd27d0
+:103d40000800e00300000000e8ffbd271400bfaf3b
+:103d50001000beaf21f0a003b080838302000224d4
+:103d6000370062140000000004000424c452400f15
+:103d70000000000005000424c452400f00000000b1
+:103d800006000424c452400f000000000500042473
+:103d900021280000029d023c14084624213800001e
+:103da0004353400f00000000448080af0100022414
+:103db000488182a3b081848f21280000137d400fa9
+:103dc0000000000003004014000000000500001087
+:103dd00000000000b081848fd87c400f00000000fc
+:103de0004c8082afa663400f000000000100042455
+:103df000481d400f000000009751400f00000000d8
+:103e00004452400f00000000fb51400f0000000032
+:103e10004480828f06004014000000004c80828f96
+:103e20000300401000000000f3ff0010000000003d
+:103e3000488180a305000424c452400f0000000004
+:103e400021e8c0031400bf8f1000be8f1800bd27eb
+:103e50000800e00300000000f8ffbd270000beaf2f
+:103e600021f0a003010002243c8182a388bf033c0f
+:103e70001061629020004234106162a021e8c0030a
+:103e80000000be8f0800bd270800e003000000000e
+:103e9000f8ffbd270000beaf21f0a0033c8180a346
+:103ea00088bf043c10618390dfff0224241062006d
+:103eb000106182a021e8c0030000be8f0800bd276a
+:103ec0000800e00300000000e8ffbd271400bfafba
+:103ed0001000beaf21f0a003b08083830200022453
+:103ee000110062140000000021200000b081858fc5
+:103ef000137d400f0000000003004004000000009c
+:103f00000500001000000000b081848fd87c400fb5
+:103f100000000000048082afa91b400f00000000d9
+:103f200001000224498182a321e8c0031400bf8f4d
+:103f30001000be8f1800bd270800e003000000003d
+:103f4000f8ffbd270000beaf21f0a00388bf043cee
+:103f5000d1608390f7ff022424106200d16082a018
+:103f600021e8c0030000be8f0800bd270800e00361
+:103f700000000000f8ffbd270000beaf21f0a00345
+:103f800088bf023cd160439008006334d16043a0f5
+:103f900021e8c0030000be8f0800bd270800e00331
+:103fa00000000000e8ffbd271400bfaf1000beaf47
+:103fb00021f0a003b0808383020002240d0062146c
+:103fc0000000000021200000b081858f137d400f8c
+:103fd0000000000003004004000000000500001085
+:103fe00000000000b081848fd87c400f00000000ea
+:103ff000408182af21e8c0031400bf8f1000be8f44
+:104000001800bd270800e00300000000e8ffbd27fe
+:104010001400bfaf1000beaf21f0a003b0808383b7
+:10402000020002240d0062140000000021200000a4
+:10403000b081858f137d400f000000000300400415
+:10404000000000000500001000000000b081848f17
+:10405000d87c400f00000000388182af21e8c00307
+:104060001400bf8f1000be8f1800bd270800e003aa
+:1040700000000000f8ffbd270000beaf21f0a00344
+:1040800001000224348182a321e8c0030000be8f16
+:104090000800bd270800e00300000000f8ffbd276e
+:1040a0000000beaf21f0a003348180a321e8c0034b
+:1040b0000000be8f0800bd270800e00300000000dc
+:1040c000d8ffbd272400bfaf2000beaf1c00b1af9a
+:1040d0001800b0af21f0a0034882838f6c82828fda
+:1040e0000e0062100000000098808383010002240b
+:1040f000f9ff6214000000006c82828f01004324eb
+:104100004882828ff4ff6214000000004882828f90
+:104110006c8282aff0ff0010000000003159400fa8
+:104120000000000088bf023c9061428c4002427c4b
+:104130000300401400000000faff0010000000001f
+:10414000ec80848f017a400f000000002180400045
+:1041500021886000f080848f017a400f0000000009
+:104160001000a0af1400a0af2120000221282002df
+:104170002130400021386000f95b400f0000000052
+:1041800021e8c0032400bf8f2000be8f1c00b18f28
+:104190001800b08f2800bd270800e00300000000d1
+:1041a000e8ffbd271400bfaf1000beaf21f0a00391
+:1041b000b0808383020002242b0062140000000000
+:1041c00001000224448182af21200000b081858f4c
+:1041d000137d400f000000000300400400000000b9
+:1041e0000d00001000000000b081848f017a400fa4
+:1041f0000000000021204000212860008f76400f41
+:10420000000000002120400021286000687a400f53
+:1042100000000000288182af21200000ac81858f42
+:10422000137d400f00000000030040040000000068
+:104230000d00001000000000ac81848f017a400f57
+:104240000000000021204000212860008f76400ff0
+:10425000000000002120400021286000687a400f03
+:1042600000000000548182af21e8c0031400bf8f1a
+:104270001000be8f1800bd270800e00300000000fa
+:10428000f8ffbd270000beaf21f0a003b0808383fc
+:10429000020002240200621400000000448180af8a
+:1042a00021e8c0030000be8f0800bd270800e0031e
+:1042b00000000000e8ffbd271400bfaf1000beaf34
+:1042c00021f0a0032120000021280000029d023cd3
+:1042d00004164624213800004353400f000000001c
+:1042e000010004241c00052400a0023c740a46249a
+:1042f000213800004353400f000000000200042456
+:1043000021280000029d023c181646242138000096
+:104310004353400f00000000030004242128000044
+:10432000029d023c28164624213800004353400fca
+:1043300000000000b080838f020002240800621495
+:10434000000000000400042421280000029d023c1b
+:1043500034164624213800004353400f000000006b
+:1043600021e8c0031400bf8f1000be8f1800bd27c6
+:104370000800e00300000000d0ffbd272c00bfaf05
+:104380002800beaf21f0a0031000c427029d023c0c
+:10439000401645249080868f486e400f0000000034
+:1043a000020004245a0005241000c627213800000a
+:1043b0004353400f000000001881828f3e004018d8
+:1043c000000000001881848fae7c400f00000000c8
+:1043d000029d033c212040005816658c237c400f31
+:1043e000000000002000c2af2000c48f017a400fff
+:1043f0000000000021304000213860001000c42778
+:10440000029d023c44164524486e400f0000000007
+:10441000030004244b0005241000c62721380000a7
+:104420004353400f000000000480848fae7c400f97
+:104430000000000021204000017a400f0000000031
+:10444000029d063c21204000212860006416c78c94
+:104450006016c68cd977400f000000002120400074
+:10446000212860002a7a400f00000000b88182af46
+:10447000b881848f017a400f000000002130400095
+:10448000213860001000c427029d023c44164524d8
+:10449000486e400f00000000040004244b00052477
+:1044a0001000c627213800004353400f00000000d1
+:1044b0000800001000000000030004244b00052445
+:1044c000029d023c50164624213800004353400f01
+:1044d000000000004460400f000000007960400fc1
+:1044e00000000000b080838f020002240d006214df
+:1044f000000000009751400f000000006c81828393
+:1045000003004010000000004452400f0000000073
+:10451000498182830300401000000000fb51400fde
+:104520000000000021e8c0032c00bf8f2800be8fd0
+:104530003000bd270800e00300000000e8ffbd27b1
+:104540001400bfaf1000beaf21f0a0032120000077
+:1045500021280000029d023c041646242138000058
+:104560004353400f000000000100042421280000f4
+:10457000029d023c68164624213800004353400f38
+:104580000000000088bf023c5061428c0000427c69
+:104590000a0040100000000005000424212800004b
+:1045a000029d023c7c164624213800004353400ff4
+:1045b00000000000080000100000000005000424b6
+:1045c00021280000029d023c881646242138000064
+:1045d0004353400f00000000029d023c2481848f61
+:1045e000a816458c137d400f000000000300400416
+:1045f000000000000a000010000000000300042476
+:1046000021280000029d023c941646242138000017
+:104610004353400f000000000400001000000000a1
+:1046200003000424c452400f000000004452400f15
+:10463000000000009751400f00000000fb51400fa8
+:104640000000000021e8c0031400bf8f1000be8fdf
+:104650001800bd270800e00300000000d0ffbd27c0
+:104660002c00bfaf2800beaf21f0a003029d023c8a
+:104670002481848fe416458c137d400f00000000d8
+:104680000a00401000000000029d023c2481848f3b
+:10469000e816458c137d400f000000000300401019
+:1046a00000000000260000100000000007000424a5
+:1046b000c452400f00000000029d023c2481848f00
+:1046c000e416458c137d400f0000000003004010ed
+:1046d0000000000008000010000000000700042493
+:1046e0000a000524029d023cac1646242138000035
+:1046f0004353400f00000000029d023c2481848f40
+:10470000e816458c137d400f0000000003004010a8
+:10471000000000002f00001000000000070004242b
+:104720000a000524029d023cc016462421380000e0
+:104730004353400f0000000026000010000000005e
+:104740002481848fd87c400f000000002000c2af7d
+:104750001000c427029d023cd41645242000c68fb9
+:10476000486e400f00000000070004242d000524bf
+:104770001000c627213800004353400f00000000fe
+:1047800088bf023c5061428c0000427c0a0040100d
+:10479000000000000700042423000524029d023cc1
+:1047a000dc164624213800004353400f000000006f
+:1047b0000800001000000000070004242300052466
+:1047c000029d023ce0164624213800004353400f6e
+:1047d0000000000021e8c0032c00bf8f2800be8f1e
+:1047e0003000bd270800e00300000000d0ffbd2717
+:1047f0002c00bfaf2800beaf21f0a0030480848f3f
+:104800006666023c676642341800820010100000a1
+:1048100083180200c3170400231062002000c2aff7
+:104820001000c427029d023cec1645242000c68fd0
+:10483000486e400f000000000700042455000524c6
+:104840001000c627213800004353400f000000002d
+:104850000400042421280000029d023c3416462452
+:10486000213800004353400f000000000480848f73
+:10487000ae7c400f0000000021204000017a400f74
+:1048800000000000029d063c21204000212860001d
+:10489000fc16c78cf816c68cd977400f00000000b4
+:1048a00021204000212860002a7a400f00000000eb
+:1048b000b88182afb881848f017a400f0000000078
+:1048c00021304000213860001000c427029d023cc6
+:1048d00044164524486e400f0000000004000424e4
+:1048e0004b0005241000c627213800004353400f19
+:1048f00000000000498180a321e8c0032c00bf8f85
+:104900002800be8f3000bd270800e0030000000033
+:10491000d8ffbd272400bfaf2000beaf21f0a00309
+:104920004c80828f02004104000000004c8080af68
+:104930001000c427029d023cd41645244c80868f6b
+:10494000486e400f000000000700042421280000ea
+:104950001000c627213800004353400f000000001c
+:104960006c8180a321e8c0032400bf8f2000be8f8c
+:104970002800bd270800e00300000000e0ffbd277d
+:104980001c00bfaf1800beaf21f0a00321108000b3
+:104990002000c2a31000c0a31000c2930800422c44
+:1049a0002000401000000000b0ff03241000c2935c
+:1049b00021106200ff00423021204000c256400f0b
+:1049c0000000000021200000c256400f000000003f
+:1049d00010000424c256400f000000001100c0a3c4
+:1049e0001100c2830a004004000000002000c293ae
+:1049f00021204000e456400f000000001100c29347
+:104a0000010042241100c2a3f5ff001000000000c5
+:104a10001000c293010042241000c2a3deff001068
+:104a20000000000021e8c0031c00bf8f1800be8feb
+:104a30002000bd270800e00300000000e0ffbd27c4
+:104a40001c00bfaf1800beaf21f0a00321108000f2
+:104a50002400c5af2000c2a3b0ff03242000c293ee
+:104a600021106200ff00423021204000c256400f5a
+:104a70000000000021200000c256400f000000008e
+:104a800010000424c256400f000000001000c0a314
+:104a90001000c2932400c38f2a1043000900401065
+:104aa0000000000018000424e456400f000000003d
+:104ab0001000c293010042241000c2a3f4ff0010b2
+:104ac000000000002400c28f1000c2a31000c283a7
+:104ad000090040040000000021200000e456400fbf
+:104ae000000000001000c293010042241000c2a385
+:104af000f6ff00100000000021e8c0031c00bf8f7b
+:104b00001800be8f2000bd270800e0030000000051
+:104b1000e0ffbd271c00bfaf1800beaf21f0a0030f
+:104b2000211080002000c2a3b0ff03242000c29304
+:104b300021106200ff00423021204000c256400f89
+:104b40000000000021200000c256400f00000000bd
+:104b500010000424c256400f000000001000c0a343
+:104b60001000c28309004004000000002120000062
+:104b7000e456400f000000001000c29301004224e0
+:104b80001000c2a3f6ff00100000000021e8c003df
+:104b90001c00bf8f1800be8f2000bd270800e00357
+:104ba00000000000d8ffbd272400bfaf2000beaf2b
+:104bb00021f0a003211080002800c2a32800c29386
+:104bc0001c00c2af010002241c00c38f150062103c
+:104bd000000000001c00c38f020062280600401085
+:104be000000000001c00c28f0900401000000000ff
+:104bf0001400001000000000020002241c00c38ffb
+:104c00000d006210000000000e0000100000000007
+:104c1000029d023c280842241400c2af0900001083
+:104c200000000000029d023c280c42241400c2af88
+:104c30000400001000000000029d023c28104224e5
+:104c40001400c2af1000c0a31000c2930800422c91
+:104c500028004010000000001000c293c0110200a4
+:104c60001800c2afb0ff03241000c29321106200ed
+:104c7000ff00423021204000c256400f00000000db
+:104c800021200000c256400f000000001000042444
+:104c9000c256400f000000001100c0a31100c283e3
+:104ca0000f004004000000001100c3931400c28fe5
+:104cb000211862001800c28f21106200000042908b
+:104cc00021204000e456400f000000001100c29374
+:104cd000010042241100c2a3f0ff001000000000f8
+:104ce0001000c293010042241000c2a3d6ff00109e
+:104cf0000000000021e8c0032400bf8f2000be8f09
+:104d00002800bd270800e00300000000d0ffbd27f9
+:104d10002c00bfaf2800beaf21f0a0033000c4af0d
+:104d20003400c5af3800c6af2110e0003c00c2a37c
+:104d30001c00c0af3400c28f1000c2a31000c29389
+:104d40000f0042301100c2a31000c29302110200f2
+:104d5000100042341200c2a33000c28fb0ff0324ff
+:104d600021106200ff00423021204000c256400f57
+:104d7000000000001100c29321204000c256400fe5
+:104d8000000000001200c29321204000c256400fd4
+:104d9000000000001400c0af1400c38f3800c28fa1
+:104da00021106200000042909700401000000000b7
+:104db0001400c38f3800c28f21106200000042909f
+:104dc0005300422c14004010000000002000c527b2
+:104dd0001400c38f3800c28f21106200000044907d
+:104de000211080008018020021186400029d023cfe
+:104df0002814422460ff4224211062002120a000d8
+:104e00002128400005000624af6a400f0000000082
+:104e10003c000010000000001400c38f3800c28f57
+:104e200021106200000042907f00422c2e004010b2
+:104e3000000000001400c38f3800c28f21106200f0
+:104e4000000042905c00422c14004014000000005e
+:104e50002000c5271400c38f3800c28f21106200c4
+:104e60000000449021108000801802002118640086
+:104e7000029d023c281542245cfe4224211062005f
+:104e80002120a0002128400005000624af6a400f21
+:104e9000000000001b000010000000002000c527db
+:104ea0001400c38f3800c28f2110620000004490ac
+:104eb000211080008018020021186400029d023c2d
+:104ec0002815422461fe4224211062002120a00006
+:104ed0002128400005000624af6a400f00000000b2
+:104ee00008000010000000002000c2272120400020
+:104ef000029d023c2814452405000624af6a400f99
+:104f0000000000001800c0af1800c28f0500422842
+:104f100032004010000000001c00c28f80004228b8
+:104f20001b004010000000003c00c2930a00401427
+:104f3000000000001800c38f1000c227211043009a
+:104f40001000429021204000e456400f0000000075
+:104f50000a000010000000001800c38f1000c227d4
+:104f6000211043001000429027100200ff00423041
+:104f700021204000e456400f000000001c00c28fba
+:104f8000010042241c00c2af0f000010000000000e
+:104f90003000c28fb1ff032421106200ff004230b5
+:104fa00021204000c256400f000000001800c38faf
+:104fb0001000c22721104300100042902120400021
+:104fc000e456400f000000001800c28f0100422488
+:104fd0001800c2afccff001000000000212000002c
+:104fe000e456400f000000001c00c28f0100422464
+:104ff0001c00c2af1400c28f010042241400c2afd3
+:1050000065ff00100000000021e8c0032c00bf8fe6
+:105010002800be8f3000bd270800e003000000001c
+:10502000e8ffbd271400bfaf1000beaf21f0a00302
+:10503000212000005f52400f0000000021200000ee
+:105040000a000524029d023c041646242138000073
+:105050004353400f00000000010004241400052405
+:10506000029d023c00174624213800004353400fa4
+:10507000000000000200042414000524029d023cec
+:1050800008174624213800004353400f0000000059
+:105090000300042414000524029d023c1417462436
+:1050a000213800004353400f000000000400042496
+:1050b00014000524029d023c2017462421380000dc
+:1050c0004353400f00000000050004241400052491
+:1050d000029d023c2c174624213800004353400f08
+:1050e0000000000021e8c0031400bf8f1000be8f35
+:1050f0001800bd270800e00300000000e8ffbd27fe
+:105100001400bfaf1000beaf21f0a00321200000ab
+:105110005f52400f00000000212000000a0005241b
+:10512000029d023c04164624213800004353400fe0
+:10513000000000000100042421280000029d023c20
+:105140003c174624213800004353400f0000000064
+:105150000400042421280000029d023c4417462438
+:10516000213800004353400f0000000005000424d4
+:1051700021280000029d023c4c17462421380000e3
+:105180004353400f000000000600042421280000c3
+:10519000029d023c54174624213800004353400f1f
+:1051a0000000000021e8c0031400bf8f1000be8f74
+:1051b0001800bd270800e00300000000e8ffbd273d
+:1051c0001400bfaf1000beaf21f0a00321200000eb
+:1051d0005f52400f00000000212000000a0005245b
+:1051e000029d023c04164624213800004353400f20
+:1051f000000000000100042414000524029d023c6c
+:105200005c174624213800004353400f0000000083
+:1052100021e8c0031400bf8f1000be8f1800bd2707
+:105220000800e00300000000e8ffbd271400bfaf46
+:105230001000beaf21f0a00301000424c452400faf
+:10524000000000000100042414000524029d023c1b
+:1052500020174624213800004353400f000000006f
+:1052600021e8c0031400bf8f1000be8f1800bd27b7
+:105270000800e00300000000e8ffbd271400bfaff6
+:105280001000beaf21f0a003212000005f52400fac
+:10529000000000000100042421280000029d023cbf
+:1052a0006c174624213800004353400f00000000d3
+:1052b00021e8c0031400bf8f1000be8f1800bd2767
+:1052c0000800e00300000000d8ffbd272400bfafa6
+:1052d0002000beaf21f0a0032800c4af2c00c5af52
+:1052e0003000c6af2110e0003400c2a3212000002e
+:1052f0005f52400f0000000001000424212800003c
+:10530000029d023c80174624213800004353400f81
+:10531000000000002800c48f017a400f0000000048
+:1053200021304000213860001000c427029d023c5b
+:105330008c174524486e400f000000000300042431
+:10534000212800001000c627213800004353400fd9
+:10535000000000002c00c48f017a400f0000000004
+:1053600021304000213860001000c427029d023c1b
+:1053700094174524486e400f0000000004000424e8
+:10538000212800001000c627213800004353400f99
+:10539000000000003400c283130040100000000031
+:1053a0003000c48f017a400f00000000213040001f
+:1053b000213860001000c427029d023c9c17452440
+:1053c000486e400f00000000050004242128000062
+:1053d0001000c627213800004353400f0000000092
+:1053e000080000100000000005000424212800002f
+:1053f000029d023ca4174624213800004353400f6d
+:105400000000000021e8c0032400bf8f2000be8ff1
+:105410002800bd270800e00300000000e8ffbd27ca
+:105420001400bfaf1000beaf21f0a0032120000088
+:105430005f52400f000000002120000021280000e2
+:10544000029d023cb0174624213800004353400f10
+:10545000000000000200042421280000029d023cfc
+:10546000bc174624213800004353400f00000000c1
+:105470000400042421280000029d023ccc1746248d
+:10548000213800004353400f0000000021e8c00312
+:105490001400bf8f1000be8f1800bd270800e00366
+:1054a00000000000e8ffbd271400bfaf1000beaf32
+:1054b00021f0a0031800c4af1c00c5af2110c0002c
+:1054c0002000c2a31800c28f0800422c73014010b4
+:1054d000000000001800c28f80180200029d023cec
+:1054e000e4174224211062000000428c08004000b2
+:1054f000000000002000c393010004241c00c58f9d
+:10550000029d023cdc174624213860004353400fc3
+:1055100000000000020004241c00c58f029d023c14
+:10552000e0174624213800004353400f00000000dc
+:10553000030004241c00c58f029d023ce017462492
+:10554000213800004353400f0000000004000424f1
+:105550001c00c58f029d023ce01746242138000044
+:105560004353400f00000000050004241c00c58fb9
+:10557000029d023ce0174624213800004353400faf
+:1055800000000000060004241c00c58f029d023ca0
+:10559000e0174624213800004353400f000000006c
+:1055a000070004241c00c58f029d023ce01746241e
+:1055b000213800004353400f000000003701001065
+:1055c00000000000010004241c00c58f029d023c65
+:1055d000e0174624213800004353400f000000002c
+:1055e0002000c393020004241c00c58f029d023cce
+:1055f000dc174624213860004353400f00000000b0
+:10560000030004241c00c58f029d023ce0174624c1
+:10561000213800004353400f000000000400042420
+:105620001c00c58f029d023ce01746242138000073
+:105630004353400f00000000050004241c00c58fe8
+:10564000029d023ce0174624213800004353400fde
+:1056500000000000060004241c00c58f029d023ccf
+:10566000e0174624213800004353400f000000009b
+:10567000070004241c00c58f029d023ce01746244d
+:10568000213800004353400f0000000003010010c8
+:1056900000000000010004241c00c58f029d023c94
+:1056a000e0174624213800004353400f000000005b
+:1056b000020004241c00c58f029d023ce017462412
+:1056c000213800004353400f000000002000c39326
+:1056d000030004241c00c58f029d023cdc174624f5
+:1056e000213860004353400f0000000004000424f0
+:1056f0001c00c58f029d023ce017462421380000a3
+:105700004353400f00000000050004241c00c58f17
+:10571000029d023ce0174624213800004353400f0d
+:1057200000000000060004241c00c58f029d023cfe
+:10573000e0174624213800004353400f00000000ca
+:10574000070004241c00c58f029d023ce01746247c
+:10575000213800004353400f00000000cf0000102c
+:1057600000000000010004241c00c58f029d023cc3
+:10577000e0174624213800004353400f000000008a
+:10578000020004241c00c58f029d023ce017462441
+:10579000213800004353400f0000000003000424a0
+:1057a0001c00c58f029d023ce017462421380000f2
+:1057b0004353400f000000002000c3930400042462
+:1057c0001c00c58f029d023cdc1746242138600076
+:1057d0004353400f00000000050004241c00c58f47
+:1057e000029d023ce0174624213800004353400f3d
+:1057f00000000000060004241c00c58f029d023c2e
+:10580000e0174624213800004353400f00000000f9
+:10581000070004241c00c58f029d023ce0174624ab
+:10582000213800004353400f000000009b0000108f
+:1058300000000000010004241c00c58f029d023cf2
+:10584000e0174624213800004353400f00000000b9
+:10585000020004241c00c58f029d023ce017462470
+:10586000213800004353400f0000000003000424cf
+:105870001c00c58f029d023ce01746242138000021
+:105880004353400f00000000040004241c00c58f97
+:10589000029d023ce0174624213800004353400f8c
+:1058a000000000002000c393050004241c00c58fe5
+:1058b000029d023cdc174624213860004353400f10
+:1058c00000000000060004241c00c58f029d023c5d
+:1058d000e0174624213800004353400f0000000029
+:1058e000070004241c00c58f029d023ce0174624db
+:1058f000213800004353400f0000000067000010f3
+:1059000000000000010004241c00c58f029d023c21
+:10591000e0174624213800004353400f00000000e8
+:10592000020004241c00c58f029d023ce01746249f
+:10593000213800004353400f0000000003000424fe
+:105940001c00c58f029d023ce01746242138000050
+:105950004353400f00000000040004241c00c58fc6
+:10596000029d023ce0174624213800004353400fbb
+:1059700000000000050004241c00c58f029d023cad
+:10598000e0174624213800004353400f0000000078
+:105990002000c393060004241c00c58f029d023c16
+:1059a000dc174624213860004353400f00000000fc
+:1059b000070004241c00c58f029d023ce01746240a
+:1059c000213800004353400f000000003300001056
+:1059d00000000000010004241c00c58f029d023c51
+:1059e000e0174624213800004353400f0000000018
+:1059f000020004241c00c58f029d023ce0174624cf
+:105a0000213800004353400f00000000030004242d
+:105a10001c00c58f029d023ce0174624213800007f
+:105a20004353400f00000000040004241c00c58ff5
+:105a3000029d023ce0174624213800004353400fea
+:105a400000000000050004241c00c58f029d023cdc
+:105a5000e0174624213800004353400f00000000a7
+:105a6000060004241c00c58f029d023ce01746245a
+:105a7000213800004353400f000000002000c39372
+:105a8000070004241c00c58f029d023cdc1746243d
+:105a9000213860004353400f0000000021e8c0039c
+:105aa0001400bf8f1000be8f1800bd270800e00350
+:105ab00000000000f8ffbd270000beaf21f0a003ea
+:105ac0000800c4af80bf033c0800c28f205a62acfc
+:105ad00080bf023c105a428c0000427c03004014fc
+:105ae00000000000faff00100000000080bf023c30
+:105af000205a428c21e8c0030000be8f0800bd2759
+:105b00000800e00300000000e8ffbd271400bfaf5d
+:105b10001000beaf21f0a003211080001800c2a326
+:105b200088bf043c10618390bfff022424106200f0
+:105b3000106182a088bf043c50608390dfff022484
+:105b400024106200506082a01800c29321204000ff
+:105b5000ad56400f0000000088bf033c50606290cb
+:105b600020004234506062a088bf033c1061629004
+:105b700040004234106162a021e8c0031400bf8fce
+:105b80001000be8f1800bd270800e00300000000d1
+:105b9000e8ffbd271400bfaf1000beaf21f0a00387
+:105ba000211080001800c2a388bf033c10616290de
+:105bb00040004234106162a088bf043c5060839072
+:105bc000dfff022424106200506082a01800c293fc
+:105bd00021204000ad56400f0000000088bf033c6c
+:105be0005060629020004234506062a088bf033c45
+:105bf0001061629040004234106162a021e8c0034d
+:105c00001400bf8f1000be8f1800bd270800e003ee
+:105c100000000000e0ffbd271c00bfaf1800beafb2
+:105c200021f0a003211080002000c2a31000c0a317
+:105c30001000c2930800422c200040100000000019
+:105c4000b0ff03241000c29321106200ff00423015
+:105c500021204000c256400f00000000212000001b
+:105c6000c256400f0000000010000424c256400f2e
+:105c7000000000001100c0a31100c2830a0040040c
+:105c8000000000002000c29321204000e456400f95
+:105c9000000000001100c293010042241100c2a3c1
+:105ca000f5ff0010000000001000c2930100422424
+:105cb0001000c2a3deff00100000000021e8c003b6
+:105cc0001c00bf8f1800be8f2000bd270800e00316
+:105cd00000000000e0ffbd271c00bfaf1800beaff2
+:105ce00021f0a0031000c0af80bf033c208102342c
+:105cf000005a62ac88bf043c10618390bfff02244d
+:105d000024106200106182a088bf043c5060839020
+:105d1000dfff022424106200506082a088bf033c91
+:105d2000106162907f004230106162a01000c0af2d
+:105d30001000c28fd007422c060040100000000067
+:105d40001000c28f010042241000c2aff8ff001003
+:105d50000000000088bf043c1061839080ff022493
+:105d600025106200106182a01000c0af1000c28f29
+:105d7000d007422c06004010000000001000c28f27
+:105d8000010042241000c2aff8ff00100000000024
+:105d900088bf023c5060439020006334506043a0b1
+:105da000d5000424c256400f000000001000042457
+:105db000c256400f00000000d3000424c256400f1a
+:105dc0000000000021200000c256400f000000002b
+:105dd000a8000424c256400f000000003f00042425
+:105de000c256400f00000000d8000424c256400fe5
+:105df0000000000021200000c256400f00000000fb
+:105e000040000424c256400f00000000a0000424fb
+:105e1000c256400f00000000c8000424c256400fc4
+:105e200000000000da000424c256400f0000000009
+:105e300012000424c256400f000000008100042418
+:105e4000c256400f00000000f0000424c256400f6c
+:105e500000000000a4000424c256400f000000000f
+:105e6000d9000424c256400f00000000f2000424b0
+:105e7000c256400f00000000a6000424c256400f86
+:105e80000000000026000424c256400f000000005d
+:105e900001000424c256400f000000002120000031
+:105ea000c256400f0000000021200000c256400fe3
+:105eb0000000000001000424c256400f0000000052
+:105ec000212000000557400f000000001000c0af67
+:105ed0001000c28fd007422c0600401000000000c6
+:105ee0001000c28f010042241000c2aff8ff001062
+:105ef00000000000af000424c256400f0000000064
+:105f000021e8c0031c00bf8f1800be8f2000bd27f2
+:105f10000800e00300000000e8ffbd271400bfaf49
+:105f20001000beaf21f0a003212000005f52400fff
+:105f30000000000001000424e952400f00000000ae
+:105f4000c8000424e14a400f0000000021200000a6
+:105f50005f52400f0000000021200000e952400f76
+:105f600000000000c8000424e14a400f00000000c7
+:105f700021e8c0031400bf8f1000be8f1800bd279a
+:105f80000800e00300000000e0ffbd271c00bfafd9
+:105f90001800beaf21f0a003075a400f0000000018
+:105fa000c657400f0000000088bf023c5060428c82
+:105fb000c000427c0300401400000000faff001003
+:105fc000000000006d5b400f000000001000c2af39
+:105fd0001000c28f1400c2af010002241400c38f4e
+:105fe00018006210000000001400c38f0200622835
+:105ff00006004010000000001400c28f0d00401089
+:1060000000000000e8ff0010000000000200022471
+:106010001400c38f1000621000000000030002246f
+:106020001400c38f1400621000000000deff001097
+:10603000000000002258400f00000000daff0010ae
+:106040000000000001000424ac60400f00000000cc
+:10605000d5ff001000000000b080838302000224fe
+:10606000d1ff6214000000003a1e400f0000000043
+:10607000cdff001000000000f261400f00000000a2
+:10608000c9ff001000000000d0ffbd272c00bfafeb
+:106090002800beaf21f0a0032c8180a3df5a400f5f
+:1060a000000000000101401000000000212000005d
+:1060b0005f52400f00000000212000000a0005246c
+:1060c000029d023c08184624213800004353400f2b
+:1060d0000000000088bf023c5060428cc000427c3f
+:1060e0000300401400000000faff00100000000050
+:1060f000c448400f000000001900401400000000d8
+:106100000200042421280000029d023c1c184624a1
+:10611000213800004353400f000000000400042415
+:1061200021280000029d023c30184624213800003e
+:106130004353400f00000000fa000424e14a400fde
+:106140000000000088bf023c9061428c4002427c0b
+:10615000e7ff401400000000d40000100000000021
+:1061600002000424c452400f000000000400042474
+:10617000c452400f00000000505c400f00000000bf
+:1061800088bf023c5060428cc000427c0300401437
+:1061900000000000faff00100000000088bf023c71
+:1061a0009061428c4002427c0300401400000000d9
+:1061b000be00001000000000c080838f0300022496
+:1061c0000700621000000000c080838f01000224dd
+:1061d00003006210000000007f00001000000000bb
+:1061e000f261400f000000000300401400000000b6
+:1061f000ae0000100000000003000224ac8082af5b
+:10620000212000005f52400f00000000ad50400f01
+:1062100000000000e965400f0000000001000424b8
+:10622000bd61400f0000000088bf023c9061428cbd
+:106230004002427c21004014000000003159400f10
+:106240000000000088bf023c9061428c4002427c0a
+:106250000300401400000000faff001000000000de
+:106260004882838f6c82828f0e00621000000000d3
+:106270009880838301000224f9ff6214000000006b
+:106280006c82828f010043244882828ff4ff621463
+:10629000000000004882828f6c8282aff0ff001005
+:1062a00000000000ec80848ff080858f213000009a
+:1062b00021380000f95b400f00000000de50400f65
+:1062c00000000000505e400f0000000000a0023cf3
+:1062d000400a422401004390280002240300621473
+:1062e00000000000f7ff001000000000b35e400f48
+:1062f00000000000e881838319828683f88182830d
+:106300001000a2afe081828f1400a2af08828283c6
+:106310001800a2af1c82828f1c00a2afe981828389
+:106320002000a2afdc81828f2400a2af2120600078
+:10633000cc81858fbc81878f504c400f00000000be
+:10634000c95f400f00000000b08083830200022478
+:106350000300621400000000a91b400f00000000b1
+:1063600088bf023c5061428c4001427c06004014d0
+:1063700000000000010002242c8182a3fc81828f96
+:106380000a004224fc8182af88bf023c5061428ceb
+:106390000001427c060040140000000001000224bd
+:1063a0002c8182a3fc81828ff6ff4224fc8182af84
+:1063b00098808283010042382b1802009c80828fd3
+:1063c0002b10020025106200220040100000000087
+:1063d00095ff001000000000212000005f52400fd8
+:1063e000000000000200042421280000029d023c5d
+:1063f00040184624213800004353400f000000009d
+:106400000300042421280000029d023c5418462465
+:10641000213800004353400f000000000400042412
+:1064200021280000029d023c641846242138000007
+:106430004353400f0000000088bf023c9061428c33
+:106440004002427c0300401000000000faff0010f0
+:106450000000000021200000481d400f0000000047
+:1064600021200000bd61400f00000000d081828f1c
+:10647000f08182aff081848f892d400f00000000f1
+:10648000075a400f000000000755400f00000000b1
+:1064900088bf023c9061428c4002427c0300401065
+:1064a00000000000faff00100000000021e8c00317
+:1064b0002c00bf8f2800be8f3000bd270800e003ee
+:1064c00000000000e8ffbd271400bfaf1000beaf02
+:1064d00021f0a00388bf023c9061428c4002427cc4
+:1064e0000300401400000000faff0010000000004c
+:1064f00004000424c452400f0000000005000424de
+:10650000c452400f0000000006000424c452400f93
+:10651000000000000500042421280000029d023c28
+:106520007c184624213800004353400f000000002f
+:1065300001000224208282a3c881848ff481858f88
+:106540000c82868f21380000f95b400f00000000ac
+:106550000500042421280000029d023c3018462436
+:10656000213800004353400f000000004452400f08
+:10657000000000009751400f00000000f4010424c7
+:10658000e14a400f0000000088bf023c9061428c4d
+:106590004002427c0300401000000000f3ff0010a6
+:1065a00000000000208280a305000424c452400f94
+:1065b0000000000001000424481d400f00000000fe
+:1065c000524f400f0000000021e8c0031400bf8fad
+:1065d0001000be8f1800bd270800e0030000000077
+:1065e000e0ffbd271c00bfaf1800beaf21f0a00325
+:1065f0002000c4af02000424c452400f0000000079
+:1066000003000424c452400f0000000004000424ce
+:10661000c452400f0000000005000424c452400f83
+:106620000000000006000424c452400f00000000d7
+:1066300007000424c452400f000000002000c28f55
+:106640001000c2af1000c38f0700601000000000f0
+:10665000010002241000c38f22006210000000001d
+:106660003f00001000000000030004242128000067
+:10667000029d023c84184624213800004353400ff9
+:1066800000000000b0808383020002240b0062142b
+:106690000000000021200000481d400f0000000005
+:1066a0000400042421280000029d023c9018462486
+:1066b000213800004353400f00000000c881848f40
+:1066c000f481858f0c82868f21380000f95b400fa2
+:1066d0000000000001000224988082a3270000101f
+:1066e000000000000300042421280000029d023c59
+:1066f000a0184624213800004353400f000000003a
+:10670000b0808383020002240b00621400000000aa
+:1067100021200000481d400f000000000400042458
+:1067200021280000029d023c9018462421380000d8
+:106730004353400f00000000c881848ff481858f8f
+:106740000c82868f21380000f95b400f00000000aa
+:1067500001000224988082a30800001000000000bd
+:106760000300042421280000029d023cb4184624a2
+:10677000213800004353400f0000000005000424ae
+:1067800021280000029d023cc41846242138000044
+:106790004353400f0000000096000424e14a400fdc
+:1067a000000000000500042421280000029d023c96
+:1067b000d4184624213800004353400f0000000045
+:1067c00096000424e14a400f0000000088bf023c0c
+:1067d0009061428c4002427c0300401000000000a7
+:1067e000e6ff00100000000088bf023c9061428c70
+:1067f0004002427c0300401400000000faff001039
+:106800000000000021e8c0031c00bf8f1800be8fed
+:106810002000bd270800e00300000000e8ffbd27be
+:106820001400bfaf1000beaf21f0a00381bf033c36
+:106830006090629020004234609062a088bf043c67
+:1068400040608390dfff022424106200406082a039
+:1068500088bf043c00618390bfff022424106200c3
+:10686000006182a088bf033c006162907f004230db
+:10687000006162a081bf043c61908390f7ff022415
+:1068800024106200619082a088bf033c4160629046
+:1068900008004234416062a081bf043c6190839053
+:1068a000efff022424106200619082a088bf033ca5
+:1068b0004160629010004234416062a081bf033c9d
+:1068c0006090629001004234609062a088bf033cf7
+:1068d0004060629001004234406062a081bf033c8e
+:1068e0006090629004004234609062a081bf033cdb
+:1068f0006090629008004234609062a081bf033cc7
+:106900006090629010004234609062a081bf043cad
+:106910006190839080ff022425106200619082a024
+:1069200088bf033c4060629004004234406062a033
+:1069300088bf033c4060629008004234406062a01f
+:1069400088bf033c4060629010004234406062a007
+:1069500088bf043c4160839080ff022425106200c0
+:10696000416082a088bf033c4061629010004234c5
+:10697000406162a088bf033c4061629020004234c5
+:10698000406162a088bf033c816162900200423492
+:10699000816162a088bf033ce061629010004234d4
+:1069a000e06162a088bf033ce06162902000423455
+:1069b000e06162a088bf033ce06162904000423425
+:1069c000e06162a088bf033ce16162901000423444
+:1069d000e16162a088bf033ce26162900200423440
+:1069e000e26162a088bf033ce2616290040042342d
+:1069f000e26162a088bf033ce1616290080042341a
+:106a0000e16162a088bf033cc06062901000423424
+:106a1000c06062a088bf033c816062902000423465
+:106a2000816062a088bf033c816062904000423474
+:106a3000816062a088bf033ce16162902000423423
+:106a4000e16162a088bf033ce061629002004234d1
+:106a5000e06162a088bf033ce061629001004234c3
+:106a6000e06162a081bf023c009040ac81bf023c6b
+:106a7000109040ac81bf033c021f0224209062ac06
+:106a800081bf023c509040ac81bf043c0190839098
+:106a900080ff022425106200019082a088bf043c80
+:106aa00040618390feff022424106200406182a0b6
+:106ab00088bf043c50618390feff022424106200d2
+:106ac000506182a088bf043c00618390dfff0224f4
+:106ad00024106200006182a088bf043c1061839092
+:106ae000dfff022424106200106182a088bf043cf2
+:106af000c1608390f7ff022424106200c16082a06d
+:106b000088bf043cd1608390f7ff02242410620008
+:106b1000d16082a080bf023c007040ace965400fac
+:106b2000000000009a1d400f000000003557400f84
+:106b300000000000107f400f000000002c8180a3a7
+:106b4000fc8180af029d023cd818428cc88182af84
+:106b5000029d023cdc18428cf48182af21100000bf
+:106b60000c8282af21e8c0031400bf8f1000be8fdb
+:106b70001800bd270800e00300000000d8ffbd2773
+:106b80002400bfaf2000beaf21f0a0031000c0afb3
+:106b90001400c0a31000c28f1f00401400000000aa
+:106ba0000c0004241e1d400f00000000a08082afd6
+:106bb000a880838fa080828f21106200a88082af7e
+:106bc000a480828f01004224a48082afa480828f9f
+:106bd00004004228efff401400000000a880828fcc
+:106be0001800c2af1800c28f04004104000000006a
+:106bf0001800c38f030063241800c3af1800c38fad
+:106c0000831003001000c2afa48080afa88080afc3
+:106c1000e0ff0010000000001000c28f0e004004d2
+:106c2000000000001000c28fc90042280a00401076
+:106c300000000000010002241400c2a3010004248b
+:106c400014000524029d023ce0184624213800006f
+:106c50004353400f000000001000c28fc8004228bc
+:106c60000e004014000000001000c28f9101422865
+:106c70000a00401000000000020002241400c2a319
+:106c80000100042414000524029d023cec18462453
+:106c9000213800004353400f000000001000c28f55
+:106ca000900142280e004014000000001000c28f26
+:106cb000590242280a00401000000000030002248c
+:106cc0001400c2a30100042414000524029d023c08
+:106cd000fc184624213800004353400f00000000f8
+:106ce0001000c28f580242280e004014000000001d
+:106cf0001000c28f210342280a004010000000004b
+:106d0000040002241400c2a301000424140005247a
+:106d1000029d023c0c194624213800004353400fc9
+:106d2000000000001000c28f200342280e00401413
+:106d3000000000001000c28fe90342280a00401042
+:106d400000000000050002241400c2a30100042476
+:106d500014000524029d023c20194624213800001d
+:106d60004353400f000000001000c28ffc03422874
+:106d700009004014000000001400c0a30100042416
+:106d800014000524029d023c3019462421380000dd
+:106d90004353400f000000001400c28321e8c003e9
+:106da0002400bf8f2000be8f2800bd270800e0030d
+:106db00000000000e0ffbd271c00bfaf1800beaf01
+:106dc00021f0a0031000c0afdf5a400f0000000008
+:106dd000b08082a30854400f00000000815b400f88
+:106de000000000001000c2af1000c28f21e8c003f5
+:106df0001c00bf8f1800be8f2000bd270800e003d5
+:106e000000000000e0ffbd271c00bfaf1800beafb0
+:106e100021f0a0031000c0af88bf023c5060428c3c
+:106e2000c000437c010002246700621400000000df
+:106e300005000424a71e400f0000000088bf023c8c
+:106e40005060428c0001427c13004014000000009e
+:106e500005000424a71e400f0000000088bf023c6c
+:106e60005060428c0001427c03004014000000008e
+:106e7000faff0010000000001000c28f0100422441
+:106e80001000c2af1000c28f04004228020040145c
+:106e9000000000001000c0af88bf023c5060428c70
+:106ea000c003427c130040140000000005000424cd
+:106eb000a71e400f0000000088bf023c5060428cbb
+:106ec000c003427c0300401400000000faff0010e1
+:106ed000000000001000c28fffff42241000c2af6c
+:106ee0001000c28f030041040000000003000224d0
+:106ef0001000c2af1000c28f1400c2af0100022404
+:106f00001400c38f1b006210000000001400c38f28
+:106f10000200622806004010000000001400c28f2a
+:106f20000d00401000000000bbff0010000000003a
+:106f3000020002241400c38f15006210000000003c
+:106f4000030002241400c38f180062100000000028
+:106f5000b1ff0010000000000200042421280000fe
+:106f6000010006242955400f00000000aaff001070
+:106f70000000000003000424212800000100062472
+:106f80002955400f00000000a3ff00100000000082
+:106f90000400042421280000010006242955400f84
+:106fa000000000009cff0010000000000500042409
+:106fb00021280000010006242955400f0000000090
+:106fc00095ff0010000000001000c28f21e8c003f0
+:106fd0001c00bf8f1800be8f2000bd270800e003f3
+:106fe00000000000d0ffbd272c00bfaf2800beafbf
+:106ff00021f0a0033000c4af3400c5af3800c6afe5
+:107000002110e0003c00c2a388bf033c0100023c09
+:10701000641062ac88bf033c0100023c681062aca3
+:1070200001000224bc8082af47000224e88182a3d1
+:10703000cc8180af58000224198282a33000c28f15
+:10704000bc8182af59000224f88182a33400c28f30
+:10705000e08182af3c00c2830700401000000000c6
+:107060005a000224088282a33800c28f1c8282af99
+:107070000400001000000000088280a3211000001e
+:107080001c8282af46000224e98182a32110000005
+:10709000dc8182afe881838319828683f8818283d1
+:1070a0001000a2afe081828f1400a2af0882828319
+:1070b0001800a2af1c82828f1c00a2afe9818283dc
+:1070c0002000a2afdc81828f2400a2af21206000cb
+:1070d000cc81858fbc81878f504c400f0000000011
+:1070e000e88180a3cc8180af198280a321100000a9
+:1070f000bc8182aff88180a321100000e08182afc3
+:10710000088280a3211000001c8282afe98180a345
+:1071100021100000dc8182afbc8080affa00042423
+:10712000e14a400f0000000021e8c0032c00bf8f9f
+:107130002800be8f3000bd270800e00300000000db
+:10714000e8ffbd271400bfaf1000beaf21f0a003c1
+:10715000988083830100022406006214000000006e
+:10716000988080a3d08180af9c8080af8c8080afde
+:10717000908080af1b1f400f0000000003004014f0
+:1071800000000000fbff001000000000aa5c400fa0
+:107190000000000088bf023c9061428c4002427cab
+:1071a000030040140000000039000010000000003f
+:1071b000f35d400f00000000c08082af00a0023ce1
+:1071c000740a4424029d023c3c1945245a30400f65
+:1071d00000000000f08182aff081828fd08182af09
+:1071e000f081828f000042380100422c25104200bd
+:1071f00020004010000000000200042421280000ac
+:10720000029d023c40194624213800004353400fa0
+:10721000000000000300042428000524029d023c15
+:1072200050194624213800004353400f000000004d
+:107230000400042421280000029d023c301846244a
+:10724000213800004353400f00000000fa000424de
+:10725000e14a400f0000000088bf023c9061428c70
+:107260004002427ce4ff40140000000008000010cf
+:1072700000000000020004245a000524029d023c84
+:1072800060194624213800004353400f00000000dd
+:1072900021e8c0031400bf8f1000be8f1800bd2767
+:1072a0000800e0030000000080ffbd277c00bfafa6
+:1072b0007800beaf21f0a003200002244800c2a342
+:1072c000029d023c6819428c5000c2af01000224aa
+:1072d0005800c2af5c00c0af6000c0af5000c22712
+:1072e0004800c39321204000212860001000c627d9
+:1072f000c746400f000000005800c2af5800c28fc0
+:10730000370040140000000001000224c88082af52
+:107310001000c427d647400f000000005800c2af3d
+:107320005800c28f0400401400000000c880828f03
+:1073300001004224c88082af5800c28f030040146d
+:1073400000000000f2ff0010000000006000c28f8b
+:1073500023004014000000005000c2274800c393df
+:1073600021204000212860001000c627c746400f9a
+:10737000000000005800c2af01000224c48082afa8
+:10738000010002245c00c2af5c00c28fc880838f02
+:107390002a1043000a004010000000001000c4271b
+:1073a000d647400f000000005800c2af5c00c28ffb
+:1073b000010042245c00c2aff3ff00100000000097
+:1073c000c880828fc48082af02000424212800007c
+:1073d0001000c627213800004353400f0000000072
+:1073e0005800c28f2900401000000000c88080af04
+:1073f000c48080af0200042421280000029d023cca
+:107400006c194624213800004353400f000000004f
+:107410000300042421280000029d023c8019462418
+:10742000213800004353400f0000000005000424f1
+:1074300021280000029d023c9419462421380000b6
+:107440004353400f000000000600042421280000e0
+:10745000029d023ca4194624213800004353400fea
+:1074600000000000fa000424e14a400f0000000080
+:1074700088bf023c9061428c4002427cddff401498
+:1074800000000000cb000010000000005800c28f78
+:10749000a50040140000000088bf023c5060428cf0
+:1074a0000001427c330040140000000088bf023c11
+:1074b0005060428c0001427c030040140000000038
+:1074c000faff0010000000001e000424e14a400ff3
+:1074d000000000001000c427d647400f0000000045
+:1074e0005800c2af5800c28f0f00401400000000c7
+:1074f000c480828fc880838f2a10620005004010ec
+:1075000000000000c880828fc48082af100000108d
+:1075100000000000c480828f01004224c48082af3a
+:107520000b000010000000005000c2274800c39369
+:1075300021204000212860001000c627c746400fc8
+:10754000000000005800c2af01000224c48082afd6
+:1075500002000424c452400f000000000200042472
+:10756000212800001000c627213800004353400f97
+:107570000000000088bf023c5060428cc003427c87
+:107580003f0040140000000088bf023c5060428c65
+:10759000c003427c0300401400000000faff00100a
+:1075a000000000001e000424e14a400f000000001b
+:1075b0001000c427d647400f000000005800c2af9b
+:1075c0005800c28f0300401400000000f8ff0010b4
+:1075d000000000005000c2274800c3932120400053
+:1075e000212860001000c627c746400f0000000099
+:1075f0005800c2afc480828fffff4224c48082af94
+:10760000c480828f0500401400000000c880828f73
+:10761000c48082af010002246000c2af01000224d6
+:107620005c00c2af5c00c28fc480838f2a1043000d
+:107630000a004010000000001000c427d647400f89
+:10764000000000005800c2af5c00c28f010042245d
+:107650005c00c2aff3ff0010000000000200042431
+:10766000c452400f00000000020004242128000042
+:107670001000c627213800004353400f00000000cf
+:107680000600042421280000029d023cb019462473
+:10769000213800004353400f000000006800c2275b
+:1076a00021204000029d023cb8194524c480868fe9
+:1076b000486e400f000000006800c2270600042446
+:1076c0001900052421304000213800004353400fa9
+:1076d000000000000600042441000524029d023c35
+:1076e000bc194624213800004353400f000000001d
+:1076f0006800c22721204000029d023cb8194524a1
+:10770000c880868f486e400f000000006800c227c6
+:10771000060004245a0005242130400021380000ce
+:107720004353400f0000000088bf023c9061428c30
+:107730004002427c03004014000000001d000010c5
+:107740000000000088bf023c5060428cc000427cb8
+:10775000010042380100432c5800c28f000042381b
+:107760000100422c241062000300401000000000c1
+:1077700046ff00100000000088bf023c5060428cb1
+:10778000c000437c010002240300621400000000da
+:10779000d2fe00100000000000a0023c740a442445
+:1077a0001000c527336b400f000000002000c28f7f
+:1077b000e48182af21e8c0037c00bf8f7800be8fd8
+:1077c0008000bd270800e00300000000f0ffbd2797
+:1077d0000800beaf21f0a003080002240100c2a3ec
+:1077e0000100c293500040100000000000a0023cc5
+:1077f0000100c393740a42242110620000004380f8
+:107800002e000224430062140000000000a0023c8d
+:107810000100c393740a42242110620001004280d7
+:10782000470042380100442c00a0023c0100c393f1
+:10783000740a422421106200020042804300423850
+:107840000100422c2420820000a0023c0100c393ce
+:10785000740a422421106200030042804f00423823
+:107860000100422c2410820007004010000000009c
+:10787000010002240000c2a3010002240400c2afe0
+:10788000290000100000000000a0023c0100c3938a
+:10789000740a4224211062000100428042004238f2
+:1078a0000100442c00a0023c0100c393740a42244e
+:1078b0002110620002004280460042380100422c42
+:1078c0002420820000a0023c0100c393740a4224d9
+:1078d0002110620003004280420042380100422c25
+:1078e0002410820007004010000000000300022462
+:1078f0000000c2a3030002240400c2af0a0000106b
+:10790000000000000000c0a30400c0af060000108b
+:10791000000000000100c293ffff42240100c2a347
+:10792000afff0010000000000400c28f21e8c00378
+:107930000800be8f1000bd270800e0030000000013
+:10794000d0ffbd272c00bfaf2800beaf21f0a003a1
+:10795000010002242000c2af2400c0af988080a3a1
+:10796000d081828ff08182af9080828f010042248b
+:10797000908082af00a0033c3e000224400a62a037
+:10798000f081848f8c80858f213000009e38400fdd
+:107990000000000006004010000000000100042468
+:1079a0007859400f0000000001000224988082a353
+:1079b000988082833f0040140000000018828427d2
+:1079c0000100052401000624f081878fce35400f89
+:1079d000000000009c8082af00a0023c2000c38f0a
+:1079e000400a42242118620018828293000062a09b
+:1079f0002000c28f010042242000c2af188283837e
+:107a00002800022415006214000000001882842758
+:107a10000100052401000624f081878fce35400f38
+:107a2000000000009c8082aff081848fbe35400f43
+:107a300000000000030040100000000007000010dc
+:107a400000000000188283830a00022403006210f1
+:107a500000000000edff001000000000f081848fa6
+:107a6000be35400f0000000008004010000000007c
+:107a7000f081848f892d400f000000000100022456
+:107a8000988082a307000010000000001882838302
+:107a90000a0002240300621000000000c7ff00106b
+:107aa00000000000f081848f0632400f00000000cb
+:107ab0008c8082af21e8c0032c00bf8f2800be8fce
+:107ac0003000bd270800e00300000000e0ffbd27f4
+:107ad0001c00bfaf1800beaf21f0a00301000224bc
+:107ae0001000c2af1400c0af01000224948082af26
+:107af00000a0023c400a4224010043900d000224f1
+:107b00000300621400000000dc0000100000000010
+:107b10009480838f0100022427006214000000007b
+:107b20001400c28f0a0040140000000000a0023cb4
+:107b30001000c38f400a42242110620000004290ce
+:107b4000e88182a31000c28f010042241000c2af5e
+:107b50001400c38fd48182272120620000a0023c40
+:107b60001000c38f400a422421106200000042909e
+:107b7000000082a01400c28f010042241400c2af92
+:107b800000a0023c1000c38f400a42242110620072
+:107b9000000043902000022407006214000000004f
+:107ba0001000c28f010042241000c2af1400c0af09
+:107bb00002000224948082af9480838f020002240a
+:107bc00027006214000000001400c28f0a00401455
+:107bd0000000000000a0023c1000c38f400a4224b5
+:107be0002110620000004290198282a31000c28f0f
+:107bf000010042241000c2af1400c38f24828227e8
+:107c00002120620000a0023c1000c38f400a4224e1
+:107c10002110620000004290000082a01400c28f78
+:107c2000010042241400c2af00a0023c1000c38f28
+:107c3000400a4224211062000000439020000224e8
+:107c400007006214000000001000c28f01004224ef
+:107c50001000c2af1400c0af03000224948082afb2
+:107c60009480838f03000224270062140000000028
+:107c70001400c28f0a0040140000000000a0023c63
+:107c80001000c38f400a422421106200000042907d
+:107c9000f88182a31000c28f010042241000c2affd
+:107ca0001400c38f008282272120620000a0023cc2
+:107cb0001000c38f400a422421106200000042904d
+:107cc000000082a01400c28f010042241400c2af41
+:107cd00000a0023c1000c38f400a42242110620021
+:107ce00000004390200002240700621400000000fe
+:107cf0001000c28f010042241000c2af1400c0afb8
+:107d000004000224948082af9480838f04000224b4
+:107d100027006214000000001400c28f0a00401403
+:107d20000000000000a0023c1000c38f400a422463
+:107d30002110620000004290088282a31000c28fce
+:107d4000010042241000c2af1400c38f10828227aa
+:107d50002120620000a0023c1000c38f400a422490
+:107d60002110620000004290000082a01400c28f27
+:107d7000010042241400c2af00a0023c1000c38fd7
+:107d8000400a422421106200000043902000022497
+:107d900007006214000000001000c28f010042249e
+:107da0001000c2af1400c0af05000224948082af5f
+:107db0009480838f050002241900621400000000e3
+:107dc0001400c28f0a0040140000000000a0023c12
+:107dd0001000c38f400a422421106200000042902c
+:107de000e98182a31000c28f010042241000c2afbb
+:107df0001400c38fc08182272120620000a0023cb2
+:107e00001000c38f400a42242110620000004290fb
+:107e1000000082a01400c28f010042241400c2afef
+:107e200000a0023c1000c38f400a422421106200cf
+:107e3000000043900a0002240300621400000000c6
+:107e40000e000010000000001000c28f010042244c
+:107e50001000c2af00a0023c1000c38f400a4224b1
+:107e600021106200000043900d0002240300621004
+:107e7000000000001eff001000000000d4818427d5
+:107e8000096d400f00000000cc8182af248284275e
+:107e9000026d400f000000002120400021286000fa
+:107ea0002a7a400f00000000bc8182af0082842744
+:107eb000026d400f000000002120400021286000da
+:107ec0002a7a400f00000000e08182af10828427f0
+:107ed000026d400f000000002120400021286000ba
+:107ee0002a7a400f000000001c8282afc0818427e4
+:107ef000026d400f0000000021204000212860009a
+:107f00002a7a400f00000000dc8182af21e8c00324
+:107f10001c00bf8f1800be8f2000bd270800e003a3
+:107f200000000000f0ffbd270800beaf21f0a00355
+:107f3000310002240000c2af0000c28f0b004010cd
+:107f40000000000000a0023c0000c38f400a422451
+:107f500021106200000040a00000c28fffff4224f9
+:107f60000000c2aff4ff0010000000000000c28f4c
+:107f7000030040140000000000a0023c400a40a0a2
+:107f8000e88180a3070002240000c2af0000c28f76
+:107f90000a004010000000000000c38fd481822737
+:107fa00021106200000040a00000c28fffff4224a9
+:107fb0000000c2aff5ff0010000000000000c28ffb
+:107fc0000200401400000000d48180a3198280a325
+:107fd000070002240000c2af0000c28f0a00401058
+:107fe000000000000000c38f24828227211062005d
+:107ff000000040a00000c28fffff42240000c2af7b
+:10800000f5ff0010000000000000c28f02004014c5
+:1080100000000000248280a3f88180a307000224ce
+:108020000000c2af0000c28f0a0040100000000034
+:108030000000c38f0082822721106200000040a050
+:108040000000c28fffff42240000c2aff5ff001006
+:10805000000000000000c28f020040140000000079
+:10806000008280a3088280a3070002240000c2af20
+:108070000000c28f0a004010000000000000c38f03
+:108080001082822721106200000040a00000c28ff1
+:10809000ffff42240000c2aff5ff00100000000007
+:1080a0000000c28f0200401400000000108280a374
+:1080b000e98180a3070002240000c2af0000c28f44
+:1080c0000a004010000000000000c38fc08182271a
+:1080d00021106200000040a00000c28fffff422478
+:1080e0000000c2aff5ff0010000000000000c28fca
+:1080f0000200401400000000c08180a321e8c003fa
+:108100000800be8f1000bd270800e003000000003b
+:10811000e0ffbd271c00bfaf1800beaf21f0a003d9
+:10812000211000001000c2af6c82828f4882838fc2
+:108130002a1062000a004010000000006c82838f49
+:108140004882828f2310620021204000ae7c400fc5
+:10815000000000001000c2af090000100000000085
+:108160006c82838f4882828f231062000002422437
+:1081700021204000ae7c400f000000001000c2af84
+:10818000029d023c1000c48fc019458c237c400f17
+:10819000000000001000c2af029d023c1000c48f1e
+:1081a000c419458cb57b400f000000001000c2af21
+:1081b0001000c48fd87c400f00000000060004248b
+:1081c000212840008f52400f0000000021e8c0032a
+:1081d0001c00bf8f1800be8f2000bd270800e003e1
+:1081e00000000000d8ffbd272000bfaf1c00beafbd
+:1081f0001800b0af21f0a003211000001000c2afa2
+:108200008c80848fae7c400f0000000021804000f5
+:10821000e481848fae7c400f00000000212000022a
+:1082200021284000237c400f000000001000c2af56
+:10823000029d023c1000c48fc819458cb57b400fcd
+:10824000000000001000c2af029d023cc819448c1f
+:108250001000c58f137d400f000000000300400494
+:10826000000000000400001000000000029d023c1d
+:10827000c819428c1000c2af1000c48fd87c400fc8
+:108280000000000005000424212840008f52400f08
+:108290000000000021e8c0032000bf8f1c00be8f3b
+:1082a0001800b08f2800bd270800e0030000000080
+:1082b000c8ffbd273400bfaf3000beaf21f0a00320
+:1082c000211080003800c2a3211000002000c2af9e
+:1082d000211000002400c2af211000002800c2af0e
+:1082e0004882838f6c82828f03006210000000003e
+:1082f000fbff00100000000088bf033c0100023caf
+:10830000641062ac88bf023c681040ac60ea023482
+:108310004c8182af008180a3018180a3028180a370
+:1083200001000424bd61400f000000003f54400fd5
+:108330000000000088bf023c5060428cc000427cbc
+:108340000300401400000000faff001000000000cd
+:1083500088bf023c9061428c4002437c01000224b1
+:10836000d80062140000000001000224048182afe2
+:108370004c81828fe9034228040040140000000071
+:108380004c81828fb5ff42244c8182af4c81828f19
+:108390006500422804004014000000004c81828fd8
+:1083a000fbff42244c8182af4c81828f9001422896
+:1083b0000300401000000000900102244c8182afb5
+:1083c00088bf023c5060428cc000427c04004014d4
+:1083d00000000000848280af01000224008182a39b
+:1083e00088bf023c5060428c8000427c05004014f3
+:1083f0000000000001000224848282af01000224f8
+:10840000008182a388bf023c5060428cc000427c45
+:10841000070040100000000088bf023c5060428c02
+:108420008000427c0200401000000000008180a318
+:1084300088bf023c5060428cc003427c0400401460
+:1084400000000000648280af01000224018182a349
+:1084500088bf023c5060428c0001427c0500401401
+:108460000000000001000224648282af01000224a7
+:10847000018182a388bf023c5060428cc003427cd1
+:10848000070040100000000088bf023c5060428c92
+:108490000001427c0200401000000000018180a326
+:1084a00088bf023c5061428c4001427c0400401471
+:1084b00000000000708280af01000224028182a3cc
+:1084c00088bf023c5061428c0001427c0500401490
+:1084d0000000000001000224708282af010002242b
+:1084e000028182a388bf023c5061428c4001427ce1
+:1084f000070040100000000088bf023c5061428c21
+:108500000001427c0200401000000000028180a3b4
+:1085100000818283090040140000000001818283f1
+:108520000600401400000000028182830300401412
+:108530000000000060ea02344c8182af3800c28340
+:1085400083ff4010000000003482848fae7c400f17
+:108550000000000021204000017a400f00000000d0
+:10856000029d063c2120400021286000dc19c78cb8
+:10857000d819c68ca378400f0000000021204000cd
+:10858000212860002a7a400f000000002000c2afbe
+:108590002000c48f017a400f00000000213040000d
+:1085a000213860001000c427029d023cd0194524e8
+:1085b000486e400f00000000040004244000052421
+:1085c0001000c627213800004353400f0000000070
+:1085d0006882848fae7c400f0000000021204000a4
+:1085e000017a400f00000000029d063c212040005f
+:1085f00021286000dc19c78cd819c68ca378400fdd
+:108600000000000021204000212860002a7a400f4d
+:10861000000000002400c2af2400c48f017a400f84
+:108620000000000021304000213860001000c42705
+:10863000029d023cd0194524486e400f0000000006
+:1086400005000424400005241000c627213800003e
+:108650004353400f000000003c82848fae7c400feb
+:1086600000000000029d033c21204000e019658cc1
+:10867000237c400f000000002800c2af2800c48ff8
+:10868000017a400f000000002130400021386000d6
+:108690001000c427029d023cd0194524486e400fab
+:1086a0000000000006000424400005241000c62736
+:1086b000213800004353400f0000000024ff001049
+:1086c00000000000048180af88bf023c0100033c31
+:1086d000641043ac88bf023c681040ac21e8c00382
+:1086e0003400bf8f3000be8f3800bd270800e00384
+:1086f00000000000f8ffbd270000beaf21f0a0037e
+:108700000800c4af0800c38f0100022418006214df
+:108710000000000088bf043cd0608390f7ff022473
+:1087200024106200d06082a088bf043cd160839096
+:10873000fbff022424106200d16082a088bf043ca9
+:1087400051608390dfff022424106200516082a0f8
+:1087500088bf033c0100023c641062ac88bf033c4c
+:108760000100023c681062ac120000100000000022
+:1087700088bf033cd060629008004234d06062a0a1
+:1087800088bf033cd160629004004234d16062a093
+:1087900088bf033c5160629020004234516062a067
+:1087a00088bf033c0100023c641062ac88bf023cfd
+:1087b000681040ac21e8c0030000be8f0800bd2750
+:1087c0000800e00300000000e0ffbd271c00bfaf71
+:1087d0001800beaf21f0a0039e54400f000000001f
+:1087e000008180a3018180a3028180a3e965400ffd
+:1087f0000000000001000424bd61400f00000000e3
+:1088000001000224048182aff40102244c8182af72
+:108810000300042421280000029d023ce4194624a0
+:10882000213800004353400f0000000001000224e3
+:10883000708282af01000224028182a31000c0afc7
+:108840001000c38f0300023c3f0d42342a10430046
+:1088500006004014000000001000c28f01004224f6
+:108860001000c2aff6ff001000000000028180a3dc
+:108870000300042421280000029d023cf019462434
+:10888000213800004353400f00000000e803022499
+:108890004c8182af01000224648282af0100022475
+:1088a000018182a31000c0af1000c28f5fea0334c1
+:1088b0002a10620006004014000000001000c28f61
+:1088c000010042241000c2aff7ff001000000000ba
+:1088d000018180a30300042421280000029d023ca2
+:1088e000fc194624213800004353400f00000000cb
+:1088f000e80302244c8182af88bf023cd060428ce6
+:108900000001427c210040140000000088bf023cae
+:108910009061428c4002427c1c004010000000002c
+:1089200001000224848282af88bf023cd060428c66
+:108930000001427c0a0040140000000088bf023c95
+:108940009061428c4002427c050040100000000013
+:1089500001000224008182a3f3ff00100000000048
+:10896000008180a31000c0af1000c28f204e4228ab
+:10897000e1ff4010000000001000c28f01004224ff
+:108980001000c2aff8ff0010000000000100022438
+:10899000008182a31000c0af1000c28f10274228b0
+:1089a00006004010000000001000c28f01004224a9
+:1089b0001000c2aff8ff001000000000008180a38b
+:1089c00060ea02344c8182af88bf023cd060428ca6
+:1089d0000001427c260040100000000088bf023cdd
+:1089e0009061428c4002427c210040100000000057
+:1089f000848280af88bf023cd060428c0001427c00
+:108a00000a0040100000000088bf023c9061428cc8
+:108a10004002427c050040100000000001000224da
+:108a2000008182a3f3ff001000000000008180a3fa
+:108a30001000c0af1000c28fd007422806004010bf
+:108a4000000000001000c28f010042241000c2afdd
+:108a5000f8ff001000000000addf0224348282af76
+:108a60003482828f388282afd7ff0010000000006e
+:108a70000300042421280000029d023c081a462419
+:108a8000213800004353400f00000000e803022497
+:108a90004c8182af88bf023c9060428c4003427c94
+:108aa000200040140000000088bf023c9061428c0e
+:108ab0004002427c1b00401000000000648280af36
+:108ac00088bf023c9060428c4003427c0a00401404
+:108ad0000000000088bf023c9061428c4002427c52
+:108ae000050040100000000001000224018182a363
+:108af000f3ff001000000000018180a31000c0af50
+:108b00001000c28f204e4228e2ff401000000000fb
+:108b10001000c28f010042241000c2aff8ff001005
+:108b20000000000001000224018182a31000c0aff8
+:108b30001000c28f102742280600401000000000dd
+:108b40001000c28f010042241000c2aff8ff0010d5
+:108b500000000000018180a360ea02344c8182aff2
+:108b600088bf023c9060428c4003427c270040104a
+:108b70000000000088bf023c9061428c4002427cb1
+:108b8000220040100000000001000224648282af35
+:108b900088bf023c9060428c4003427c0a00401037
+:108ba0000000000088bf023c9061428c4002427c81
+:108bb000050040100000000001000224018182a392
+:108bc000f3ff001000000000018180a31000c0af7f
+:108bd0001000c28fd007422806004010000000009d
+:108be0001000c28f010042241000c2aff8ff001035
+:108bf00000000000f2170224688282af6882828f30
+:108c0000508282afd6ff0010000000000300042451
+:108c100021280000029d023c141a4624213800003d
+:108c20004353400f00000000f40102244c8182af46
+:108c300088bf023c9060428c8003427c200040143c
+:108c40000000000088bf023c9061428c4002427ce0
+:108c50001b00401000000000708280af88bf023c03
+:108c60009060428c8003427c0a00401400000000a7
+:108c700088bf023c9061428c4002427c050040105b
+:108c80000000000001000224028182a3f3ff001013
+:108c900000000000028180a31000c0af1000c28f4e
+:108ca000d0074228e2ff4010000000001000c28ff1
+:108cb000010042241000c2aff8ff001000000000c5
+:108cc00001000224028182a31000c0af1000c28ff5
+:108cd0001027422806004010000000001000c28f3c
+:108ce000010042241000c2aff8ff00100000000095
+:108cf000028180a3881302244c8182af88bf023c8a
+:108d00009060428c8003427c2600401000000000ee
+:108d100088bf023c9061428c4002427c210040109e
+:108d20000000000001000224708282af88bf023c74
+:108d30009060428c8003427c0a00401000000000da
+:108d400088bf023c9061428c4002427c050040108a
+:108d50000000000001000224028182a3f3ff001042
+:108d600000000000028180a31000c0af1000c28f7d
+:108d7000d007422806004010000000001000c28ffb
+:108d8000010042241000c2aff8ff001000000000f4
+:108d90003c8280af3c82828f5c8282afd7ff001022
+:108da00000000000048180af88bf033c0100023c4a
+:108db000641062ac88bf023c681040ac88bf023cc3
+:108dc0009061428c4002427c170040140000000079
+:108dd0000300042421280000029d023c201a46249e
+:108de000213800004353400f000000001000c0afc6
+:108df0001000c38f1e00023c7f8442342a104300bf
+:108e000006004014000000001000c28f0100422440
+:108e10001000c2aff6ff0010000000001400c0af49
+:108e200016000010000000000300042421280000a8
+:108e3000029d023c301a4624213800004353400f63
+:108e4000000000001000c0af1000c38f1e00023ce5
+:108e50007f8442342a1043000600401400000000c2
+:108e60001000c28f010042241000c2aff6ff0010b4
+:108e700000000000010002241400c2af1400c28fe1
+:108e800021e8c0031c00bf8f1800be8f2000bd2743
+:108e90000800e00300000000e8ffbd271400bfaf9a
+:108ea0001000beaf21f0a00301000224788082af41
+:108eb000010002247c8082af808080af20030224e6
+:108ec0004c8182afc881848f017a400f000000007e
+:108ed000029d063c2120400021286000441ac78cd6
+:108ee000401ac68cd977400f0000000021204000b6
+:108ef000212860002a7a400f00000000608282afc3
+:108f0000f481848f017a400f00000000029d063c2e
+:108f10002120400021286000441ac78c401ac68cca
+:108f2000d977400f00000000212040002128600078
+:108f30002a7a400f00000000548282af6082848f42
+:108f4000256a400f00000000308282af5482848f77
+:108f5000256a400f00000000808282af88bf033c7a
+:108f60000100023c641062ac88bf033c0100023c7b
+:108f7000681062acc767400f00000000788080afc7
+:108f80007c8080affa000424e14a400f000000001a
+:108f900021e8c0031400bf8f1000be8f1800bd274a
+:108fa0000800e0030000000000e85d4100681a408e
+:108fb00000701b40c0ffbd273c00bbaf00601b40e2
+:108fc00082d21a003800bbaf847a5b7f44201b7cbe
+:108fd00000609b403400beaf3000a4af2c00a3afb4
+:108fe0002800a2af21f0a0030400c0a30481828f57
+:108ff0009800401000000000fc80828f0800c2af83
+:10900000010002240800c38f260062100000000047
+:109010000800c38f02006228060040100000000014
+:109020000800c28f090040100000000082000010fc
+:1090300000000000020002240800c38f6b006210d1
+:10904000000000007c0000100000000088bf043c0d
+:10905000d060828c8482838fc439627cd06082ac81
+:1090600088bf043cd060828c6482838f444a627cd7
+:10907000d06082ac88bf043c5060828c7082838f49
+:10908000444a627c506082ac80bf033c05000224ed
+:10909000200c62ac01000224fc8082af660000104c
+:1090a00000000000008182831200401000000000d8
+:1090b00088bf033cd060629004004234d06062a05c
+:1090c0008482828f06004014000000003482828f68
+:1090d00001004224348282af0b0000100000000027
+:1090e0003482828fffff4224348282af0600001058
+:1090f0000000000088bf043cd0608390fbff022486
+:1091000024106200d06082a001818283120040108e
+:109110000000000088bf033cd1606290010042342f
+:10912000d16062a06482828f0600401400000000bb
+:109130006882828f01004224688282af0b00001097
+:10914000000000006882828fffff4224688282afa5
+:10915000060000100000000088bf043cd16083902e
+:10916000feff022424106200d16082a0028182836b
+:10917000120040100000000088bf033c5160629064
+:1091800001004234516062a07082828f0600401458
+:10919000000000003c82828f010042243c8282afaa
+:1091a0000b000010000000003c82828fffff422471
+:1091b0003c8282af060000100000000088bf043c23
+:1091c00051608390feff022424106200516082a04f
+:1091d00080bf023c0a000324200c43ac020002249e
+:1091e000fc8082af140000100000000080bf033c30
+:1091f0004c81828f200c62ac88bf043cd06083908d
+:10920000fbff022424106200d06082a088bf043ccf
+:10921000d1608390feff022424106200d16082a0fe
+:1092200088bf043c51608390feff0224241062003a
+:10923000516082a0fc8080af80bf023c100c40ac2b
+:1092400088bf033c0100023c341062ac48010010ae
+:1092500000000000f880828f2400c2af01000224c9
+:109260002400c38fa5006210000000002400c38ffb
+:109270000200622806004010000000002400c28f97
+:109280000900401000000000340100100000000040
+:10929000020002242400c38f0d01621000000000b0
+:1092a0002e010010000000002c82828f8c004014e0
+:1092b000000000004882838f6c82828f88006210d9
+:1092c0000000000000a0043c4882828f8018020049
+:1092d000800a8224211062000000428c4c8282affe
+:1092e00000a0043c4882828f80180200800a8224f9
+:1092f00021106200000040ac4882828f01004224ad
+:10930000488282af4882828f0c00c2af0c00c38fac
+:109310001000c3af1000c28f040041040000000021
+:109320001000c38fff0163241000c3af1000c38f70
+:1093300043120300401202000c00c38f231062008e
+:10934000488282af010002242c8282af0008023cd6
+:109350000000c2af030002240400c2a34c82828f2b
+:109360000000c38f241043002a00401000000000ba
+:109370000400c2931400c2af050002241400c38f7e
+:1093800017006210000000001400c38f060062285e
+:109390000700401000000000030002241400c38fe7
+:1093a00009006210000000004200001000000000f0
+:1093b000070002241400c38f0f0062100000000099
+:1093c0003c0000100000000088bf023c5160439048
+:1093d00002006334516043a036000010000000001a
+:1093e00088bf023cd160439002006334d16043a047
+:1093f000300000100000000088bf043cd060839063
+:1094000080ff022425106200d06082a02900001095
+:10941000000000000400c2931800c2af050002243f
+:109420001800c38f18006210000000001800c38fde
+:10943000060062280700401000000000030002241c
+:109440001800c38f0900621000000000190000100e
+:1094500000000000070002241800c38f11006210f2
+:1094600000000000130000100000000088bf043c52
+:1094700051608390fdff022424106200516082a09d
+:109480000c0000100000000088bf043cd1608390f5
+:10949000fdff022424106200d16082a005000010ac
+:1094a0000000000088bf023cd06043907f00633022
+:1094b000d06043a00400c293020042240400c2a36f
+:1094c0000000c28f801002000000c2af0000c28ff7
+:1094d0000300401000000000a0ff0010000000008a
+:1094e00080bf023c05000324200c43ac0100022491
+:1094f000f88082af99000010000000002c82828f5b
+:109500006c004010000000000004023c0000c2afec
+:10951000020002240400c2a34c82828f0000c38f89
+:10952000241043002d004010000000000400c293ee
+:109530001c00c2af040002241c00c38f170062107d
+:10954000000000001c00c38f0500622807004010c7
+:1095500000000000020002241c00c38f09006210fa
+:109560000000000048000010000000000600022477
+:109570001c00c38f110062100000000042000010a8
+:109580000000000088bf023c51604390010063343a
+:10959000516043a03c0000100000000088bf033c65
+:1095a000d160629001004234d16062a001000224c7
+:1095b0000600c2a3340000100000000088bf033c76
+:1095c000d060629004004234d06062a001000224a6
+:1095d0000500c2a32c000010000000000400c2938c
+:1095e0002000c2af040002242000c38f18006210c4
+:1095f000000000002000c38f050062280700401013
+:1096000000000000020002242000c38f0900621045
+:10961000000000001c0000100000000006000224f2
+:109620002000c38f1200621000000000160000101e
+:109630000000000088bf043c51608390feff0224bc
+:1096400024106200516082a00f0000100000000092
+:1096500088bf043cd1608390feff02242410620086
+:10966000d16082a00600c0a3070000100000000027
+:1096700088bf043cd0608390fbff0224241062006a
+:10968000d06082a00500c0a30400c293020042245f
+:109690000400c2a30000c28f801002000000c2af0d
+:1096a0000000c28f03004010000000009aff00106d
+:1096b0000000000080bf023c0a000324200c43ace1
+:1096c00002000224f88082af240000100000000095
+:1096d0002c82828f0c00401000000000ffff02343b
+:1096e0000000c2af4c82838f0000c28f2410620042
+:1096f000248082af80bf033c2480828f200c62ac28
+:10970000040000100000000080bf033c8813022406
+:10971000200c62ac88bf043cd0608390fbff022425
+:1097200024106200d06082a088bf043cd160839086
+:10973000feff022424106200d16082a088bf043c96
+:1097400051608390feff022424106200516082a0c9
+:10975000f88080af2c8280af4c8280af80bf023c0b
+:10976000100c40ac88bf033c0100023c341062acda
+:1097700021e8c0033400be8f3000a48f2c00a38fdb
+:109780002800a28f00606041c00000003c00ba8f3a
+:1097900000709a403800ba8f4000bd2700609a40a0
+:1097a00018000042e8ffbd271400bfaf1000beaf95
+:1097b00021f0a00380bf033c30800234000662ac7d
+:1097c00081bf043c00f28390f7ff02242410620062
+:1097d00000f282a081bf033c61906290010042349c
+:1097e000619062a088bf043c41608390feff022428
+:1097f00024106200416082a081bf033c61906290ae
+:1098000002004234619062a088bf043c41608390b2
+:10981000fdff022424106200416082a081bf033c4e
+:109820006190629020004234619062a088bf043c45
+:1098300041608390dfff022424106200416082a017
+:1098400088bf033cc060629010004234c06062a0d8
+:1098500088bf043cc1608390feff02242410620094
+:10986000c16082a088bf043cc1608390fdff0224d8
+:1098700024106200c16082a088bf043cc160839054
+:10988000fbff022424106200c16082a088bf033c59
+:109890008160629020004234816062a088bf043cf5
+:1098a000c0608390fbff022424106200c06082a08d
+:1098b00088bf033cc06062907f004230c06062a0fd
+:1098c00088bf043cc0608390f7ff0224241062002c
+:1098d000c06082a088bf033c816062904000423437
+:1098e000816062a088bf033cd0606290080042346f
+:1098f000d06062a088bf033cd16062900400423413
+:10990000d16062a088bf033c516062902000423465
+:10991000516062a080bf023c000c40ac80bf033ca1
+:1099200010000224080c62ac80bf023c100c40ac5a
+:1099300080bf033cf4010224200c62ac88bf033cce
+:109940001c000224d41062ac88bf033c1c0002241b
+:10995000d81062ac107f400f0000000088bf033cad
+:109960000100023c341062ac80bf033c0080023432
+:10997000080c62ac88bf033c0100023c641062ac7e
+:1099800088bf023c681040ac488280af6c8280afd8
+:10999000408180af388180af21e8c0031400bf8fc1
+:1099a0001000be8f1800bd270800e0030000000073
+:1099b000e0ffbd271c00bfaf1800beaf21f0a00321
+:1099c0002000c4af2400c5af2000c28f188182af31
+:1099d0002400c28f748282af2000c38f8888023c2b
+:1099e00089884234180062001010000021104300e2
+:1099f00043210200c3170300231082002000c2afde
+:109a00002000c28f090040100000000006df033470
+:109a10002000c28f1a006200f40140001210000002
+:109a20004c8182af0300001000000000d007022428
+:109a30004c8182af3881828f050040180000000001
+:109a40003881828fd08082af0300001000000000b8
+:109a5000b0040224d08082af4c81848fd079400f33
+:109a600000000000029d063c2120400021286000eb
+:109a70004c1ac78c481ac68cd977400f00000000da
+:109a80002120400021286000687a400f000000007b
+:109a9000cc8082af098282831a004014000000004b
+:109aa0004081828f05004018000000004081828fb5
+:109ab0004c8182af0300001000000000b6030224b6
+:109ac0004c8182af34818283150040140000000075
+:109ad0002880838f0100022403006214000000002c
+:109ae000b81e400f0000000088bf023c1061439088
+:109af00001006334106143a0288080af080000108b
+:109b0000000000002880828f030040140000000045
+:109b1000de1e400f0000000001000224288082affa
+:109b2000bc80828f12004010000000004081828fb4
+:109b300007004018000000004081828f4c8182aff6
+:109b40004081828fcc8082af0500001000000000b1
+:109b5000b60302244c8182afb6030224cc8082afcc
+:109b600088bf023c1061439001006334106143a040
+:109b700021e8c0031c00bf8f1800be8f2000bd2746
+:109b80000800e00300000000e8ffbd271400bfaf9d
+:109b90001000beaf21f0a0031800c4af2110a00038
+:109ba0001c00c2a31800c38f14000224030062101b
+:109bb000000000002100001000000000029d023c97
+:109bc000b481848f501a458cb57b400f0000000093
+:109bd000608282af029d023c9c81848f501a458c2a
+:109be000b57b400f00000000548282af029d023c12
+:109bf000a881848f501a458cb57b400f000000006f
+:109c0000888282af6082848f256a400f0000000046
+:109c1000308282af5482848f256a400f000000009a
+:109c2000808282af8882848f256a400f0000000006
+:109c3000588282af3100001000000000b481848f90
+:109c4000017a400f00000000029d063c21204000e8
+:109c5000212860005c1ac78c581ac68cd977400f2f
+:109c60000000000021204000212860002a7a400fd7
+:109c700000000000608282af9c81848f017a400fd7
+:109c800000000000029d063c2120400021286000c9
+:109c90005c1ac78c581ac68cd977400f0000000098
+:109ca00021204000212860002a7a400f0000000097
+:109cb000548282af029d023ca881848f601a458c39
+:109cc000b57b400f00000000888282af6082848fe5
+:109cd000256a400f00000000308282af5482848fda
+:109ce000256a400f00000000808282af8882848f46
+:109cf000256a400f00000000588282af21e8c003af
+:109d00001400bf8f1000be8f1800bd270800e003ad
+:109d100000000000d8ffbd272400bfaf2000beaf69
+:109d200021f0a0033882838f3482828f2310620057
+:109d3000088182af5082838f6882828f23106200f5
+:109d40000c8182af5c82838f3c82828f2310620001
+:109d5000108182af348280af688280af3c8280af56
+:109d60000881848fd079400f00000000029d063cde
+:109d700021204000212860006c1ac78c681ac68c0c
+:109d8000a378400f0000000021204000212860003f
+:109d90002a7a400f000000001000c2af0c81848faf
+:109da000d079400f00000000029d063c21204000b9
+:109db000212860006c1ac78c681ac68ca378400fe3
+:109dc0000000000021204000212860002a7a400f76
+:109dd000000000001400c2af1081848f6666023c50
+:109de000676642341800820010100000831a0200d7
+:109df000c31704002310620021204000ae7c400ff6
+:109e0000000000001800c2af029d023c1000c48f89
+:109e1000701a458c1a7b400f00000000c88182af89
+:109e2000029d023c1400c48f741a458c1a7b400fab
+:109e300000000000f48182af1800c48f21280000c8
+:109e40001a7b400f000000000c8282af21e8c003a3
+:109e50002400bf8f2000be8f2800bd270800e0032c
+:109e600000000000f8ffbd270000beaf21f0a003f6
+:109e70003482838f3882828f0700621000000000d6
+:109e80003882838f0881828f231862003482828f08
+:109e900021104300348282af6882838f5082828f88
+:109ea00007006210000000005082838f0c81828fb7
+:109eb000231862006882828f21104300688282af7b
+:109ec0003c82838f5c82828f07006210000000005a
+:109ed0005c82838f1081828f231862003c82828f84
+:109ee000211043003c8282af029d023c781a428cd2
+:109ef000c88182af029d023c7c1a428cf48182af01
+:109f0000211000000c8282af21e8c0030000be8f48
+:109f10000800bd270800e00300000000e0ffbd27a7
+:109f20001c00bfaf1800beaf21f0a0036882828f73
+:109f30001000a2af3c82828f1400a2af3082848fc7
+:109f40008082858f5882868f3482878fdd67400fad
+:109f500000000000c769400f0000000021e8c003b6
+:109f60001c00bf8f1800be8f2000bd270800e00333
+:109f70000000000098ffbd276400bfaf6000beafc7
+:109f800021f0a0036800c4af6c00c5af7000c6af7d
+:109f90007400c7af1000c0af010002241400c2afac
+:109fa000010002241800c2af010002241c00c2af4d
+:109fb0007400c38f6800c28f231062002000c2affc
+:109fc0007800c38f6c00c28f231062002400c2afe0
+:109fd0007c00c38f7000c28f231062002800c2afc4
+:109fe0002000c38f2000c28f211062002c00c2af5e
+:109ff0002400c38f2400c28f211062003000c2af42
+:10a000002800c38f2800c28f211062003400c2af25
+:10a010006800c28f3800c2af6c00c28f3c00c2af74
+:10a020007000c28f4000c2af4400c0af4800c0af54
+:10a030004c00c0af5000c0af5400c0af5800c0af1c
+:10a040005c00c0a37880828f0300401400000000f1
+:10a050002000c0af2c00c0af7c80828f0300401472
+:10a06000000000002400c0af3000c0af8080828fad
+:10a0700003004014000000002800c0af3400c0af4f
+:10a080002000c28f07004014000000007400c28f3f
+:10a090006800c2af3482828f308282afd480828fd8
+:10a0a000b48182af2400c28f07004014000000007a
+:10a0b0007800c28f6c00c2af6882828f808282afcc
+:10a0c000d880828f9c8182af2800c28f0700401405
+:10a0d000000000007c00c28f7000c2af3c82828f03
+:10a0e000588282afdc80828fa88182af2000c28f2d
+:10a0f000130041040000000088bf033cd060629060
+:10a100007f004230d06062a07f0003245c00c293d5
+:10a11000241043005c00c2a3ffff02241400c2af5e
+:10a120002000c28f231002002000c2af2c00c28f7b
+:10a13000231002002c00c2af0a0000100000000033
+:10a1400088bf043cd060839080ff02242510620009
+:10a15000d06082a05c00c39380ff022425106200bf
+:10a160005c00c2a32400c28f140041040000000060
+:10a1700088bf043cd1608390fdff0224241062005c
+:10a18000d16082a05c00c393dfff02242410620030
+:10a190005c00c2a3ffff02241800c2af2400c28fdc
+:10a1a000231002002400c2af3000c28f231002002f
+:10a1b0003000c2af080000100000000088bf033c60
+:10a1c000d160629002004234d16062a05c00c29310
+:10a1d000200042345c00c2a32800c28f1200410458
+:10a1e0000000000088bf033c5160629002004234ce
+:10a1f000516062a05c00c293080042345c00c2a3bc
+:10a20000ffff02241c00c2af2800c28f23100200ef
+:10a210002800c2af3400c28f231002003400c2af46
+:10a220000a0000100000000088bf043c51608390c9
+:10a23000fdff022424106200516082a05c00c393e1
+:10a24000f7ff0224241062005c00c2a32000c28f2a
+:10a25000000042380100432c2400c28f0000423825
+:10a260000100422c24106200060040100000000093
+:10a270002800c28f0300401000000000d080828fb1
+:10a280004c8182af2800c38f2000c28f2a10620049
+:10a29000010044382800c38f2400c28f2a106200b6
+:10a2a000010042382410820003004010000000002a
+:10a2b000010002241000c2af2000c38f2800c28f0b
+:10a2c0002a106200010044382000c38f2400c28f8e
+:10a2d0002a1062000100423824108200030040105e
+:10a2e00000000000020002241000c2af2400c38f4f
+:10a2f0002000c28f2a106200010044382400c38f5e
+:10a300002800c28f2a106200010042382410820007
+:10a310000300401000000000030002241000c2af40
+:10a320002000c28f000042380100432c2400c28f5d
+:10a33000000042380100422c241862002800c28f1d
+:10a34000000042380100422c24106200020040103c
+:10a35000000000001000c0af1000c38f01000224f5
+:10a360004a006214000000004000c38f1c00c28f2e
+:10a37000211062004000c2af4400c38f2c00c28f86
+:10a38000211062004400c2af4800c38f3000c28f6a
+:10a39000211062004800c2af4400c38f2800c28f62
+:10a3a0002a1043000e004010000000003800c38f48
+:10a3b0001400c28f211062003800c2af4400c38f66
+:10a3c0003400c28f231062004400c2af0100022497
+:10a3d0005000c2af5c00c293400042345c00c2a394
+:10a3e0004800c28f2800c38f2a1062000e00401060
+:10a3f000000000003c00c38f1800c28f21106200d3
+:10a400003c00c2af4800c38f3400c28f23106200eb
+:10a410004800c2af010002245400c2af5c00c293e6
+:10a42000100042345c00c2a35c00c29304004234ba
+:10a430005c00c2a35c00c3935000c28f202c027c3e
+:10a440005400c28f2014027c212060002130400083
+:10a450005c6a400f000000005000c0af5400c0af65
+:10a460005800c0af5c00c393abff0224241062000d
+:10a470005c00c2a34000c38f7c00c28f0300621047
+:10a4800000000000b8ff0010000000001000c38fa3
+:10a49000020002244a006214000000003800c38f4a
+:10a4a0001400c28f211062003800c2af4c00c38f6d
+:10a4b0003400c28f211062004c00c2af4800c38f2d
+:10a4c0003000c28f211062004800c2af4c00c38f21
+:10a4d0002000c28f2a1043000e0040100000000030
+:10a4e0004000c38f1c00c28f211062004000c2af29
+:10a4f0004c00c38f2c00c28f231062004c00c2afef
+:10a50000010002245800c2af5c00c2930400423430
+:10a510005c00c2a34800c28f2000c38f2a106200d3
+:10a520000e004010000000003c00c38f1800c28fd6
+:10a53000211062003c00c2af4800c38f2c00c28fc4
+:10a54000231062004800c2af010002245400c2afd1
+:10a550005c00c293100042345c00c2a35c00c29352
+:10a56000400042345c00c2a35c00c3935000c28f21
+:10a57000202c027c5400c28f2014027c2120600019
+:10a58000213040005c6a400f000000005000c0af66
+:10a590005400c0af5800c0af5c00c393abff0224af
+:10a5a000241062005c00c2a33800c38f7400c28f05
+:10a5b0000300621000000000b8ff0010000000005f
+:10a5c0001000c38f030002244e006214000000003c
+:10a5d0003c00c38f7800c28f4a0062100000000068
+:10a5e0003c00c38f1800c28f211062003c00c2af34
+:10a5f0004400c38f2c00c28f211062004400c2af00
+:10a600004c00c38f3400c28f211062004c00c2afd7
+:10a610004400c38f2400c28f2a1043000e00401054
+:10a62000000000003800c38f1400c28f21106200a8
+:10a630003800c2af4400c38f3000c28f23106200c5
+:10a640004400c2af010002245000c2af5c00c293bc
+:10a65000400042345c00c2a34c00c28f2400c38f70
+:10a660002a1062000e004010000000004000c38f5e
+:10a670001c00c28f211062004000c2af4c00c38f8b
+:10a680003000c28f231062004c00c2af01000224d0
+:10a690005800c2af5c00c293040042345c00c2a305
+:10a6a0005c00c293100042345c00c2a35c00c39300
+:10a6b0005000c28f202c027c5400c28f2014027cd8
+:10a6c00021206000213040005c6a400f0000000043
+:10a6d0005000c0af5400c0af5800c0af5c00c3937f
+:10a6e000abff0224241062005c00c2a33c00c38fb5
+:10a6f0007800c28f0300621000000000b8ff001055
+:10a700000000000021e8c0036400bf8f6000be8f1e
+:10a710006800bd270800e00300000000f8ffbd2727
+:10a720000000beaf21f0a0033082828f348282af5e
+:10a730008082828f688282af5882828f3c8282af11
+:10a74000e080828fec8082afe480828ff08082afe5
+:10a75000e880828ff48082afd480828fe08082afe5
+:10a76000d880828fe48082afdc80828fe88082afe5
+:10a77000b481828fd48082af9c81828fd88082af57
+:10a78000a881828fdc8082af211000007c8282afa2
+:10a7900021100000448282af21100000408282af6d
+:10a7a00021100000608282af21100000548282af2d
+:10a7b00021100000888282af308280af808280af1b
+:10a7c000588280af21e8c0030000be8f0800bd277b
+:10a7d0000800e00300000000d0ffbd272c00bfaf41
+:10a7e0002800beaf21f0a0033000c4af3000c48ffa
+:10a7f000017a400f00000000212040002128600065
+:10a800001000c6274876400f000000001800c2afb5
+:10a810001c00c3af1000c48f1400c58f687a400fae
+:10a82000000000002000c2af029d023c801a448c50
+:10a83000841a458c1800c68f1c00c78fab7a400f56
+:10a840000000000003004018000000000800001095
+:10a85000000000002000c28f010042242000c2af8f
+:10a860002000c28f2400c2af0300001000000000cf
+:10a870002000c28f2400c2af2400c28f21e8c00391
+:10a880002c00bf8f2800be8f3000bd270800e003da
+:10a8900000000000d0ffbd272c00bfaf2800beafd6
+:10a8a00021f0a0033000c4af3000c48f017a400f04
+:10a8b0000000000021204000212860001000c62771
+:10a8c0004876400f000000001800c2af1c00c3af64
+:10a8d0001000c48f1400c58f687a400f000000007c
+:10a8e0002000c2af029d023c881a448c8c1a458c11
+:10a8f0001800c68f1c00c78fab7a400f0000000005
+:10a9000003004018000000000400001000000000d8
+:10a910002000c28f010042242000c2af029d023cf1
+:10a920001800c48f1c00c58f901a468c941a478c4f
+:10a93000ab7a400f00000000030040180000000048
+:10a9400004000010000000002000c28fffff42241e
+:10a950002000c2af2000c28f21e8c0032c00bf8faf
+:10a960002800be8f3000bd270800e0030000000073
+:10a97000e0ffbd271800beaf21f0a003211080002a
+:10a980002118a0002120c0002000c2a32400c3a3de
+:10a990002800c4a30000c0af2000c2930000c2afd3
+:10a9a0000000c28f001602000000c2af2400c28364
+:10a9b00008004010000000002800c283050040107d
+:10a9c00000000000cc80828f0400c2af03000010a2
+:10a9d000000000004c81828f0400c2af0000c28fd3
+:10a9e0000400c38f251043000000c2af6c82828f29
+:10a9f000010042240800c2af0800c28f0c00c2afa1
+:10aa00000c00c38f04006104000000000c00c48f20
+:10aa1000ff0184240c00c4af0c00c38f4312030059
+:10aa2000401202000800c48f231882004882828fdf
+:10aa30000300621400000000ecff001000000000a2
+:10aa400000a0043c6c82828f80180200800a82245d
+:10aa5000211862000000c28f000062ac6c82828ffd
+:10aa6000010042246c8282af6c82828f1000c2afe0
+:10aa70001000c38f1400c3af1400c48f04008104fe
+:10aa8000000000001400c28fff0142241400c2af76
+:10aa90001400c38f43120300401202001000c48f41
+:10aaa000231082006c8282af21e8c0031800be8fa1
+:10aab0002000bd270800e0030000000021108000f6
+:10aac0005600c0100c00ca2c4d0040152618a400da
+:10aad0000300633023380400290060100300e730ce
+:10aae0000600e0102330c7000000a3980300a388ed
+:10aaf0002128a700000083b8212087000f00c33061
+:10ab00002338c3001100e010213060002138e50037
+:10ab10000000a3980300a3880400a8980700a88851
+:10ab20000800a9980b00a9880c00aa980f00aa8811
+:10ab3000000083ac040088ac080089ac1000a52498
+:10ab400010008424f2ffa714fcff8aac0300c3307a
+:10ab50002338c3002a00e010213060002138e500ce
+:10ab60000000a3980300a3880400a5240400842403
+:10ab7000fbffa714fcff83ac2100001000000000c5
+:10ab80000500e0102330c7000000a3982128a7008b
+:10ab9000000083b8212087000f00c3302338c30092
+:10aba0000d00e010213060002138e5000000a38c8a
+:10abb0000400a88c0800a98c0c00aa8c000083acaf
+:10abc000040088ac080089ac1000a524100084247f
+:10abd000f6ffa714fcff8aac0300c3302338c30080
+:10abe0000700e010213060002138e5000000a38c50
+:10abf0000400a52404008424fcffa714fcff83acfc
+:10ac00000600c0102138c5000000a3900100a52453
+:10ac100001008424fcffa714ffff83a00800e003c9
+:10ac200000000000211080002600c0101000ca2c77
+:10ac30001f004015ff00a530005205002528aa007e
+:10ac4000005405002528aa00030083300500601089
+:10ac5000040007242338e3002330c700000085b830
+:10ac6000212087000f00c3302338c3000800e01004
+:10ac7000213060002138e400000085ac040085ac80
+:10ac8000080085ac10008424fbff8714fcff85ac12
+:10ac90000300c3302338c3000500e01021306000fa
+:10aca0002138e40004008424feff8714fcff85acf7
+:10acb0000400c0102138c40001008424feff871462
+:10acc000ffff85a00800e00300000000254085008c
+:10acd000030008310300001121108000380000102b
+:10ace0000000aa900000aa8c0101093c010129354d
+:10acf000c07909002340490124400f0107000011d9
+:10ad000024600a0105008811000000000000a5244d
+:10ad10000000aa902a000010000084240400ab8cdc
+:10ad200000008aac2340690124400f010700001194
+:10ad300024600b0105008811000000000400a52418
+:10ad40000000aa901e000010040084240800aa8cb1
+:10ad500004008bac2340490124400f01070000117f
+:10ad600024600a0105008811000000000800a524e5
+:10ad70000000aa9012000010080084240c00ab8c84
+:10ad800008008aac2340690124400f01070000112c
+:10ad900024600b0105008811000000000c00a524b0
+:10ada0000000aa90060000100c0084241000aa8c59
+:10adb0000c008bac10008424ceff00101000a524e2
+:10adc0000300401500008aa00800e0030000000016
+:10add0000100ab900300601501008ba00800e003a8
+:10ade000000000000200aa900300401502008aa0a3
+:10adf0000800e003000000000300ab9003006015b2
+:10ae000003008ba00800e003000000000400aa90eb
+:10ae10000300401504008aa00800e00300000000c1
+:10ae20000500ab900300601505008ba00800e0034f
+:10ae3000000000000600aa900300401506008aa04a
+:10ae40000800e003000000000700ab90030060155d
+:10ae500007008ba00800e003000000000800aa9093
+:10ae600008008424d6ff00100800a52400008a9062
+:10ae70002110800003004015000000000800e003de
+:10ae80000000022401008a90030040150000000029
+:10ae90000800e0030100022402008a90030040152c
+:10aea000000000000800e0030200022403008a9072
+:10aeb00003004015822004000800e0030300022480
+:10aec000010084248020040000008a8c0101093cd8
+:10aed00001012935c07909002340490124400f01af
+:10aee0000600001124600a0104008811000000001f
+:10aef00000008a90220000100000842404008b8c43
+:10af00002340690124400f010600001124600b0159
+:10af1000040088110000000004008a90180000104e
+:10af20000400842408008a8c2340490124400f0136
+:10af30000600001124600a010400881100000000ce
+:10af400008008a900e000010080084240c008b8cee
+:10af50002340690124400f010600001124600b0109
+:10af600004008811000000000c008a90040000100a
+:10af70000c00842410008a8cd7ff00101000842459
+:10af80000400401500000000000084240800e003d5
+:10af90002310820001008a90040040150000000088
+:10afa000010084240800e0032310820002008a903c
+:10afb0000400401500000000020084240800e003a3
+:10afc0002310820003008a90030084240800e00319
+:10afd00023108200b0ffbd270000a1af0400a2af84
+:10afe0000800a3af0c00a4af1000a5af1400a6afdb
+:10aff0001800a7af1c00a8af2000a9af2400aaaf7b
+:10b000002800abaf2c00acaf3000adaf3400aeaf1a
+:10b010003800afaf3c00b8af4000b9af4400bfaf9d
+:10b02000124000004800a8af104000005000a8af38
+:10b0300000680440006005408a6e400f0000000078
+:10b040005000a88f110000014800a88f13000001d4
+:10b050000000a18f0400a28f0800a38f0c00a48f12
+:10b060001000a58f1400a68f1800a78f1c00a88fb2
+:10b070002000a98f2400aa8f2800ab8f2c00ac8f52
+:10b080003000ad8f3400ae8f3800af8f3c00b88fea
+:10b090004000b98f4400bf8f5000bd27c0000000a2
+:10b0a000180000422518a40003006230200040145c
+:10b0b000214080000400c92c1c0020152138a0006c
+:10b0c0000000af8cfefe183cfffe053727700f0016
+:10b0d0002168e50180800c3c2458ae0180808335d6
+:10b0e00024506301120040552128e0002148a000af
+:10b0f000212860000000e28cfcffc6240400d92c4b
+:10b10000000082ac0400e724080020170400842417
+:10b110000000ed8c27600d002158a90124506c011e
+:10b1200024184501f4ff60500000e28c2128e00063
+:10b130000e00c010ffffc2240000a790ffffc6242e
+:10b14000000087a00100a524f9ffe0140100842479
+:10b150000600c010ffffc224ffff0324ffff4224ac
+:10b16000000080a0fdff4314010084240800e003d8
+:10b17000211000010300823018004014ff00a530a8
+:10b18000003a05002540a7000034080025380601d4
+:10b190008080033c21308000fefe043cfffe8934a9
+:10b1a000808068340000cf8c2610e7012168e90117
+:10b1b00027700f0027c8020021c049002458ae01a3
+:10b1c00024601903245068010300401524188801e5
+:10b1d000f4ff60500400c6242120c00000008390ca
+:10b1e000ff00693003002515211080000800e003ee
+:10b1f00000000000f9ff6014010084240800e0034f
+:10b2000021100000e0ffbd2700a0053c1000b0affa
+:10b210000000b0241800b2af1400b1af219080003c
+:10b2200000a0113c1c00bfaf596e400f212000024e
+:10b230001c01238e01000424380064ac5d6e400fb5
+:10b24000212000021c01228e1000508c0d000012e3
+:10b250001c012a8e0400028e08004018ffff4724bc
+:10b2600080480700214030010800068d09f8c00021
+:10b27000040007aef8ff00100400028ef3ff001078
+:10b280000000108e3400428d0300401000000000ca
+:10b2900009f8400000000000ad6e400f2120400280
+:10b2a000029d073cad1ae62421108600000045905f
+:10b2b000200082240100a3300800e0030a1083006c
+:10b2c000029d073cad1ae62421108600000045903f
+:10b2d000e0ff82240200a3300800e0030a1083008c
+:10b2e000029d053cad1aa32421208300000082901a
+:10b2f0000800e00307004230029d053cad1aa3247c
+:10b3000021208300000082900800e0030300423007
+:10b310000800e0038000822c029d053cad1aa324a6
+:10b3200021208300000082900800e00320004230ca
+:10b33000029d053cad1aa3242120830000008290c9
+:10b340000800e00304004230029d053cad1aa3242e
+:10b3500021208300000082900800e00317004230a3
+:10b36000029d053cad1aa324212083000000829099
+:10b370000800e00302004230029d053cad1aa32400
+:10b3800021208300000082800800e0039700423003
+:10b39000029d053cad1aa324212083000000829069
+:10b3a0000800e00310004230029d053cad1aa324c2
+:10b3b00021208300000082800800e00388004230e2
+:10b3c000029d053cad1aa324212083000000829039
+:10b3d0000800e00301004230029d053cad1aa324a1
+:10b3e00021208300000082900800e00344004230e6
+:10b3f0000800e0037f0082300800e0032000822480
+:10b400000800e003e0ff8224e8ffbd271000bfaf83
+:10b410008c6d400f212800001000bf8f0800e00352
+:10b420001800bd27e8ffbd27212800001000bfaf8e
+:10b43000116d400f0a0006241000bf8f0800e003c2
+:10b440001800bd27000083802138800021500000b3
+:10b4500021700000215800000e00601021680000db
+:10b46000029d093cad1a2825211068000000428089
+:10b4700088004330080060500000e3800100e724aa
+:10b480000000ec800300801121188801f8ff0010f3
+:10b49000000062800000e3802b0008240300681095
+:10b4a0002d000f2404006f14000000002d007838d8
+:10b4b00001000e2f0100e7241100c0141000032426
+:10b4c0000000e280300019241c0059140a000624f0
+:10b4d0000100e7240000e380780009240800062426
+:10b4e0000400691001000d2458000c2414006c1491
+:10b4f000ff7f023c0100e72410000010100006242a
+:10b500000f00c314ff7f023c0000ef8030000824ce
+:10b510000c00e815ffff43340100e7240000e3803e
+:10b52000780018240400781001000d245800192414
+:10b5300004007914ffff43340100e724ff7f023c3d
+:10b54000ffff43341a006600f401c0002148e00008
+:10b550000000e7802400e01012600000029d083c1b
+:10b56000ad1a1825217860002110f80000004390e2
+:10b570000400793007002017d0ffe824030068306a
+:10b580001900001101006330a9fff924c9ffe82464
+:10b590000a4023032a18060101007938c21708005f
+:10b5a000253859001100e05401006f2d2a388a0116
+:10b5b0000800e01401000d24080060550100292551
+:10b5c0000250467123c8ea012a10280302004050a5
+:10b5d0002150480101000b2401002925000027818a
+:10b5e000e2ffe0542110f80001006f2d2460cf012c
+:10b5f00023300a000b50cc000800601121104001dc
+:10b6000022000b2400a00a3c04024bad0300c0152d
+:10b610000080023cff7f0e3cffffc2350200a010fd
+:10b620000a488d000000a9ac0800e00300000000fb
+:10b63000e8ffbd271000bfaf537d400f00000000a2
+:10b640001000bf8f0800e0031800bd27e8ffbd27ea
+:10b650001000bfaf0400828c21188000ffff062479
+:10b66000010004242128400003004610000060acc3
+:10b6700004000010040066ac986e400f000000004b
+:10b68000212840001000bf8f2110a0000800e00317
+:10b690001800bd27e8ffbd271000b0af1400bfaff2
+:10b6a00010008394020062300e0040102180800060
+:10b6b0000000838c0e0060041400bf8f0c00848c8b
+:10b6c00003006410232883009a6e400f0800048e44
+:10b6d0000800058e0c00068e040005ae0300001065
+:10b6e000000006aeffff0724040087ac1400bf8fe4
+:10b6f0001000b08f211000000800e0031800bd27e3
+:10b70000d8ffbd271c00b1af1800b0af2000bfaffd
+:10b710000c00a28c2180a00021888000010005245b
+:10b7200006004014212000021000a4279a6e400f4a
+:10b730001000b1a323000010000000ae0000068e30
+:10b74000ffff03240100c5240d00a314000005ae73
+:10b750000800078e00a0083c040405250800e0143a
+:10b760008000062410000a96040005ae100049353a
+:10b77000000006ae080005ae0c0006ae100009a6db
+:10b78000a56d400f0000000000000e8e04000c8e1e
+:10b79000ffffcd2501008b250a00042400000dae1b
+:10b7a000000091a10700241604000bae10001896ab
+:10b7b00008000f330300e01121200002a56d400fa7
+:10b7c00000000000211020022000bf8f1c00b18f5c
+:10b7d0001800b08f0800e0032800bd27e0ffbd2758
+:10b7e0001000b0af0280c5701800b2af1400b1af46
+:10b7f0001c00bfaf2188c000219080001100001202
+:10b80000212800001000e6942120e0000100c23051
+:10b81000060040104000c3341000e3a400a0043c24
+:10b820000900032407000010040283aca56d400f3b
+:10b8300000000000212800029a6e400f21204002e3
+:10b84000212820021c00bf8f1800b28f1400b18f76
+:10b850001000b08f2110a0000800e0032000bd27d9
+:10b8600010008794ffffe330241065004000e634a9
+:10b870000600401001000324100086a409000524de
+:10b8800000a0043c040285ac211800000800e0037d
+:10b8900021106000c8ffbd27ffffa9242128c00098
+:10b8a0002130e000029d073c21408000ffff0b2477
+:10b8b0001000a42782000a240c1de2243000bfaf30
+:10b8c0002200aba72000aaa71c00a9af1400a8afb4
+:10b8d0002800a2af1000a9af6d6f400f1800a8afed
+:10b8e0001400a38f3000bf8f3800bd270800e0038d
+:10b8f000000060a02110a000ff7f053ce8ffbd27ed
+:10b900002138c000ffffa5341000bfaf256e400fe7
+:10b91000213040001000bf8f0800e0031800bd2751
+:10b92000e8ffbd272110a000ff7f053c2000a6af47
+:10b930002400a7afffffa5342000a7271000bfaf4a
+:10b94000256e400f213040001000bf8f0800e0033b
+:10b950001800bd270800e003211000000800e003e4
+:10b96000211000000800e003211000000800e0039f
+:10b97000211000000800e003211000000800e0038f
+:10b98000211000000800e003211000000800e0037f
+:10b99000211000000800e003211000000800e0036f
+:10b9a000211000000800e003ffff02240800e0036c
+:10b9b000000000000800e003000000000800e003b1
+:10b9c000000000000800e003000000000800e003a1
+:10b9d000000000000800e003000000000000828c6e
+:10b9e000e8ffbd27040040141000bfaf020003248d
+:10b9f00009f8a000000083ac1000bf8f21100000e8
+:10ba00000800e0031800bd270800e003ffff022440
+:10ba10000800e003ffff02240800e00321100000fb
+:10ba20000800e0032110a000ffff0010000000004c
+:10ba3000ffff0010000000000800e003000000000d
+:10ba40000800e0030000000000601a40bfff1b3c3c
+:10ba5000ffff7b3724d05b0300609a401800004250
+:10ba60000800e003ffff0224e0ffbd271400b1af90
+:10ba70001000b0af1800bfaf218880000800801010
+:10ba80002180a000070000121800bf8f0000248250
+:10ba90001375400fffff1026faff0010010031263a
+:10baa0001800bf8f1400b18f1000b08f0800e003a2
+:10bab0002000bd27ffff001000000000e0ffbd27b1
+:10bac0001800b2af1400b1af1000b0af1c00bfaf90
+:10bad000218880002190c0000c00a010ffffb0243e
+:10bae00000002482d874400f21284002ffff032465
+:10baf000ffff10260300431401003126040000104c
+:10bb0000ffff0224f7ff03560000248221100000eb
+:10bb10001c00bf8f1800b28f1400b18f1000b08fbf
+:10bb20000800e0032000bd27e0ffbd271800b2afea
+:10bb30001400b1af1000b0af1c00bfaf2180a00057
+:10bb4000219080002188c0000d0000122100022eeb
+:10bb5000200007240b3802022128e00021202002c7
+:10bb600021304002af6e400f23800702ffff032405
+:10bb7000f5ff4314ffff0224030000101c00bf8fd9
+:10bb8000211000001c00bf8f1800b28f1400b18f6d
+:10bb90001000b08f0800e0032000bd27d0ffbd27b4
+:10bba0001400b1af2188e0004000a78f1800b2afa9
+:10bbb0001000b0af0100f2302180c0000100432e20
+:10bbc0001c00b3af2a981102029d063c241073009a
+:10bbd0002800b6af2400b5af2000b4af2c00bfaf33
+:10bbe00021a0a000d01bc624ffff1624232830026a
+:10bbf00021a880000400401021180000ca6e400fe8
+:10bc000000000000211840002120800221280002ad
+:10bc10000e0076102130a002af6e400f0000000031
+:10bc20000b0056102a2030020a0040520a802402db
+:10bc3000029d053cd01ba6242120a0020300601217
+:10bc400023283002ca6e400f000000002a20300274
+:10bc50000a802402211000022c00bf8f2800b68f1a
+:10bc60002400b58f2000b48f1c00b38f1800b28f52
+:10bc70001400b18f1000b08f0800e0033000bd2722
+:10bc8000c8ffbd272c00b5af1c00b1af21a8c00074
+:10bc90002188e00021300000213800002800b4afe6
+:10bca0002400b3af2000b2af1800b0af3000bfaf78
+:10bcb000219080002198a0004800b48fab7a400ffb
+:10bcc0004c00b08311004010029d023cc81c468c01
+:10bcd000cc1c478c21204002d977400f21286002dc
+:10bce00021204000212860004876400f1000a62740
+:10bcf0000b000010029d063c000025a20000a48e4f
+:10bd000001008324210000100000a3aed079400f71
+:10bd1000d0ff04261000a2af1400a3af029d063c82
+:10bd2000d01cc48cd41cc58c1400a78fab7a400fd8
+:10bd30001000a68f16004104211020022e000624b8
+:10bd40003000052400008d822660a60101008b2da5
+:10bd500023208b0200008a90ffff942401004825d5
+:10bd6000204c087c3a0027290800e014000088a035
+:10bd7000f4ff9114000085a0dfffa05631000524d8
+:10bd800031000e24ffff2ea2ffff312621102002da
+:10bd90003000bf8f2c00b58f2800b48f2400b38fe4
+:10bda0002000b28f1c00b18f1800b08f0800e00394
+:10bdb0003800bd2718fbbd27e404bfafe004beafc9
+:10bdc000dc04b7afd804b6afd404b5afd004b4af79
+:10bdd000cc04b3afc804b2afc404b1afc004b0afb9
+:10bde0001800838cec04a5af1000628ce804a4afab
+:10bdf0000100052409f84000f004a6af9404a0afa8
+:10be000034054010ffff0324ec04a68f0000c4801b
+:10be10000100c52429058010ec04a5af25000724e6
+:10be200006008710ec04a88fd874400fe804a58f93
+:10be30009404a48f1f0500100100832400001281c8
+:10be40000b004416ffff0624e804a58fd874400faa
+:10be500025000424ec04ac8f9404aa8f01008b25e8
+:10be600001004925ec04abafe7ff00109404a9af33
+:10be70009c04a0af2d0007242b00052420000424df
+:10be80002300032430000224030047169c04ad8fd6
+:10be9000100000100100a835030045169c04ae8f69
+:10bea0000c0000100200c835030044169c04af8f3c
+:10beb000080000100400e835030043169c04b08f0e
+:10bec0000400001008000836080042169c04b18fd8
+:10bed00010002836ec04b28f9c04a8af0100532652
+:10bee000ec04b3afe8ff0010000072822a001424b3
+:10bef0000e005416d0ff4526f004a28ffcff1f242d
+:10bf000003005e2424b0df03ec04b98f0000d88e58
+:10bf100001003727ec04b7af9804b8af0000f282f5
+:10bf20000400d52611000010f004b5af0a00a32cc0
+:10bf3000160060109804a0af0a0003249804ac8f88
+:10bf4000ec04ad8f025883710100aa25ec04aaaf5e
+:10bf50002148720100005281d0ff2825d0ff4426dd
+:10bf60000a00872cf5ffe0149804a8af9804a88f66
+:10bf7000070001052e0011249c04b08f23700800d7
+:10bf800001000f369c04afaf9804aeaf2e00112411
+:10bf90002600511668000c24ec04b28f2a000624f7
+:10bfa00001005326ec04b3af000072820d00461668
+:10bfb000d0ff4226f004be8fec04b78f0300d827d1
+:10bfc0000100f626fcff192424a81903ec04b6afdf
+:10bfd0000000d2820000a68e0400b4260f000010dc
+:10bfe000f004b4af0a005f2c0f00e0132130000012
+:10bff0000a000324ec04aa8f0220c3700100482524
+:10c00000ec04a8af2148920000001281d0ff47261f
+:10c010000a00e52cf7ffa014d0ff26250000c32856
+:10c02000ffff0b240b30630168000c2412004c1638
+:10c030006c001524ec04a58f0100ad800700b2153b
+:10c040009c04b38f9c04b08f0100ae2480000f3697
+:10c050009c04afaf03000010ec04aeaf00017136da
+:10c060009c04b1afec04b28f01005426ec04b4afd1
+:10c07000270000100000928212005516710007245c
+:10c08000ec04a48f010096800700d2169c04bf8f99
+:10c090009c04b98f01009724000838379c04b8af7e
+:10c0a00003000010ec04b7af0002fe379c04beafe3
+:10c0b000ec04a58f0100a224ec04a2af1400001030
+:10c0c00000005280090047164c000b24ec04aa8f94
+:10c0d0009c04a88f01004425ec04a4af00009280ca
+:10c0e000000809350a0000109c04a9af09004b168e
+:10c0f000ec04b18fec04ae8f9c04ac8f0100cd2515
+:10c10000ec04adaf000483350000b2819c04a3af02
+:10c11000ec04b18f9c04a38f0100302602006f3025
+:10c120000400e011ec04b0affbff14242498740069
+:10c130009c04b3af9c04a58f0100b5300400a0128d
+:10c14000bcff4326efff172424b0b7009c04b6af12
+:10c150003500782c5504001321100000029d053c89
+:10c1600080f80300f01ba22421f0e2030000d98f25
+:10c1700008002003000000009c04a78f0002f23496
+:10c180009c04b2af9c04aa8ff7ff0424001048352a
+:10c19000244804010d0000109c04a9af9c04a38f47
+:10c1a00000026b349c04abaf15000010080014248f
+:10c1b0009c04ad8f0002ac359c04acaf9c04af8fe7
+:10c1c000f7ff10242470f0019c04aeaf0c000010a7
+:10c1d0000a0014249c04b38f00407136070000103d
+:10c1e0009c04b1af9c04b58f0040b4369c04b4af3e
+:10c1f0009c04b78f0802f6369c04b6af10001424d6
+:10c20000ffff18240300d8149c04be8f0400001004
+:10c2100001000624efff1f2424c8df039c04b9afec
+:10c220009c04a58f0010b6300b00c0120008a2308d
+:10c230000c004014f004ab8ff004a98ffcff022423
+:10c24000030027252410e2000000528c2120400228
+:10c2500010000010c32f120009004010f004ad8f31
+:10c26000f004ab8ff8ff0a240700642524408a00fd
+:10c270000000048d0400058d070000100800022551
+:10c28000fcff0c240300a32524106c000000448c48
+:10c290002128000004004224f004a2af2180800085
+:10c2a0002188a0002198c0005f00b2270800c012ba
+:10c2b00021b800000700a10421180000238010000d
+:10c2c000238811002b10100023882202010017245c
+:10c2d000211800001b001016212800021a007114fa
+:10c2e00025101102330000129c04ae8f0040c631ad
+:10c2f0001b00b400f4018002102000000a008f2807
+:10c300000300e05137009124040000103000842421
+:10c3100057009024212020020a2006021b00b400ae
+:10c32000f4018002000044a2ffff7326ffff5226a3
+:10c3300012a80000eeffa016122800001e00001038
+:10c34000ffff6226251011021a004010c3af14002f
+:10c3500021282002213080022138a0024580400f90
+:10c36000212000020a00582806000017300045244a
+:10c370009c04bf8f570059240040fe3337004524ea
+:10c380000a283e03000045a22120000221282002a5
+:10c3900021308002267f400f2138a00221804000fa
+:10c3a0002188600025104300ffff5226e6ff0010a1
+:10c3b000ffff7326ffff6226070040049c04a88f3e
+:10c3c00030000324ffff4224000043a2fdff41048c
+:10c3d000ffff52269c04a88f100013312500601225
+:10c3e0009c04ae8f2000a5279804a98f233845020e
+:10c3f00021282701080002310c004010c1ffa424ad
+:10c400000800082407008816feff8c2401004b82d8
+:10c4100030000a2404006a511000833a030000101f
+:10c42000c0ffa4241000833a0a2083010900c052ef
+:10c43000ffff83240600e056ffff84249c04a68fa0
+:10c440000600cd300300a011ffff8324ffff8424ea
+:10c45000ffff8324070062049c04ae8f3000022497
+:10c46000ffff6324000042a2fdff6104ffff52268c
+:10c470009c04ae8f0800c4311600801008000f2401
+:10c4800008008f5610001124010050823000032450
+:10c490000400035210001124000043a20d000010fc
+:10c4a000ffff52260b009116212840029c04b28ff8
+:10c4b000ffffa324004054320200801658000424d9
+:10c4c00078000424300015240000a4a0ffff72248b
+:10c4d000000075a01000c012010045260b00e016f8
+:10c4e0002d0002249c04b78f0200f6320300c01214
+:10c4f0009c04b98f050000102b000224040038337f
+:10c50000050000530100452620000224000042a23d
+:10c51000ffff52260100452623f0a5031f0300104c
+:10c520006000c627f004ac8ff8ff0a2407008b25b3
+:10c5300024406a010000098d0400078d6000a9af46
+:10c540006400a7af6000b08f6400b18f08000525bc
+:10c550000055337eff077f3af004a5af2300e017b4
+:10c56000a004a6af212000022128200221300002d1
+:10c57000ab7a400f213820020700405021200002f2
+:10c58000029d033c9804a78fe804a48ff01c652447
+:10c59000040300100300062421282002213000009b
+:10c5a000ab7a400f2138000009004304029d043c8f
+:10c5b000029d063c9c04ad8f9804a78fe804a48fcd
+:10c5c000fc1cc52404000624f80200101000adafc6
+:10c5d000f41c85249c04ae8f9804a78fe804a48fd4
+:10c5e00004000624f10200101000aeafffff0f247c
+:10c5f0000400cf14a404a0af0600142413000010fc
+:10c60000a004b4af2800d5281100a01621400002d4
+:10c6100067005e3a4700593a2bb81e002bc019003c
+:10c6200024b0f8020600c016d9ffc2249c04b38fc0
+:10c6300008007f320400e01327000724d9ffc2243a
+:10c64000a404a2af27000724a004a7af2140000242
+:10c65000214820026900a0a39004a0afa004be8fcf
+:10c66000a804b2af0a002106b404a0af2150000113
+:10c67000029d083cdc1c058d2d000924268825021e
+:10c680007002a9a3214040010200001021482002ad
+:10c690007002a0a38004a627212000014876400f45
+:10c6a000212820016900ad276902ac2721a860007c
+:10c6b000ffff8b250100a32521a04000b804a3aff4
+:10c6c000ac04a3af2198600024000010b004abaf0d
+:10c6d000c81c108fcc1c118f2120c0022128e00221
+:10c6e00021382002a378400f213000022120400091
+:10c6f000212860008004a6274876400f029d173c41
+:10c70000e01ce68ee41ce78e21204000212860001a
+:10c710008804a2afd076400f8c04a3af2120400044
+:10c720002130000221286000d977400f21382002f3
+:10c7300021204000687a400f21286000b004af8fac
+:10c74000300056240000f6a19004ae8fffffe425d0
+:10c750000100c625b004a4af9004a6af8004b68f34
+:10c760008404b78f21300000213800002120c0024e
+:10c77000ab7a400f2128e002d5ff4014029d183cff
+:10c78000650019246c00591266005f2a0600e01348
+:10c790006600072445000224670042124700022475
+:10c7a000030000100000000005004712670002248b
+:10c7b000580142126900a68300020010b804b08f2d
+:10c7c0009004b28f10004012b804a38fb004a58f5c
+:10c7d0006902a9270100a4242b5089000e004011f2
+:10c7e000a004ad8f00008b906902ac270100842467
+:10c7f0002b408c0000006ba2faff0015010073268d
+:10c8000005000010a004ad8f30001324000073a0b9
+:10c8100001007324a004ad8f0600a0152e0004248f
+:10c820009c04ae8f0800c6310500c0102120800294
+:10c830002e000424000064a201007326212080023f
+:10c840002128a00221300000ab7a400f21380000df
+:10c850002f004010a004af8f1d00e01121208002a6
+:10c86000029d113cc81c268ecc1c278e21208002e4
+:10c87000d977400f2128a002212040002128600004
+:10c880004876400f8804a6278804a48f8c04a58fbf
+:10c8900021a04000687a400f21a860003000562493
+:10c8a000ffffde27000076a20800c01301007326f8
+:10c8b000212080022128a00221300000ab7a400f05
+:10c8c00021380000e7ff4014029d113c2120800226
+:10c8d0002128a00221300000ab7a400f213800004f
+:10c8e0000b004010b804a78fffff7726213000000f
+:10c8f0007002b027212080022128a0021000b7afcb
+:10c900001800b0af206f400f1400a0afac04a2af6e
+:10c91000a801c013ffffc22730000424ffff032437
+:10c92000ffff4224000064a2fdff431401007326b0
+:10c93000a10100106900a6839004b88f390000138c
+:10c9400021208002b004a28fb804b98f01005f904b
+:10c950000100432400003fa30500c0170100302759
+:10c960009c04b28f080047321800e01001006d24cb
+:10c97000b804aa8f2e000924010049a11200c01397
+:10c9800002005025b004a88f6902a52702000325e4
+:10c990002b1065000a0040100000000000006b90a2
+:10c9a000ffffde2700000ba20700c01301001026c6
+:10c9b000010063246902ac27f6ff00102b106c0005
+:10c9c0001500c0179004a48f01006d246902a627ea
+:10c9d0002b98a601100060129004a48fffff0e2672
+:10c9e0001000aeaf010075807002b4271400b5af1f
+:10c9f0001800b4afb804a78f21a0000021a8000040
+:10ca00009004a62721208002206f400f2128a00239
+:10ca1000ac04a2af9004a48fffff83243d0000105c
+:10ca20009004a3af2128a00221300000ab7a400f70
+:10ca3000213800002b004010b804a78fffff02240c
+:10ca40009004a2af029d0f3cc81ce68dcc1ce78d64
+:10ca500021208002d977400f2128a0022120400008
+:10ca6000212860004876400f8804a6278804b08fec
+:10ca70008c04b18f213000002138000021200002f9
+:10ca80002128200221a04000ab7a400f21a860009d
+:10ca9000030040149004b68fe9ff0010ffffc22688
+:10caa00021200002687a400f21282002b804b18fab
+:10cab00030005024000030a20500c01701003026cd
+:10cac0009c04b88f080017331300e0122120800265
+:10cad000b804b98f2e001f24020030270d0000106b
+:10cae00001003fa3300002240000e2a00500c017af
+:10caf0000100f0249c04aa8f080052310600401265
+:10cb000021208002b804a98f2e000524010025a150
+:10cb100002003025212080022128a00221300000bf
+:10cb2000ab7a400f213800002f00401000000000b9
+:10cb30001d00c01321208002029d0b3cc81c668d85
+:10cb4000cc1c678d21208002d977400f2128a002bc
+:10cb500021204000212860004876400f8804a62745
+:10cb60008804a48f8c04a58f21a04000687a400f10
+:10cb700021a8600030004824ffffde27000008a243
+:10cb80000800c01301001026212080022128a002e5
+:10cb900021300000ab7a400f21380000e7ff40143d
+:10cba000029d0b3c212080022128a00221300000a0
+:10cbb000ab7a400f213800000b004010ac04a78f67
+:10cbc0007002ac27ffff13269004a62721208002c5
+:10cbd0002128a0021000b3af1800acaf206f400fa7
+:10cbe0001400a0afac04a2af0700c013ffffc22720
+:10cbf00030000424ffff0324ffff4224000004a2ae
+:10cc0000fdff431401001026b404be8f1400c0536e
+:10cc10009004a48f9c04a68f0800cd301000a0556e
+:10cc20009004a48f30000324ac04b58f2ba0b00275
+:10cc30000600805200001682ffff102600000e82c0
+:10cc4000fbffc3112ba0b002000016822e00cf3aca
+:10cc50000100e42d23180402010070249004a48f25
+:10cc6000a804b18f02000526000011a2060081046d
+:10cc70007804a8272d001724232004002130a000c9
+:10cc800004000010010017a22b001824010018a2b4
+:10cc90002130a0000a00902817000016213800015a
+:10cca0000a0005241a008500f401a000ffffe72414
+:10ccb000101000001220000030005f240a009928a4
+:10ccc000f8ff20130000ffa0ffffe52430008a24b6
+:10ccd0002b18a800ffffeaa0b60060102198c00042
+:10cce0000000a7900100a5240000c7a02b18a800f1
+:10ccf000f9ff00100100c624300089243000082408
+:10cd00000000a8a00100a9a00200a624a90000100c
+:10cd10002198c000a004ab8f010010249004a38fc1
+:10cd20000b80cb032a2803021300a014feff4d261c
+:10cd300016006014b004ae8f212080022128a002ca
+:10cd400021300000ab7a400f213800001e00401057
+:10cd5000b804a48f029d0c3ce81c868dec1c878dca
+:10cd600021208002ab7a400f2128a0021600410446
+:10cd7000b804a48ffeff4d2601001324ffff1e26da
+:10cd8000a804adafecfe0010b404b3af6902a6274f
+:10cd90000100c4252bf086000e00c0130000000027
+:10cda00000008f906902b627010084242b1896009a
+:10cdb00000006fa2ffff1026f9ff60140100732628
+:10cdc000040000100000000030001124000091a0b9
+:10cdd00001009324060000162e0019249c04b88f2d
+:10cde000080017330500e012219000002e001924de
+:10cdf000000079a201001224010073262120800284
+:10ce00002128a00221300000ab7a400f2138000019
+:10ce10004c0040509c04b58f380000122120800245
+:10ce2000029d113ccc1c278ec81c268e212080021e
+:10ce3000d977400f2128a002212040008804a6278e
+:10ce40004876400f212860008804a48f8c04a58fa9
+:10ce500021a04000687a400f21a8600030005f24c4
+:10ce600000007fa28804a48f8c04a58f21300000cd
+:10ce700021380000ab7a400f0100732615004014e2
+:10ce80009004a28fe7ff4050029d113c1200001059
+:10ce9000ffff1026cc1c278e21208002d977400f5f
+:10cea0002128a00221204000212860004876400f60
+:10ceb0008804a6278804a48f8c04a58f21a0400095
+:10cec000687a400f21a8600030004a2400006aa25e
+:10ced00001007326ffff10260700001221208002a8
+:10cee0002128a00221300000ab7a400f2138000039
+:10cef000e8ff4014c81c268e212080022128a002b1
+:10cf000021300000ab7a400f213800000d00405066
+:10cf10009c04b58fb804a78fffff68267002a9276d
+:10cf200021300000212080022128a0021000a8af9b
+:10cf30001800a9af206f400f1400a0afac04a2af3f
+:10cf40009c04b58f0800b4320b0080120000000072
+:10cf500018000012ffff022630000424ffff032404
+:10cf6000ffff4224000064a2fdff4314010073266a
+:10cf7000110000106900a6830f0040126900a6830b
+:10cf800030000324ac04b28f2b8053020600005201
+:10cf900000006c82ffff732600006782fbffe31036
+:10cfa0002b80530200006c822e008b392b280b0043
+:10cfb000219865026900a683b804b08fac04ad8fd8
+:10cfc0007002a3936900be270b80c60305006010a2
+:10cfd00023886d02ffff102601003126110000108a
+:10cfe000000003a29c04ae8f0200d3310600601241
+:10cff0009c04b68fffff10262b000324010031266e
+:10d0000008000010000003a20400cf320600e01167
+:10d010009c04bf8fffff102620000424000004a200
+:10d02000010031269c04bf8fa404b98f9804a88ff7
+:10d030000100f433219039020100982e2a98480209
+:10d0400024b813030700e01221200000029d023cd7
+:10d05000e804a48fd01b4624ca6e400f2328120177
+:10d0600021204000ffff152405009510e804a68f3d
+:10d0700021200002af6e400f212820022120400015
+:10d08000a404a58f274004002b5008002b4805005e
+:10d09000248849010600201200000000e804a48f43
+:10d0a000029d103cca6e400fb01b06262120400096
+:10d0b0000c0095109804a78f0b0080122a28f2000c
+:10d0c0000a0060120b3845029804b48f029d153c8b
+:10d0d000e804a48fd01ba626ca6e400f2328920214
+:10d0e0009804a78f2a28f2000b3845026f00001021
+:10d0f0002110e000f004b38ffcff062403007e261d
+:10d100002458c60300006d8d9c04ac8f9804a78f33
+:10d11000e804a48f040072257804a52701000624e2
+:10d120007804ada31000acaf20000010f004b2af43
+:10d13000f004a48ffcff0324030096242478c30288
+:10d140000000f18d0400ee25f004aeaf04002016bf
+:10d1500021802002029d173c041df126218020021f
+:10d16000ffff18240900d814ffffc3249b6b400f56
+:10d170002120200207000010218002020600201357
+:10d1800021282002ffff632401001026fbff630417
+:10d190000000198221282002233011029804a78f51
+:10d1a000e804a48f9c04bf8f1000bfafe76e400f50
+:10d1b000000000003e0000109404ad8f9c04b18f6d
+:10d1c000000822320d0040109c04ab8ff004a58fa4
+:10d1d000fcff07240300b52424a0a7029404a88f11
+:10d1e00000008a8ec34f080004009026f004b0af00
+:10d1f000000048ad2c000010040049ad000272315f
+:10d200000b0040529c04a38ff004af8ffcff0e2450
+:10d210000300f32524306e020000cc8c9404ad8f03
+:10d220000400de24f004beaf1f00001000008dad2e
+:10d23000f004a48f000176300900c012030083249b
+:10d24000fcff022424f862000000f78f9404b88fda
+:10d250000400f927f004b9af130000100000f8a68d
+:10d260009c04aa8f8000513109002012fcff0c247d
+:10d27000fcff152424a075000000898e9404a88f5b
+:10d2800004009026f004b0af07000010000028a1b1
+:10d2900024586c000000678d9404a58f040072254b
+:10d2a000f004b2af0000e5ac211000009404ad8f93
+:10d2b0002118a201d4fa00109404a3afe804ae8fa1
+:10d2c0009404be8f1000d395ffff03244000663204
+:10d2d0000a18c603e404bf8fe004be8fdc04b78fd6
+:10d2e000d804b68fd404b58fd004b48fcc04b38fd8
+:10d2f000c804b28fc404b18fc004b08f2110600085
+:10d300000800e003e804bd2700a0063ce8ffbd27b5
+:10d310001c01c28c1000bfaf211880000400448c97
+:10d320002130a0006d6f400f212860001000bf8fda
+:10d330000800e0031800bd270800e003ffff0224f7
+:10d340000800e003211080000800e0032110000025
+:10d350000800e003211000000800e003010002249f
+:10d36000e0ffbd271400b1af1000b0af1800bfaf91
+:10d370001800a38c2180a0001000628c21888000fe
+:10d380002120a00009f840000100052419004010e8
+:10d39000ffff03240000078e0a00283affffe6245f
+:10d3a00021202002212800020100032d0600c004d4
+:10d3b000000006ae10000b96c0006a7d24484301b1
+:10d3c000070020112130200218000c8e0400908ddf
+:10d3d00009f80002000000000500001021304000a4
+:10d3e0000400058e0100a4240000b1a0040004aed6
+:10d3f0002118c0001800bf8f1400b18f1000b08f2b
+:10d40000211060000800e0032000bd27e8ffbd27d1
+:10d410001000bfafd874400f000000001000bf8f95
+:10d420000800e0031800bd2700a0033ce8ffbd276b
+:10d430001c01628c1000bfafd874400f0400458cf3
+:10d440001000bf8f0800e0031800bd272024047cd3
+:10d4500080bf033c1062658c0002a27cfdff40107f
+:10d460000000000080bf033c206264ac0800e003c1
+:10d47000000000004050050042550a00c04a050067
+:10d48000427d040025482f01c042040000800e3c6c
+:10d4900025482e0140680700426d0d00c06207005c
+:10d4a000427d060025608f01c05a060025608e016e
+:10d4b0002470c501ffff4f25fe07e12d5600201007
+:10d4c00000000000ffffaf25fe07e12d6e002010d9
+:10d4d0000000000023384d014b00e0040000000074
+:10d4e00042400800c07f090025400f014248090062
+:10d4f00042580b00c07f0c0025586f0142600c00a1
+:10d500002b780b0123400b012b102f0123482f01f7
+:10d510002b782c012578e2010500e01123482c012d
+:10d5200021400b012b780b0121482c0121482f01b0
+:10d530002a780001214008012148290121482f01b2
+:10d54000ffffe724eeffe1040000000008002015c3
+:10d5500025500d0003000015000000000d00001014
+:10d5600000000a242548000100000824e0ff4a25a5
+:10d57000203827710700e010000000002350470109
+:10d58000223007000630c8000440e8000448e900e3
+:10d59000254826011400401d00000000010007245a
+:10d5a0002338ea002000e12c0500201400000000d0
+:10d5b0002540090000000924faff0015e0ffe724d8
+:10d5c0000800e01000000000253009000640e800d7
+:10d5d0000648e90020000f242338e7010430e60064
+:10d5e0002540060100000a24c2220800407d0900ef
+:10d5f00025208f0040280900022b0500007d0a002d
+:10d600002528af002528ae002510040025180500a8
+:10d610000800e003000000003b004015000000008f
+:10d620002a780001214008012148290121482f01c1
+:10d6300025782801a3ffe011000000000800201554
+:10d640000000000003000015000000009dff001016
+:10d6500000000a242548000100000824e0ff4a25b4
+:10d660002038277197ffe010000000002350470189
+:10d67000223007000630c8000440e8000448e900f2
+:10d6800090ff0010254826011b00a0150000000097
+:10d690002a78600121586b0121608c0121608f0183
+:10d6a00025788b011800e0110000000008008015ab
+:10d6b00000000000030060150000000085ff00105e
+:10d6c00000000d242560600100000b24e0ffad2563
+:10d6d000203887717fffe010000000002368a70159
+:10d6e000223007000630cb000458eb000460ec0049
+:10d6f00078ff00102560860140780c002578eb014a
+:10d70000c1ffe01100000000f8ff053cbeff001063
+:10d710000000042440380500423d0700ffffe924d3
+:10d72000fe07212d0c0020100000000002fce72461
+:10d730000f80013cffff21342428a100e03f013c81
+:10d740002528a1000000c7ac2510040025180500fd
+:10d750000800e003000000001300e01400000000d7
+:10d760004048050025482401f6ff20110000000074
+:10d770000080013c2440a1000100e724ffffe724d2
+:10d780002a488000212084002128a5002128a90002
+:10d790001000013c2b08a100f8ff2014000000003d
+:10d7a000e2ff00102528a800f8ff053c0000072430
+:10d7b000e4ff00102520070040480500424d090005
+:10d7c000ffff2c25fe07812d0f0020100000000018
+:10d7d00021482601ffff2c25fe07812d2100201066
+:10d7e000000000000f80013cffff21342428a1002d
+:10d7f000006509002528ac00251004002518050047
+:10d800000800e003000000000063050025608401bb
+:10d81000f9ff80110000000004002011000000004a
+:10d82000f8ff053cf4ff0010000004240100292546
+:10d830000080013c2450a100ffff29252a608000c0
+:10d84000212084002128a5002128ac001000013ce3
+:10d850002b08a100f8ff201400000000dcff0010de
+:10d860002528aa00c04205004265040025400c019d
+:10d87000c03a04000080013c254001010080013cc9
+:10d88000050020192428a100f07f013c2528a100d3
+:10d89000d9ff00100000042401000a24235049018c
+:10d8a0002000412d0700201400000000e0ff4a2165
+:10d8b0002b2007000d00081025380401f8ff001088
+:10d8c00000000834090040110000000022580a003e
+:10d8d00004206701045868010638470106404801e2
+:10d8e00002008010253867010200e7340004e724b5
+:10d8f0000004ec2c21400c01c262070001008c31b5
+:10d900002338ec00c22207004065080025208c0067
+:10d910004060080002630c00b7ff00102528ac002f
+:10d9200025380400254005000080013c2458a10052
+:10d9300040480500424d0900ffff2c25fe07812dc0
+:10d94000370020100000000033040a24235049014e
+:10d95000350041292f00201000000000200041293f
+:10d960000600201400000000e0ff4a250000042407
+:10d970000628450105000010042845010300401950
+:10d98000000000000620440104204401234005015a
+:10d990002338e4000000c4ac0400c5ac0800001546
+:10d9a0000b0029250300e014000000000d0000100a
+:10d9b000000009242540e00000000724e0ff29259d
+:10d9c000202004710700801000000000234824017b
+:10d9d00022500400065047010438870004408800a4
+:10d9e00025400a01c22207004065080025208c005e
+:10d9f00040280800022b0500006509002528ac001e
+:10da00002528ab0025100400251805000800e003b8
+:10da1000000000000400cbacfaff00100000c0ac16
+:10da2000fcff201100000000f8ff053c000004246a
+:10da30000000c4acf3ff00100400c5ac0080013c42
+:10da40002440a10040380500423d0700ff070124a3
+:10da50002a00e1100000000033040a2423384701a3
+:10da60002200e018000000003500e1280800201422
+:10da7000000000002a000015000000002550a4004e
+:10da800024004015000000002500001000000000e8
+:10da900005000015000000002b50040023200400a6
+:10daa000232805002328aa001f00ea3001000924ca
+:10dab00004484901234809002000e12804002014fb
+:10dac0000000000000000424020000102428a90027
+:10dad0002420890005000015000000002b500400e0
+:10dae00023200400232805002328aa002510040071
+:10daf000251805000800e0030000000000530500a1
+:10db0000255044010900401500000000f7ff0010f7
+:10db100000000000f03f053cf4ff0010000004246a
+:10db200025280800f1ff001000000424f8ff053c40
+:10db3000eeff0010000004240080013c2638e100c4
+:10db400040580500425d0b00c0520500427d0400b4
+:10db500025504f01c04a04000080083c2550480170
+:10db60004070070042750e00c06a0700427d060043
+:10db70002568af01c06206002568a801ffff6f2578
+:10db8000fe07e12d8d00201000000000ffffcf25d3
+:10db9000fe07e12dbb002010000000000080013cca
+:10dba0002428a10023406e012c0000110000000079
+:10dbb00015000019000000002000012d07002014ae
+:10dbc00000000000e0ff08212b300c0023000d10a6
+:10dbd0002560a601f8ff001000000d341f000011a1
+:10dbe000000000002220080004308c0004208d007a
+:10dbf00006600c0106680d011800c01025608c003d
+:10dc00001600001002008c3525580e002340080035
+:10dc10002000012d0700201400000000e0ff082173
+:10dc20002b3009000d000a1025484601f8ff0010ae
+:10dc300000000a3409000011000000002220080042
+:10dc40000430890004208a000648090106500a01b0
+:10dc50000200c01025488900020029352678a70057
+:10dc60001c00e0050000000021482c012b782c014d
+:10dc700021504d0121504f0102004d1100000000c4
+:10dc80002b784d013700e0110000000001002f311a
+:10dc90000200e0110000000002002935424809009e
+:10dca000c07f0a0025482f0142500a000080013c35
+:10dcb0002550410101006b25ff0701242900611552
+:10dcc00000000000f07f013c2528a1003700001073
+:10dcd000000004242b782c0123482c012b104f0129
+:10dce00023504f012b784d012578e2010700e01108
+:10dcf00023504d010080013c2628a1002b7809000b
+:10dd00002348090023500a0023504f010800401502
+:10dd10000000000003002015000000000d000010ae
+:10dd200000000b242550200100000924e0ff6b2592
+:10dd300020404871070000110000000023586801ce
+:10dd400022200800062089000448090104500a0125
+:10dd500025504401257849010200e015000000002b
+:10dd60000000052468006019000000000004292557
+:10dd700000042f2d21504f012b784f0121586f01a6
+:10dd8000c27a09000100ef3123482f01c2220900a5
+:10dd9000407d0a0025208f0040780a00027b0f009a
+:10dda0002528af00007d0b002528af0025100400ba
+:10ddb000251805000800e003000000002a78200173
+:10ddc0002148290121504a012300601521504f01ab
+:10ddd000257849011400e0110000000008004015fa
+:10dde00000000000030020150000000067ff001085
+:10ddf00000000b242550200100000924e0ff6b25c2
+:10de00002040487161ff00110000000023586801a4
+:10de100022200800062089000448090104500a0154
+:10de20005aff001025504401ff0701241500c111bd
+:10de3000000000002140e700257806010300e015fe
+:10de400000000000d9ffe0040000000025100600db
+:10de5000d8ff001025180700257849012700e01594
+:10de600000000000ff070124d0ffc11500000000e2
+:10de70002678a7002100e00500000000f3ff001055
+:10de8000000000002a78800121608c012168ad012a
+:10de90001700c0152168af012578ac01c3ffe01160
+:10dea000000000000800a01500000000030080151d
+:10deb0000000000039ff001000000e2425688001da
+:10dec00000000c24e0ffce252040a87133ff001194
+:10ded000000000002370c8012220080006208c00ea
+:10dee00004600c0104680d012cff00102568a401da
+:10def0002578ac01d5ffe01100000000f8ff053cdb
+:10df0000aaff0010000004240100082423400b0194
+:10df10002000012d0700201400000000e0ff082170
+:10df20002b3009000d000a1025484601f8ff0010ab
+:10df300000000a340900001100000000222008003f
+:10df40000430890004208a000648090106500a01ad
+:10df50000200c010254889000200293583ff001007
+:10df600000000b244050050042550a00c04a05003d
+:10df7000427d040025482f01c042040000800e3c71
+:10df800025482e0140680700426d0d00c062070061
+:10df9000427d060025608f01c05a060025608e0173
+:10dfa0002628a7002428ae00ffff4f25fe07e12dfd
+:10dfb0004700201000000000ffffaf25fe07e12d05
+:10dfc0006f0020100000000002fcaf2521504f011f
+:10dfd00019002c01123800001070000019000b010c
+:10dfe000122000001030000019002b011258000010
+:10dff000106800002130cb002b78cb002138ed00d9
+:10e000002138ef000200ed10000000002b78ed0039
+:10e010002170cf0119000c011240000010480000cf
+:10e020002130c8002b78c8002138e9002138ef00e2
+:10e030000200e910000000002b78e9002170cf01f8
+:10e04000257886000200e011000000000100e7349e
+:10e0500025480e0006002005254007002a7800010b
+:10e06000214008012148290121482f01ffff4a25ad
+:10e07000ffff4f25fe07e12d680020100000000083
+:10e080000004082500040f2d21482f012b782f01b3
+:10e0900021504f01c27a08000100ef3123400f01e7
+:10e0a000c2220800407d090025208f004078090029
+:10e0b000027b0f002528af00007d0a002528af0055
+:10e0c00025100400251805000800e00300000000ea
+:10e0d0002a78000121400801214829011c0040152f
+:10e0e00021482f01257828011400e01100000000cc
+:10e0f00008002015000000000300001500000000cb
+:10e10000adff001000000a2425480001000008248b
+:10e11000e0ff4a2520702e71a7ffc011000000000b
+:10e1200023504e0122380e000638e8000440c80192
+:10e130000448c901a0ff001025482701ff0701245a
+:10e140003300a11100000000ddff001000000000fe
+:10e15000257828012e00e015000000000500a0151c
+:10e160000000000040780c002578eb012800e01149
+:10e1700000000000ff0701242100a115000000009d
+:10e180002a78600121586b0121608c011900a015cb
+:10e1900021608f0125788b011400e0110000000040
+:10e1a000080080150000000003006015000000005a
+:10e1b00085ff001000000d242560600100000b2485
+:10e1c000e0ffad25203086717fffc0100000000009
+:10e1d0002368a601227006000670cb010458cb000c
+:10e1e0000460cc0078ff001025608e01b4ff0010a1
+:10e1f0000000042425788b010500e01500000000d4
+:10e20000f07f013c2528a100adff00100000042490
+:10e21000f8ff053caaff001000000424f8ff401d91
+:10e220000000000001000e242370ca012000c12d4f
+:10e230000700201400000000e0ffce212b30080072
+:10e240000d00091025402601f8ff001000000934d8
+:10e250000900c0110000000022380e000430e80060
+:10e260000438e9000640c8010648c9010200c01090
+:10e270002540e800020008350004082500040f2da1
+:10e2800021482f0183ff0010c257090040500500ac
+:10e2900042550a00c04a0500427d040025482f016e
+:10e2a000c042040000800e3c25482e014068070053
+:10e2b000426d0d00c0620700427d060025608f019f
+:10e2c000c05a060025608e012628a7002428ae002b
+:10e2d000ffff4f25fe07e12dcb00201000000000be
+:10e2e000ffffaf25fe07e12df40020100000000025
+:10e2f00023504d01ff034a2542400800c07f09001a
+:10e3000025400f0142480900023c0c00f401e000e6
+:10e310001b0027011270000010480000ffff86312b
+:10e320001900ce0012200000004c0900027c0800f9
+:10e3300025482f012b7824010600e01123482401f1
+:10e34000ffffce2521482c012b082c01fcff2010bb
+:10e3500000000000f401e0001b002701123800005b
+:10e36000104800001900c70012200000004c0900ee
+:10e37000ffff0f3125482f012b7824010600e01103
+:10e3800023482401ffffe72421482c012b082c01fe
+:10e39000fcff20100000000000740e002170c70177
+:10e3a0001900cb01123800001020000000000824e2
+:10e3b0002b780701234007012b102f0123482f0141
+:10e3c0002b7824012578e2010b00e0112348240179
+:10e3d000ffffce2521400b012b780b0121482c019a
+:10e3e00021482f0102002c11000000002b782c0185
+:10e3f000f7ffe0110000000006002c1500000000ef
+:10e4000025200b002548080000000d242a000010dc
+:10e4100025380d00023c0c00f401e0001b00270130
+:10e420001268000010480000ffff86311900cd007f
+:10e4300012200000004c0900027c080025482f0132
+:10e440002b7824010600e01123482401ffffad25ad
+:10e4500021482c012b082c01fcff2010000000009b
+:10e46000f401e0001b0027011238000010480000f2
+:10e470001900c70012200000004c0900ffff0f31f7
+:10e4800025482f012b7824010600e01123482401a0
+:10e49000ffffe72421482c012b082c01fcff201052
+:10e4a00000000000006c0d002168a7011900ab01fd
+:10e4b0001238000010200000000008242b7807010b
+:10e4c000234007012b102f0123482f012b78240113
+:10e4d0002578e2010b00e01123482401ffffad2560
+:10e4e00021400b012b780b0121482c0121482f01e1
+:10e4f00002002c11000000002b782c01f7ffe01126
+:10e50000000000000600c005000000002a78a001fd
+:10e510002168ad012170ce012170cf01ffff4a2596
+:10e52000257828010200e011000000000100ad354f
+:10e5300025480e0025400d00ffff4f25fe07e12d69
+:10e5400015002010000000000004082500040f2d15
+:10e5500021482f012b782f0121504f01c27a08004a
+:10e560000100ef3123400f01c2220800407d090065
+:10e5700025208f0040780900027b0f002528af007e
+:10e58000007d0a002528af0025100400251805008d
+:10e590000800e003000000004400401d00000000ef
+:10e5a00001000e242370ca012000c12d0700201491
+:10e5b00000000000e0ffce212b2008000d00091014
+:10e5c00025402401f8ff0010000009340900c011a3
+:10e5d0000000000022300e000420c8000430c900f2
+:10e5e0000640c8010648c901020080102540c80045
+:10e5f000020008350004082500040f2d21482f01d2
+:10e60000d6ff0010c25709002a78000121400801f6
+:10e61000214829011700401521482f01257828019c
+:10e620001400e011000000000800201500000000a8
+:10e63000030000150000000029ff001000000a245c
+:10e640002548000100000824e0ff4a2520702e71b3
+:10e6500023ffc0110000000023504e0122300e00a5
+:10e660000630c8000440c8010448c9011cff00105e
+:10e670002548260105004d150000000040780c00db
+:10e680002578eb012b00e01100000000ff070124ba
+:10e690000a00a11100000000bbff401100000000b3
+:10e6a000257828012300e01500000000f07f013ce0
+:10e6b0002528a100b4ff0010000004242a7860017e
+:10e6c00021586b0121608c011700a01521608f017a
+:10e6d00025788b01f5ffe01100000000080080158f
+:10e6e00000000000030060150000000000ff0010a3
+:10e6f00000000d242560600100000b24e0ffad2523
+:10e7000020708e71fafec011000000002368ae0177
+:10e7100022300e000630cb000458cb010460cc013f
+:10e72000f3fe00102560860125788b010200e011c0
+:10e7300000000000f8ff053c93ff001000000424d7
+:10e740000000052425480500253805002530040073
+:10e750000c00c010000000000600c1040000000012
+:10e760000080093c2b5005002328050023300600bb
+:10e770002330ca001e0407242040c8702338e80054
+:10e7800004300601c24205004055060025400a013a
+:10e790004050060002530a0025482a010055070090
+:10e7a00025482a0125100800251809000800e00363
+:10e7b0000000000000000524253805002530040075
+:10e7c0000500c010000000001e0407242048c97086
+:10e7d0002338e90004302601c242050040550600f6
+:10e7e00025400a0140480600024b09000055070079
+:10e7f00025482a0125100800251809000800e00313
+:10e8000000000000c23d0400ff00e7300080013c32
+:10e8100024308100ffffe924fe00212d0c00201090
+:10e82000000000008003e724404a0400024b090076
+:10e830002530c900402f0400004d07002530c900d5
+:10e8400025100500251806000800e0030000000060
+:10e850000000052421208400f7ff80100000000044
+:10e860000900e01400000000ffffe72421208400dd
+:10e870008000013c2b088100fbff201400000000f9
+:10e88000e8ff001000000000ff07072400ff013c24
+:10e89000010021342b088100e7ff20140000000054
+:10e8a000e5ff0010f8ff063cc03a0500425d040099
+:10e8b0002538eb00c03204000080013c2538e1001f
+:10e8c0000080013c2448a10040400500424508006a
+:10e8d00080fc0825ffff0b25fe00612d1100201094
+:10e8e000000000000200c010000000000100e7343a
+:10e8f0008000e7248000eb2c21400b01025a070026
+:10e9000001006b312338eb0040380700423a070022
+:10e91000c05d08002538eb002510e9000800e00381
+:10e92000000000007f040124070001150000000022
+:10e9300040580700255866010300601100000000e0
+:10e94000f6ff0010c0ff023cff0001290400201464
+:10e9500000000000807f013cf0ff00102510210125
+:10e9600001000a24235048012000412d03002014f7
+:10e9700000000000e9ff00102510090020000c2411
+:10e9800023608a01045887012530cb0006384701ef
+:10e99000000008240080013cd2ff00102538e1006f
+:10e9a000c03a0500425504002538ea000080013cc9
+:10e9b0002538e1004050050042550a001e04062497
+:10e9c0002330ca000b00c018000000002000c12c3a
+:10e9d0000200201400000000000007340200a1041f
+:10e9e0000638c70023380700251007000800e00399
+:10e9f0000000000002008010000000000100a534ab
+:10ea0000f07f013c010021342b08a10003002014f9
+:10ea100000000000f5ff00100080023cff7f023c78
+:10ea2000f2ff0010ffff4234c03a050042550400d7
+:10ea30002538ea000080013c2538e10040500500ff
+:10ea400042550a001e0406242330ca000b00c004ed
+:10ea5000000000002000c12c020020140000000073
+:10ea6000000007340200a1040638c700233807005d
+:10ea7000251007000800e0030000000002008010dd
+:10ea8000000000000100a534f07f013c01002134aa
+:10ea90002b08a1000300201400000000f5ff001067
+:10eaa0000080023cf3ff0010ffff0224feff092458
+:10eab000405005004058070025586401255866015c
+:10eac00025504b0103004015000000003c000010e1
+:10ead00000000224020080104040050001000825cb
+:10eae000e0ff013c010021342b0801013600201019
+:10eaf000000000000200c01040400700010008258f
+:10eb0000e0ff013c010021342b0801012e00201000
+:10eb1000000000001600a104000000000300e00453
+:10eb20000000000026000010ffff02242b5086008a
+:10eb3000232086002b58aa002328aa002b50a700c8
+:10eb400025504b01030040112328a7001c00001092
+:10eb5000010002242550a400030040110000000021
+:10eb600017000010ffff022415000010000002240f
+:10eb70000300e10400000000110000100100022465
+:10eb80002b508600232086002b58aa002328aa0099
+:10eb90002b50a70025504b01030040112328a7004c
+:10eba00007000010ffff02242550a40003004011bd
+:10ebb00000000000020000100100022400000224f6
+:10ebc0000800e00300000000fdff00102510090010
+:10ebd0000080013c2628a10025100400251805000e
+:10ebe0000800e00300000000ff7f013cffff21342c
+:10ebf0002428a10025100400251805000800e003c2
+:10ec000000000000020080104040050001000825bf
+:10ec1000e0ff013c010021342b0801010300201416
+:10ec2000000000000c000010010002240200c010cf
+:10ec30004040070001000825e0ff013c01002134ad
+:10ec40002b08010103002014000000000200001046
+:10ec500001000224000002240800e003000000007c
+:10ec60000080013c2628a100c24d0400ff0029318c
+:10ec7000c25d0500ff006b310080073c00420400cc
+:10ec8000254007010052050025504701ffff2d25b3
+:10ec9000fe00a12d6100201000000000ffff6d2587
+:10eca000fe00a12d770020100000000023602b0142
+:10ecb0000d008005000000002000812903002014c1
+:10ecc000000000001500001002000a2425300a0090
+:10ecd00006508a0104688a011000a6110000000095
+:10ece0000e00001002004a3525480b0023600c007e
+:10ecf00020008129030020140000000007000010fc
+:10ed000002000824253008000640880104688801b4
+:10ed10000200a611000000000200083524608700f0
+:10ed2000266885011000a0050000000021400a01ae
+:10ed30002b680a011700a0110000000001000d312e
+:10ed40000200a01100000000020008354240080047
+:10ed500001002925ff0001240e00211500000000fc
+:10ed60000c000010000008242b680a010400a01108
+:10ed700023400a0123400800030000102660870199
+:10ed800050000011000000002030067123482601c9
+:10ed90000440c8000e002019000000008000082573
+:10eda00080000d2d21482d01026a08000100ad31bf
+:10edb00023400d014040080042420800c06d090098
+:10edc00025400d0125100c010800e00300000000a3
+:10edd000010006242330c9002000c12c3900201076
+:10ede000000000000080013c2540010120000d24ae
+:10edf0002368a6010448a801020020110640c800ab
+:10ee0000010008350000092480000d25e3ffa1055d
+:10ee100000000000e1ff0010010009240e00201591
+:10ee20000000000021400801050000110000000062
+:10ee300020600c7123482c0198ff001004408801c9
+:10ee4000ff0001240f006111000000000080013c60
+:10ee50001800a11400000000216808011b00a01583
+:10ee600000000000ff0001241400611500000000f4
+:10ee7000266885001500a005000000000d000010a8
+:10ee800000000000080060150000000021504a0149
+:10ee90000a0040110000000020604c7123586c01f2
+:10eea00082ff001004508a0121684a010700a01562
+:10eeb00000000000c4ff001025100500c2ff001074
+:10eec00025100400c0ff001000000224beff001047
+:10eed000c0ff023cc23d0400ff00e730c24d050008
+:10eee000ff00293100800a3c003204002530ca00ae
+:10eef0000042050025400a012660850024504c018f
+:10ef0000ffffec24fe00812d2100201000000000f6
+:10ef1000ffff2c25fe00812d360020100000000090
+:10ef20001900c800125800000200601110300000e3
+:10ef30000100c6340300c004000000004030060099
+:10ef4000ffffe72482ff2c252138ec00ffffec2493
+:10ef5000fe00812d3a002010000000008000c62431
+:10ef60008000cc2c2138ec000262060001008c31bc
+:10ef70002330cc004030060042320600c065070056
+:10ef80002530cc002510ca000800e0030000000076
+:10ef90000d00e014000000002130c6000500c01084
+:10efa000000000002058cb702338eb00d8ff001081
+:10efb00004306601ff0001241f0021110000000041
+:10efc00015000010000000002160c6001a00801526
+:10efd000000000000400201500000000216008016e
+:10efe0001500801100000000ff0001240f00211512
+:10eff000000000000a002015000000002140080168
+:10f00000050000110000000020580b7123482b015f
+:10f01000c3ff001004406801dbff001025100a0048
+:10f02000216008010400801500000000807f013c81
+:10f03000d5ff001025104101d3ff0010c0ff023c96
+:10f04000faffe01c0000000001000b2423586701b8
+:10f050002000612df0ff20100000000020000c2493
+:10f0600023608b01043886010200e010063066013f
+:10f070000200c634000007248000cc24b7ff8105bd
+:10f0800000000000b5ff00100100072400800b3cc9
+:10f09000c2450400ff000831c2550500ff004a3197
+:10f0a000003a04002538eb00004a050025482b01f2
+:10f0b0002670850024586e01ffff0e25fe00c12d2d
+:10f0c0003f00201000000000ffff4e25fe00c12d74
+:10f0d00053002010000000002b08e900030020145a
+:10f0e0000000000042380700010008258263090083
+:10f0f000f40180011b00ec00122000001030000021
+:10f10000ff3f2d311900a4011228000080330600b2
+:10f110002b70c5000400c0112330c500ffff8424fc
+:10f120002130c9002b70c900f40180011b00cc0004
+:10f1300012380000103000001900a701122800004a
+:10f14000803306002b70c5000400c0112330c500b9
+:10f15000ffffe7242130c9002b70c9008073040031
+:10f160002138ee000200c010003907000100e7342a
+:10f170007e000e242370ca0121400e01ffff0e25e0
+:10f18000fe00c12d34002010000000008000e724a4
+:10f190008000ee2c21400e01027207000100ce31ea
+:10f1a0002338ee0040380700423a0700c0750800d7
+:10f1b0002538ee002510eb000800e00300000000f9
+:10f1c00008000015000000002138e7000500e010ed
+:10f1d000000000002060ec7023400c01baff00101a
+:10f1e000043887010400481500000000217029013f
+:10f1f0002f00c01100000000ff0001240800411191
+:10f200000000000012000011000000002170e70063
+:10f210002700c015000000002200001000000000c0
+:10f220000800401500000000214829011d002011a0
+:10f230000000000020602c7123504c01a6ff00103c
+:10f2400004488901217029011900c015000000003f
+:10f25000d9ff001025100b001200001d0000000057
+:10f2600001000c24236088012000812df8ff20106c
+:10f270000000000020000e242370cc010440c701d0
+:10f2800002000011063887010200e734000008245c
+:10f290008000ee24bdffc10500000000bbff001090
+:10f2a00001000824807f013cc3ff0010251061018c
+:10f2b000c1ff0010c0ff023c0080013c1200801022
+:10f2c000243081000200810400000000232004009b
+:10f2d0009e000524203887702328a7000420e4001e
+:10f2e000800084248000882c2128a8000342040088
+:10f2f000010008312320880040200400422204003d
+:10f30000c045050025208800251086000800e00380
+:10f31000000000000f008010000000009e00062486
+:10f32000202885702330c5000420a4008000842498
+:10f330008000872c2130c700023a04000100e7302a
+:10f34000232087004020040042220400c03d060024
+:10f3500025208700251004000800e00300000000bd
+:10f36000002a04000080013c2528a100c23d0400c1
+:10f37000ff00e7309e0006242330c7000c00c018b1
+:10f38000000000002000c12803002014000000003d
+:10f390000500001000000224020081040628c500b8
+:10f3a00023280500251005000800e00300000000e8
+:10f3b000807f013c010021342b08810003002014d0
+:10f3c00000000000f8ff00100080023cff7f023cbc
+:10f3d000f5ff0010ffff4234002a04000080013cca
+:10f3e0002528a100c23d0400ff00e7309e0006244e
+:10f3f0002330c7000c00c004000000002000c1281a
+:10f40000030020140000000005000010000002248a
+:10f41000020081040628c5002328050025100500e8
+:10f420000800e00300000000807f013c010021345f
+:10f430002b0881000300201400000000f8ff0010da
+:10f440000080023cf6ff0010ffff0224feff0824ac
+:10f4500040300400403805002548c7001b0020113b
+:10f460000000000000ff013c010021342b08c10016
+:10f47000190020100000000000ff013c01002134b1
+:10f480002b08e1001400201000000000020081049d
+:10f4900042300600233006000200a1044238070073
+:10f4a000233807002a08c7000300201000000000ce
+:10f4b00007000010ffff02242a08e60003002010c6
+:10f4c00000000000020000100100022400000224dd
+:10f4d0000800e00300000000fdff001025100800f8
+:10f4e00040100400421002000800e0030000000089
+:10f4f0000080013c261081000800e00300000000ad
+:10f500004030040000ff013c010021342b08c10001
+:10f5100003002014000000000a0000100100022473
+:10f520004030050000ff013c010021342b08c100e0
+:10f53000030020140000000002000010010002245b
+:10f54000000002240800e00300000000b8ffbd270f
+:10f550004800a4af4000beaf3400b5af3000b4af38
+:10f560002c00b3af4400bfaf3c00b7af3800b6af1c
+:10f570002800b2af2400b1af2000b0af00008880f7
+:10f58000029d063cad1ac4242110040100004780ee
+:10f590004800b38f8800e3304c00a5af1000a0af47
+:10f5a0001400a0af21f000001800a0af21a00000bf
+:10f5b0000800601021a80000010073260000688286
+:10f5c000215004010000498188002531fbffa0542f
+:10f5d000010073262d000424d40004112b000c24f8
+:10f5e000d7000c5101007326ad1ad72421701701e2
+:10f5f0000000cd910400a6311b00c01001000f24b3
+:10f60000029d163c1800afafc81cc68ecc1cc78e1e
+:10f61000d0ff12252128a002d977400f2120800297
+:10f620002120400221a84000d079400f21a0600095
+:10f63000213040002120a0022128800221386000d2
+:10f64000d076400f010073260000688225f0d203b7
+:10f65000219017010000519221a040000400303297
+:10f66000e9ff001621a860002e0016248a0016511a
+:10f67000010073261800a48f280080104c00a48f6e
+:10f680004500063965000d390100ab2d0100cc2c79
+:10f6900025406c01210000114c00a48f010073264d
+:10f6a000000064822d000e2421280000af008e107f
+:10f6b000213800002b000f24a3008f500100732677
+:10f6c00021c09700000016930400d7320d00e0120d
+:10f6d000029d193cad1a2627809005002150450255
+:10f6e00040280a00010073262148a400000064821b
+:10f6f000211886000000629004005f30f6ffe017da
+:10f70000d0ff25251400b18f238005000b280702a8
+:10f71000213825021400a7af4c00a48f05008010eb
+:10f720004800ab8f1800ac8f4c00a88f0a986c0172
+:10f73000000013ad1400a28f28004010029d1f3c52
+:10f74000c39f0200029d0f3c26705300029d0d3c9a
+:10f75000681de68d6c1de78d2390d30121b040001c
+:10f76000181db32503000010090003241000001227
+:10f7700021180002ffff702407c01202c0c8030056
+:10f7800001001733214033032120c000f7ffe012ae
+:10f790002128e0000000068dd977400f0400078d76
+:10f7a0002138600021304000f2ff001621180002cd
+:10f7b0006a00c00621208002d977400f2128a002cc
+:10f7c0002120400021286000647e400f2130c002cb
+:10f7d00021a0400021a86000029d1f3c741df68fef
+:10f7e000040080162438b602f07f023c5800e21074
+:10f7f00022000324259095020100452e2b501e0067
+:10f800002448aa005d002055220015241000a78f6f
+:10f810000e00e014211080022118a0024400bf8fc6
+:10f820004000be8f3c00b78f3800b68f3400b58fd4
+:10f830003000b48f2c00b38f2800b28f2400b18f1a
+:10f840002000b08f0800e0034800bd27212080027f
+:10f85000f47a400f2128a00221a0400021a86000d6
+:10f86000211080022118a0024400bf8f4000be8feb
+:10f870003c00b78f3800b68f3400b58f3000b48f9e
+:10f880002c00b38f2800b28f2400b18f2000b08fde
+:10f890000800e0034800bd270000688221f8170136
+:10f8a0000000f9930400383372ff0013029d163ce8
+:10f8b000010003241800a3afc81cc68ecc1cc78e41
+:10f8c000d0ff12252128a002d977400f21208002e5
+:10f8d0002120400221804000d079400f2188600023
+:10f8e0002138600021282002212000022130400020
+:10f8f000d076400f01007326000068821400a98fa3
+:10f900002150170121a0400000004291ffff252552
+:10f910000400473021a8600025f0d203e6ffe01480
+:10f920001400a5af57ff00104500063901007326eb
+:10f930000000688201000b242bff00101000abaf09
+:10f9400029ff0010000068825dff00100000648243
+:10f9500000a01e3cadff00100402c3afa378400f0f
+:10f960002128a00297ff00102120400001007326eb
+:10f970000000648252ff00100100072400a0143c24
+:10f98000040295ae21a00000a0ff001021a80000f5
+:10f990000055a77cffffe324fe07622c2140800076
+:10f9a0002150c000c007ab7c3f0040100098a97cec
+:10f9b000029d043c7c1d858c01fce424253025013e
+:10f9c0002148c00021788a00c04809004257080039
+:10f9d000ff03e72525482a014100e018c040080040
+:10f9e000070006311d00c014c000057d40670900f6
+:10f9f000c2300800ff07e4282540cc003100801009
+:10fa0000c2480900029d033c7c1d798c21780000ce
+:10fa100024c039012550f801070040512138000069
+:10fa200021100001029d083c8c1d058d21404000e5
+:10fa3000247025012148c001c06a0b002520a701c0
+:10fa40000035040021600000252088012528c90018
+:10fa5000211080000800e0032118a0000300a22468
+:10fa60002118000021400201029d183c2bc8020110
+:10fa700021482301841d0f8f21483901216800008e
+:10fa800024502f012560aa01d9ff80114067090089
+:10fa9000c07709004240080025400e014248090095
+:10faa000d2ff00100100e7240400e01421108000c0
+:10fab000253889002900e014026809000800e003e5
+:10fac0002118a000c06a0b00ff07a735002d070012
+:10fad00021200000211080000800e0032118a00070
+:10fae00001001924233027033800d82818000053b8
+:10faf00001000824232806002000a2302718c00097
+:10fb00000660c800041869000668c90040180300b0
+:10fb1000256083012000c3300b60a3010b68030044
+:10fb200021500001040040140418a8000218090024
+:10fb30000440a300251848012b20030021280000c1
+:10fb4000254084012548a501a5ff00102138e600c5
+:10fb500021480000a2ff00102138e60002fc042426
+:10fb60000300a0152018a37120700e712000c3257a
+:10fb7000f5ff632494ff601021788a00271060004d
+:10fb80000438690006104800043068004210020082
+:10fb90002538e200200062300b38c2000b30020032
+:10fba000232083002140c00086ff00102148e00090
+:10fbb00080bf033c105a648c0000827cfdff401023
+:10fbc0000000000080bf033c205a628c0800e00364
+:10fbd000000000001f008f30029d0e3c80600f006f
+:10fbe000901dcd2521308d0100c00b3c0220093c29
+:10fbf000e01f6a3500e028350000c38c2438a800d7
+:10fc000024208a0080bf023c8001a57c252087003b
+:10fc1000305a43ac0500a01480bf053c40001924b5
+:10fc200080bf183c145a19af80bf053c005aa4ace1
+:10fc30000800e003000000000800e00300606241eb
+:10fc4000e8ffbd271000bfaf006805408000063cfc
+:10fc50002520a600006884400010032488bf023cd1
+:10fc6000247f400f081043ac1000bf8f0800e00352
+:10fc70001800bd2701008430030080100000000040
+:10fc80000800e003206060410800e003006060417c
+:10fc90000800e003206062412118e0002140a0003c
+:10fca0002138c0003a006014216080002b10a600ab
+:10fcb0008c004010000000002030c670c200c0144c
+:10fcc00023280600023407001b000601f401c000cf
+:10fcd000ffffeb3002740c001248000010c000005f
+:10fce0001250000002482b71007c18002528ee01fc
+:10fcf0002b68a9001b000601f401c0000900a051f7
+:10fd00002320a9002128a7002b40a70004000015ec
+:10fd1000ffff4a252bc8a900fc002057ffff4a25fa
+:10fd20002320a9001b008600f401c000ffff8331df
+:10fd30001268000010280000124800000258ab7141
+:10fd400000140500254043002b600b011b008600ba
+:10fd5000f401c00009008051005c0a002140070145
+:10fd60002b3007010400c014ffffa9252b700b01e5
+:10fd70002b380e0023482701005c0a00252069016a
+:10fd800021300000211080000800e0032118c0008d
+:10fd90002b58a30021200000faff6015213000003d
+:10fda000204869708e0020112b10870120000d243f
+:10fdb0002370a901045023010678c70125684f016b
+:10fdc00006c8c50102540d001b002a03f4014001be
+:10fdd00006c0cc0104282501ffffaf312570b80013
+:10fde00004c02c01021c0e00043827011220000060
+:10fdf000105800001260000002408f70004c0b0091
+:10fe0000255823012b3068011b002a03f40140010f
+:10fe10000b00c0502318680121586d012b106d0193
+:10fe200006004014ffff8c242b3068010400c01032
+:10fe300023186801ffff8c2521586d0123186801e4
+:10fe40001b006a00f4014001ffffcb3112480000a3
+:10fe5000104000001230000002482f7100240800fa
+:10fe600025408b002bc809011b006a00f4014001ea
+:10fe70000b002053007c0c0021400d012b280d01ac
+:10fe80000600a014ffffc6242b7009010400c01156
+:10fe9000007c0c0021400d01ffffc624007c0c00fb
+:10fea0002520e60119008700102800002318090109
+:10feb0002b60650009008055ffff842412100000ac
+:10fec0002668a3002b5002030100b82d24380a0332
+:10fed000acffe05021300000ffff8424a9ff001098
+:10fee000213000004500c01001000a242050ea70b3
+:10fef0004900401520000924232807010100062499
+:10ff0000024c0700ffffed301b00a900f4012001a7
+:10ff100002cc0c0012500000101800001258000013
+:10ff200002504d7100240300254099002b700a01f6
+:10ff30001b00a900f40120010900c01123780a0167
+:10ff4000214007012b2807010400a014ffff6b25a7
+:10ff50002b100a016b004054ffff6b2523780a0128
+:10ff60001b00e901f4012001ffff983112c80000d5
+:10ff7000104000001250000002602d730074080051
+:10ff80002540d8012b680c011b00e901f401200178
+:10ff90000900a011001c0b00214007012b4807019c
+:10ffa00005002015ffff2a272b380c012b600700c6
+:10ffb00023504c01001c0b0025206a0021108000fa
+:10ffc0000800e0032118c0000620a4000418c8009f
+:10ffd000254064000460cc003aff00100438c700dc
+:10ffe0002b20650001004538255085002b200a0094
+:10fff000211080000800e0032118c0001b0046010a
+:020000041d02db
+:10000000f401c000123800002050ea70bbff40111c
+:10001000232807012000092423782a0104384701f6
+:1000200006c8e801024c07001b002903f401200167
+:100030000670ec0104104801ffffed3025784e00fa
+:1000400002240f001230000010280000127000007f
+:100050000240cd70001c0500255864002bc06801cb
+:100060001b002903f40120010a00001304604c0165
+:10007000215867012b50670106004015ffffce2471
+:100080002bc068010400001323c86801ffffce25c0
+:100090002158670123c868011b002903f4012001ce
+:1000a000ffffe43112280000104000001230000071
+:1000b0000250ad70001c0800254064002b580a0156
+:1000c0001b002903f40120010b00601100c40e0085
+:1000d000214007012b10070107004014ffffa62451
+:1000e0002b780a010500e05125300603ffffc624e6
+:1000f0002140070100c40e002530060382ff0010d6
+:1001000023280a0195ff00102140070104ff001079
+:100110002128a700e8ffbd272140e0001000b2af72
+:100120000c00b1af0800b0af2190a0032150c00077
+:1001300021588000400000152138a0002b10a60097
+:100140005c0040102070ce707900c01523280e008e
+:10015000024c0a001b00e900f4012001ffff4f31af
+:1001600002640b00128000001030000002280f72a1
+:10017000006c06002530ac012b40c5001b00e900d7
+:10018000f40120010a0000112318c5002130ca0023
+:100190002b38ca000600e0142318c5002bc8c50080
+:1001a0000000383b2188ca000b3038022318c500f4
+:1001b0001b006900f4012001ffff713112c800002b
+:1001c00010c0000002582f73007c18002540f10178
+:1001d0002b380b011b006900f40120010a00e0101c
+:1001e00023180b0121400a012b480a0106002015a3
+:1001f00023180b012b100b0121200a0100004a38a3
+:100200000b408a0023180b010660c3010300401253
+:100210002168000000004cae04004dae0000a28f2b
+:100220000400a38f1000b28f0c00b18f0800b08fb4
+:100230000800e0031800bd272b70a8000a00c05179
+:1002400020700e711000b28f0c00b18f0800b08fbb
+:10025000211080002118a0000000a4af0400a5af69
+:100260000800e0031800bd273700c01520000f2448
+:100270002b6886000100ac392b3005012528cc0005
+:100280000700a0102160600123808a002388e80015
+:100290002b40900023382802215800022160600181
+:1002a000deff40122168e00000004caedbff0010d2
+:1002b00004004dae7e00c0100100092420704e7174
+:1002c0008200c01520000f242330ea00024c0a00ef
+:1002d000ffff4f311b00c900f401200102240b0075
+:1002e000124000001028000002380f71001c0500a9
+:1002f000252864002b10a7001b00c900f401200171
+:10030000abff40102318a7002128aa002b30aa0019
+:10031000a7ffc0542318a7002b80a70000000d3aa8
+:100320002160aa000b288d01a1ff00102318a7004f
+:100330000620a4000418c701253864000450c60133
+:1003400083ff00100458cb0123c0ee010448c8010c
+:1003500006c806032578390106200503024c0f0064
+:100360001b008900f401200106380b030468c50155
+:10037000fffff13125c8a7010480cb010438ca0171
+:10038000021c19001230000010600000125800001a
+:100390000250d170002c0c002540a3002b100a0144
+:1003a0001b008900f40120010b00405023180a01b2
+:1003b00021400f012b100f0106004014ffffcb243a
+:1003c0002b200a010400801023180a01ffff6b256f
+:1003d00021400f0123180a011b006900f4012001cc
+:1003e000ffff2533125000001040000012300000c3
+:1003f0000250517100640800254085012b880a01d4
+:100400001b006900f40120010b00201200140b00f6
+:1004100021400f012b680f010700a015ffffc62424
+:100420002bc80a010500201325484600ffffc624fb
+:1004300021400f0100140b00254846001900270138
+:100440001030000023400a012b58060107006015f8
+:10045000122800002660c8000100912d2b1805020b
+:100460002420230206008010000000002350a70073
+:100470002b38aa002368cf002330a7012128400190
+:1004800066ff401223780502232806012b400f0245
+:100490002380a8000430100306c0cf012560d800d7
+:1004a0000668d00100004cae5cff001004004daea9
+:1004b0001b002601f401c0001250000020704e7194
+:1004c00082ffc0112330ea0020000f242380ee01b8
+:1004d0000450ca0106200702024c0a001b008900d2
+:1004e000f401200106680b020430c701ffff4f3101
+:1004f0002538cd00021c07001260000010400000eb
+:1005000002308f71002c08002540a3002b1006013b
+:100510001b008900f4012001050040100458cb01a4
+:1005200021400a012b880a01190020122b10060114
+:10053000231806011b006900f4012001ffffe530cc
+:1005400012680000106000000238af7100440c0017
+:10055000253005012b20c7001b006900f401200194
+:100560005cff80502330c7002130ca002b80ca00b6
+:1005700058ff00562330c7002bc8c7000000383b87
+:100580002188ca000b30380252ff00102330c70008
+:100590000000593821c00a01e5ff00100b40190383
+:020000040000fa
+:020000041d02db
+:1005a00000040000ff030000fe030000fc03000045
+:1005b000fa030000f7030000f2030000ec03000060
+:1005c000e3030000d8030000c9030000b6030000e5
+:1005d0009f03000083030000610300003b03000051
+:1005e00010030000e1020000af0200007b020000e7
+:1005f0004702000013020000e0010000b10100000a
+:10060000840100005a0100003501000013010000c0
+:10061000f4000000d9000000c1000000000000004c
+:1006200000000000389c2c41000000000000394010
+:10063000000080bf00c0794400c07944000080bf42
+:10064000000020410000000000000000389c2c4108
+:1006500000000000000039402cc4009d54c6009ddd
+:1006600054c6009d54c6009d54c6009d54c6009dae
+:1006700054c6009d54c6009d54c6009d54c6009d9e
+:1006800054c6009d54c6009d54c6009d54c6009d8e
+:1006900054c6009d54c6009d54c6009decc5009de7
+:1006a00054c6009d54c6009d54c6009d54c6009d6e
+:1006b00040c3009d54c6009d54c6009d54c6009d75
+:1006c00054c6009d54c6009d54c6009d54c6009d4e
+:1006d00054c6009d54c6009d2cc4009d54c6009d68
+:1006e00054c6009d54c6009d54c6009d54c6009d2e
+:1006f00054c6009d54c6009d54c6009d54c6009d1e
+:1007000054c6009d54c6009d54c6009d54c6009d0d
+:1007100054c6009d54c6009d54c6009decc5009d66
+:1007200054c6009d54c6009d54c6009d54c6009ded
+:1007300040c3009d2e2e00002020202020202020bd
+:1007400020202000000000000095000000000000b4
+:100750000000000001f9000000000000000000009f
+:1007600009af000000000000010000000a1b0000ab
+:1007700000000000010000000cc3000000000000a9
+:10078000000000000daf00000200000000000000ab
+:1007900010ff0000000000000000000011ff00003a
+:1007a000000000000100000012ff00000000000037
+:1007b0000100000018ff0000000000000100000020
+:1007c00019ff0000000000000100000020ff0000f1
+:1007d000000000000000000021ff000000000000f9
+:1007e0000000000026df0000010000000000000003
+:1007f0003773000000000000000000003a250000f0
+:1008000003000000000000003b2500000000000085
+:100810000000000054454d5045524154555245206a
+:100820004348414e47450000000000000000000022
+:1008300000000000000000000000000000000000b8
+:1008400000000000000000000000000000000000a8
+:100850000000000000000000000000000000000098
+:10086000e0e0606060ffff6363e3e3030303ffff17
+:100870000000000000000000000000000000000078
+:100880000000000000000000000000000000000068
+:100890000000000000000000000000000000000058
+:1008a0000000000000000000000000000000000048
+:1008b0000000000000000000000000000000000038
+:1008c0000000000000000000000000000000000028
+:1008d0000000000000000000000000000000000018
+:1008e000ffffc0c0c0c7c7c6c6ffff060606070792
+:1008f00000000000000000000000000000000000f8
+:1009000000000000000000000000000000000000e7
+:1009100000000000000000000000000000000000d7
+:1009200000000000000000000000000000000000c7
+:1009300000000000000000000000000000000000b7
+:1009400000000000000000000000000000000000a7
+:100950000000000000000000000000000000000097
+:100960000000000000000000000000000000000087
+:100970000000000000000000000000000000000077
+:100980000000000000000000000000000000000067
+:100990000000000000000000000000000000000057
+:1009a000000000000000000000000040c0c0c0c007
+:1009b000c0c0c0c0c0c0c0c0c0c0c0c08080000037
+:1009c0000000000000000000000000000000000027
+:1009d0000000000000000000000000000000000017
+:1009e00000000000000040c0c0c0c0c0c0c0c08047
+:1009f000000000000080c0c0c0c0c0c0c0c0400037
+:100a000000000000000000000000000000000000e6
+:100a100000000000000000000000000000000000d6
+:100a2000000000000000000000000000ffffffffca
+:100a3000ffffff7171f1f1ffffffffff7f3f00003c
+:100a4000009c9c9c9c9c9c9c9c9cfcfcfcfcfcf846
+:100a5000f0000004fcfcfcfcfcfcf81c1c1cfcfc76
+:100a6000fcfcfcf8f00000ffffff0f7fffffffff23
+:100a7000fce000e0fc3f07ffffffffffffff00007f
+:100a800000009c9c9c9c9c9c9c9c9cfcfcfcfcfcfe
+:100a9000f8f0000000fcfcfcfcfcfcf81c1c1cfc3e
+:100aa000fcfcfcfcf8f00000000000407f7f7f7f32
+:100ab0007f7f7f400000073f7f7f7f7f7c7040000b
+:100ac0003f7f7f7f7f7f7f7171717f7f7f7f7f7fa0
+:100ad0007f400000ffffffffffffff7070707f7f10
+:100ae0007f7f7f7f3f00407f7f7f0000031f7f7fee
+:100af0007f7f7f0f0100407f7f7f7f7f7f7f400070
+:100b0000003f7f7f7f7f7f7f7171717f7f7f7f7fde
+:100b10007f7f4000407f7f7f7f7f7f7f4000407fdf
+:100b20007f7f7f7f7f7f400000000000000000008b
+:100b300000000000000000000000000000000000b5
+:100b400000000000000000000000000000000000a5
+:100b50000000000007070707070707040000000060
+:100b60000000000000000000000000000000000085
+:100b70000000000000000000000000000000000075
+:100b80000000000000000000000000000000000065
+:100b90000000000000000000000000000000000055
+:100ba0000000000000000000000000000000000045
+:100bb0000000000000000000000000000000000035
+:100bc0000000000000000000000000000000000025
+:100bd0000000000000000000000000000000000015
+:100be0000000000000000000000000000000000005
+:100bf00000000000000000000000000000000000f5
+:100c000000000000000000000000000000000000e4
+:100c100000000000000000000000000000000000d4
+:100c200000000000000000000000000000000000c4
+:100c300000000000000000000000000000000000b4
+:100c400000000000000000000000000000000000a4
+:100c5000000000000000000000c060301088e45474
+:100c60006e6e26f32f272323272ff3266e5664cc90
+:100c7000983020e08000000000000000000000002c
+:100c80000000000000000000000000000000000064
+:100c90000000000000000000000000000000000054
+:100ca0000000000000000000000000000000000044
+:100cb0000000000000000000000000000000000034
+:100cc0000000000000000000000000000000000024
+:100cd000000000000000c0fc472632f93f10080861
+:100ce00008f80f0908080808080809ff080808108c
+:100cf000173df326655ffcc0000000000000000007
+:100d000000000000000000000000000000000000e3
+:100d100000000000000000000000000000000000d3
+:100d200000000000000000000000000000000000c3
+:100d300000000000000000000000000000000000b3
+:100d400000000000000000000000000000000000a3
+:100d50000000000000000f74c888107fd0302060b1
+:100d6000607fc04040404040404040ff60602030d5
+:100d700010f01f90d8e87c0f000000000000000079
+:100d80000000000000000000000000000000000063
+:100d90000000000000000000000000000000000053
+:100da0000000000000000000000000000000000043
+:100db0000000000000000000000000000000000033
+:100dc0000000000000000000000000000000000023
+:100dd000000000000000000003070d3b276e5ca828
+:100de000c888977cd090101090d03c97d8e8b8cca9
+:100df00067371b0d07010000000000000000000025
+:100e000000000000000000000000000000000000e2
+:100e100000000000000000000000000000000000d2
+:100e200000000000000000000000000000c0c04002
+:100e30004040c0c08000c000c0c0c0c08080c000b2
+:100e400080c0c0c0c0000000000000c0c0c0c0c062
+:100e500000000000c0c0c0c0c0c0c080000080c092
+:100e6000c0c1c1c1810303c383030101010000802c
+:100e7000c00000000000c0c0404040c0c080000072
+:100e8000c0c000000080c00000c0c0c0c08080c0e2
+:100e90000080c0c0c0c00000000080c0c0c0c00052
+:100ea000000000000000000000000000003f3f269e
+:100eb0002226361f0f003f0000003f3f00000000c9
+:100ec00033333434343c18000000003f3d04040444
+:100ed000040404003f3f060e1e1e362700061f3086
+:100ee000303030301f06003f030f1c38381c0f0312
+:100ef0003f00000000003f3f262226361f0f000063
+:100f00000001033e03010000000000003f0000005c
+:100f1000001f1f3434343434340033333434343c1d
+:100f200018000000000000000000000000000000a9
+:100f300000000000000000000000000000000000b1
+:100f400000000000000000000000000000000000a1
+:100f50000000000080808000e0f0f81818b0a000c9
+:100f6000e0f0f818f8f0e000f8f8f810f8f8f018e9
+:100f7000f8f8f00000000000000000000000000091
+:100f80000000000000000000000000000000000061
+:100f90000000000000000000000000000000000051
+:100fa0000000000000000000000000000000000041
+:100fb0000000000000000000000000000000000031
+:100fc0000000000000000000000000000000000021
+:100fd00000000000030303000001030303010000fd
+:100fe00000010303030100000303030003030300e4
+:100ff00003030300000000000000000000000000e8
+:1010000000000000000000000000000000000000e0
+:1010100000000000000000000000000000000000d0
+:1010200000000000000000000000000000000000c0
+:1010300000000000000000000000000000000000b0
+:1010400000000000000000000000000000000000a0
+:101050000000000000000000000000000000000090
+:101060000000000000000000000000000000000080
+:101070000000000000000000000000000000000070
+:101080000000000000000000000000000000000060
+:101090000000000000000000000000000000000050
+:1010a0000000000000000000000000000000000040
+:1010b0000000000000000000000000000000000030
+:1010c0000000000000000000000000000000000020
+:1010d0000000000000000000000000000000000010
+:1010e0000000000000000000000000000000000000
+:1010f00000000000000000000000000000000000f0
+:1011000000000000000000000000000000000000df
+:1011100000000000000000000000000000000000cf
+:1011200000000000000000000000000080402020bf
+:1011300040800000000000000000000000000000ef
+:10114000000000000000000000000000000000009f
+:10115000000000000000000000000000000000008f
+:10116000000000000000000000000000000000007f
+:10117000000000000000000000000000000000006f
+:10118000000000000000000000000000000000005f
+:10119000000000000000000000000000000000004f
+:1011a00000000000000000000000fc0300c0c0c000
+:1011b000c00003fc00000000000000000000000070
+:1011c00000000000000000000000020502003c4298
+:1011d0008181816600000000000000000000000026
+:1011e00000000000000000000000000000000000ff
+:1011f00000000000000000000000000000000000ef
+:1012000000008040201010080808040404040408aa
+:1012100008081010204080000000000000000000be
+:1012200000000000000000000000ff0000ffffffc2
+:10123000ff0000ff000000000000000000000000b0
+:10124000000000000000000000000000000080809e
+:10125000808000000000000000000000000000008e
+:10126000000000000000000000000000000000007e
+:10127000800000008000000000000000000000006e
+:10128000f00e010000000000000080e0e0e000003f
+:10129000000000000000010ef0000000000000004f
+:1012a00000000000000000000000ff0000ffffff42
+:1012b000ff0000ff00000000000000000000000030
+:1012c00000000000000000000000000000007f049b
+:1012d000040000324a4a7c007e04027c00000000c8
+:1012e00000000000000000000000000000000003fb
+:1012f00004631c3348300000000000f00808f000d0
+:10130000010e3040880404020101000000000000ca
+:10131000000000008040300e01e010902000e0103e
+:1013200010e000000000000080c0fff0f8ffffffa9
+:10133000fff8f0ffc0800000000000000000000087
+:10134000000000000000000000000000000000009d
+:10135000000000000000000000000000000000008d
+:10136000000000000000000000000000000000007d
+:10137000000000000000000000000003040403005f
+:10138000000000000001010202020404040404023f
+:101390000202010100000000000709080700070819
+:1013a0000807000000000000ffffffffffffffff36
+:1013b000ffff7f3f1f0f0000000000000000000043
+:1013c000000000000000000000020502003c428115
+:1013d00081816600000000000000000000000000a5
+:1013e00000000000000000000000000000000000fd
+:1013f00000000000000000000000000000ff0919cc
+:10140000294680ff1111110e00ff0678807806ff33
+:1014100000000000000000000000000000000000cc
+:101420000000000000000000000000000000005f5d
+:1014300000000003000300143e143e14242a7f2af7
+:1014400012433308666136495522500005030000f7
+:10145000001c2241000041221c0014083e08140810
+:10146000083e08080050300000080808080800601e
+:1014700060000020100804023e5149453e04027fee
+:101480000000426151494622414949361814127ff1
+:101490001027454545393e4949493201017109073f
+:1014a0003649494936264949493e0036360000004a
+:1014b000563600000814224100141414141400417c
+:1014c00022140802015109063e4159555e7e090960
+:1014d000097e7f494949363e414141227f41414190
+:1014e0003e7f494949417f090909013e4141493a45
+:1014f0007f0808087f00417f4100304040403f7f27
+:10150000081422417f404040407f020c027f7f024e
+:1015100004087f3e4141413e7f090909061e212101
+:10152000215e7f0909097600264949493201017f78
+:1015300001013f4040403f1f2040201f7f201020de
+:101540007f41221c22410708700807615149454329
+:10155000007f410000020408102004020102044040
+:1015600040404040000102040020545454787f441d
+:101570004444383844444444384444447f38545400
+:10158000541804047e0505085454543c7f08040490
+:101590007800447d40002040443d007f10284400f6
+:1015a00000417f40007c047804787c08040478388b
+:1015b000444444387c14141408081414147c007c2b
+:1015c000080404485454542004043f44443c40401c
+:1015d000207c1c2040201c3c4030403c44281028eb
+:1015e000440c5050503c4464544c44000836414133
+:1015f00000007f00004141360800020102040200a1
+:10160000000000005261704d616e2076312e302e48
+:10161000382d4572696b0000472d436f6465204c7f
+:10162000696e653a0000000048656164205370658a
+:1016300065643a004578742e20526174653a000062
+:101640002531750025352e31666d6d2f7300000034
+:101650004e6f74205365740000007042000000005b
+:1016600079e9263108acac3f4578747275646572cf
+:1016700020436f6e74726f6c0000000048656174e7
+:101680006572204f6e200000486561746572204fbe
+:1016900066660000203c31303043204d6f746f721d
+:1016a000204f4646000000000000c84254454d50ff
+:1016b00045524154555245204552524f5200000068
+:1016c000544845524d4953544f52204552524f525f
+:1016d0000000000025337543000000002a000000d0
+:1016e0002000000000c07944000080bf25337552ff
+:1016f000504d00000000000084471b47acc5a73fc9
+:101700004d454e550000000052554e2046494c456f
+:10171000000000004d414e55414c204d4f564500b4
+:10172000544f4f4c2053455455500000484f4d45a1
+:1017300020544f4f4c204845414400004d414e55e8
+:10174000414c0000585f537465703a00595f537400
+:1017500065703a005a5f537465703a004155544fb2
+:101760003a204c6f6164696e672e2e00484f4d49d8
+:101770004e4720504c4541534520574149540000a5
+:101780004d4f564520544f3a00000000583d253635
+:101790002e326600593d25362e3266005a3d2536da
+:1017a0002e3266004e4f205a204d4f564500000005
+:1017b00050726f672e456e640000000052657475ac
+:1017c000726e20746f204d656e7500003c3c3c20ad
+:1017d0005072657373204573632e00003e00000055
+:1017e000202000009c5a019df454019dc455019d88
+:1017f0009456019d6457019d3458019d0459019de3
+:10180000d459019d000000005261704d616e207638
+:10181000312e302e382d4572696b0000496e73658c
+:1018200072742053442d43617264206f7200000073
+:101830003c3c45534320544f20524553554d4500a1
+:10184000496e76616c69642046696c6520547970d4
+:1018500065000000506c65617365206f6e6c7920c7
+:10186000757365002a2e424642206f72202a2e4749
+:10187000434f2046696c657300000000504155538a
+:10188000450000004572726f7220544553540000a9
+:101890004578747275646572204f464600000000fa
+:1018a00046696c65204572726f72203a7365656b8c
+:1018b00020707400556e6b6e6f776e204572726f7c
+:1018c00072000000203c45534320544f20524553a2
+:1018d000554d45003c000000000002430000c8c216
+:1018e000546f6f6c3a2050656e000000546f6f6c3f
+:1018f0003a2045787472756465720000546f6f6c9d
+:101900003a2045787472756465723200546f6f6c5a
+:101910003a204e6f7420446566696e65640000006d
+:10192000546f6f6c3a20526f75746572000000003e
+:10193000546f6f6c3a204e6f6e65000072000000ad
+:1019400046696c65204572726f722020202000006d
+:1019500046696c65204e6f7420466f756e6400009a
+:101960004f70656e000000002a2e2a0046696e64e2
+:10197000204669727374204572726f720000000015
+:101980004e6f2066696c6573206f6e2063617264b0
+:1019900000000000537769746368204f46462f4f5c
+:1019a0004e000000746f20526573657400000000e3
+:1019b00046696c6500000000253375006f66000005
+:1019c000000000440000fe420000fe420000000053
+:1019d00025362e32660000002db29defa7a64e40a0
+:1019e000000020455a20444f574e20202020200040
+:1019f0005920464f5257415244202000484f4d45f0
+:101a00002058202020200000484f4d4520592020fc
+:101a100020200000484f4d45205a20202020000063
+:101a2000484f4d452041424f52544544000000006c
+:101a3000484f4d4520434f4d504c45544500000004
+:101a40002db29defa7a64e4039b4c876be9ff63f93
+:101a50000000c842000000002db29defa7a64e4036
+:101a600000002045000000002db29defa7a64e40cb
+:101a700000808443000048c3000002430000c8c245
+:101a8000000000000000e03f000000000000e03f18
+:101a9000000000000000e0bf4cb6019d00b7019db2
+:101aa00094b6019ddcb7019d60b8019d0020202007
+:101ab00020202020202028282828282020202020fe
+:101ac00020202020202020202020202020801010d6
+:101ad000101010101010101010101010100404042a
+:101ae00004040404040404101010101010104141e8
+:101af00041414141010101010101010101010101d6
+:101b000001010101010101011010101010104242e9
+:101b100042424242020202020202020202020202a5
+:101b20000202020202020202101010102000000045
+:101b300000000000000000000000000000000000a5
+:101b40000000000000000000000000000000000095
+:101b50000000000000000000000000000000000085
+:101b60000000000000000000000000000000000075
+:101b70000000000000000000000000000000000065
+:101b80000000000000000000000000000000000055
+:101b90000000000000000000000000000000000045
+:101ba0000000000000000000000000000000000035
+:101bb0003030303030303030303030303030303025
+:101bc0003030303030303030303030303030303015
+:101bd0002020202020202020202020202020202005
+:101be00020202020202020202020202020202020f5
+:101bf00078c1019d24c5019da8d2019d24c5019de8
+:101c0000a8d2019da8d2019da8d2019da8d2019d74
+:101c1000a8d2019da8d2019da8d2019d9cc1019d81
+:101c2000e4c1019da8d2019da8d2019da8d2019d29
+:101c3000a8d2019db0c1019da8d2019da8d2019d4d
+:101c4000d4c1019da8d2019da8d2019da8d2019d19
+:101c5000a8d2019da8d2019da8d2019da8d2019d24
+:101c6000a8d2019da8d2019da8d2019df4d0019dca
+:101c700084c1019d24c5019d24c5019d24c5019dec
+:101c8000a8d2019d84c1019da8d2019da8d2019d29
+:101c9000a8d2019da8d2019dbcd1019da8c1019de2
+:101ca000f0c1019da8d2019da8d2019d30d1019d16
+:101cb000a8d2019dbcc1019da8d2019da8d2019dc1
+:101cc000fcc1019d00000000000000000000244055
+:101cd0000000000000001040000000000000008034
+:101ce0007b14ae47e17a843f2d431cebe2361a3f6a
+:101cf0004e614e002b496e66000000002d496e6655
+:101d000000000000286e756c6c29000038d3019d1e
+:101d100040d3019d48d3019d50d3019d58d3019dcf
+:101d200000000000000014400000000000003940e6
+:101d300000000000008883400000000084d71741a5
+:101d40000080e03779c34142176e05b5b5b89344ba
+:101d5000f5f93fe9034f3849321d30f9487782528f
+:101d60003cbf737fdd4f1565000000000000f03fb1
+:101d7000ffffffffffffff7f0000000000001000db
+:101d80000000000000000001ffffffffffff0f0049
+:101d9000ff0000003f0000000f00000003000000f3
+:101da000df000000370000000d000000020000000e
+:101db000bf0000002f0000000b0000000200000028
+:101dc0009f00000027000000090000000100000043
+:101dd0007f0000001f00000007000000010000005d
+:101de0005f00000017000000050000000000000078
+:101df0003f0000000f000000030000000000000092
+:101e00001f000000070000000100000000000000ab
+:020000040000fa
+:020000041d02db
+:101e10000c00000000000000010001041f0c1d0068
+:101e20000c0000001400000098fc019d7c040000e0
+:101e30000c00000000000000010001041f0c1d0048
+:101e40001c000000140000001401029d8c0400001e
+:101e5000440e185011107c11117d11127e000000eb
+:020000040000fa
+:020000041d02db
+:101e600000000000ffffffff000000000000000076
+:101e70000000000000000000000000000000000062
+:101e8000840000a0a00000a0bc0000a0800000a072
+:101e90007c0300a001000000000000000000000022
+:101ea0000000000000000000000000000000000032
+:101eb0000000000000000000000000000000000022
+:101ec0000000000000000000000000000000000012
+:101ed0000000000000000000000000000000000002
+:101ee00000000000ffffffffffffffff00000000fa
+:101ef000000400000910000000000000981a029d74
+:101f0000ffffffff000000000000000000040000d1
+:101f10000a10010000000000981a029dffffffff59
+:101f200000000000000000000000000002000200ad
+:101f300000000000981a029dfdffffff0000000056
+:101f40000000000000000000000000000000000091
+:041f5000000000008d
+:020000040000fa
+:020000041d02db
+:101f540090010000f5ff000001000000ffff0000f9
+:101f6400ffffffff9c0600a0010000001e00000010
+:0c1f7400ffff000001000000200000a0a2
+:00000001FF
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.map b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.map new file mode 100644 index 00000000..327a10b2 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.map @@ -0,0 +1,2008 @@ +Archive member included because of file (symbol)
+
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memcpy.o)
+ OLED.o (memcpy)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memset.o)
+ FSIO.o (memset)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strcpy.o)
+ FSIO.o (strcpy)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strlen.o)
+ FSIO.o (strlen)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(general-exception.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (_general_exception_context)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ FSIO.o (strncpy)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ FSIO.o (strchr)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (exit)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ FSIO.o (tolower)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ RapMan.o (atof)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ RapMan.o (atoi)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o) (strtol)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o) (strtod)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o) (_libc_data)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o) (_filbuf_simple)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ OLED.o (sprintf)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o) (pthread_mutex_lock)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(general-exception.o) (_general_exception_handler)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (_bootstrap_exception_handler)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (_on_reset)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (_on_bootstrap)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-nmi-handler.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (_nmi_handler)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o) (_mon_getc)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o) (_mon_write)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o) (_exit)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctype.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o) (_ctype)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(errno.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o) (errno)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o) (vfprintf)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o) (_io_strfuncs)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o) (fputc)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o) (_mon_putc)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(mod32.o)
+ Stepper.o (modf)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(ceil32.o)
+ G_Code.o (ceil)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(dp32.o)
+ Extruder.o (dpsub)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(fp32.o)
+ Extruder.o (fpsub)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o) (__strtod)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o) (__ldexp)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ SD-SPI.o (getcSPI2)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ SD-SPI.o (OpenSPI2)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ Extruder.o (INTDisableInterrupts)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ Extruder.o (INTEnableSystemMultiVectoredInt)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ Extruder.o (INTRestoreInterrupts)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_brg_tbl_lib.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o) (SpiBrgConvTbl)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o) (INTEnableInterrupts)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_udivdi3.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o) (__udivdi3)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_umoddi3.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o) (__umoddi3)
+
+Allocating common symbols
+Common symbol size file
+
+fDim_1 0x4 RapMan.o
+LineBuffer 0x32 RapMan.o
+S_F_Code 0x4 Extruder.o
+Dim_4 0x8 RapMan.o
+LowValue 0x4 Extruder.o
+SBReady 0x4 Stepper.o
+M_Code 0x4 G_Code.o
+gDataBuffer 0x200 FSIO.o
+SCB 0x800 Stepper.o
+X_Rest_mm 0x4 RapMan.o
+Fraction 0x4 Extruder.o
+G_Code 0x4 G_Code.o
+iInst_Code 0x4 RapMan.o
+temperature1 0x4 Extruder.o
+Reverse_Steps 0x4 Extruder.o
+gFileSlotOpen 0x3 FSIO.o
+FilePointer 0x4 RapMan.o
+gTimeCrtMS 0x1 FSIO.o
+MDD_SDSPI_finalLBA 0x4 SD-SPI.o
+lX_Steps 0x4 Stepper.o
+Inst_Code 0x8 RapMan.o
+GY 0x4 G_Code.o
+lSaveSteps_X 0x4 Stepper.o
+cwd 0x3c FSIO.o
+defaultString 0xd FSIO.o
+tempCWDobj 0x3c FSIO.o
+fDim_4 0x4 RapMan.o
+fDim_2 0x4 RapMan.o
+FeedRate_ManualChange
+ 0x1 Extruder.o
+SaveFileSize 0x4 RapMan.o
+lHomeStepsX 0x4 Stepper.o
+lSaveSteps_Z 0x4 Stepper.o
+Delta_Z 0x4 Stepper.o
+StepReady 0x4 Extruder.o
+FastMoveMotorEnable
+ 0x1 Extruder.o
+Delta_Y 0x4 Stepper.o
+Message 0x14 Extruder.o
+GI_Val 0x4 G_Code.o
+GJ_Val 0x4 G_Code.o
+gFATBuffer 0x200 FSIO.o
+SBR 0x4 Stepper.o
+gTimeCrtTime 0x2 FSIO.o
+gFileArray 0xb4 FSIO.o
+FatRootDirClusterValue
+ 0x4 FSIO.o
+GZ 0x4 G_Code.o
+SBCode 0x4 Stepper.o
+G_CodeRapidZMove 0x4 Extruder.o
+gDiskData 0x20 FSIO.o
+lHomeStepsY 0x4 Stepper.o
+Y_Steps 0x4 Stepper.o
+gTimeWrtDate 0x2 FSIO.o
+Inst_Code_Letter 0x1 RapMan.o
+Dim_4_Letter 0x1 RapMan.o
+Ops_mode 0x4 RapMan.o
+pointer 0x4 RapMan.o
+Y_Rest_mm 0x4 RapMan.o
+Dim_2_Letter 0x1 RapMan.o
+lZ_Steps 0x4 Stepper.o
+ManualChange 0x4 RapMan.o
+EnableFanControl 0x1 Extruder.o
+G_CodeRapidXYMove 0x4 Extruder.o
+Dim_2 0x8 RapMan.o
+lHomeStepsZ 0x4 Stepper.o
+X_Steps 0x4 Stepper.o
+Dim_3_Letter 0x1 RapMan.o
+ExtruderStatus 0x1 RapMan.o
+Set_Y_Dir 0x4 Stepper.o
+gTimeCrtDate 0x2 FSIO.o
+Z_Rest_mm 0x4 RapMan.o
+Ex_Reverse 0x4 Extruder.o
+Change_M104 0x1 Extruder.o
+lSaveSteps_Y 0x4 Stepper.o
+SBW 0x4 Stepper.o
+GP_Val 0x4 G_Code.o
+Set_Z_Dir 0x4 Stepper.o
+S_M_Code 0x4 Stepper.o
+SBuf 0x1 Stepper.o
+TempClusterCalc 0x4 FSIO.o
+GS_Val 0x4 G_Code.o
+Delta_X 0x4 Stepper.o
+lY_Steps 0x4 Stepper.o
+dirCleared 0x1 FSIO.o
+RPM_Change 0x1 Extruder.o
+gFileTemp 0x3c FSIO.o
+GX 0x4 G_Code.o
+Feed_Rate 0x4 Extruder.o
+Dim_3 0x8 RapMan.o
+CharBuffer 0x1 RapMan.o
+defaultArray 0xa FSIO.o
+Range 0x4 Extruder.o
+Dim_1_Letter 0x1 RapMan.o
+Prime_Steps 0x4 Extruder.o
+Reverse_Step_Count 0x4 Extruder.o
+fDim_3 0x4 RapMan.o
+Set_X_Dir 0x4 Stepper.o
+DataVal 0x4 Extruder.o
+PauseFlag 0x1 RapMan.o
+HighValue 0x4 Extruder.o
+raw_temperature 0x4 Extruder.o
+Dim_1 0x8 RapMan.o
+TempVal 0x4 Extruder.o
+ExtrusionRate 0x4 OLED.o
+Temp_Change 0x1 Extruder.o
+gTimeAccDate 0x2 FSIO.o
+Prime_Step_Count 0x4 Extruder.o
+FSerrno 0x1 FSIO.o
+SaveFileName 0xc RapMan.o
+Z_Steps 0x4 Stepper.o
+gTimeWrtTime 0x2 FSIO.o
+
+Microchip PIC32 Memory-Usage Report
+
+kseg0 Program-Memory Usage
+section address length [bytes] (dec) Description
+------- ---------- ------------------------- -----------
+.text 0x9d006a00 0x19ba0 105376 Application's executable code
+.rodata 0x9d0205a0 0x1870 6256 Read-only constant data
+.eh_frame 0x9d021e10 0x50 80 Stack unwind info
+.data 0x9d021e60 0xf4 244 Data-initialization template
+.sdata 0x9d021f54 0x2c 44 Small data-initialization template
+ Total kseg0_program_mem used : 0x1b580 112000 22.3% of 0x7a600
+
+kseg0 Boot-Memory Usage
+section address length [bytes] (dec) Description
+------- ---------- ------------------------- -----------
+.startup 0x9d006490 0x1e0 480 C startup code
+ Total kseg0_boot_mem used : 0x1e0 480 19.9% of 0x970
+
+Exception-Memory Usage
+section address length [bytes] (dec) Description
+------- ---------- ------------------------- -----------
+.app_excpt 0x9d005180 0x10 16 General-Exception handler
+.vector_8 0x9d005300 0x8 8 Interrupt Vector 8
+.vector_12 0x9d005380 0x8 8 Interrupt Vector 12
+.vector_16 0x9d005400 0x8 8 Interrupt Vector 16
+ Total exception_mem used : 0x28 40 1.0% of 0x1000
+
+kseg1 Boot-Memory Usage
+section address length [bytes] (dec) Description
+------- ---------- ------------------------- -----------
+.reset 0x9d006000 0x10 16 Reset handler
+.bev_excpt 0x9d006380 0x10 16 BEV-Exception handler
+ Total kseg1_boot_mem used : 0x20 32 2.7% of 0x490
+ --------------------------------------------------------------------------
+ Total Program Memory used : 0x1b7a8 112552 22.1% of 0x7c400
+ --------------------------------------------------------------------------
+
+
+kseg1 Data-Memory Usage
+section address length [bytes] (dec) Description
+------- ---------- ------------------------- -----------
+.data 0xa0000000 0xf4 244 Initialized data
+.sdata 0xa00000f4 0x2c 44 Small initialized data
+.sbss 0xa0000120 0x25c 604 Small uninitialized data
+.bss 0xa000037c 0xf04 3844 Uninitialized data
+.stack 0xa0001280 0x400 1024 Minimum space reserved for stack
+ Total kseg1_data_mem used : 0x1680 5760 17.6% of 0x8000
+ --------------------------------------------------------------------------
+ Total Data Memory used : 0x1680 5760 17.6% of 0x8000
+ --------------------------------------------------------------------------
+
+Memory Configuration
+
+Name Origin Length Attributes
+kseg0_program_mem 0x9d006a00 0x0007a600 xr
+kseg0_boot_mem 0x9d006490 0x00000970
+exception_mem 0x9d005000 0x00001000
+kseg1_boot_mem 0x9d006000 0x00000490
+debug_exec_mem 0xbfc02000 0x00000ff0
+config3 0xbfc02ff0 0x00000004
+config2 0xbfc02ff4 0x00000004
+config1 0xbfc02ff8 0x00000004
+config0 0xbfc02ffc 0x00000004
+kseg1_data_mem 0xa0000000 0x00008000 w !x
+sfrs 0xbf800000 0x00100000
+*default* 0x00000000 0xffffffff
+
+Linker script and memory map
+
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+LOAD Extruder.o
+LOAD FSIO.o
+LOAD SD-SPI.o
+LOAD G_Code.o
+LOAD OLED.o
+LOAD RapMan.o
+LOAD Stepper.o
+ 0x00000001 __MPLAB_BUILD = 0x1
+ 0x00000001 __MPLAB_DEBUG = 0x1
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a
+START GROUP
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libdsp.a
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral_32MX440F256H.a
+END GROUP
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a
+ 0x00000400 PROVIDE (_min_stack_size, 0x400)
+ 0x00000000 PROVIDE (_min_heap_size, 0x0)
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/./proc/32MX440F256H\processor.o
+ 0x00000001 PROVIDE (_vector_spacing, 0x1)
+ 0x9d005000 _ebase_address = 0x9d005000
+ 0x9d006000 _RESET_ADDR = 0x9d006000
+ 0x9d006380 _BEV_EXCPT_ADDR = 0x9d006380
+ 0x9d006480 _DBG_EXCPT_ADDR = 0x9d006480
+ 0xbfc02000 _DBG_CODE_ADDR = 0xbfc02000
+ 0x9d005180 _GEN_EXCPT_ADDR = (_ebase_address + 0x180)
+
+.config_BFC02FF0
+ *(.config_BFC02FF0)
+
+.config_BFC02FF4
+ 0xbfc02ff4 0x4
+ *(.config_BFC02FF4)
+ .config_BFC02FF4
+ 0xbfc02ff4 0x4 RapMan.o
+
+.config_BFC02FF8
+ 0xbfc02ff8 0x4
+ *(.config_BFC02FF8)
+ .config_BFC02FF8
+ 0xbfc02ff8 0x4 RapMan.o
+
+.config_BFC02FFC
+ 0xbfc02ffc 0x4
+ *(.config_BFC02FFC)
+ .config_BFC02FFC
+ 0xbfc02ffc 0x4 RapMan.o
+
+.reset 0x9d006000 0x10
+ *(.reset)
+ .reset 0x9d006000 0x10 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+ 0x9d006000 _reset
+
+.bev_excpt 0x9d006380 0x10
+ *(.bev_handler)
+ .bev_handler 0x9d006380 0x10 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+
+.dbg_excpt 0x9d006480 0x0
+ 0x9d006480 . = (. + DEFINED (_DEBUGGER)?0x8:0x0)
+
+.dbg_code 0xbfc02000 0x0
+ 0xbfc02000 . = (. + DEFINED (_DEBUGGER)?0xff0:0x0)
+
+.app_excpt 0x9d005180 0x10
+ *(.gen_handler)
+ .gen_handler 0x9d005180 0x10 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+
+.vector_0 0x9d005200 0x0
+ *(.vector_0)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_0) <= (_vector_spacing << 0x5))), function at exception vector 0 too large)
+
+.vector_1 0x9d005220 0x0
+ *(.vector_1)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_1) <= (_vector_spacing << 0x5))), function at exception vector 1 too large)
+
+.vector_2 0x9d005240 0x0
+ *(.vector_2)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_2) <= (_vector_spacing << 0x5))), function at exception vector 2 too large)
+
+.vector_3 0x9d005260 0x0
+ *(.vector_3)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_3) <= (_vector_spacing << 0x5))), function at exception vector 3 too large)
+
+.vector_4 0x9d005280 0x0
+ *(.vector_4)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_4) <= (_vector_spacing << 0x5))), function at exception vector 4 too large)
+
+.vector_5 0x9d0052a0 0x0
+ *(.vector_5)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_5) <= (_vector_spacing << 0x5))), function at exception vector 5 too large)
+
+.vector_6 0x9d0052c0 0x0
+ *(.vector_6)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_6) <= (_vector_spacing << 0x5))), function at exception vector 6 too large)
+
+.vector_7 0x9d0052e0 0x0
+ *(.vector_7)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_7) <= (_vector_spacing << 0x5))), function at exception vector 7 too large)
+
+.vector_8 0x9d005300 0x8
+ *(.vector_8)
+ .vector_8 0x9d005300 0x8 Extruder.o
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_8) <= (_vector_spacing << 0x5))), function at exception vector 8 too large)
+
+.vector_9 0x9d005320 0x0
+ *(.vector_9)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_9) <= (_vector_spacing << 0x5))), function at exception vector 9 too large)
+
+.vector_10 0x9d005340 0x0
+ *(.vector_10)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_10) <= (_vector_spacing << 0x5))), function at exception vector 10 too large)
+
+.vector_11 0x9d005360 0x0
+ *(.vector_11)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_11) <= (_vector_spacing << 0x5))), function at exception vector 11 too large)
+
+.vector_12 0x9d005380 0x8
+ *(.vector_12)
+ .vector_12 0x9d005380 0x8 Extruder.o
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_12) <= (_vector_spacing << 0x5))), function at exception vector 12 too large)
+
+.vector_13 0x9d0053a0 0x0
+ *(.vector_13)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_13) <= (_vector_spacing << 0x5))), function at exception vector 13 too large)
+
+.vector_14 0x9d0053c0 0x0
+ *(.vector_14)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_14) <= (_vector_spacing << 0x5))), function at exception vector 14 too large)
+
+.vector_15 0x9d0053e0 0x0
+ *(.vector_15)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_15) <= (_vector_spacing << 0x5))), function at exception vector 15 too large)
+
+.vector_16 0x9d005400 0x8
+ *(.vector_16)
+ .vector_16 0x9d005400 0x8 Stepper.o
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_16) <= (_vector_spacing << 0x5))), function at exception vector 16 too large)
+
+.vector_17 0x9d005420 0x0
+ *(.vector_17)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_17) <= (_vector_spacing << 0x5))), function at exception vector 17 too large)
+
+.vector_18 0x9d005440 0x0
+ *(.vector_18)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_18) <= (_vector_spacing << 0x5))), function at exception vector 18 too large)
+
+.vector_19 0x9d005460 0x0
+ *(.vector_19)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_19) <= (_vector_spacing << 0x5))), function at exception vector 19 too large)
+
+.vector_20 0x9d005480 0x0
+ *(.vector_20)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_20) <= (_vector_spacing << 0x5))), function at exception vector 20 too large)
+
+.vector_21 0x9d0054a0 0x0
+ *(.vector_21)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_21) <= (_vector_spacing << 0x5))), function at exception vector 21 too large)
+
+.vector_22 0x9d0054c0 0x0
+ *(.vector_22)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_22) <= (_vector_spacing << 0x5))), function at exception vector 22 too large)
+
+.vector_23 0x9d0054e0 0x0
+ *(.vector_23)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_23) <= (_vector_spacing << 0x5))), function at exception vector 23 too large)
+
+.vector_24 0x9d005500 0x0
+ *(.vector_24)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_24) <= (_vector_spacing << 0x5))), function at exception vector 24 too large)
+
+.vector_25 0x9d005520 0x0
+ *(.vector_25)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_25) <= (_vector_spacing << 0x5))), function at exception vector 25 too large)
+
+.vector_26 0x9d005540 0x0
+ *(.vector_26)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_26) <= (_vector_spacing << 0x5))), function at exception vector 26 too large)
+
+.vector_27 0x9d005560 0x0
+ *(.vector_27)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_27) <= (_vector_spacing << 0x5))), function at exception vector 27 too large)
+
+.vector_28 0x9d005580 0x0
+ *(.vector_28)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_28) <= (_vector_spacing << 0x5))), function at exception vector 28 too large)
+
+.vector_29 0x9d0055a0 0x0
+ *(.vector_29)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_29) <= (_vector_spacing << 0x5))), function at exception vector 29 too large)
+
+.vector_30 0x9d0055c0 0x0
+ *(.vector_30)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_30) <= (_vector_spacing << 0x5))), function at exception vector 30 too large)
+
+.vector_31 0x9d0055e0 0x0
+ *(.vector_31)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_31) <= (_vector_spacing << 0x5))), function at exception vector 31 too large)
+
+.vector_32 0x9d005600 0x0
+ *(.vector_32)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_32) <= (_vector_spacing << 0x5))), function at exception vector 32 too large)
+
+.vector_33 0x9d005620 0x0
+ *(.vector_33)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_33) <= (_vector_spacing << 0x5))), function at exception vector 33 too large)
+
+.vector_34 0x9d005640 0x0
+ *(.vector_34)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_34) <= (_vector_spacing << 0x5))), function at exception vector 34 too large)
+
+.vector_35 0x9d005660 0x0
+ *(.vector_35)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_35) <= (_vector_spacing << 0x5))), function at exception vector 35 too large)
+
+.vector_36 0x9d005680 0x0
+ *(.vector_36)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_36) <= (_vector_spacing << 0x5))), function at exception vector 36 too large)
+
+.vector_37 0x9d0056a0 0x0
+ *(.vector_37)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_37) <= (_vector_spacing << 0x5))), function at exception vector 37 too large)
+
+.vector_38 0x9d0056c0 0x0
+ *(.vector_38)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_38) <= (_vector_spacing << 0x5))), function at exception vector 38 too large)
+
+.vector_39 0x9d0056e0 0x0
+ *(.vector_39)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_39) <= (_vector_spacing << 0x5))), function at exception vector 39 too large)
+
+.vector_40 0x9d005700 0x0
+ *(.vector_40)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_40) <= (_vector_spacing << 0x5))), function at exception vector 40 too large)
+
+.vector_41 0x9d005720 0x0
+ *(.vector_41)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_41) <= (_vector_spacing << 0x5))), function at exception vector 41 too large)
+
+.vector_42 0x9d005740 0x0
+ *(.vector_42)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_42) <= (_vector_spacing << 0x5))), function at exception vector 42 too large)
+
+.vector_43 0x9d005760 0x0
+ *(.vector_43)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_43) <= (_vector_spacing << 0x5))), function at exception vector 43 too large)
+
+.vector_44 0x9d005780 0x0
+ *(.vector_44)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_44) <= (_vector_spacing << 0x5))), function at exception vector 44 too large)
+
+.vector_45 0x9d0057a0 0x0
+ *(.vector_45)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_45) <= (_vector_spacing << 0x5))), function at exception vector 45 too large)
+
+.vector_46 0x9d0057c0 0x0
+ *(.vector_46)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_46) <= (_vector_spacing << 0x5))), function at exception vector 46 too large)
+
+.vector_47 0x9d0057e0 0x0
+ *(.vector_47)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_47) <= (_vector_spacing << 0x5))), function at exception vector 47 too large)
+
+.vector_48 0x9d005800 0x0
+ *(.vector_48)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_48) <= (_vector_spacing << 0x5))), function at exception vector 48 too large)
+
+.vector_49 0x9d005820 0x0
+ *(.vector_49)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_49) <= (_vector_spacing << 0x5))), function at exception vector 49 too large)
+
+.vector_50 0x9d005840 0x0
+ *(.vector_50)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_50) <= (_vector_spacing << 0x5))), function at exception vector 50 too large)
+
+.vector_51 0x9d005860 0x0
+ *(.vector_51)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_51) <= (_vector_spacing << 0x5))), function at exception vector 51 too large)
+
+.vector_52 0x9d005880 0x0
+ *(.vector_52)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_52) <= (_vector_spacing << 0x5))), function at exception vector 52 too large)
+
+.vector_53 0x9d0058a0 0x0
+ *(.vector_53)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_53) <= (_vector_spacing << 0x5))), function at exception vector 53 too large)
+
+.vector_54 0x9d0058c0 0x0
+ *(.vector_54)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_54) <= (_vector_spacing << 0x5))), function at exception vector 54 too large)
+
+.vector_55 0x9d0058e0 0x0
+ *(.vector_55)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_55) <= (_vector_spacing << 0x5))), function at exception vector 55 too large)
+
+.vector_56 0x9d005900 0x0
+ *(.vector_56)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_56) <= (_vector_spacing << 0x5))), function at exception vector 56 too large)
+
+.vector_57 0x9d005920 0x0
+ *(.vector_57)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_57) <= (_vector_spacing << 0x5))), function at exception vector 57 too large)
+
+.vector_58 0x9d005940 0x0
+ *(.vector_58)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_58) <= (_vector_spacing << 0x5))), function at exception vector 58 too large)
+
+.vector_59 0x9d005960 0x0
+ *(.vector_59)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_59) <= (_vector_spacing << 0x5))), function at exception vector 59 too large)
+
+.vector_60 0x9d005980 0x0
+ *(.vector_60)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_60) <= (_vector_spacing << 0x5))), function at exception vector 60 too large)
+
+.vector_61 0x9d0059a0 0x0
+ *(.vector_61)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_61) <= (_vector_spacing << 0x5))), function at exception vector 61 too large)
+
+.vector_62 0x9d0059c0 0x0
+ *(.vector_62)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_62) <= (_vector_spacing << 0x5))), function at exception vector 62 too large)
+
+.vector_63 0x9d0059e0 0x0
+ *(.vector_63)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_63) <= (_vector_spacing << 0x5))), function at exception vector 63 too large)
+
+.startup 0x9d006490 0x1e0
+ *(.startup)
+ .startup 0x9d006490 0x1e0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+
+.text 0x9d006a00 0x19ba0
+ 0x9d006a00 _text_begin = .
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ .text 0x9d006a00 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+ .text 0x9d006a18 0x1254 Extruder.o
+ 0x9d007520 Extruder_Status
+ 0x9d007668 InitExtruder
+ 0x9d006d2c T3InterruptHandler
+ 0x9d007b78 Extruder_Prime
+ 0x9d0078e8 Manual_Extruder
+ 0x9d006a18 T2InterruptHandler
+ 0x9d006fb4 Control_Temperature
+ 0x9d007ae0 Extruder_Reverse
+ 0x9d007478 Read_Analog
+ 0x9d006ea4 Control_Stepper_Motor
+ 0x9d007a34 delay_us
+ 0x9d0072b0 Thermistor_LookUp
+ 0x9d007a9c delay_ms
+ .text 0x9d007c6c 0xa6a4 FSIO.o
+ 0x9d00df3c ValidateChars
+ 0x9d00c818 FSftell
+ 0x9d00ca0c FSrewind
+ 0x9d00c848 FSremove
+ 0x9d00ca78 FSerror
+ 0x9d00adf4 FindEmptyEntries
+ 0x9d00ad1c CreateFirstCluster
+ 0x9d010e90 FSrmdir
+ 0x9d00b2f8 FILEallocate_new_cluster
+ 0x9d00cde8 ReadByte
+ 0x9d00f0b0 chdirhelper
+ 0x9d00ffe4 GetPreviousEntry
+ 0x9d00b060 PopulateEntries
+ 0x9d00b24c CacheTime
+ 0x9d00d6f8 FSfeof
+ 0x9d009070 GetFullClusterNumber
+ 0x9d00cb28 FILECreateHeadCluster
+ 0x9d00d738 FSfread
+ 0x9d00d048 FSattrib
+ 0x9d00f070 FSchdir
+ 0x9d00cca4 EraseCluster
+ 0x9d0119a4 eraseDir
+ 0x9d011f58 FindNext
+ 0x9d00e278 FSfseek
+ 0x9d00e630 ReadFAT
+ 0x9d010c58 writeDotEntries
+ 0x9d00b804 Fill_File_Object
+ 0x9d00b624 FSfclose
+ 0x9d00cea0 ReadDWord
+ 0x9d00c168 FSfopen
+ 0x9d00cf34 Cluster2Sector
+ 0x9d00eabc WriteFAT
+ 0x9d00ca9c FileObjectCopy
+ 0x9d00badc LoadDirAttrib
+ 0x9d00bc10 FILEerase
+ 0x9d00847c FILEget_next_cluster
+ 0x9d00a860 Cache_File_Entry
+ 0x9d00b458 FATfindEmptyCluster
+ 0x9d0109e4 CreateDIR
+ 0x9d00f85c FSgetcwd
+ 0x9d0085f0 DISKmount
+ 0x9d00ac18 CreateFileEntry
+ 0x9d00a4f8 Write_File_Entry
+ 0x9d00bdc0 FSrename
+ 0x9d009508 FSformat
+ 0x9d008acc LoadBootSector
+ 0x9d0081e8 FILEopen
+ 0x9d007db8 FILEfind
+ 0x9d00da84 FormatFileName
+ 0x9d011b1c FindFirst
+ 0x9d0090c8 FSCreateMBR
+ 0x9d010ee0 rmdirhelper
+ 0x9d00d648 flushData
+ 0x9d00ce24 ReadWord
+ 0x9d00d19c FSfwrite
+ 0x9d00dcfc FormatDirName
+ 0x9d0102ec FSmkdir
+ 0x9d0086b4 LoadMBR
+ 0x9d00a644 FAT_erase_cluster_chain
+ 0x9d01032c mkdirhelper
+ 0x9d007c6c FSInit
+ .text 0x9d012310 0xe30 SD-SPI.o
+ 0x9d01239c MDD_SDSPI_InitIO
+ 0x9d012378 MDD_SDSPI_ReadCapacity
+ 0x9d012c30 WriteSPIM
+ 0x9d012d94 MDD_SDSPI_MediaInitialize
+ 0x9d01296c MDD_SDSPI_SectorWrite
+ 0x9d012b54 MDD_SDSPI_WriteProtectState
+ 0x9d012c98 MDD_SDSPI_ReadMedia
+ 0x9d012310 MDD_SDSPI_MediaDetect
+ 0x9d012bfc CloseSPIM
+ 0x9d012b84 Delayms
+ 0x9d012354 MDD_SDSPI_ReadSectorSize
+ 0x9d012cf4 OpenSPIM
+ 0x9d01274c MDD_SDSPI_SectorRead
+ 0x9d012400 MDD_SDSPI_ShutdownMedia
+ 0x9d012444 SendMMCCmd
+ .text 0x9d013140 0x1174 G_Code.o
+ 0x9d014074 M_Code_M224
+ 0x9d013e90 M_Code_M107
+ 0x9d0139a8 G_Code_G0
+ 0x9d013a24 G_Code_G1
+ 0x9d0140c0 M_Code_M226
+ 0x9d013e58 M_Code_M106
+ 0x9d013be4 G_Code_G20
+ 0x9d013cdc M_Code_M101
+ 0x9d013b74 G_Code_G4
+ 0x9d01409c M_Code_M225
+ 0x9d013c84 G_Code_G91
+ 0x9d014280 M_Code_M228
+ 0x9d013140 G_CodeRun
+ 0x9d013f74 M_Code_M221
+ 0x9d013d48 M_Code_M104
+ 0x9d013fa4 M_Code_M222
+ 0x9d013c34 G_Code_G28
+ 0x9d013c0c G_Code_G21
+ 0x9d013abc G_Code_G2
+ 0x9d01400c M_Code_M223
+ 0x9d013c54 G_Code_G90
+ 0x9d0141a0 M_Code_M227
+ 0x9d013b18 G_Code_G3
+ 0x9d013d14 M_Code_M103
+ 0x9d013ec8 M_Code_M108
+ 0x9d013f40 M_Code_M220
+ 0x9d013ca4 G_Code_G92
+ .text 0x9d0142b4 0x1cd4 OLED.o
+ 0x9d0151bc OLED_Auto_Screen
+ 0x9d0152c8 OLED_RapManMove_Screen
+ 0x9d015b08 write_command
+ 0x9d015278 OLED_Home_Screen
+ 0x9d014d0c OLED_FastText57
+ 0x9d01497c OLED_Fill_RAM
+ 0x9d015cd4 OLED_Init
+ 0x9d015020 OLED_Start_Menu
+ 0x9d014378 OLED_UpdatePrintScreen
+ 0x9d015f18 OLED_Start_Msg
+ 0x9d014a3c OLED_ProgressBar
+ 0x9d014ba4 OLED_BitMapFill_RAM
+ 0x9d015ab4 WriteSPI
+ 0x9d015b90 write_data
+ 0x9d015228 OLED_ToolSetup_Screen
+ 0x9d014b10 OLED_ClearLine
+ 0x9d0147ec OLED_UpdateSetRPM
+ 0x9d0142b4 OLED_Printing_Screen
+ 0x9d01541c OLED_FileEnd_Screen
+ 0x9d01465c OLED_UpdateThermistorReading
+ 0x9d0154a4 OLED_SetCursor
+ 0x9d01453c OLED_Extruder_Screen
+ 0x9d015c14 Fill_RAM
+ 0x9d0150fc OLED_Manual_Screen
+ 0x9d014910 OLED_UpdateSetTemperature
+ .text 0x9d015f88 0x2328 RapMan.o
+ 0x9d0181e4 ShowPrintProgress
+ 0x9d016e04 GetMenuSelection
+ 0x9d0172a8 GetFileToOpen
+ 0x9d016088 Print_Gcode_File
+ 0x9d016fe4 RapMan_MoveTo
+ 0x9d017940 ReadData
+ 0x9d016db4 Start_Menu
+ 0x9d017140 OpenReadSDFile
+ 0x9d0177cc Get_file_Type
+ 0x9d0165e0 ErrorCondition
+ 0x9d017f24 FlushBuffer
+ 0x9d016b7c GetTool_ID
+ 0x9d0164c4 Pause_Print
+ 0x9d015f88 main
+ 0x9d01681c Setup
+ 0x9d017acc GetCodes
+ 0x9d018110 ShowBufferFillState
+ .text 0x9d0182b0 0x280c Stepper.o
+ 0x9d0187c8 RapMan_Home
+ 0x9d0186f4 Axis_Stepper_Motors
+ 0x9d018e98 GoToRest
+ 0x9d0197a4 Stepper_InitIO
+ 0x9d01a7d8 f_to_ul
+ 0x9d019d14 OriginOffset
+ 0x9d01a71c Stepper_SaveValues
+ 0x9d019e64 ResetOrigin
+ 0x9d0182b0 Manual_Mode
+ 0x9d0199b0 Stepper_LoadNewValues
+ 0x9d019b88 Stepper_CalcSteps
+ 0x9d019f74 Bresenham_3D_Line
+ 0x9d018fa8 T4Interrupt
+ 0x9d01a970 AddToStepBuffer
+ 0x9d01a894 f_to_sl
+ 0x9d019f1c Stepper_Run3DLine
+ .text 0x9d01aabc 0x168 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memcpy.o)
+ 0x9d01aabc memcpy
+ .text 0x9d01ac24 0xa8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memset.o)
+ 0x9d01ac24 memset
+ .text 0x9d01accc 0x1a0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strcpy.o)
+ 0x9d01accc strcpy
+ .text 0x9d01ae6c 0x168 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strlen.o)
+ 0x9d01ae6c strlen
+ .text.general_exception
+ 0x9d01afd4 0xd0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(general-exception.o)
+ 0x9d01afd4 _general_exception_context
+ .text.strncpy 0x9d01b0a4 0xd0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ 0x9d01b0a4 strncpy
+ .text.strchr 0x9d01b174 0x90 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ 0x9d01b174 strchr
+ .text.exit 0x9d01b204 0x9c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ 0x9d01b204 exit
+ .text.tolower 0x9d01b2a0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b2a0 tolower
+ .text.toupper 0x9d01b2c0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b2c0 toupper
+ .text.isalnum 0x9d01b2e0 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b2e0 isalnum
+ .text.isalpha 0x9d01b2f8 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b2f8 isalpha
+ .text.isascii 0x9d01b310 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b310 isascii
+ .text.iscntrl 0x9d01b318 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b318 iscntrl
+ .text.isdigit 0x9d01b330 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b330 isdigit
+ .text.isgraph 0x9d01b348 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b348 isgraph
+ .text.islower 0x9d01b360 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b360 islower
+ .text.isprint 0x9d01b378 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b378 isprint
+ .text.ispunct 0x9d01b390 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b390 ispunct
+ .text.isspace 0x9d01b3a8 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b3a8 isspace
+ .text.isupper 0x9d01b3c0 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b3c0 isupper
+ .text.isxdigit
+ 0x9d01b3d8 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b3d8 isxdigit
+ .text.toascii 0x9d01b3f0 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b3f0 toascii
+ .text._tolower
+ 0x9d01b3f8 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b3f8 _tolower
+ .text._toupper
+ 0x9d01b400 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b400 _toupper
+ .text.atof 0x9d01b408 0x1c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ 0x9d01b408 atof
+ .text.atoi 0x9d01b424 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ 0x9d01b424 atoi
+ .text.strtol 0x9d01b444 0x1ec C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ 0x9d01b444 strtol
+ .text.strtod 0x9d01b630 0x1c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ 0x9d01b630 strtod
+ .text._filbuf_simple
+ 0x9d01b64c 0x48 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0x9d01b64c _filbuf_simple
+ .text._fflush_simple
+ 0x9d01b694 0x6c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0x9d01b694 _fflush_simple
+ .text._flsbuf_simple
+ 0x9d01b700 0xdc C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0x9d01b700 _flsbuf_simple
+ .text._fwrite_simple
+ 0x9d01b7dc 0x84 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0x9d01b7dc _fwrite_simple
+ .text._fsync_simple
+ 0x9d01b860 0x34 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0x9d01b860 _fsync_simple
+ .text.__vsnprintf
+ 0x9d01b894 0x60 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ 0x9d01b894 __vsnprintf
+ .text.vsprintf
+ 0x9d01b8f4 0x2c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ 0x9d01b8f4 vsprintf
+ .text.sprintf 0x9d01b920 0x34 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ 0x9d01b920 sprintf
+ .text._weak_pthread_mutex_init
+ 0x9d01b954 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b954 _weak_pthread_mutex_init
+ 0x9d01b954 pthread_mutex_init
+ .text._weak_pthread_mutex_destroy
+ 0x9d01b95c 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b95c _weak_pthread_mutex_destroy
+ 0x9d01b95c pthread_mutex_destroy
+ .text._weak_pthread_mutex_lock
+ 0x9d01b964 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b964 _weak_pthread_mutex_lock
+ 0x9d01b964 pthread_mutex_lock
+ .text._weak_pthread_mutex_trylock
+ 0x9d01b96c 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b96c _weak_pthread_mutex_trylock
+ 0x9d01b96c pthread_mutex_trylock
+ .text._weak_pthread_mutex_unlock
+ 0x9d01b974 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b974 _weak_pthread_mutex_unlock
+ 0x9d01b974 pthread_mutex_unlock
+ .text._weak_pthread_mutex_setname_np
+ 0x9d01b97c 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b97c pthread_mutex_setname_np
+ 0x9d01b97c _weak_pthread_mutex_setname_np
+ .text._weak_pthread_mutexattr_init
+ 0x9d01b984 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b984 _weak_pthread_mutexattr_init
+ 0x9d01b984 pthread_mutexattr_init
+ .text._weak_pthread_mutexattr_destroy
+ 0x9d01b98c 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b98c pthread_mutexattr_destroy
+ 0x9d01b98c _weak_pthread_mutexattr_destroy
+ .text._weak_pthread_mutexattr_setname_np
+ 0x9d01b994 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b994 _weak_pthread_mutexattr_setname_np
+ 0x9d01b994 pthread_mutexattr_setname_np
+ .text._weak_pthread_mutexattr_settype_np
+ 0x9d01b99c 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b99c _weak_pthread_mutexattr_settype_np
+ 0x9d01b99c pthread_mutexattr_settype_np
+ .text._weak_pthread_sysconf_np
+ 0x9d01b9a4 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9a4 _weak_pthread_sysconf_np
+ 0x9d01b9a4 pthread_sysconf_np
+ .text._weak_pthread_sigdisable_np
+ 0x9d01b9ac 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9ac _weak_pthread_sigdisable_np
+ 0x9d01b9ac pthread_sigdisable_np
+ .text._weak_pthread_sigrestore_np
+ 0x9d01b9b4 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9b4 pthread_sigrestore_np
+ 0x9d01b9b4 _weak_pthread_sigrestore_np
+ .text._weak__pthread_cleanup_push
+ 0x9d01b9bc 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9bc _weak__pthread_cleanup_push
+ 0x9d01b9bc _pthread_cleanup_push
+ .text._weak__pthread_cleanup_pop
+ 0x9d01b9c4 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9c4 _pthread_cleanup_pop
+ 0x9d01b9c4 _weak__pthread_cleanup_pop
+ .text._weak__pthread_cleanup_push_defer
+ 0x9d01b9cc 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9cc _weak__pthread_cleanup_push_defer
+ 0x9d01b9cc _pthread_cleanup_push_defer
+ .text._weak__pthread_cleanup_pop_restore
+ 0x9d01b9d4 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9d4 _pthread_cleanup_pop_restore
+ 0x9d01b9d4 _weak__pthread_cleanup_pop_restore
+ .text._weak_pthread_once
+ 0x9d01b9dc 0x2c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9dc _weak_pthread_once
+ 0x9d01b9dc pthread_once
+ 0x9d01b9dc _pthread_once
+ .text._weak_pthread_key_create
+ 0x9d01ba08 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01ba08 pthread_key_create
+ 0x9d01ba08 _weak_pthread_key_create
+ .text._weak_pthread_setspecific
+ 0x9d01ba10 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01ba10 _weak_pthread_setspecific
+ 0x9d01ba10 pthread_setspecific
+ .text._weak_pthread_getspecific
+ 0x9d01ba18 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01ba18 pthread_getspecific
+ 0x9d01ba18 _weak_pthread_getspecific
+ .text._weak__libc_private_storage
+ 0x9d01ba20 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01ba20 _libc_private_storage
+ 0x9d01ba20 _weak__libc_private_storage
+ .text._general_exception_handler
+ 0x9d01ba28 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ 0x9d01ba28 _general_exception_handler
+ .text._bootstrap_exception_handler
+ 0x9d01ba30 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ 0x9d01ba30 _bootstrap_exception_handler
+ .text._on_reset
+ 0x9d01ba38 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ 0x9d01ba38 _on_reset
+ .text._on_bootstrap
+ 0x9d01ba40 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ 0x9d01ba40 _on_bootstrap
+ .text 0x9d01ba48 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-nmi-handler.o)
+ 0x9d01ba48 _nmi_handler
+ .text._mon_getc
+ 0x9d01ba60 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ 0x9d01ba60 _mon_getc
+ .text._mon_write
+ 0x9d01ba68 0x4c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ 0x9d01ba68 _mon_write
+ .text._exit 0x9d01bab4 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ 0x9d01bab4 _exit
+ .text.__sputn 0x9d01babc 0x6c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .text.repl 0x9d01bb28 0x74 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .text._outcnvrt
+ 0x9d01bb9c 0xe4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .text.rounded 0x9d01bc80 0x134 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .text.vfprintf
+ 0x9d01bdb4 0x1554 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ 0x9d01bdb4 vfprintf
+ .text.vprintf 0x9d01d308 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ 0x9d01d308 vprintf
+ .text._filbuf_string
+ 0x9d01d338 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .text._flsbuf_string
+ 0x9d01d340 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .text._fflush_string
+ 0x9d01d348 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .text._fwrite_string
+ 0x9d01d350 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .text._fsync_string
+ 0x9d01d358 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .text.fputc 0x9d01d360 0xac C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ 0x9d01d360 fputc
+ .text.putc 0x9d01d40c 0x1c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ 0x9d01d40c putc
+ .text.putchar 0x9d01d428 0x24 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ 0x9d01d428 putchar
+ .text._mon_putc
+ 0x9d01d44c 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ 0x9d01d44c _mon_putc
+ .text 0x9d01d474 0x5c8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(mod32.o)
+ 0x9d01d7b8 __mchp_ldexp
+ 0x9d01d474 dpfmod
+ 0x9d01d920 modf
+ 0x9d01d474 fmod
+ 0x9d01d7b8 dpldexp
+ 0x9d01d920 dpmodf
+ 0x9d01d714 dpfrexp
+ 0x9d01d714 frexp
+ .text 0x9d01da3c 0xfc C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(ceil32.o)
+ 0x9d01da3c ceil
+ 0x9d01da3c dpceil
+ .text 0x9d01db38 0x1128 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(dp32.o)
+ 0x9d01ebe8 fabs
+ 0x9d01eaac __eqdf2
+ 0x9d01eaac __gtdf2
+ 0x9d01db38 dpsub
+ 0x9d01e740 __floatsidf
+ 0x9d01eaac __ltdf2
+ 0x9d01e7b4 ultodp
+ 0x9d01df64 dpmul
+ 0x9d01e8a8 dptofp
+ 0x9d01ea28 __fixunsdfsi
+ 0x9d01eaac dpcmp
+ 0x9d01e804 __extendsfdf2
+ 0x9d01db40 __adddf3
+ 0x9d01ea28 dptoul
+ 0x9d01e28c dpdiv
+ 0x9d01e740 litodp
+ 0x9d01e9a0 __fixdfsi
+ 0x9d01eaac __ledf2
+ 0x9d01e804 fptodp
+ 0x9d01ebd0 __negdf2
+ 0x9d01db40 dpadd
+ 0x9d01e28c __divdf3
+ 0x9d01df64 __muldf3
+ 0x9d01e8a8 __truncdfsf2
+ 0x9d01eaac __nedf2
+ 0x9d01e9a0 dptoli
+ 0x9d01ec04 nan
+ 0x9d01ebe8 dpfabs
+ 0x9d01eaac __gedf2
+ 0x9d01ec04 dpnan
+ 0x9d01db38 __subdf3
+ .text 0x9d01ec60 0x8ec C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(fp32.o)
+ 0x9d01f08c __divsf3
+ 0x9d01f2b8 sitofp
+ 0x9d01f360 __fixsfsi
+ 0x9d01f08c fpdiv
+ 0x9d01ec60 __subsf3
+ 0x9d01f360 fptoli
+ 0x9d01f44c __lesf2
+ 0x9d01f4e0 fabsf
+ 0x9d01f44c __nesf2
+ 0x9d01f314 uitofp
+ 0x9d01f44c __gtsf2
+ 0x9d01f3d8 fptoui
+ 0x9d01f4e0 fpfabs
+ 0x9d01f2b8 __floatsisf
+ 0x9d01f360 fptosi
+ 0x9d01f500 fpnan
+ 0x9d01f44c __eqsf2
+ 0x9d01ec68 fpadd
+ 0x9d01f4f0 __negsf2
+ 0x9d01f44c __ltsf2
+ 0x9d01ec60 fpsub
+ 0x9d01f44c fpcmp
+ 0x9d01eed4 __mulsf3
+ 0x9d01f44c __gesf2
+ 0x9d01f500 nanf
+ 0x9d01f2b8 litofp
+ 0x9d01eed4 fpmul
+ 0x9d01f3d8 __fixunssfsi
+ 0x9d01ec68 __addsf3
+ 0x9d01f3d8 fptoul
+ 0x9d01f314 ultofp
+ .text.__strtod
+ 0x9d01f54c 0x444 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ 0x9d01f54c __strtod
+ .text.__ldexp 0x9d01f990 0x220 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ 0x9d01f990 __ldexp
+ .text.getcSPI2
+ 0x9d01fbb0 0x24 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ 0x9d01fbb0 getcSPI2
+ .text.OpenSPI2
+ 0x9d01fbd4 0x64 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ 0x9d01fbd4 OpenSPI2
+ .text.INTDisableInterrupts
+ 0x9d01fc38 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ 0x9d01fc38 INTDisableInterrupts
+ .text.INTEnableSystemMultiVectoredInt
+ 0x9d01fc40 0x34 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ 0x9d01fc40 INTEnableSystemMultiVectoredInt
+ .text.INTRestoreInterrupts
+ 0x9d01fc74 0x1c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ 0x9d01fc74 INTRestoreInterrupts
+ .text.INTEnableInterrupts
+ 0x9d01fc90 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+ 0x9d01fc90 INTEnableInterrupts
+ .text 0x9d01fc98 0x47c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_udivdi3.o)
+ 0x9d01fc98 __udivdi3
+ .text 0x9d020114 0x48c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_umoddi3.o)
+ 0x9d020114 __umoddi3
+ *(.text.*personality*)
+ *(.gnu.warning)
+ *(.mips16.fn.*)
+ *(.mips16.call.*)
+ 0x9d0205a0 _text_end = .
+
+.rodata 0x9d0205a0 0x1870
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ .rodata 0x9d0205a0 0xb8 Extruder.o
+ 0x9d0205a0 Therm_Table
+ .rodata 0x9d020658 0xf0 FSIO.o
+ .rodata 0x9d020748 0xcc SD-SPI.o
+ 0x9d020748 sdmmc_cmdtable
+ .rodata 0x9d020814 0x14 G_Code.o
+ .rodata 0x9d020828 0xfe0 OLED.o
+ 0x9d021528 TEXT2
+ 0x9d020c28 BfB_LOGO
+ 0x9d021028 EXTRUDER_SCREEN
+ 0x9d020828 RAPMAN_LOGO
+ 0x9d021428 TEXT
+ .rodata 0x9d021808 0x1c4 RapMan.o
+ *fill* 0x9d0219cc 0x4 00
+ .rodata 0x9d0219d0 0xc8 Stepper.o
+ .rodata 0x9d021a98 0x14 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ 0x9d021a98 _io_funcs
+ .rodata 0x9d021aac 0x104 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctype.o)
+ 0x9d021aac _ctype
+ .rodata 0x9d021bb0 0x114 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ *fill* 0x9d021cc4 0x4 00
+ .rodata.cst8 0x9d021cc8 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ 0x30 (size before relaxing)
+ .rodata.str1.4
+ 0x9d021cf0 0x1b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ 0x1c (size before relaxing)
+ *fill* 0x9d021d0b 0x1 00
+ .rodata 0x9d021d0c 0x14 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ 0x9d021d0c _io_strfuncs
+ .rodata 0x9d021d20 0x48 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .rodata.cst8 0x9d021d68 0x10 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ 0x18 (size before relaxing)
+ .rodata.cst8 0x9d021d78 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .rodata 0x9d021d90 0x80 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_brg_tbl_lib.o)
+ 0x9d021d90 SpiBrgConvTbl
+ *(.rodata1)
+ 0x9d021e10 . = ALIGN (0x4)
+
+.sdata2 0x9d021e10 0x0
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ 0x9d021e10 . = ALIGN (0x4)
+
+.sbss2 0x9d021e10 0x0
+ *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+ 0x9d021e10 . = ALIGN (0x4)
+
+.eh_frame_hdr
+ *(.eh_frame_hdr)
+
+.eh_frame 0x9d021e10 0x50
+ *(.eh_frame)
+ .eh_frame 0x9d021e10 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_udivdi3.o)
+ .eh_frame 0x9d021e30 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_umoddi3.o)
+
+.dbg_data 0xa0000000 0x0
+ 0xa0000000 . = (. + DEFINED (_DEBUGGER)?0x200:0x0)
+
+.data 0xa0000000 0xf4 load address 0x9d021e60
+ 0xa0000000 _data_begin = .
+ *(.data .data.* .gnu.linkonce.d.*)
+ .data 0xa0000000 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ 0xa0000000 __exfun_mx
+ .data 0xa0000020 0xd4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ *(.gnu.linkonce.d.*personality*)
+ *(.data1)
+ 0x9d021e60 _data_image_begin = LOADADDR (.data)
+
+.eh_frame
+ *(.eh_frame)
+ 0xa00080f0 _gp = (ALIGN (0x10) + 0x7ff0)
+
+.got
+ *(.got.plt)
+ *(.got)
+
+.sdata 0xa00000f4 0x2c load address 0x9d021f54
+ 0xa00000f4 _sdata_begin = .
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ .sdata 0xa00000f4 0xc Extruder.o
+ 0xa00000fc Direction
+ 0xa00000f8 PR3_Setting
+ 0xa00000f4 RPM_Setting
+ .sdata 0xa0000100 0xc FSIO.o
+ 0xa0000100 gLastFATSectorRead
+ 0xa0000108 cwdptr
+ 0xa0000104 gLastDataSectorRead
+ .sdata 0xa000010c 0x10 Stepper.o
+ 0xa000010c BufferEmpty
+ 0xa0000110 StepRPM_Setting
+ 0xa0000118 FirstPass
+ 0xa0000114 PR4_Setting
+ .sdata 0xa000011c 0x4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ 0xa000011c _libc_data
+ 0xa0000120 _sdata_end = .
+
+.lit8
+ *(.lit8)
+
+.lit4
+ *(.lit4)
+ 0xa0000120 . = ALIGN (0x4)
+ 0xa0000120 _data_end = .
+ 0xa0000120 _bss_begin = .
+
+.sbss 0xa0000120 0x25c
+ 0xa0000120 _sbss_begin = .
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ .sbss 0xa0000120 0x34 Extruder.o
+ 0xa000014c UART_Counter
+ 0xa0000144 RPM_Setting_Old
+ 0xa0000134 temperature_OK
+ 0xa000012c AveSamplesThermistor
+ 0xa000013c SetTemperature
+ 0xa0000124 ADC_reading
+ 0xa0000128 SampleCountThermistor
+ 0xa0000130 HeaterON
+ 0xa0000148 New_Data
+ 0xa0000150 Temperature_Cycle
+ 0xa0000138 update_temp
+ 0xa0000140 Step_Cycle
+ 0xa0000120 Thermistor_Failure_Counter
+ .sbss 0xa0000154 0xc FSIO.o
+ 0xa0000154 gNeedFATWrite
+ 0xa0000158 gBufferOwner
+ 0xa000015c gNeedDataWrite
+ 0xa000015f recache
+ 0xa000015d nextClusterIsLast
+ 0xa000015e gBufferZeroed
+ .sbss 0xa0000160 0x1c G_Code.o
+ 0xa0000170 GZ_On
+ 0xa0000164 Inch_mm
+ 0xa0000178 GJ_On
+ 0xa000016c GY_On
+ 0xa0000160 F_Code
+ 0xa0000174 GI_On
+ 0xa0000168 GX_On
+ .sbss 0xa000017c 0x40 RapMan.o
+ 0xa0000190 ADC_readingToolID
+ 0xa00001a0 ToolType
+ 0xa000018c ItemsRead
+ 0xa0000198 AveSamplesToolID
+ 0xa0000194 SampleCountToolID
+ 0xa00001b0 FileType
+ 0xa000019c Operation_Mode
+ 0xa00001a8 SetRPM
+ 0xa00001ac GoToRestSpeed
+ 0xa0000188 EOF_Flag
+ 0xa00001a4 SetTemp
+ 0xa0000184 Word_Count
+ 0xa000017c PosInFile
+ 0xa0000180 LineNumber
+ .sbss 0xa00001bc 0x48 Stepper.o
+ 0xa00001d8 Save2_Z
+ 0xa00001c0 ZFeed_Rate
+ 0xa00001ec ManualStepperInt_Cycle
+ 0xa00001bc xyrate
+ 0xa00001e8 StepperInt_Cycle
+ 0xa00001c8 Save_Y
+ 0xa00001f1 moveY
+ 0xa00001dc Save3_X
+ 0xa00001cc Save_Z
+ 0xa00001d4 Save2_Y
+ 0xa00001f4 Manual_Mode_Set
+ 0xa00001d0 Save2_X
+ 0xa00001e4 Save3_Z
+ 0xa00001f0 moveX
+ 0xa00001f2 moveZ
+ 0xa00001e0 Save3_Y
+ 0xa00001c4 Save_X
+ .sbss 0xa0000204 0x4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(errno.o)
+ 0xa0000204 errno
+ *(.scommon)
+ .scommon 0xa0000208 0x5c Extruder.o
+ 0xa0000208 S_F_Code
+ 0xa000020c LowValue
+ 0xa0000210 Fraction
+ 0xa0000214 temperature1
+ 0xa0000218 Reverse_Steps
+ 0xa000021c FeedRate_ManualChange
+ 0xa0000220 StepReady
+ 0xa0000224 FastMoveMotorEnable
+ 0xa0000228 G_CodeRapidZMove
+ 0xa000022c EnableFanControl
+ 0xa0000230 G_CodeRapidXYMove
+ 0xa0000234 Ex_Reverse
+ 0xa0000238 Change_M104
+ 0xa0000239 RPM_Change
+ 0xa000023c Feed_Rate
+ 0xa0000240 Range
+ 0xa0000244 Prime_Steps
+ 0xa0000248 Reverse_Step_Count
+ 0xa000024c DataVal
+ 0xa0000250 HighValue
+ 0xa0000254 raw_temperature
+ 0xa0000258 TempVal
+ 0xa000025c Temp_Change
+ 0xa0000260 Prime_Step_Count
+ .scommon 0xa0000264 0x1c FSIO.o
+ 0xa0000264 gFileSlotOpen
+ 0xa0000267 gTimeCrtMS
+ 0xa0000268 gTimeCrtTime
+ 0xa000026c FatRootDirClusterValue
+ 0xa0000270 gTimeWrtDate
+ 0xa0000272 gTimeCrtDate
+ 0xa0000274 TempClusterCalc
+ 0xa0000278 dirCleared
+ 0xa000027a gTimeAccDate
+ 0xa000027c FSerrno
+ 0xa000027e gTimeWrtTime
+ .scommon 0xa0000280 0x4 SD-SPI.o
+ 0xa0000280 MDD_SDSPI_finalLBA
+ .scommon 0xa0000284 0x24 G_Code.o
+ 0xa0000284 M_Code
+ 0xa0000288 G_Code
+ 0xa000028c GY
+ 0xa0000290 GI_Val
+ 0xa0000294 GJ_Val
+ 0xa0000298 GZ
+ 0xa000029c GP_Val
+ 0xa00002a0 GS_Val
+ 0xa00002a4 GX
+ .scommon 0xa00002a8 0x4 OLED.o
+ 0xa00002a8 ExtrusionRate
+ .scommon 0xa00002ac 0x70 RapMan.o
+ 0xa00002ac fDim_1
+ 0xa00002b0 Dim_4
+ 0xa00002b8 X_Rest_mm
+ 0xa00002bc iInst_Code
+ 0xa00002c0 FilePointer
+ 0xa00002c4 Inst_Code
+ 0xa00002cc fDim_4
+ 0xa00002d0 fDim_2
+ 0xa00002d4 SaveFileSize
+ 0xa00002d8 Inst_Code_Letter
+ 0xa00002d9 Dim_4_Letter
+ 0xa00002dc Ops_mode
+ 0xa00002e0 pointer
+ 0xa00002e4 Y_Rest_mm
+ 0xa00002e8 Dim_2_Letter
+ 0xa00002ec ManualChange
+ 0xa00002f0 Dim_2
+ 0xa00002f8 Dim_3_Letter
+ 0xa00002f9 ExtruderStatus
+ 0xa00002fc Z_Rest_mm
+ 0xa0000300 Dim_3
+ 0xa0000308 CharBuffer
+ 0xa0000309 Dim_1_Letter
+ 0xa000030c fDim_3
+ 0xa0000310 PauseFlag
+ 0xa0000314 Dim_1
+ .scommon 0xa000031c 0x60 Stepper.o
+ 0xa000031c SBReady
+ 0xa0000320 lX_Steps
+ 0xa0000324 lSaveSteps_X
+ 0xa0000328 lHomeStepsX
+ 0xa000032c lSaveSteps_Z
+ 0xa0000330 Delta_Z
+ 0xa0000334 Delta_Y
+ 0xa0000338 SBR
+ 0xa000033c SBCode
+ 0xa0000340 lHomeStepsY
+ 0xa0000344 Y_Steps
+ 0xa0000348 lZ_Steps
+ 0xa000034c lHomeStepsZ
+ 0xa0000350 X_Steps
+ 0xa0000354 Set_Y_Dir
+ 0xa0000358 lSaveSteps_Y
+ 0xa000035c SBW
+ 0xa0000360 Set_Z_Dir
+ 0xa0000364 S_M_Code
+ 0xa0000368 SBuf
+ 0xa000036c Delta_X
+ 0xa0000370 lY_Steps
+ 0xa0000374 Set_X_Dir
+ 0xa0000378 Z_Steps
+ 0xa000037c _sbss_end = .
+
+.bss 0xa000037c 0xf04
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ .bss 0xa000037c 0x88 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ .bss 0xa0000404 0x80 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .bss 0xa0000484 0x4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0xa0000484 __isthreaded
+ *(COMMON)
+ COMMON 0xa0000488 0x14 Extruder.o
+ 0xa0000488 Message
+ COMMON 0xa000049c 0x5a2 FSIO.o
+ 0xa000049c gDataBuffer
+ 0xa000069c cwd
+ 0xa00006d8 defaultString
+ 0xa00006e8 tempCWDobj
+ 0xa0000724 gFATBuffer
+ 0xa0000924 gFileArray
+ 0xa00009d8 gDiskData
+ 0xa00009f8 gFileTemp
+ 0xa0000a34 defaultArray
+ *fill* 0xa0000a3e 0x2 00
+ COMMON 0xa0000a40 0x40 RapMan.o
+ 0xa0000a40 LineBuffer
+ 0xa0000a74 SaveFileName
+ COMMON 0xa0000a80 0x800 Stepper.o
+ 0xa0000a80 SCB
+ 0xa0001280 . = ALIGN (0x4)
+ 0xa0001280 . = ALIGN (0x4)
+ 0xa0001280 _end = .
+ 0xa0001280 _bss_end = .
+
+.heap 0xa0001280 0x0
+ 0xa0001280 _heap = .
+ 0xa0001280 . = (. + _min_heap_size)
+
+.stack 0xa0001280 0x400
+ 0xa0001680 . = (. + _min_stack_size)
+ *fill* 0xa0001280 0x400 00
+
+.ramfunc 0xa0001800 0x0 load address 0x9d021f80
+ 0xa0001800 _ramfunc_begin = .
+ *(.ramfunc .ramfunc.*)
+ 0xa0001800 . = ALIGN (0x4)
+ 0xa0001800 _ramfunc_end = .
+ 0x9d021f80 _ramfunc_image_begin = LOADADDR (.ramfunc)
+ 0x00000000 _ramfunc_length = SIZEOF (.ramfunc)
+ 0x00001800 _bmxdkpba_address = (_ramfunc_begin - 0xa0000000)
+ 0x00008000 _bmxdudba_address = 0x8000
+ 0x00008000 _bmxdupba_address = 0x8000
+ 0xa0008000 _stack = (_ramfunc_length > 0x0)?(_ramfunc_begin - 0x4):0xa0008000
+ 0x00000001 ASSERT (((_min_stack_size + _min_heap_size) <= (_stack - _heap)), Not enough space to allocate both stack and heap. Reduce heap and/or stack size.)
+
+.pdr 0x00000000 0x2240
+ *(.pdr)
+ .pdr 0x00000000 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+ .pdr 0x000000a0 0x1e0 Extruder.o
+ .pdr 0x00000280 0x7a0 FSIO.o
+ .pdr 0x00000a20 0x1e0 SD-SPI.o
+ .pdr 0x00000c00 0x360 G_Code.o
+ .pdr 0x00000f60 0x320 OLED.o
+ .pdr 0x00001280 0x220 RapMan.o
+ .pdr 0x000014a0 0x220 Stepper.o
+ .pdr 0x000016c0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memcpy.o)
+ .pdr 0x000016e0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memset.o)
+ .pdr 0x00001700 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strcpy.o)
+ .pdr 0x00001720 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strlen.o)
+ .pdr 0x00001740 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(general-exception.o)
+ .pdr 0x00001760 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .pdr 0x00001780 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .pdr 0x000017a0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .pdr 0x000017c0 0x220 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .pdr 0x000019e0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .pdr 0x00001a00 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .pdr 0x00001a20 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .pdr 0x00001a40 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .pdr 0x00001a60 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .pdr 0x00001b00 0x60 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .pdr 0x00001b60 0x2c0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .pdr 0x00001e20 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .pdr 0x00001e40 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .pdr 0x00001e60 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .pdr 0x00001e80 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .pdr 0x00001ea0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-nmi-handler.o)
+ .pdr 0x00001ec0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .pdr 0x00001ee0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .pdr 0x00001f00 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .pdr 0x00001f20 0xc0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .pdr 0x00001fe0 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .pdr 0x00002080 0x60 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .pdr 0x000020e0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .pdr 0x00002100 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .pdr 0x00002120 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .pdr 0x00002140 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .pdr 0x00002160 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .pdr 0x00002180 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .pdr 0x000021a0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .pdr 0x000021c0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .pdr 0x000021e0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+ .pdr 0x00002200 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_udivdi3.o)
+ .pdr 0x00002220 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_umoddi3.o)
+
+.reginfo 0x00000000 0x18
+ *(.reginfo)
+ .reginfo 0x00000000 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+
+.stab
+ *(.stab)
+
+.stabstr
+ *(.stabstr)
+
+.stab.excl
+ *(.stab.excl)
+
+.stab.exclstr
+ *(.stab.exclstr)
+
+.stab.index
+ *(.stab.index)
+
+.stab.indexstr
+ *(.stab.indexstr)
+
+.comment 0x00000000 0x1479
+ *(.comment)
+ .comment 0x00000000 0x4d Extruder.o
+ .comment 0x0000004d 0x4d FSIO.o
+ .comment 0x0000009a 0x4d SD-SPI.o
+ .comment 0x000000e7 0x4d G_Code.o
+ .comment 0x00000134 0x4d OLED.o
+ .comment 0x00000181 0x4d RapMan.o
+ .comment 0x000001ce 0x4d Stepper.o
+ .comment 0x0000021b 0x56 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memset.o)
+ .comment 0x00000271 0x56 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strcpy.o)
+ .comment 0x000002c7 0x56 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strlen.o)
+ .comment 0x0000031d 0x9d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .comment 0x000003ba 0x9c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .comment 0x00000456 0x9a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .comment 0x000004f0 0x9c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .comment 0x0000058c 0x9a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .comment 0x00000626 0x9a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .comment 0x000006c0 0x9c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .comment 0x0000075c 0x9c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .comment 0x000007f8 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ .comment 0x00000898 0xa1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .comment 0x00000939 0x9f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .comment 0x000009d8 0x9b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .comment 0x00000a73 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .comment 0x00000ac0 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .comment 0x00000b0d 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .comment 0x00000b5a 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .comment 0x00000ba7 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .comment 0x00000bf4 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .comment 0x00000c41 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .comment 0x00000c8e 0x9b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctype.o)
+ .comment 0x00000d29 0x9b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(errno.o)
+ .comment 0x00000dc4 0x9f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .comment 0x00000e63 0xa2 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .comment 0x00000f05 0x9d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .comment 0x00000fa2 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .comment 0x00000fef 0xea C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .comment 0x000010d9 0xeb C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .comment 0x000011c4 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .comment 0x00001211 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .comment 0x0000125e 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .comment 0x000012ab 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .comment 0x000012f8 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .comment 0x00001345 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_brg_tbl_lib.o)
+ .comment 0x00001392 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+ .comment 0x000013df 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_udivdi3.o)
+ .comment 0x0000142c 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_umoddi3.o)
+
+.debug
+ *(.debug)
+
+.line
+ *(.line)
+
+.debug_srcinfo
+ *(.debug_srcinfo)
+
+.debug_sfnames
+ *(.debug_sfnames)
+
+.debug_aranges 0x00000000 0x740
+ *(.debug_aranges)
+ .debug_aranges
+ 0x00000000 0x20 Extruder.o
+ .debug_aranges
+ 0x00000020 0x20 FSIO.o
+ .debug_aranges
+ 0x00000040 0x20 SD-SPI.o
+ .debug_aranges
+ 0x00000060 0x20 G_Code.o
+ .debug_aranges
+ 0x00000080 0x20 OLED.o
+ .debug_aranges
+ 0x000000a0 0x20 RapMan.o
+ .debug_aranges
+ 0x000000c0 0x20 Stepper.o
+ .debug_aranges
+ 0x000000e0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_aranges
+ 0x00000108 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_aranges
+ 0x00000130 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_aranges
+ 0x00000158 0xa8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_aranges
+ 0x00000200 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_aranges
+ 0x00000228 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_aranges
+ 0x00000250 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_aranges
+ 0x00000278 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_aranges
+ 0x000002a0 0x48 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_aranges
+ 0x000002e8 0x38 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_aranges
+ 0x00000320 0xd0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_aranges
+ 0x000003f0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_aranges
+ 0x00000418 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_aranges
+ 0x00000440 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_aranges
+ 0x00000468 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_aranges
+ 0x00000490 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_aranges
+ 0x000004b8 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_aranges
+ 0x000004e0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_aranges
+ 0x00000508 0x50 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_aranges
+ 0x00000558 0x48 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .debug_aranges
+ 0x000005a0 0x38 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_aranges
+ 0x000005d8 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_aranges
+ 0x00000600 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_aranges
+ 0x00000628 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_aranges
+ 0x00000650 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_aranges
+ 0x00000678 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_aranges
+ 0x000006a0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_aranges
+ 0x000006c8 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_aranges
+ 0x000006f0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_aranges
+ 0x00000718 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_pubnames
+ 0x00000000 0x21eb
+ *(.debug_pubnames)
+ .debug_pubnames
+ 0x00000000 0x3ef Extruder.o
+ .debug_pubnames
+ 0x000003ef 0x5d9 FSIO.o
+ .debug_pubnames
+ 0x000009c8 0x18c SD-SPI.o
+ .debug_pubnames
+ 0x00000b54 0x31b G_Code.o
+ .debug_pubnames
+ 0x00000e6f 0x30a OLED.o
+ .debug_pubnames
+ 0x00001179 0x469 RapMan.o
+ .debug_pubnames
+ 0x000015e2 0x42b Stepper.o
+ .debug_pubnames
+ 0x00001a0d 0x1e C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_pubnames
+ 0x00001a2b 0x1d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_pubnames
+ 0x00001a48 0x1b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_pubnames
+ 0x00001a63 0xe1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_pubnames
+ 0x00001b44 0x1b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_pubnames
+ 0x00001b5f 0x1b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_pubnames
+ 0x00001b7a 0x1d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_pubnames
+ 0x00001b97 0x1d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_pubnames
+ 0x00001bb4 0x70 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_pubnames
+ 0x00001c24 0x3b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_pubnames
+ 0x00001c5f 0x2da C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_pubnames
+ 0x00001f39 0x31 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_pubnames
+ 0x00001f6a 0x33 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_pubnames
+ 0x00001f9d 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_pubnames
+ 0x00001fbd 0x24 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_pubnames
+ 0x00001fe1 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_pubnames
+ 0x00002001 0x21 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_pubnames
+ 0x00002022 0x1c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_pubnames
+ 0x0000203e 0x2b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_pubnames
+ 0x00002069 0x31 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_pubnames
+ 0x0000209a 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_pubnames
+ 0x000020ba 0x1f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_pubnames
+ 0x000020d9 0x1e C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_pubnames
+ 0x000020f7 0x1f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_pubnames
+ 0x00002116 0x1f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_pubnames
+ 0x00002135 0x2b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_pubnames
+ 0x00002160 0x36 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_pubnames
+ 0x00002196 0x2b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_pubnames
+ 0x000021c1 0x2a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_info 0x00000000 0x9d30
+ *(.debug_info .gnu.linkonce.wi.*)
+ .debug_info 0x00000000 0xe49 Extruder.o
+ .debug_info 0x00000e49 0x382b FSIO.o
+ .debug_info 0x00004674 0xc3f SD-SPI.o
+ .debug_info 0x000052b3 0xa9e G_Code.o
+ .debug_info 0x00005d51 0xc7f OLED.o
+ .debug_info 0x000069d0 0x15cf RapMan.o
+ .debug_info 0x00007f9f 0x140e Stepper.o
+ .debug_info 0x000093ad 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_info 0x000093dd 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_info 0x0000940d 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_info 0x0000943d 0x150 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_info 0x0000958d 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_info 0x000095bd 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_info 0x000095ed 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_info 0x0000961d 0x3a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_info 0x00009657 0x78 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_info 0x000096cf 0x54 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_info 0x00009723 0x1aa C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_info 0x000098cd 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_info 0x000098fd 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_info 0x0000992d 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_info 0x0000995d 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_info 0x0000998d 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_info 0x000099bd 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_info 0x000099ed 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_info 0x00009a1d 0x8a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_info 0x00009aa7 0x73 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .debug_info 0x00009b1a 0x54 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_info 0x00009b6e 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_info 0x00009b9e 0x42 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_info 0x00009be0 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_info 0x00009c10 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_info 0x00009c40 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_info 0x00009c70 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_info 0x00009ca0 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_info 0x00009cd0 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_info 0x00009d00 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_abbrev 0x00000000 0x133d
+ *(.debug_abbrev)
+ .debug_abbrev 0x00000000 0x20a Extruder.o
+ .debug_abbrev 0x0000020a 0x2ad FSIO.o
+ .debug_abbrev 0x000004b7 0x268 SD-SPI.o
+ .debug_abbrev 0x0000071f 0x170 G_Code.o
+ .debug_abbrev 0x0000088f 0x239 OLED.o
+ .debug_abbrev 0x00000ac8 0x21f RapMan.o
+ .debug_abbrev 0x00000ce7 0x1e0 Stepper.o
+ .debug_abbrev 0x00000ec7 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_abbrev 0x00000eea 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_abbrev 0x00000f0d 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_abbrev 0x00000f30 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_abbrev 0x00000f53 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_abbrev 0x00000f76 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_abbrev 0x00000f99 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_abbrev 0x00000fbc 0x32 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_abbrev 0x00000fee 0x1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ .debug_abbrev 0x00000fef 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_abbrev 0x00001012 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_abbrev 0x00001035 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_abbrev 0x00001058 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_abbrev 0x0000107b 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_abbrev 0x0000109e 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_abbrev 0x000010c1 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_abbrev 0x000010e4 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_abbrev 0x00001107 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_abbrev 0x0000112a 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_abbrev 0x0000114d 0x1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctype.o)
+ .debug_abbrev 0x0000114e 0x1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(errno.o)
+ .debug_abbrev 0x0000114f 0x58 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_abbrev 0x000011a7 0x21 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .debug_abbrev 0x000011c8 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_abbrev 0x000011eb 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_abbrev 0x0000120e 0x39 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_abbrev 0x00001247 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_abbrev 0x0000126a 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_abbrev 0x0000128d 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_abbrev 0x000012b0 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_abbrev 0x000012d3 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_abbrev 0x000012f6 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_abbrev 0x00001319 0x1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_brg_tbl_lib.o)
+ .debug_abbrev 0x0000131a 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_line 0x00000000 0x3164
+ *(.debug_line)
+ .debug_line 0x00000000 0x271 Extruder.o
+ .debug_line 0x00000271 0xf44 FSIO.o
+ .debug_line 0x000011b5 0x241 SD-SPI.o
+ .debug_line 0x000013f6 0x214 G_Code.o
+ .debug_line 0x0000160a 0x2eb OLED.o
+ .debug_line 0x000018f5 0x3d5 RapMan.o
+ .debug_line 0x00001cca 0x3bd Stepper.o
+ .debug_line 0x00002087 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_line 0x0000210d 0x85 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_line 0x00002192 0x83 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_line 0x00002215 0x85 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_line 0x0000229a 0x83 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_line 0x0000231d 0x83 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_line 0x000023a0 0x85 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_line 0x00002425 0x85 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_line 0x000024aa 0x8a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_line 0x00002534 0x88 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_line 0x000025bc 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_line 0x00002642 0xa2 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_line 0x000026e4 0xa4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_line 0x00002788 0x91 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_line 0x00002819 0x95 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_line 0x000028ae 0x8a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_line 0x00002938 0x8b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_line 0x000029c3 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_line 0x00002a49 0x88 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_line 0x00002ad1 0x8b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .debug_line 0x00002b5c 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_line 0x00002be2 0x8a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_line 0x00002c6c 0x94 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_line 0x00002d00 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_line 0x00002d86 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_line 0x00002e26 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_line 0x00002ec6 0xa9 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_line 0x00002f6f 0xa4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_line 0x00003013 0xa9 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_line 0x000030bc 0xa8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_frame 0x00000000 0x1e28
+ *(.debug_frame)
+ .debug_frame 0x00000000 0x1b0 Extruder.o
+ .debug_frame 0x000001b0 0x790 FSIO.o
+ .debug_frame 0x00000940 0x1d0 SD-SPI.o
+ .debug_frame 0x00000b10 0x340 G_Code.o
+ .debug_frame 0x00000e50 0x32c OLED.o
+ .debug_frame 0x0000117c 0x228 RapMan.o
+ .debug_frame 0x000013a4 0x1fc Stepper.o
+ .debug_frame 0x000015a0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_frame 0x000015c0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_frame 0x000015e0 0x34 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_frame 0x00001614 0x120 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_frame 0x00001734 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_frame 0x0000175c 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_frame 0x00001784 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_frame 0x000017a4 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_frame 0x000017cc 0x98 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_frame 0x00001864 0x58 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_frame 0x000018bc 0x178 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_frame 0x00001a34 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_frame 0x00001a54 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_frame 0x00001a74 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_frame 0x00001a94 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_frame 0x00001ab4 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_frame 0x00001ad4 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_frame 0x00001b04 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_frame 0x00001b24 0xf8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_frame 0x00001c1c 0x60 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .debug_frame 0x00001c7c 0x60 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_frame 0x00001cdc 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_frame 0x00001cfc 0x44 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_frame 0x00001d40 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_frame 0x00001d60 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_frame 0x00001d80 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_frame 0x00001da0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_frame 0x00001dc0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_frame 0x00001de8 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_frame 0x00001e08 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_str 0x00000000 0x1617
+ *(.debug_str)
+ .debug_str 0x00000000 0x2e Extruder.o
+ .debug_str 0x0000002e 0x277 FSIO.o
+ .debug_str 0x000002a5 0x2e SD-SPI.o
+ .debug_str 0x000002d3 0x2c G_Code.o
+ .debug_str 0x000002ff 0x4f OLED.o
+ .debug_str 0x0000034e 0x49 RapMan.o
+ .debug_str 0x00000397 0x43 Stepper.o
+ .debug_str 0x000003da 0xb8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_str 0x00000492 0x6f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ 0xb6 (size before relaxing)
+ .debug_str 0x00000501 0x66 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ 0xb2 (size before relaxing)
+ .debug_str 0x00000567 0xe3 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x13a (size before relaxing)
+ .debug_str 0x0000064a 0x6b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ 0xb2 (size before relaxing)
+ .debug_str 0x000006b5 0x6b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ 0xb2 (size before relaxing)
+ .debug_str 0x00000720 0x6f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ 0xb6 (size before relaxing)
+ .debug_str 0x0000078f 0x71 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ 0xbf (size before relaxing)
+ .debug_str 0x00000800 0xb7 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0xfe (size before relaxing)
+ .debug_str 0x000008b7 0x80 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ 0xcf (size before relaxing)
+ .debug_str 0x00000937 0x2d9 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x320 (size before relaxing)
+ .debug_str 0x00000c10 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ 0xe7 (size before relaxing)
+ .debug_str 0x00000cb0 0xa4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ 0xeb (size before relaxing)
+ .debug_str 0x00000d54 0x7e C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ 0xc5 (size before relaxing)
+ .debug_str 0x00000dd2 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ 0xcd (size before relaxing)
+ .debug_str 0x00000e58 0x77 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ 0xbe (size before relaxing)
+ .debug_str 0x00000ecf 0x79 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ 0xc0 (size before relaxing)
+ .debug_str 0x00000f48 0x6f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ 0xb6 (size before relaxing)
+ .debug_str 0x00000fb7 0x9b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ 0xe2 (size before relaxing)
+ .debug_str 0x00001052 0xb8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ 0xff (size before relaxing)
+ .debug_str 0x0000110a 0x77 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ 0xc3 (size before relaxing)
+ .debug_str 0x00001181 0x77 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ 0xbe (size before relaxing)
+ .debug_str 0x000011f8 0x77 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ 0xc7 (size before relaxing)
+ .debug_str 0x0000126f 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ 0xb6 (size before relaxing)
+ .debug_str 0x00001277 0x8c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ 0xd3 (size before relaxing)
+ .debug_str 0x00001303 0x8c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ 0xd3 (size before relaxing)
+ .debug_str 0x0000138f 0xa1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ 0xe8 (size before relaxing)
+ .debug_str 0x00001430 0xa7 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ 0xee (size before relaxing)
+ .debug_str 0x000014d7 0xa1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ 0xe8 (size before relaxing)
+ .debug_str 0x00001578 0x9f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+ 0xe6 (size before relaxing)
+
+.debug_loc
+ *(.debug_loc)
+
+.debug_macinfo
+ *(.debug_macinfo)
+
+.debug_weaknames
+ *(.debug_weaknames)
+
+.debug_funcnames
+ *(.debug_funcnames)
+
+.debug_typenames
+ *(.debug_typenames)
+
+.debug_varnames
+ *(.debug_varnames)
+
+/DISCARD/
+ *(.note.GNU-stack)
+OUTPUT(bfb-firmware-dev.elf elf32-tradlittlemips)
+
+.mdebug.abi32 0x9d021f80 0x0
+
+.rel.dyn 0x9d021f80 0x0
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.mcp b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.mcp new file mode 100644 index 00000000..23e03a46 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.mcp @@ -0,0 +1,114 @@ +[HEADER]
+magic_cookie={66E99B07-E706-4689-9E80-9B2582898A13}
+file_version=1.0
+device=PIC32MX440F256H
+[PATH_INFO]
+BuildDirPolicy=BuildDirIsProjectDir
+dir_src=
+dir_bin=
+dir_tmp=
+dir_sin=
+dir_inc=C:\Documents and Settings\erik\My Documents\bfb-firmware-dev;C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral;C:\Program Files\Microchip\MPLAB C32\pic32mx\include;C:\Microchip Solutions\Microchip\Include
+dir_lib=
+dir_lkr=
+[CAT_FILTERS]
+filter_src=*.s;*.c
+filter_inc=*.h;*.inc
+filter_obj=*.o
+filter_lib=*.a
+filter_lkr=*.ld
+[CAT_SUBFOLDERS]
+subfolder_src=
+subfolder_inc=
+subfolder_obj=
+subfolder_lib=
+subfolder_lkr=
+[FILE_SUBFOLDERS]
+file_000=.
+file_001=.
+file_002=.
+file_003=.
+file_004=.
+file_005=.
+file_006=.
+file_007=.
+file_008=.
+file_009=.
+file_010=.
+file_011=.
+file_012=.
+file_013=.
+file_014=.
+file_015=.
+file_016=.
+[GENERATED_FILES]
+file_000=no
+file_001=no
+file_002=no
+file_003=no
+file_004=no
+file_005=no
+file_006=no
+file_007=no
+file_008=no
+file_009=no
+file_010=no
+file_011=no
+file_012=no
+file_013=no
+file_014=no
+file_015=no
+file_016=no
+[OTHER_FILES]
+file_000=no
+file_001=no
+file_002=no
+file_003=no
+file_004=no
+file_005=no
+file_006=no
+file_007=no
+file_008=no
+file_009=no
+file_010=no
+file_011=no
+file_012=no
+file_013=no
+file_014=no
+file_015=no
+file_016=no
+[FILE_INFO]
+file_000=Extruder.c
+file_001=FSIO.c
+file_002=SD-SPI.c
+file_003=G_Code.c
+file_004=OLED.c
+file_005=RapMan.c
+file_006=Stepper.c
+file_007=RapMan.h
+file_008=extruder.h
+file_009=stepper.h
+file_010=Screens.h
+file_011=SD-SPI.h
+file_012=HardwareProfile.h
+file_013=FSIO.h
+file_014=OLED.h
+file_015=G_Code.h
+file_016=Enviroment.h
+[SUITE_INFO]
+suite_guid={14495C23-81F8-43F3-8A44-859C583D7760}
+suite_state=
+[TOOL_SETTINGS]
+TS{CB0AF4B8-4022-429D-8F99-8A56782B2C6D}=-gdwarf-2
+TS{9C698E0A-CBC9-4EFF-AE7D-B569F93E7322}=-g
+TS{77F59DA1-3C53-4677-AC5F-A03EB0125170}=-o"$(BINDIR_)$(TARGETBASE).$(TARGETSUFFIX)" -Map="$(BINDIR_)$(TARGETBASE).map"
+TS{0396C0A1-9052-4E4F-8B84-EF0162B1B4E9}=
+[INSTRUMENTED_TRACE]
+enable=0
+transport=0
+format=0
+[CUSTOM_BUILD]
+Pre-Build=
+Pre-BuildEnabled=1
+Post-Build=
+Post-BuildEnabled=1
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.mcs b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.mcs new file mode 100644 index 00000000..be6fed88 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.mcs @@ -0,0 +1,123 @@ +[Header]
+MagicCookie={0b13fe8c-dfe0-40eb-8900-6712719559a7}
+Version=1.0
+[File000]
+Location=Z:\home\erik\dev\bfb-firmware-dev3\Extruder.o
+Folder=Intermediary
+DeviceName=PIC32MX440F256H
+LanguageToolSuiteID={14495C23-81F8-43F3-8A44-859C583D7760}
+LanguageToolID={430F471F-7ECB-4852-A80D-DEF9A5C8E751}
+LanguageToolLocation=C:\Program Files\Microchip\MPLAB C32 Suite\bin\pic32-gcc.exe
+PPAD=$(BINDIR)||$(TMPDIR)||$(AINDIR)||$(INCDIR)|C:\Documents and Settings\erik\My Documents\bfb-firmware-dev;C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral;C:\Program Files\Microchip\MPLAB C32\pic32mx\include;C:\Microchip Solutions\Microchip\Include||$(LIBDIR)||$(LKRDIR)||
+SOLK=<src>|Extruder.c|FSIO.c|SD-SPI.c|G_Code.c|OLED.c|RapMan.c|Stepper.c||<obj>||<lib>||<lkr>||
+SuiteArgsString=
+ToolArgsString=-g
+TraceCmdString=
+DebugOptions=-D__DEBUG
+[File001]
+Location=Z:\home\erik\dev\bfb-firmware-dev3\FSIO.o
+Folder=Intermediary
+DeviceName=PIC32MX440F256H
+LanguageToolSuiteID={14495C23-81F8-43F3-8A44-859C583D7760}
+LanguageToolID={430F471F-7ECB-4852-A80D-DEF9A5C8E751}
+LanguageToolLocation=C:\Program Files\Microchip\MPLAB C32 Suite\bin\pic32-gcc.exe
+PPAD=$(BINDIR)||$(TMPDIR)||$(AINDIR)||$(INCDIR)|C:\Documents and Settings\erik\My Documents\bfb-firmware-dev;C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral;C:\Program Files\Microchip\MPLAB C32\pic32mx\include;C:\Microchip Solutions\Microchip\Include||$(LIBDIR)||$(LKRDIR)||
+SOLK=<src>|Extruder.c|FSIO.c|SD-SPI.c|G_Code.c|OLED.c|RapMan.c|Stepper.c||<obj>||<lib>||<lkr>||
+SuiteArgsString=
+ToolArgsString=-g
+TraceCmdString=
+DebugOptions=-D__DEBUG
+[File002]
+Location=Z:\home\erik\dev\bfb-firmware-dev3\SD-SPI.o
+Folder=Intermediary
+DeviceName=PIC32MX440F256H
+LanguageToolSuiteID={14495C23-81F8-43F3-8A44-859C583D7760}
+LanguageToolID={430F471F-7ECB-4852-A80D-DEF9A5C8E751}
+LanguageToolLocation=C:\Program Files\Microchip\MPLAB C32 Suite\bin\pic32-gcc.exe
+PPAD=$(BINDIR)||$(TMPDIR)||$(AINDIR)||$(INCDIR)|C:\Documents and Settings\erik\My Documents\bfb-firmware-dev;C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral;C:\Program Files\Microchip\MPLAB C32\pic32mx\include;C:\Microchip Solutions\Microchip\Include||$(LIBDIR)||$(LKRDIR)||
+SOLK=<src>|Extruder.c|FSIO.c|SD-SPI.c|G_Code.c|OLED.c|RapMan.c|Stepper.c||<obj>||<lib>||<lkr>||
+SuiteArgsString=
+ToolArgsString=-g
+TraceCmdString=
+DebugOptions=-D__DEBUG
+[File003]
+Location=Z:\home\erik\dev\bfb-firmware-dev3\G_Code.o
+Folder=Intermediary
+DeviceName=PIC32MX440F256H
+LanguageToolSuiteID={14495C23-81F8-43F3-8A44-859C583D7760}
+LanguageToolID={430F471F-7ECB-4852-A80D-DEF9A5C8E751}
+LanguageToolLocation=C:\Program Files\Microchip\MPLAB C32 Suite\bin\pic32-gcc.exe
+PPAD=$(BINDIR)||$(TMPDIR)||$(AINDIR)||$(INCDIR)|C:\Documents and Settings\erik\My Documents\bfb-firmware-dev;C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral;C:\Program Files\Microchip\MPLAB C32\pic32mx\include;C:\Microchip Solutions\Microchip\Include||$(LIBDIR)||$(LKRDIR)||
+SOLK=<src>|Extruder.c|FSIO.c|SD-SPI.c|G_Code.c|OLED.c|RapMan.c|Stepper.c||<obj>||<lib>||<lkr>||
+SuiteArgsString=
+ToolArgsString=-g
+TraceCmdString=
+DebugOptions=-D__DEBUG
+[File004]
+Location=Z:\home\erik\dev\bfb-firmware-dev3\OLED.o
+Folder=Intermediary
+DeviceName=PIC32MX440F256H
+LanguageToolSuiteID={14495C23-81F8-43F3-8A44-859C583D7760}
+LanguageToolID={430F471F-7ECB-4852-A80D-DEF9A5C8E751}
+LanguageToolLocation=C:\Program Files\Microchip\MPLAB C32 Suite\bin\pic32-gcc.exe
+PPAD=$(BINDIR)||$(TMPDIR)||$(AINDIR)||$(INCDIR)|C:\Documents and Settings\erik\My Documents\bfb-firmware-dev;C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral;C:\Program Files\Microchip\MPLAB C32\pic32mx\include;C:\Microchip Solutions\Microchip\Include||$(LIBDIR)||$(LKRDIR)||
+SOLK=<src>|Extruder.c|FSIO.c|SD-SPI.c|G_Code.c|OLED.c|RapMan.c|Stepper.c||<obj>||<lib>||<lkr>||
+SuiteArgsString=
+ToolArgsString=-g
+TraceCmdString=
+DebugOptions=-D__DEBUG
+[File005]
+Location=Z:\home\erik\dev\bfb-firmware-dev3\RapMan.o
+Folder=Intermediary
+DeviceName=PIC32MX440F256H
+LanguageToolSuiteID={14495C23-81F8-43F3-8A44-859C583D7760}
+LanguageToolID={430F471F-7ECB-4852-A80D-DEF9A5C8E751}
+LanguageToolLocation=C:\Program Files\Microchip\MPLAB C32 Suite\bin\pic32-gcc.exe
+PPAD=$(BINDIR)||$(TMPDIR)||$(AINDIR)||$(INCDIR)|C:\Documents and Settings\erik\My Documents\bfb-firmware-dev;C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral;C:\Program Files\Microchip\MPLAB C32\pic32mx\include;C:\Microchip Solutions\Microchip\Include||$(LIBDIR)||$(LKRDIR)||
+SOLK=<src>|Extruder.c|FSIO.c|SD-SPI.c|G_Code.c|OLED.c|RapMan.c|Stepper.c||<obj>||<lib>||<lkr>||
+SuiteArgsString=
+ToolArgsString=-g
+TraceCmdString=
+DebugOptions=-D__DEBUG
+[File006]
+Location=Z:\home\erik\dev\bfb-firmware-dev3\Stepper.o
+Folder=Intermediary
+DeviceName=PIC32MX440F256H
+LanguageToolSuiteID={14495C23-81F8-43F3-8A44-859C583D7760}
+LanguageToolID={430F471F-7ECB-4852-A80D-DEF9A5C8E751}
+LanguageToolLocation=C:\Program Files\Microchip\MPLAB C32 Suite\bin\pic32-gcc.exe
+PPAD=$(BINDIR)||$(TMPDIR)||$(AINDIR)||$(INCDIR)|C:\Documents and Settings\erik\My Documents\bfb-firmware-dev;C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral;C:\Program Files\Microchip\MPLAB C32\pic32mx\include;C:\Microchip Solutions\Microchip\Include||$(LIBDIR)||$(LKRDIR)||
+SOLK=<src>|Extruder.c|FSIO.c|SD-SPI.c|G_Code.c|OLED.c|RapMan.c|Stepper.c||<obj>||<lib>||<lkr>||
+SuiteArgsString=
+ToolArgsString=-g
+TraceCmdString=
+DebugOptions=-D__DEBUG
+[File007]
+Location=Z:\home\erik\dev\bfb-firmware-dev3\bfb-firmware-dev.elf
+Folder=Output
+DeviceName=PIC32MX440F256H
+LanguageToolSuiteID={14495C23-81F8-43F3-8A44-859C583D7760}
+LanguageToolID={C68E5105-1196-4333-A0BF-3DC57271E614}
+LanguageToolLocation=C:\Program Files\Microchip\MPLAB C32 Suite\bin\pic32-ld.exe
+PPAD=$(BINDIR)||$(TMPDIR)||$(AINDIR)||$(INCDIR)|C:\Documents and Settings\erik\My Documents\bfb-firmware-dev;C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral;C:\Program Files\Microchip\MPLAB C32\pic32mx\include;C:\Microchip Solutions\Microchip\Include||$(LIBDIR)||$(LKRDIR)||
+SOLK=<src>|Extruder.c|FSIO.c|SD-SPI.c|G_Code.c|OLED.c|RapMan.c|Stepper.c||<obj>||<lib>||<lkr>||
+SuiteArgsString=
+ToolArgsString=-o"$(BINDIR_)$(TARGETBASE).$(TARGETSUFFIX)" -Map="$(BINDIR_)$(TARGETBASE).map"
+TraceCmdString=
+DebugOptions=--defsym=__MPLAB_DEBUG=1
+[File008]
+Location=Z:\home\erik\dev\bfb-firmware-dev3\bfb-firmware-dev.hex
+Folder=Output
+DeviceName=PIC32MX440F256H
+LanguageToolSuiteID={14495C23-81F8-43F3-8A44-859C583D7760}
+LanguageToolID={C68E5105-1196-4333-A0BF-3DC57271E614}
+LanguageToolLocation=C:\Program Files\Microchip\MPLAB C32 Suite\bin\pic32-ld.exe
+PPAD=$(BINDIR)||$(TMPDIR)||$(AINDIR)||$(INCDIR)|C:\Documents and Settings\erik\My Documents\bfb-firmware-dev;C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral;C:\Program Files\Microchip\MPLAB C32\pic32mx\include;C:\Microchip Solutions\Microchip\Include||$(LIBDIR)||$(LKRDIR)||
+SOLK=<src>|Extruder.c|FSIO.c|SD-SPI.c|G_Code.c|OLED.c|RapMan.c|Stepper.c||<obj>||<lib>||<lkr>||
+SuiteArgsString=
+ToolArgsString=-o"$(BINDIR_)$(TARGETBASE).$(TARGETSUFFIX)" -Map="$(BINDIR_)$(TARGETBASE).map"
+TraceCmdString=
+DebugOptions=--defsym=__MPLAB_DEBUG=1
+[TOOL_LOC_STAMPS]
+tool_loc{430F471F-7ECB-4852-A80D-DEF9A5C8E751}=C:\Program Files\Microchip\MPLAB C32 Suite\bin\pic32-gcc.exe
+tool_loc{C68E5105-1196-4333-A0BF-3DC57271E614}=C:\Program Files\Microchip\MPLAB C32 Suite\bin\pic32-ld.exe
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.mcw b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.mcw Binary files differnew file mode 100644 index 00000000..a8bc95a5 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/bfb-firmware-dev.mcw diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/FSIO.c b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/FSIO.c new file mode 100644 index 00000000..6a42c66b --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/FSIO.c @@ -0,0 +1,8874 @@ +/******************************************************************************
+*
+* Microchip Memory Disk Drive File System
+*
+******************************************************************************
+* FileName: FSIO.c
+* Dependencies: GenericTypeDefs.h
+* FSIO.h
+* Physical interface include file (SD-SPI.h, CF-PMP.h, ...)
+* string.h
+* stdlib.h
+* FSDefs.h
+* ctype.h
+* salloc.h
+* Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+* Compiler: C18/C30/C32
+* Company: Microchip Technology, Inc.
+* Version: 1.2.0
+*
+* Software License Agreement
+*
+* The software supplied herewith by Microchip Technology Incorporated
+* (the �Company�) for its PICmicro� Microcontroller is intended and
+* supplied to you, the Company�s customer, for use solely and
+* exclusively on Microchip PICmicro Microcontroller products. The
+* software is owned by the Company and/or its supplier, and is
+* protected under applicable copyright laws. All rights are reserved.
+* Any use in violation of the foregoing restrictions may subject the
+* user to criminal sanctions under applicable laws, as well as to
+* civil liability for the breach of the terms and conditions of this
+* license.
+*
+* THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+*
+*****************************************************************************/
+
+#include "FSIO.h"
+#include "GenericTypeDefs.h"
+#include "string.h"
+#include "stdlib.h"
+#include "ctype.h"
+#include "MDD File System\FSDefs.h"
+
+#ifdef ALLOW_FSFPRINTF
+#include "stdarg.h"
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ #ifdef __18CXX
+ #include "salloc.h"
+ #endif
+#endif
+
+#ifndef ALLOW_WRITES
+ #ifdef ALLOW_FORMATS
+ #error Write functions must be enabled to use the format function
+ #endif
+ #ifdef ALLOW_FSFPRINTF
+ #error Write functions must be enabled to use the FSfprintf function
+ #endif
+#endif
+
+#ifdef USEREALTIMECLOCK
+ #ifdef USERDEFINEDCLOCK
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#elif defined USERDEFINEDCLOCK
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#endif
+/*****************************************************************************/
+/* Global Variables */
+/*****************************************************************************/
+
+#ifndef FS_DYNAMIC_MEM
+ FSFILE gFileArray[FS_MAX_FILES_OPEN]; // Array that contains file information (static allocation)
+ BYTE gFileSlotOpen[FS_MAX_FILES_OPEN]; // Array that indicates which elements of gFileArray are available for use
+#endif
+
+DWORD gLastFATSectorRead = 0xFFFF; // Global variable indicating which FAT sector was read last
+BYTE gNeedFATWrite = FALSE; // Global variable indicating that there is information that needs to be written to the FAT
+FSFILE * gBufferOwner = NULL; // Global variable indicating which file is using the data buffer
+DWORD gLastDataSectorRead = 0xFFFFFFFF; // Global variable indicating which data sector was read last
+BYTE gNeedDataWrite = FALSE; // Global variable indicating that there is information that needs to be written to the data section
+BYTE nextClusterIsLast = FALSE; // Global variable indicating that the entries in a directory align with a cluster boundary
+
+// Timing variables
+BYTE gTimeCrtMS; // Global time variable (for timestamps) used to indicate create time (milliseconds)
+WORD gTimeCrtTime; // Global time variable (for timestamps) used to indicate create time
+WORD gTimeCrtDate; // Global time variable (for timestamps) used to indicate create date
+WORD gTimeAccDate; // Global time variable (for timestamps) used to indicate last access date
+WORD gTimeWrtTime; // Global time variable (for timestamps) used to indicate last update time
+WORD gTimeWrtDate; // Global time variable (for timestamps) used to indicate last update date
+
+BYTE gBufferZeroed = FALSE; // Global variable indicating that the data buffer contains all zeros
+
+DWORD FatRootDirClusterValue; // Global variable containing the cluster number of the root dir (0 for FAT12/16)
+
+BYTE FSerrno; // Global error variable. Set to one of many error codes after each function call.
+
+DWORD TempClusterCalc; // Global variable used to store the calculated value of the cluster of a specified sector.
+BYTE dirCleared; // Global variable used by the "recursive" FSrmdir function to indicate that all subdirectories and files have been deleted from the target directory.
+BYTE recache = FALSE; // Global variable used by the "recursive" FSrmdir function to indicate that additional cache reads are needed.
+FSFILE tempCWDobj; // Global variable used to preserve the current working directory information.
+FSFILE gFileTemp; // Global variable used for file operations.
+
+#ifdef ALLOW_DIRS
+ FSFILE cwd; // Global current working directory
+ FSFILE * cwdptr = &cwd; // Pointer to the current working directory
+#endif
+
+
+#ifdef __18CXX
+ #pragma udata dataBuffer
+ BYTE gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ #pragma udata FATBuffer
+ BYTE gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE __attribute__ ((aligned(4))) gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ BYTE __attribute__ ((aligned(4))) gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+
+#pragma udata
+
+DISK gDiskData; // Global structure containing device information.
+
+
+
+/************************************************************************/
+/* Structures and defines */
+/************************************************************************/
+
+// Directory entry structure
+typedef struct
+{
+ char DIR_Name[DIR_NAMESIZE]; // File name
+ char DIR_Extension[DIR_EXTENSION]; // File extension
+ BYTE DIR_Attr; // File attributes
+ BYTE DIR_NTRes; // Reserved byte
+ BYTE DIR_CrtTimeTenth; // Create time (millisecond field)
+ WORD DIR_CrtTime; // Create time (second, minute, hour field)
+ WORD DIR_CrtDate; // Create date
+ WORD DIR_LstAccDate; // Last access date
+ WORD DIR_FstClusHI; // High word of the entry's first cluster number
+ WORD DIR_WrtTime; // Last update time
+ WORD DIR_WrtDate; // Last update date
+ WORD DIR_FstClusLO; // Low word of the entry's first cluster number
+ DWORD DIR_FileSize; // The 32-bit file size
+}_DIRENTRY;
+
+typedef _DIRENTRY * DIRENTRY; // A pointer to a directory entry structure
+
+#define DIRECTORY 0x12 // Value indicating that the CreateFileEntry function will be creating a directory
+
+#define DIRENTRIES_PER_SECTOR (MEDIA_SECTOR_SIZE / 32) // The number of directory entries in a sector
+
+// internal errors
+#define CE_FAT_EOF 60 // Error that indicates an attempt to read FAT entries beyond the end of the file
+#define CE_EOF 61 // Error that indicates that the end of the file has been reached
+
+typedef FSFILE * FILEOBJ; // Pointer to an FSFILE object
+
+#ifdef ALLOW_FSFPRINTF
+
+#define _FLAG_MINUS 0x1 // FSfprintf minus flag indicator
+#define _FLAG_PLUS 0x2 // FSfprintf plus flag indicator
+#define _FLAG_SPACE 0x4 // FSfprintf space flag indicator
+#define _FLAG_OCTO 0x8 // FSfprintf octothorpe (hash mark) flag indicator
+#define _FLAG_ZERO 0x10 // FSfprintf zero flag indicator
+#define _FLAG_SIGNED 0x80 // FSfprintf signed flag indicator
+
+#ifdef __18CXX
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONG 1 // FSfprintf 32-bit argument size flag
+ #define _FMT_SHRTLONG 2 // FSfprintf 24-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#else
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONGLONG 1 // FSfprintf 64-bit argument size flag
+ #define _FMT_LONG 2 // FSfprintf 32-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#endif
+
+#ifdef __18CXX
+ static const rom char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#else
+ static const char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#endif
+
+#endif
+
+/************************************************************************************/
+/* Prototypes */
+/************************************************************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls);
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead);
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle);
+DWORD Cluster2Sector(DISK * disk, DWORD cluster);
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle);
+#ifdef INCREMENTTIMESTAMP
+ void IncrementTimeStamp(DIRENTRY dir);
+#elif defined USEREALTIMECLOCK
+ void CacheTime (void);
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE ReadByte( BYTE* pBuffer, WORD index );
+ WORD ReadWord( BYTE* pBuffer, WORD index );
+ DWORD ReadDWord( BYTE* pBuffer, WORD index );
+#endif
+
+// Function pointer that points to a physical layer's MDD_xxxxx_WriteProtectState function
+extern BYTE MDD_WriteProtectState(void);
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource);
+BYTE ValidateChars (char * FileName, BYTE mode);
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode);
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode);
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n);
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type);
+
+// Write functions
+#ifdef ALLOW_WRITES
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry);
+ BYTE flushData (void);
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters);
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode);
+ BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk);
+ DWORD FATfindEmptyCluster(FILEOBJ fo);
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle);
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode);
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster);
+ BYTE EraseCluster(DISK *disk, DWORD cluster);
+ CETYPE CreateFirstCluster(FILEOBJ fo);
+ DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite);
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode);
+#endif
+
+// Directory functions
+#ifdef ALLOW_DIRS
+ BYTE GetPreviousEntry (FSFILE * fo);
+ BYTE FormatDirName (char * string, BYTE mode);
+ int CreateDIR (char * path);
+ BYTE writeDotEntries (DISK * dsk, DWORD dotAddress, DWORD dotdotAddress);
+ int eraseDir (char * path);
+#ifdef ALLOW_PGMFUNCTIONS
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs);
+ #endif
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+#else
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs);
+ #endif
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+#endif
+#endif
+
+#ifdef ALLOW_FSFPRINTF
+ #ifdef __18CXX
+ int FSvfprintf (auto FSFILE *handle, auto const rom char *formatString, auto va_list ap);
+ #else
+ int FSvfprintf (FSFILE *handle, const char *formatString, va_list ap);
+ #endif
+ int FSputc (char c, FSFILE * file);
+ unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c);
+#endif
+
+BYTE DISKmount( DISK *dsk);
+BYTE LoadMBR(DISK *dsk);
+BYTE LoadBootSector(DISK *dsk);
+DWORD GetFullClusterNumber(DIRENTRY entry);
+
+
+/*************************************************************************
+ Function:
+ int FSInit(void)
+ Summary:
+ Function to initialize the device.
+ Conditions:
+ The physical device should be connected to the microcontroller.
+ Input:
+ None
+ Return Values:
+ TRUE - Initialization successful
+ FALSE - Initialization unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Initializes the static or dynamic memory slots for holding file
+ structures. Initializes the device with the DISKmount function. Loads
+ MBR and boot sector information. Initializes the current working
+ directory to the root directory for the device if directory support
+ is enabled.
+ Remarks:
+ None
+ *************************************************************************/
+
+int FSInit(void)
+{
+ int fIndex;
+#ifndef FS_DYNAMIC_MEM
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ gFileSlotOpen[fIndex] = TRUE;
+#else
+ #ifdef __18CXX
+ SRAMInitHeap();
+ #endif
+#endif
+
+ gBufferZeroed = FALSE;
+
+ MDD_InitIO();
+
+ if(DISKmount(&gDiskData) == CE_GOOD)
+ {
+ // Initialize the current working directory to the root
+#ifdef ALLOW_DIRS
+ cwdptr->dsk = &gDiskData;
+ cwdptr->sec = 0;
+ cwdptr->pos = 0;
+ cwdptr->seek = 0;
+ cwdptr->size = 0;
+ cwdptr->name[0] = '\\';
+ for (fIndex = 1; fIndex < 11; fIndex++)
+ {
+ cwdptr->name[fIndex] = 0x20;
+ }
+ cwdptr->entry = 0;
+ cwdptr->attributes = ATTR_DIRECTORY;
+ // "FatRootDirClusterValue" indicates the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+#endif
+
+ FSerrno = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/********************************************************************************
+ Function:
+ CETYPE FILEfind (FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+ Summary
+ Finds a file on the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - FSFILE object containing information of the file found
+ foCompareTo - FSFILE object containing the name/attr of the file to be
+ found
+ cmd -
+ - LOOK_FOR_EMPTY_ENTRY: Search for empty entry.
+ - LOOK_FOR_MATCHING_ENTRY: Search for matching entry.
+ mode -
+ - 0: Match file exactly with default attributes.
+ - 1: Match file to user-specified attributes.
+ Return Values:
+ CE_GOOD - File found.
+ CE_FILE_NOT_FOUND - File not found.
+ Side Effects:
+ None.
+ Description:
+ The FILEfind function will sequentially cache directory entries within
+ the current working directory into the foDest FSFILE object. If the cmd
+ parameter is specified as LOOK_FOR_EMPTY_ENTRY the search will continue
+ until an empty directory entry is found. If the cmd parameter is specified
+ as LOOK_FOR_MATCHING_ENTRY these entries will be compared to the foCompareTo
+ object until a match is found or there are no more entries in the current
+ working directory. If the mode is specified a '0' the attributes of the FSFILE
+ entries are irrelevant. If the mode is specified as '1' the attributes of the
+ foDest entry must match the attributes specified in the foCompareTo file and
+ partial string search characters may bypass portions of the comparison.
+ Remarks:
+ None
+ ********************************************************************************/
+
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+{
+ WORD attrib, compareAttrib;
+ WORD fHandle = foDest->entry; // current entry counter
+ BYTE state,index; // state of the current object
+ CETYPE statusB = CE_FILE_NOT_FOUND;
+ BYTE character,test;
+
+ // reset the cluster
+ foDest->dirccls = foDest->dirclus;
+ compareAttrib = 0xFFFF ^ foCompareTo->attributes; // Attribute to be compared as per application layer request
+
+ if (fHandle == 0)
+ {
+ if (Cache_File_Entry(foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ if ((fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) != 0) // Maximum 16 entries possible
+ {
+ if (Cache_File_Entry (foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ if (statusB != CE_BADCACHEREAD)
+ {
+ // Loop until you reach the end or find the file
+ while(1)
+ {
+ if(statusB!=CE_GOOD) //First time entry always here
+ {
+ state = Fill_File_Object(foDest, &fHandle);
+ if(state == NO_MORE) // Reached the end of available files. Comparision over and file not found so quit.
+ {
+ break;
+ }
+ }
+ else // statusB == CE_GOOD then exit
+ {
+ break; // Code below intializes"statusB = CE_GOOD;" so, if no problem in the filled file, Exit the while loop.
+ }
+
+ if(state == FOUND) // Validate the correct matching of filled file data with the required(to be found) one.
+ {
+ /* We got something */
+ // get the attributes
+ attrib = foDest->attributes;
+
+ attrib &= ATTR_MASK;
+ switch (mode)
+ {
+ case 0:
+ // see if we are a volume id or hidden, ignore
+ if(attrib != ATTR_VOLUME)
+ {
+ statusB = CE_GOOD;
+ character = (BYTE)'m'; // random value
+
+ // search for one. if status = TRUE we found one
+ for(index = 0; index < DIR_NAMECOMP; index++)
+ {
+ // get the source character
+ character = foDest->name[index];
+ // get the destination character
+ test = foCompareTo->name[index];
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // Nope its not a match
+ break;
+ }
+ }// for loop
+ } // not dir nor vol
+ break;
+
+ case 1:
+ // Check for attribute match
+ if (((attrib & compareAttrib) == 0) && (attrib != ATTR_LONG_NAME))
+ {
+ statusB = CE_GOOD; // Indicate the already filled file data is correct and go back
+ character = (BYTE)'m'; // random value
+ if (foCompareTo->name[0] != '*') //If "*" is passed for comparion as 1st char then don't proceed. Go back, file alreay found.
+ {
+ for (index = 0; index < DIR_NAMESIZE; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ // Before calling this "FILEfind" fn, "formatfilename" must be called. Hence, extn always starts from position "8".
+ if ((foCompareTo->name[8] != '*') && (statusB == CE_GOOD))
+ {
+ for (index = 8; index < DIR_NAMECOMP; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ } // Attribute match
+
+ break;
+ }
+ } // not found
+ else
+ {
+ /*** looking for an empty/re-usable entry ***/
+ if ( cmd == LOOK_FOR_EMPTY_ENTRY)
+ statusB = CE_GOOD;
+ } // found or not
+
+ // increment it no matter what happened
+ fHandle++;
+
+ }// while
+ }
+
+ return(statusB);
+} // FILEFind
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+ Summary:
+ Loads file information from the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File to be opened
+ fHandle - Location of file
+ type -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ Return Values:
+ CE_GOOD - FILEopen successful
+ CE_NOT_INIT - Device is not yet initialized
+ CE_FILE_NOT_FOUND - Could not find the file on the device
+ CE_BAD_SECTOR_READ - A bad read of a sector occured
+ Side Effects:
+ None
+ Description:
+ This function will cache a directory entry in the directory specified
+ by the dirclus parameter of hte FSFILE object 'fo.' The offset of the
+ entry in the directory is specified by fHandle. Once the directory entry
+ has been loaded, the first sector of the file can be loaded using the
+ cluster value specified in the directory entry. The type argument will
+ specify the mode the files will be opened in. This will allow this
+ function to set the correct read/write flags for the file.
+ Remarks:
+ If the mode the file is being opened in is a plus mode (e.g. READ+) the
+ flags will be modified further in the FSfopen function.
+ **************************************************************************/
+
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+{
+ DISK *dsk; //Disk structure
+ BYTE r; //Result of search for file
+ DWORD l; //lba of first sector of first cluster
+ CETYPE error = CE_GOOD;
+
+ dsk = (DISK *)(fo->dsk);
+ if (dsk->mount == FALSE)
+ {
+ error = CE_NOT_INIT;
+ }
+ else
+ {
+ // load the sector
+ fo->dirccls = fo->dirclus;
+ // Cache no matter what if it's the first entry
+ if (*fHandle == 0)
+ {
+ if (Cache_File_Entry(fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ // If it's not the first, only cache it if it's
+ // not divisible by the number of entries per sector
+ // If it is, Fill_File_Object will cache it
+ if ((*fHandle & 0xf) != 0)
+ {
+ if (Cache_File_Entry (fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ r = Fill_File_Object(fo, fHandle);
+ if (r != FOUND)
+ error = CE_FILE_NOT_FOUND;
+ else
+ {
+ fo->seek = 0; // first byte in file
+ fo->ccls = fo->cluster; // first cluster
+ fo->sec = 0; // first sector in the cluster
+ fo->pos = 0; // first byte in sector/cluster
+
+ if ( r == NOT_FOUND)
+ {
+ error = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Determine the lba of the selected sector and load
+ l = Cluster2Sector(dsk,fo->ccls);
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+#endif
+ gBufferOwner = fo;
+ if (gLastDataSectorRead != l)
+ {
+ gBufferZeroed = FALSE;
+ if ( !MDD_SectorRead( l, dsk->buffer))
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = l;
+ }
+ } // -- found
+
+ fo->flags.FileWriteEOF = FALSE;
+ // Set flag for operation type
+#ifdef ALLOW_WRITES
+ if (type == 'w' || type == 'a')
+ {
+ fo->flags.write = 1; //write or append
+ fo->flags.read = 0;
+ }
+ else
+ {
+#endif
+ fo->flags.write = 0; //read
+ fo->flags.read = 1;
+#ifdef ALLOW_WRITES
+ } // -- flags
+#endif
+ } // -- r = Found
+ } // -- Mounted
+ return (error);
+} // -- FILEopen
+
+
+/*************************************************************************
+ Function:
+ BYTE FILEget_next_cluster(FILEOBJ fo, WORD n)
+ Summary:
+ Step through a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file to get the next cluster of
+ n - Number of links in the FAT cluster chain to jump through
+ Return Values:
+ CE_GOOD - Operation successful
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_INVALID_CLUSTER - Invalid cluster value \> maxcls
+ CE_FAT_EOF - Fat attempt to read beyond EOF
+ Side Effects:
+ None
+ Description:
+ This function will load 'n' proximate clusters for a file from
+ the FAT on the device. It will stop checking for clusters if the
+ ReadFAT function returns an error, if it reaches the last cluster in
+ a file, or if the device tries to read beyond the last cluster used
+ by the device.
+ Remarks:
+ None
+ *************************************************************************/
+
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n)
+{
+ DWORD c, c2, ClusterFailValue, LastClustervalue;
+ BYTE error = CE_GOOD;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ LastClustervalue = LAST_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT12:
+ LastClustervalue = LAST_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT16:
+ default:
+ LastClustervalue = LAST_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // loop n times
+ do
+ {
+ // get the next cluster link from FAT
+ c2 = fo->ccls;
+ if ( (c = ReadFAT( disk, c2)) == ClusterFailValue)
+ error = CE_BAD_SECTOR_READ;
+ else
+ {
+ // check if cluster value is valid
+ if ( c >= disk->maxcls)
+ {
+ error = CE_INVALID_CLUSTER;
+ }
+
+ // compare against max value of a cluster in FAT
+ // return if eof
+ if ( c >= LastClustervalue) // check against eof
+ {
+ error = CE_FAT_EOF;
+ }
+ }
+
+ // update the FSFILE structure
+ fo->ccls = c;
+
+ } while (--n > 0 && error == CE_GOOD);// loop end
+
+ return(error);
+} // get next cluster
+
+
+/**************************************************************************
+ Function:
+ BYTE DISKmount ( DISK *dsk)
+ Summary:
+ Initialies the device and loads MBR and boot sector information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure to be initialized.
+ Return Values:
+ CE_GOOD - Disk mounted
+ CE_INIT_ERROR - Initialization error has occured
+ Side Effects:
+ None
+ Description:
+ This function will use the function pointed to by the MDD_MediaInitialize
+ function pointer to initialize the device (if any initialization is
+ required). It then attempts to load the master boot record with the
+ LoadMBR function and the boot sector with the LoadBootSector function.
+ These two functions will be used to initialize a global DISK structure
+ that will be used when accessing file information in the future.
+ Remarks:
+ None
+ **************************************************************************/
+
+BYTE DISKmount( DISK *dsk)
+{
+ BYTE error = CE_GOOD;
+
+ dsk->mount = FALSE; // default invalid
+ dsk->buffer = gDataBuffer; // assign buffer
+
+ // Initialize the device
+ if(MDD_MediaInitialize() != TRUE)
+ {
+ error = CE_INIT_ERROR;
+ FSerrno = CE_INIT_ERROR;
+ }
+ else
+ {
+ // Load the Master Boot Record (partition)
+ if((error = LoadMBR(dsk)) == CE_GOOD)
+ {
+ // Now the boot sector
+ if((error = LoadBootSector(dsk)) == CE_GOOD)
+ dsk->mount = TRUE; // Mark that the DISK mounted successfully
+ }
+ } // -- Load file parameters
+
+ return(error);
+} // -- mount
+
+
+
+/********************************************************************
+ Function:
+ CETYPE LoadMBR ( DISK *dsk)
+ Summary:
+ Loads the MBR and extracts necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the master boot record to be loaded
+ Return Values:
+ CE_GOOD - MBR loaded successfully
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_BAD_PARTITION - The boot record is bad
+ Side Effects:
+ None
+ Description:
+ The LoadMBR function will use the function pointed to by the
+ MDD_SectorRead function pointer to read the 0 sector from the
+ device. If a valid boot signature is obtained, this function
+ will compare fields in that cached sector to the values that
+ would be present if that sector was a boot sector. If all of
+ those values match, it will be assumed that the device does not
+ have a master boot record and the 0 sector is actually the boot
+ sector. Otherwise, data about the partition and the actual
+ location of the boot sector will be loaded from the MBR into
+ the DISK structure pointed to by 'dsk.'
+ Remarks:
+ None
+ ********************************************************************/
+
+BYTE LoadMBR(DISK *dsk)
+{
+ PT_MBR Partition;
+ BYTE error = CE_GOOD;
+ BYTE type;
+ BootSec BSec;
+
+ // Get the partition table from the MBR
+ if ( MDD_SectorRead( FO_MBR, dsk->buffer) != TRUE)
+ {
+ error = CE_BAD_SECTOR_READ;
+ FSerrno = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ // Check if the card has no MBR
+ BSec = (BootSec) dsk->buffer;
+
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( dsk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT16;
+ return CE_GOOD;
+ }
+ else
+ {
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FAT32_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 3 ) == '3' && \
+ ReadByte( dsk->buffer, BSI_FAT32_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_32.BootSec_FilSysType[0] == 'F' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[1] == 'A' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[2] == 'T' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[3] == '3' && \
+ BSec->FAT.FAT_32.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT32;
+ return CE_GOOD;
+ }
+ }
+ }
+ // assign it the partition table strucutre
+ Partition = (PT_MBR)dsk->buffer;
+
+ // Ensure its good
+ if((Partition->Signature0 != FAT_GOOD_SIGN_0) || (Partition->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_BAD_PARTITION;
+ error = CE_BAD_PARTITION;
+ }
+ else
+ {
+ /* Valid Master Boot Record Loaded */
+
+ // Get the 32 bit offset to the first partition
+ dsk->firsts = Partition->Partition0.PTE_FrstSect;
+
+ // check if the partition type is acceptable
+ type = Partition->Partition0.PTE_FSDesc;
+
+ switch (type)
+ {
+ case 0x01:
+ dsk->type = FAT12;
+ break;
+
+ case 0x04:
+ case 0x06:
+ case 0x0E:
+ dsk->type = FAT16;
+ break;
+
+ case 0x0B:
+ case 0x0C:
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ dsk->type = FAT32; // FAT32 is supported too
+#else
+ FSerrno = CE_CARDFAT32;
+ error = CE_CARDFAT32;
+#endif
+ break;
+
+ default:
+ FSerrno = CE_UNSUPPORTED_FS;
+ error = CE_UNSUPPORTED_FS;
+ } // switch
+ }
+ }
+
+ return(error);
+}// -- LoadMBR
+
+
+/**************************************************************************
+ Function:
+ BYTE LoadBootSector (DISK *dsk)
+ Summary:
+ Load the boot sector and extract the necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the boot sector
+ Return Values:
+ CE_GOOD - Boot sector loaded
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_NOT_FORMATTED - The disk is of an unsupported format
+ CE_CARDFAT32 - FAT 32 device not supported
+ Side Effects:
+ None
+ Description:
+ LoadBootSector will use the function pointed to by the MDD_SectorWrite
+ function pointer to load the boot sector, whose location was obtained
+ by a previous call of LoadMBR. If the boot sector is loaded successfully,
+ partition information will be calcualted from it and copied into the DISK
+ structure pointed to by 'dsk.'
+ Remarks:
+ None
+ **************************************************************************/
+
+
+BYTE LoadBootSector(DISK *dsk)
+{
+ DWORD RootDirSectors;
+ DWORD TotSec,DataSec;
+ BYTE error = CE_GOOD;
+ BootSec BSec;
+ WORD BytesPerSec;
+ WORD ReservedSectorCount;
+
+ // Get the Boot sector
+ if ( MDD_SectorRead( dsk->firsts, dsk->buffer) != TRUE)
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ BSec = (BootSec)dsk->buffer;
+
+ //Verify the Boot Sector is valid
+ if((BSec->Signature0 != FAT_GOOD_SIGN_0) || (BSec->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ error = CE_NOT_FORMATTED;
+ }
+ else
+ {
+ #ifdef __18CXX
+
+ // Load count of sectors per cluster
+ dsk->SecPerClus = BSec->FAT.FAT_16.BootSec_SPC;
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + BSec->FAT.FAT_16.BootSec_ResrvSec;
+ // Load the count of FAT tables
+ dsk->fatcopy = BSec->FAT.FAT_16.BootSec_FATCount;
+ // Load the size of the FATs
+ dsk->fatsize = BSec->FAT.FAT_16.BootSec_SPF;
+ if(dsk->fatsize == 0)
+ dsk->fatsize = BSec->FAT.FAT_32.BootSec_FATSz32;
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = BSec->FAT.FAT_16.BootSec_RootDirEnts;
+
+ // Determine the total number of sectors in the partition
+ if(BSec->FAT.FAT_16.BootSec_TotSec16 != 0)
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec16;
+ }
+ else
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec32;
+ }
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = BSec->FAT.FAT_16.BootSec_BPS;
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((BSec->FAT.FAT_16.BootSec_RootDirEnts * 32) + (BSec->FAT.FAT_16.BootSec_BPS - 1)) / BSec->FAT.FAT_16.BootSec_BPS;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (dsk->root + RootDirSectors) + dsk->firsts + 2;
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #else // PIC24/30/33
+
+ // Read the count of reserved sectors
+ ReservedSectorCount = ReadWord( dsk->buffer, BSI_RESRVSEC );
+ // Load the count of sectors per cluster
+ dsk->SecPerClus = ReadByte( dsk->buffer, BSI_SPC );
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + ReservedSectorCount;
+ // Load the count of FAT tables
+ dsk->fatcopy = ReadByte( dsk->buffer, BSI_FATCOUNT );
+ // Load the size of the FATs
+ dsk->fatsize = ReadWord( dsk->buffer, BSI_SPF );
+ if(dsk->fatsize == 0)
+ dsk->fatsize = ReadDWord( dsk->buffer, BSI_FATSZ32 );
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = ReadWord( dsk->buffer, BSI_ROOTDIRENTS );
+
+ // Determine the total number of sectors in the partition
+ TotSec = ReadWord( dsk->buffer, BSI_TOTSEC16 );
+ if( TotSec == 0 )
+ TotSec = ReadDWord( dsk->buffer, BSI_TOTSEC32 );
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = ReadWord( dsk->buffer, BSI_BPS );
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((dsk->maxroot * NUMBER_OF_BYTES_IN_DIR_ENTRY) + (BytesPerSec - 1)) / BytesPerSec;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (ReservedSectorCount + (dsk->fatcopy * dsk->fatsize ) + RootDirSectors );
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #endif
+
+ // Determine the file system type based on the number of clusters used
+ if(dsk->maxcls < 4085)
+ {
+ dsk->type = FAT12;
+ }
+ else
+ {
+ if(dsk->maxcls < 65525)
+ {
+ dsk->type = FAT16;
+ }
+ else
+ {
+ #ifdef SUPPORT_FAT32
+ dsk->type = FAT32;
+ #else
+ error = CE_CARDFAT32;
+ FSerrno = CE_CARDFAT32;
+ #endif
+ }
+ }
+
+ #ifdef SUPPORT_FAT32
+ if (dsk->type == FAT32)
+ {
+ #ifdef __18CXX
+ FatRootDirClusterValue = BSec->FAT.FAT_32.BootSec_RootClus;
+ #else
+ FatRootDirClusterValue = ReadDWord( dsk->buffer, BSI_ROOTCLUS );
+ #endif
+ dsk->data = dsk->root + RootDirSectors;
+ }
+ else
+ #endif
+ {
+ FatRootDirClusterValue = 0;
+ dsk->data = dsk->root + ( dsk->maxroot >> 4);
+ }
+
+ #ifdef __18CXX
+ if(BSec->FAT.FAT_16.BootSec_BPS != MEDIA_SECTOR_SIZE)
+ #else
+ if(BytesPerSec != MEDIA_SECTOR_SIZE)
+ #endif
+ {
+ error = CE_NOT_FORMATTED;
+ FSerrno = CE_NOT_FORMATTED;
+ }
+ }
+ }
+ return(error);
+}
+
+
+
+/*************************************************************************
+ Function:
+ DWORD GetFullClusterNumber (DIRENTRY entry)
+ Summary:
+ Gets the cluster number from a directory entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ entry - The cached directory entry to get the cluster number from
+ Returns:
+ The cluster value from the passed directory entry
+ Side Effects:
+ None.
+ Description:
+ This function will load both the high and low 16-bit first cluster
+ values of a file from a directory entry and copy them into a 32-bit
+ cluster number variable, which will be returned.
+ Remarks:
+ None
+ *************************************************************************/
+
+DWORD GetFullClusterNumber(DIRENTRY entry)
+{
+
+ DWORD TempFullClusterCalc = 0;
+
+#ifndef SUPPORT_FAT32 // If FAT32 Not supported.
+ entry->DIR_FstClusHI = 0; // If FAT32 is not supported then Higher Word of the address is "0"
+#endif
+
+ // Get the cluster
+ TempFullClusterCalc = (entry->DIR_FstClusHI);
+ TempFullClusterCalc = TempFullClusterCalc << 16;
+ TempFullClusterCalc |= entry->DIR_FstClusLO;
+
+ return TempFullClusterCalc;
+}
+
+
+#ifdef ALLOW_FORMATS
+#ifdef ALLOW_WRITES
+
+
+/*********************************************************************************
+ Function:
+ int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+ Summary:
+ Creates a master boot record
+ Conditions:
+ The I/O pins for the device have been initialized by the InitIO function.
+ Input:
+ firstSector - The first sector of the partition on the device (cannot
+ be 0; that's the MBR)
+ numSectors - The number of sectors available in memory (including the
+ MBR)
+ Return Values:
+ 0 - MBR was created successfully
+ EOF - MBR could not be created
+ Side Effects:
+ None
+ Description:
+ This function can be used to create a master boot record for a device. Note
+ that this function should not be used on a device that is already formatted
+ with a master boot record (i.e. most SD cards, CF cards, USB keys). This
+ function will fill the global data buffer with appropriate partition information
+ for a FAT partition with a type determined by the number of sectors available
+ to the partition. It will then write the MBR information to the first sector
+ on the device. This function should be followed by a call to FSformat, which
+ will create a boot sector, root dir, and FAT appropriate the the information
+ contained in the new master boot record. Note that FSformat only supports
+ FAT12 and FAT16 formatting at this time, and so cannot be used to format a
+ device with more than 0x3FFD5F sectors.
+ Remarks:
+ This function can damage the device being used, and should not be called
+ unless the user is sure about the size of the device and the first sector value.
+ *********************************************************************************/
+
+int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+{
+ PT_MBR Partition;
+ DWORD CyHdSc = 0x00000000;
+ DWORD tempSector;
+
+ if ((firstSector == 0) || (numSectors <= 1))
+ return EOF;
+
+ if (firstSector > (numSectors - 1))
+ return EOF;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ return EOF;
+
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ Partition = (PT_MBR) gDataBuffer;
+
+ // Set Cylinder-head-sector address of the first sector
+ tempSector = firstSector;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[447] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[448] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[449] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the count of sectors
+ Partition->Partition0.PTE_NumSect = numSectors - firstSector;
+
+ // Set the partition type
+ // We only support creating FAT12 and FAT16 MBRs at this time
+ if (Partition->Partition0.PTE_NumSect < 0x1039)
+ {
+ // FAT12
+ Partition->Partition0.PTE_FSDesc = 0x01;
+ }
+ else if (Partition->Partition0.PTE_NumSect <= 0x3FFD5F)
+ {
+ // FAT16
+ Partition->Partition0.PTE_FSDesc = 0x06;
+ }
+ else
+ return EOF;
+
+ // Set the LBA of the first sector
+ Partition->Partition0.PTE_FrstSect = firstSector;
+
+ // Set the Cylinder-head-sector address of the last sector
+ tempSector = firstSector + numSectors - 1;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[451] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[452] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[453] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the boot descriptor. This will be 0, since we won't
+ // be booting anything from our device probably
+ Partition->Partition0.PTE_BootDes = 0x00;
+
+ // Set the signature codes
+ Partition->Signature0 = 0x55;
+ Partition->Signature1 = 0xAA;
+
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) != TRUE)
+ return EOF;
+ else
+ return 0;
+
+}
+
+
+
+/*******************************************************************
+ Function:
+ int FSformat (char mode, long int serialNumber, char * volumeID)
+ Summary:
+ Formats a device
+ Conditions:
+ The device must possess a valid master boot record.
+ Input:
+ mode - - 0 - Just erase the FAT and root
+ - 1 - Create a new boot sector
+ serialNumber - Serial number to write to the card
+ volumeID - Name of the card
+ Return Values:
+ 0 - Format was successful
+ EOF - Format was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSformat function can be used to create a new boot sector
+ on a device, based on the information in the master boot record.
+ This function will first initialize the I/O pins and the device,
+ and then attempts to read the master boot record. If the MBR
+ cannot be loaded successfully, the function will fail. Next, if
+ the 'mode' argument is specified as '0' the existing boot sector
+ information will be loaded. If the 'mode' argument is '1' an
+ entirely new boot sector will be constructed using the disk
+ values from the master boot record. Once the boot sector has
+ been successfully loaded/created, the locations of the FAT and
+ root will be loaded from it, and they will be completely
+ erased. If the user has specified a volumeID parameter, a
+ VOLUME attribute entry will be created in the root directory
+ to name the device.
+ Remarks:
+ FAT12 and FAT16 formatting is supported.
+ *******************************************************************/
+
+int FSformat (char mode, long int serialNumber, char * volumeID)
+{
+ PT_MBR masterBootRecord;
+ DWORD secCount, FAT16DataClusters, RootDirSectors;
+ BootSec BSec;
+ DISK d;
+ DISK * disk = &d;
+ WORD j;
+ DWORD fatsize, test;
+ BYTE Index;
+#ifdef __18CXX
+ // This is here because of a C18 compiler feature
+ BYTE * dataBufferPointer = gDataBuffer;
+#endif
+
+ FSerrno = CE_GOOD;
+
+ disk->buffer = gDataBuffer;
+
+ MDD_InitIO();
+
+ if (MDD_MediaInitialize() != TRUE)
+ {
+ FSerrno = CE_INIT_ERROR;
+ return EOF;
+ }
+
+ if (MDD_SectorRead (0x00, gDataBuffer) == FALSE)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+
+ // Check if the card has no MBR
+ BSec = (BootSec) disk->buffer;
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( disk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( disk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ switch (mode)
+ {
+ case 1:
+ // not enough info to construct our own boot sector
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ case 0:
+ // We have to determine the operating system, and the
+ // locations and sizes of the root dir and FAT, and the
+ // count of FATs
+ disk->firsts = 0;
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ default:
+ break;
+ }
+ }
+ else
+ {
+ masterBootRecord = (PT_MBR) &gDataBuffer;
+ disk->firsts = masterBootRecord->Partition0.PTE_FrstSect;
+ }
+ }
+
+ switch (mode)
+ {
+ // True: Rewrite the whole boot sector
+ case 1:
+ secCount = masterBootRecord->Partition0.PTE_NumSect;
+
+ if (secCount < 0x1039)
+ {
+ disk->type = FAT12;
+ // Format to FAT12 only if there are too few sectors to format
+ // as FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x01;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ if (secCount >= 0x1028)
+ {
+ // More than 0x18 sectors for FATs, 0x20 for root dir,
+ // 0x8 reserved, and 0xFED for data
+ // So double the number of sectors in a cluster to reduce
+ // the number of data clusters used
+ disk->SecPerClus = 2;
+ }
+ else
+ {
+ // One sector per cluster
+ disk->SecPerClus = 1;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT12 )
+ gDataBuffer[58] = '2';
+ }
+ else if (secCount <= 0x3FFD5F)
+ {
+ disk->type = FAT16;
+ // Format to FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x06;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ FAT16DataClusters = secCount - 0x218;
+ // Figure out how many sectors per cluster we need
+ disk->SecPerClus = 1;
+ while (FAT16DataClusters > 0xFFED)
+ {
+ disk->SecPerClus *= 2;
+ FAT16DataClusters /= 2;
+ }
+ // This shouldnt happen
+ if (disk->SecPerClus > 128)
+ {
+ FSerrno = CE_BAD_PARTITION;
+ return EOF;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT16 )
+ gDataBuffer[58] = '6';
+ }
+ else
+ {
+ // Cannot format; too many sectors
+ FSerrno = CE_NONSUPPORTED_SIZE;
+ return EOF;
+ }
+
+ // Calculate the size of the FAT
+ fatsize = (secCount - 0x21 + (2*disk->SecPerClus));
+ if (disk->type == FAT12)
+ test = (341 * disk->SecPerClus) + 2;
+ else
+ test = (256 * disk->SecPerClus) + 2;
+ fatsize = (fatsize + (test-1)) / test;
+ // Non-file system specific values
+ gDataBuffer[0] = 0xEB; //Jump instruction
+ gDataBuffer[1] = 0x3C;
+ gDataBuffer[2] = 0x90;
+ gDataBuffer[3] = 'M'; //OEM Name "MCHP FAT"
+ gDataBuffer[4] = 'C';
+ gDataBuffer[5] = 'H';
+ gDataBuffer[6] = 'P';
+ gDataBuffer[7] = ' ';
+ gDataBuffer[8] = 'F';
+ gDataBuffer[9] = 'A';
+ gDataBuffer[10] = 'T';
+ gDataBuffer[11] = 0x00; //Bytes per sector - 512
+ gDataBuffer[12] = 0x02;
+ gDataBuffer[13] = disk->SecPerClus; //Sectors per cluster
+ gDataBuffer[14] = 0x08; //Reserved sector count
+ gDataBuffer[15] = 0x00;
+ disk->fat = 0x08 + disk->firsts;
+ gDataBuffer[16] = 0x02; //number of FATs
+ disk->fatcopy = 0x02;
+ gDataBuffer[17] = 0x00; //Max number of root directory entries - 512 files allowed
+ gDataBuffer[18] = 0x02;
+ disk->maxroot = 0x200;
+ gDataBuffer[19] = 0x00; //total sectors
+ gDataBuffer[20] = 0x00;
+ gDataBuffer[21] = 0xF8; //Media Descriptor
+ gDataBuffer[22] = fatsize & 0xFF; //Sectors per FAT
+ gDataBuffer[23] = (fatsize >> 8) & 0xFF;
+ disk->fatsize = fatsize;
+ gDataBuffer[24] = 0x3F; //Sectors per track
+ gDataBuffer[25] = 0x00;
+ gDataBuffer[26] = 0xFF; //Number of heads
+ gDataBuffer[27] = 0x00;
+ // Hidden sectors = sectors between the MBR and the boot sector
+ gDataBuffer[28] = (BYTE)(disk->firsts & 0xFF);
+ gDataBuffer[29] = (BYTE)((disk->firsts / 0x100) & 0xFF);
+ gDataBuffer[30] = (BYTE)((disk->firsts / 0x10000) & 0xFF);
+ gDataBuffer[31] = (BYTE)((disk->firsts / 0x1000000) & 0xFF);
+ // Total Sectors = same as sectors in the partition from MBR
+ gDataBuffer[32] = (BYTE)(secCount & 0xFF);
+ gDataBuffer[33] = (BYTE)((secCount / 0x100) & 0xFF);
+ gDataBuffer[34] = (BYTE)((secCount / 0x10000) & 0xFF);
+ gDataBuffer[35] = (BYTE)((secCount / 0x1000000) & 0xFF);
+ gDataBuffer[36] = 0x00; // Physical drive number
+ gDataBuffer[37] = 0x00; // Reserved (current head)
+ gDataBuffer[38] = 0x29; // Signature code
+ gDataBuffer[39] = (BYTE)(serialNumber & 0xFF);
+ gDataBuffer[40] = (BYTE)((serialNumber / 0x100) & 0xFF);
+ gDataBuffer[41] = (BYTE)((serialNumber / 0x10000) & 0xFF);
+ gDataBuffer[42] = (BYTE)((serialNumber / 0x1000000) & 0xFF);
+ // Volume ID
+ if (volumeID != NULL)
+ {
+ for (Index = 0; (*(volumeID + Index) != 0) && (Index < 11); Index++)
+ {
+ gDataBuffer[Index + 43] = *(volumeID + Index);
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[43 + Index++] = 0x20;
+ }
+ }
+ else
+ {
+ for (Index = 0; Index < 11; Index++)
+ {
+ gDataBuffer[Index+43] = 0;
+ }
+ }
+ gDataBuffer[54] = 'F';
+ gDataBuffer[55] = 'A';
+ gDataBuffer[56] = 'T';
+ gDataBuffer[57] = '1';
+ gDataBuffer[59] = ' ';
+ gDataBuffer[60] = ' ';
+ gDataBuffer[61] = ' ';
+#ifdef __18CXX
+ // C18 can't reference a value greater than 256
+ // using an array name pointer
+ *(dataBufferPointer + 510) = 0x55;
+ *(dataBufferPointer + 511) = 0xAA;
+#else
+ gDataBuffer[510] = 0x55;
+ gDataBuffer[511] = 0xAA;
+#endif
+
+ disk->root = disk->fat + (disk->fatcopy * disk->fatsize);
+
+ if (MDD_SectorWrite (disk->firsts, gDataBuffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ break;
+ case 0:
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ break;
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ }
+
+ // Erase the FAT
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+ gDataBuffer[0] = 0xF8;
+ gDataBuffer[1] = 0xFF;
+ gDataBuffer[2] = 0xFF;
+ if (disk->type == FAT16)
+ gDataBuffer[3] = 0xFF;
+
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (disk->fat + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ memset (gDataBuffer, 0x00, 4);
+
+ for (Index = disk->fat + 1; Index < (disk->fat + disk->fatsize); Index++)
+ {
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (Index + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ }
+
+ // Erase the root directory
+ RootDirSectors = ((disk->maxroot * 32) + (0x200 - 1)) / 0x200;
+
+ for (Index = 1; Index < RootDirSectors; Index++)
+ {
+ if (MDD_SectorWrite (disk->root + Index, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ if (volumeID != NULL)
+ {
+ // Create a drive name entry in the root dir
+ Index = 0;
+ while ((*(volumeID + Index) != 0) && (Index < 11))
+ {
+ gDataBuffer[Index] = *(volumeID + Index);
+ Index++;
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[Index++] = ' ';
+ }
+ gDataBuffer[11] = 0x08;
+ gDataBuffer[17] = 0x11;
+ gDataBuffer[19] = 0x11;
+ gDataBuffer[23] = 0x11;
+
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ else
+ {
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ return 0;
+}
+#endif
+#endif
+
+
+/*******************************************************
+ Function:
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+ Summary:
+ Write dir entry info into a specified entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - \File structure
+ curEntry - Write destination
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will calculate the sector of the
+ directory (whose base sector is pointed to by the
+ dirccls value in the FSFILE object 'fo') that contains
+ a directory entry whose offset is indicated by the
+ curEntry parameter. It will then write the data
+ in the global data buffer (which should already
+ contain the entries for that sector) to the device.
+ Remarks:
+ None
+ *******************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+{
+ DISK *dsk;
+ BYTE status;
+ BYTE offset2;
+ DWORD sector;
+ DWORD ccls;
+
+ dsk = fo->dsk;
+
+ // get the cluster of this entry
+ ccls = fo->dirccls;
+
+ // if its not the root, it's cluster based
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // Root is always cluster-based in FAT32
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ if(ccls != FatRootDirClusterValue)
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+ }
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ // Now write it
+ // "Offset" ensures writing of data belonging to a file entry only. Hence it doesn't change other file entries.
+ if ( !MDD_SectorWrite( sector + offset2, dsk->buffer, FALSE))
+ status = FALSE;
+ else
+ status = TRUE;
+
+ return(status);
+} // Write_File_Entry
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE FAT_erase_cluster_chain (WORD cluster, DISK * dsk)
+ Summary:
+ Erase a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ cluster - The cluster number
+ dsk - The disk structure
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will parse through a cluster chain
+ starting with the cluster pointed to by 'cluster' and
+ mark all of the FAT entries as empty until the end of
+ the chain has been reached or an error occurs.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk)
+{
+ DWORD c,c2,ClusterFailValue;
+ enum _status {Good, Fail, Exit}status;
+
+ status = Good;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ c2 = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT16:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ c2 = LAST_CLUSTER_FAT16;
+ break;
+
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16; // FAT16 value itself
+ c2 = LAST_CLUSTER_FAT12;
+ break;
+ }
+
+ // Make sure there is actually a cluster assigned
+ if(cluster == 0 || cluster == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ while(status == Good)
+ {
+ // Get the FAT entry
+ if((c = ReadFAT( dsk, cluster)) == ClusterFailValue)
+ status = Fail;
+ else
+ {
+ if(c == 0 || c == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ // compare against max value of a cluster in FATxx
+ // look for the last cluster in the chain
+ if ( c >= c2)
+ status = Exit;
+
+ // Now erase this FAT entry
+ if(WriteFAT(dsk, cluster, CLUSTER_EMPTY, FALSE) == ClusterFailValue)
+ status = Fail;
+
+ // now update what the current cluster is
+ cluster = c;
+ }
+ }
+ }// while status
+ }// cluster == 0
+
+ WriteFAT (dsk, 0, 0, TRUE);
+
+ if(status == Exit)
+ return(TRUE);
+ else
+ return(FALSE);
+} // Erase cluster
+#endif
+
+/**************************************************************************
+ Function:
+ DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+ Summary:
+ Load a file entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File information
+ curEntry - Offset of the directory entry to load.
+ ForceRead - Forces loading of a new sector of the directory.
+ Return:
+ DIRENTRY - Pointer to the directory entry that was loaded.
+ Side Effects:
+ Any unwritten data in the data buffer will be written to the device.
+ Description:
+ Load the sector containing the file entry pointed to by 'curEntry'
+ from the directory pointed to by the variables in 'fo.'
+ Remarks:
+ Any modification of this function is extremely likely to
+ break something.
+ **************************************************************************/
+
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+{
+ DIRENTRY dir;
+ DISK *dsk;
+ DWORD sector;
+ DWORD cluster, LastClusterLimit;
+ DWORD ccls;
+ BYTE offset2;
+ BYTE numofclus;
+
+ dsk = fo->dsk;
+
+ // get the base sector of this directory
+ cluster = fo->dirclus;
+ ccls = fo->dirccls;
+
+ // figure out the offset from the base sector
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+ /* There are 16 entries per sector. SECTOR size is 512 bytes. Each entry in ROOT takes 32 bytes.
+ So, 512/32 = 16. So 16 file entries can be made in each sector. */
+
+ offset2 = offset2; // emulator issue
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // the ROOT is always cluster based in FAT32
+ /* In FAT32: There is no ROOT region. Root etries are made in DATA region only.
+ Every cluster of DATA which is accupied by ROOT is tracked by FAT table/entry so the ROOT can grow
+ to an amount which is restricted only by available free DATA region. */
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // if its the root its not cluster based
+ if(cluster != 0)
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ // check if a new sector of the root must be loaded
+ if (ForceRead || (*curEntry & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) // only 16 entries per sector
+ {
+ // see if we have to load a new cluster
+ if((offset2 == 0 && (*curEntry) >= DIRENTRIES_PER_SECTOR) || ForceRead)
+ {
+ if(cluster == 0)
+ {
+ ccls = 0;
+ }
+ else
+ {
+ // If ForceRead, read the number of sectors from 0
+ if(ForceRead)
+ numofclus = ((WORD)(*curEntry) / (WORD)(((WORD)DIRENTRIES_PER_SECTOR) * (WORD)dsk->SecPerClus));
+ // Otherwise just read the next sector
+ else
+ numofclus = 1;
+
+ // move to the correct cluster
+ while(numofclus)
+ {
+ ccls = ReadFAT(dsk, ccls);
+
+ if(ccls >= LastClusterLimit)
+ break;
+ else
+ numofclus--;
+ }
+ }
+ }
+
+ // see if that we have a valid cluster number
+ if(ccls < LastClusterLimit)
+ {
+ fo->dirccls = ccls; // write it back
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ /* see if we are root and about to go pass our boundaries
+ FAT32 stores the root directory in the Data Region along with files and other directories,
+ allowing it to grow without such a restraint */
+ if((ccls == FatRootDirClusterValue) && ((sector + offset2) >= dsk->data) && (FAT32 != dsk->type))
+ {
+ dir = ((DIRENTRY)NULL); // reached the end of the root
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return NULL;
+#endif
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+
+ if ( MDD_SectorRead( sector + offset2, dsk->buffer) != TRUE) // if FALSE: sector could not be read.
+ {
+ dir = ((DIRENTRY)NULL);
+ }
+ else // Sector has been read properly, Copy the root entry info of the file searched.
+ {
+ if(ForceRead) // Buffer holds all 16 root entry info. Point to the one required.
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+ else
+ dir = (DIRENTRY)dsk->buffer;
+ }
+ gLastDataSectorRead = 0xFFFFFFFF;
+ }
+ }
+ else
+ {
+ nextClusterIsLast = TRUE;
+ dir = ((DIRENTRY)NULL);
+ }
+ }
+ else
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+
+ return(dir);
+} // Cache_File_Entry
+
+
+/*************************************************************************
+ Function:
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Create a new file entry
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location to create file
+ Return Values:
+ CE_GOOD - File Creation successful
+ CE_DIR_FULL - All root directory entries are taken
+ CE_WRITE_ERROR - The head cluster of the file could not be created.
+ Side Effects:
+ Modifies the FSerrno variable.
+ Description:
+ With the data passed within fo, create a new file entry in the current
+ directory. This function will first search for empty file entries.
+ Once an empty entry is found, the entry will be populated with data
+ for a file or directory entry. Finally, the first cluster of the
+ new file will be located and allocated, and its value will be
+ written into the file entry.
+ Remarks:
+ None
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode)
+{
+ BYTE index;
+ CETYPE error = CE_GOOD;
+ char name[11];
+
+ FSerrno = CE_GOOD;
+
+ for (index = 0; index < FILE_NAME_SIZE; index ++)
+ {
+ name[index] = fo->name[index];
+ }
+
+ *fHandle = 0;
+
+ // figure out where to put this file in the directory stucture
+ if(FindEmptyEntries(fo, fHandle))
+ {
+ // found the entry, now populate it
+ if((error = PopulateEntries(fo, name ,fHandle, mode)) == CE_GOOD)
+ {
+ // if everything is ok, create a first cluster
+ error = CreateFirstCluster(fo);
+ }
+ }
+ else
+ {
+ error = CE_DIR_FULL;
+ }
+
+ FSerrno = error;
+
+ return(error);
+}
+#endif
+
+/******************************************************
+ Function:
+ CETYPE CreateFirstCluster(FILEOBJ fo)
+ Summary:
+ Create the first cluster for a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file that contains the first cluster
+ Return Values:
+ CE_GOOD - First cluster created successfully
+ CE_WRITE_ERROR - Cluster creation failed
+ Side Effects:
+ None
+ Description:
+ This function will find an unused cluster, link it to
+ a file's directory entry, and write the entry back
+ to the device.
+ Remarks:
+ None.
+ ******************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFirstCluster(FILEOBJ fo)
+{
+ CETYPE error;
+ DWORD cluster,TempMsbCluster;
+ WORD fHandle;
+ DIRENTRY dir;
+ fHandle = fo->entry;
+
+ // Now create the first cluster (head cluster)
+ if((error = FILECreateHeadCluster(fo,&cluster)) == CE_GOOD)
+ {
+ // load the file entry so the new cluster can be linked to it
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ // Now update the new cluster
+ dir->DIR_FstClusLO = (cluster & 0x0000FFFF);
+
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ // Get the higher part of cluster and store it in directory entry.
+ TempMsbCluster = (cluster & 0x0FFF0000); // Since only 28 bits usedin FAT32. Mask the higher MSB nibble.
+ TempMsbCluster = TempMsbCluster >> 16; // Get the date into Lsb place.
+ dir->DIR_FstClusHI = TempMsbCluster;
+#else // If FAT32 support not enabled
+ TempMsbCluster = 0; // Just to avoid compiler warnigng.
+ dir->DIR_FstClusHI = 0;
+#endif
+
+ // now write it
+ if(Write_File_Entry(fo, &fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+ } // Create Cluster
+
+ return(error);
+}// End of CreateFirstCluster
+#endif
+
+/**********************************************************
+ Function:
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Find an empty dir entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Start of entries
+ Return Values:
+ TRUE - One found
+ FALSE - None found
+ Side Effects:
+ None
+ Description:
+ This function will cache directory entries, starting
+ with the one pointed to by the fHandle argument. It will
+ then search through the entries until an unused one
+ is found. If the end of the cluster chain for the
+ directory is reached, a new cluster will be allocated
+ to the directory (unless it's a FAT12 or FAT16 root)
+ and the first entry of the new cluster will be used.
+ Remarks:
+ None.
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+{
+ BYTE status = NOT_FOUND;
+ BYTE amountfound;
+ BYTE a;
+ WORD bHandle;
+ DWORD b;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ if((dir = Cache_File_Entry( fo, fHandle, TRUE)) == NULL)
+ {
+ status = CE_BADCACHEREAD;
+ }
+ else
+ {
+ // while its still not found
+ while(status == NOT_FOUND)
+ {
+ amountfound = 0;
+ bHandle = *fHandle;
+
+ // find (number) continuous entries
+ do
+ {
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // increase number
+ (*fHandle)++;
+ }while((a == DIR_DEL || a == DIR_EMPTY) && (dir != (DIRENTRY)NULL) && (++amountfound < 1));
+
+ // --- now why did we exit?
+ if(dir == NULL) // Last entry of the cluster
+ {
+ //setup the current cluster
+ b = fo->dirccls; // write it back
+
+ // make sure we are not the root directory
+ if(b == FatRootDirClusterValue)
+ {
+ if (fo->dsk->type != FAT32)
+ status = NO_MORE;
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ if(amountfound == 1)
+ {
+ status = FOUND;
+ *fHandle = bHandle;
+ }
+ }
+ }// while
+
+ // copy the base handle over
+ *fHandle = bHandle;
+ }
+
+ if(status == FOUND)
+ return(TRUE);
+ else
+ return(FALSE);
+}
+#endif
+
+/**************************************************************************
+ Function:
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle)
+ Summary:
+ Populate a dir entry with data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ name - Name of the file
+ fHandle - Location of the file
+ Return Values:
+ CE_GOOD - Population successful
+ Side Effects:
+ None
+ Description:
+ This function will write data into a new file entry. It will also
+ load timestamp data (based on the method selected by the user) and
+ update the timestamp variables.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode)
+{
+ BYTE error = CE_GOOD;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+
+ if (dir == NULL)
+ return CE_BADCACHEREAD;
+
+ // copy the contents over
+ strncpy(dir->DIR_Name,name,DIR_NAMECOMP);
+
+ // setup no attributes
+ if (mode == DIRECTORY)
+ dir->DIR_Attr = ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = ATTR_ARCHIVE;
+
+ dir->DIR_NTRes = 0x00; // nt reserved
+ dir->DIR_FstClusHI = 0x0000; // high word of this enty's first cluster number
+ dir->DIR_FstClusLO = 0x0000; // low word of this entry's first cluster number
+ dir->DIR_FileSize = 0x0; // file size in DWORD
+
+ // Timing information for uncontrolled clock mode
+#ifdef INCREMENTTIMESTAMP
+ dir->DIR_CrtTimeTenth = 0xB2; // millisecond stamp
+ dir->DIR_CrtTime = 0x7278; // time created
+ dir->DIR_CrtDate = 0x32B0; // date created
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = 0x32B0; // Last Access date
+ dir->DIR_WrtTime = 0x7279; // last update time
+ dir->DIR_WrtDate = 0x32B0; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ dir->DIR_CrtTime = gTimeCrtTime; // time created //
+ dir->DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate; // Last Access date
+ dir->DIR_WrtTime = gTimeWrtTime; // last update time
+ dir->DIR_WrtDate = gTimeWrtDate; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ // The user will have set the time before this funciton is called
+ dir->DIR_CrtTimeTenth = gTimeCrtMS;
+ dir->DIR_CrtTime = gTimeCrtTime;
+ dir->DIR_CrtDate = gTimeCrtDate;
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate;
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+ fo->size = dir->DIR_FileSize;
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ fo->attributes = dir->DIR_Attr;
+ fo->entry = *fHandle;
+
+ // just write the last entry in
+ if (Write_File_Entry(fo,fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+
+ return(error);
+}
+
+#ifdef USEREALTIMECLOCK
+
+/*************************************************************************
+ Function:
+ void CacheTime (void)
+ Summary:
+ Automatically store timestamp information from the RTCC
+ Conditions:
+ RTCC module enabled. Should not be called by the user.
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ This function will automatically load information from an RTCC
+ module and use it to update the global timing variables. These can
+ then be used to update file timestamps.
+ Remarks:
+ None.
+ *************************************************************************/
+
+void CacheTime (void)
+{
+#ifdef __C30__
+ WORD year, monthday, weekhour, minsec, c, result;
+ BYTE ptr1, ptr0;
+
+ if(RCFGCALbits.RTCPTR0)
+ ptr0 = 1;
+ else
+ ptr0 = 0;
+ if (RCFGCALbits.RTCPTR1)
+ ptr1 = 1;
+ else
+ ptr1 = 0;
+
+ RCFGCALbits.RTCPTR0 = 1;
+ RCFGCALbits.RTCPTR1 = 1;
+ year = RTCVAL;
+ monthday = RTCVAL;
+ weekhour = RTCVAL;
+ minsec = RTCVAL;
+
+ if (ptr0 == 1)
+ RCFGCALbits.RTCPTR0 = 1;
+
+ if (ptr1 == 1)
+ RCFGCALbits.RTCPTR1 = 1;
+
+ c = 0;
+ c += (year & 0x0F);
+ c += ((year & 0xF0) >> 4) * 10;
+ // c equals the last 2 digits of the year from 2000 to 2099
+ // Add 20 to adjust it to FAT time (from 1980 to 2107)
+ c += 20;
+ // shift the result to bits
+ result = c << 9;
+
+ if ((monthday & 0x1000) == 0x1000)
+ {
+ c = 10;
+ }
+ else
+ {
+ c = 0;
+ }
+ c += ((monthday & 0x0F00) >> 8);
+ c <<= 5;
+ result |= c;
+
+ c = (monthday & 0x00F0) >> 4;
+ c *= 10;
+ c += (monthday & 0x000F);
+
+ result |= c;
+
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+ gTimeAccDate = result;
+
+ c = ((weekhour & 0x00F0) >> 4) * 10;
+ c += (weekhour & 0x000F);
+ result = c << 11;
+ c = ((minsec & 0xF000) >> 12) * 10;
+ c += (minsec & 0x0F00) >> 8;
+ result |= (c << 5);
+ c = ((minsec & 0x00F0) >> 4) * 10;
+ c += (minsec & 0x000F);
+
+ // If seconds mod 2 is 1, add 1000 ms
+ if (c % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ c >>= 1;
+ result |= c;
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+#elif defined __C32__
+ rtccTime tm; // time structure
+ rtccDate dt; // date structure
+ RtccGetTimeDate(&tm, &dt);
+ gTimeCrtTime = tm.w[1] | tm.w[0];
+ gTimeWrtDate = dt.w[1] | tm.w[0];
+#endif
+}
+#endif
+
+#ifdef USERDEFINEDCLOCK
+
+/***********************************************************************************************************
+ Function:
+ int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+ Summary:
+ Manually set timestamp variables
+ Conditions:
+ USERDEFINEDCLOCK macro defined in FSconfig.h.
+ Input:
+ year - The year (1980\-2107)
+ month - The month (1\-12)
+ day - The day of the month (1\-31)
+ hour - The hour (0\-23)
+ minute - The minute (0\-59)
+ second - The second (0\-59)
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ Lets the user manually set the timing variables. The values passed in will be converted to the format
+ used by the FAT timestamps.
+ Remarks:
+ Call this before creating a file or directory (set create time) and
+ before closing a file (set last access time, last modified time)
+ ***********************************************************************************************************/
+
+int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+{
+ unsigned int result;
+
+ if ((year < 1980) || (year > 2107) || (month < 1) || (month > 12) ||
+ (day < 1) || (day > 31) || (hour > 23) || (minute > 59) || (second > 59))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ result = (year - 1980) << 9;
+ result |= (unsigned int)((unsigned int)month << 5);
+ result |= (day);
+
+ gTimeAccDate = result;
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+
+ result = ((unsigned int)hour << 11);
+ result |= (unsigned int)((unsigned int)minute << 5);
+ result |= (second/2);
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+
+ if (second % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ FSerrno = CE_GOOD;
+ return 0;
+}
+#endif
+
+#endif
+
+/***********************************************************************
+ Function:
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+ Summary;
+ Allocate a new cluster to a file
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ mode -
+ - 0 - Allocate a cluster to a file
+ - 1 - Allocate a cluster to a directory
+ Return Values:
+ CE_GOOD - Cluster allocated
+ CE_DISK_FULL - No clusters available
+ Side Effects:
+ None
+ Description:
+ This function will find an empty cluster on the device using the
+ FATfindEmptyCluster function. It will then mark it as the last
+ cluster in the file in the FAT chain, and link the current last
+ cluster of the passed file to the new cluster. If the new
+ cluster is a directory cluster, it will be erased (so there are no
+ extraneous directory entries). If it's allocated to a non-directory
+ file, it doesn't need to be erased; extraneous data in the cluster
+ will be unviewable because of the file size parameter.
+ Remarks:
+ None.
+ ***********************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+{
+ DISK * dsk;
+ DWORD c,curcls;
+
+ dsk = fo->dsk;
+ c = fo->ccls;
+
+ // find the next empty cluster
+ c = FATfindEmptyCluster(fo);
+ if (c == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ return CE_DISK_FULL;
+
+
+ // mark the cluster as taken, and last in chain
+ if(dsk->type == FAT12)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT12, FALSE);
+ else if (dsk->type == FAT16)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT16, FALSE);
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT32, FALSE);
+#endif
+
+ // link current cluster to the new one
+ curcls = fo->ccls;
+
+ WriteFAT( dsk, curcls, c, FALSE);
+
+ // update the FILE structure
+ fo->ccls = c;
+
+ // IF this is a dir, we need to erase the cluster
+ // If it's a file, we can leave it- the file size
+ // will limit the data we see to the data that's been
+ // written
+ if (mode == 1)
+ return (EraseCluster(dsk, c));
+ else
+ return CE_GOOD;
+
+} // allocate new cluster
+#endif
+
+/***********************************************
+ Function:
+ DWORD FATfindEmptyCluster(FILEOBJ fo)
+ Summary:
+ Find the next available cluster on the device
+ Conditions:
+ This function should not be called by the
+ user.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ DWORD - Address of empty cluster
+ 0 - Could not find empty cluster
+ Side Effects:
+ None
+ Description:
+ This function will search through the FAT to
+ find the next available cluster on the device.
+ Remarks:
+ Should not be called by user
+ ***********************************************/
+
+#ifdef ALLOW_WRITES
+DWORD FATfindEmptyCluster(FILEOBJ fo)
+{
+ DISK * disk;
+ DWORD value = 0x0;
+ DWORD c,curcls, EndClusterLimit, ClusterFailValue;
+
+ disk = fo->dsk;
+ c = fo->ccls;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ EndClusterLimit = END_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ EndClusterLimit = END_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT12:
+ EndClusterLimit = END_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // just in case
+ if(c < 2)
+ c = 2;
+
+ curcls = c;
+ ReadFAT(disk, c);
+
+ // sequentially scan through the FAT looking for an empty cluster
+ while(c)
+ {
+ // look at its value
+ if ( (value = ReadFAT(disk, c)) == ClusterFailValue)
+ {
+ c = 0;
+ break;
+ }
+
+ // check if empty cluster found
+ if (value == CLUSTER_EMPTY)
+ break;
+
+ c++; // check next cluster in FAT
+ // check if reached last cluster in FAT, re-start from top
+ if (value == EndClusterLimit || c >= disk->maxcls)
+ c = 2;
+
+ // check if full circle done, disk full
+ if ( c == curcls)
+ {
+ c = 0;
+ break;
+ }
+ } // scanning for an empty cluster
+
+ return(c);
+}
+#endif
+
+/************************************************************
+ Function:
+ int FSfclose(FSFILE *fo)
+ Summary:
+ Update file information and free FSFILE objects
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to the file to close
+ Return Values:
+ 0 - File closed successfully
+ EOF - Error closing the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will update the directory entry for the
+ file pointed to by 'fo' with the information contained
+ in 'fo,' including the new file size and attributes.
+ Timestamp information will also be loaded based on the
+ method selected by the user and written to the entry
+ as the last modified time and date. The file entry will
+ then be written to the device. Finally, the memory
+ used for the specified file object will be freed from
+ the dynamic heap or the array of FSFILE objects.
+ Remarks:
+ A function to flush data to the device without closing the
+ file can be created by removing the portion of this
+ function that frees the memory and the line that clears
+ the write flag.
+ ************************************************************/
+
+int FSfclose(FSFILE *fo)
+{
+ WORD fHandle;
+#ifndef FS_DYNAMIC_MEM
+ WORD fIndex;
+#endif
+ int error = 72;
+#ifdef ALLOW_WRITES
+ DIRENTRY dir;
+#endif
+
+ FSerrno = CE_GOOD;
+ fHandle = fo->entry;
+
+#ifdef ALLOW_WRITES
+ if(fo->flags.write)
+ {
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ // Write the current FAT sector to the disk
+ WriteFAT (fo->dsk, 0, 0, TRUE);
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = EOF;
+ return error;
+ }
+
+ // update the time
+#ifdef INCREMENTTIMESTAMP
+ IncrementTimeStamp(dir);
+#elif defined USERDEFINEDCLOCK
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#elif defined USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#endif
+
+ Nop();
+
+ dir->DIR_FileSize = fo->size;
+
+ dir->DIR_Attr = fo->attributes;
+
+ // just write the last entry in
+ if(Write_File_Entry(fo,&fHandle))
+ error = 0;
+ else
+ {
+ FSerrno = CE_WRITE_ERROR;
+ error = EOF;
+ }
+
+ // it's now closed
+ fo->flags.write = FALSE;
+ }
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ FS_free((unsigned char *)fo);
+#else
+
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( fo == &gFileArray[fIndex] )
+ {
+ gFileSlotOpen[fIndex] = TRUE;
+ break;
+ }
+ }
+#endif
+
+ // File opened in read mode
+ if (error == 72)
+ error = 0;
+
+ return(error);
+} // FSfclose
+
+
+
+
+/*******************************************************
+ Function:
+ void IncrementTimeStamp(DIRENTRY dir)
+ Summary:
+ Automatically set the timestamp to "don't care" data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ dir - Pointer to directory structure
+ Return Values:
+ None
+ Side Effects:
+ None
+ Description:
+ This function will increment the timestamp variable in
+ the 'dir' directory entry. This is used for the
+ don't-care timing method.
+ Remarks:
+ None
+ *******************************************************/
+#ifdef INCREMENTTIMESTAMP
+void IncrementTimeStamp(DIRENTRY dir)
+{
+ BYTE seconds;
+ BYTE minutes;
+ BYTE hours;
+
+ BYTE day;
+ BYTE month;
+ BYTE year;
+
+ seconds = (dir->DIR_WrtTime & 0x1f);
+ minutes = ((dir->DIR_WrtTime & 0x07E0) >> 5);
+ hours = ((dir->DIR_WrtTime & 0xF800) >> 11);
+
+ day = (dir->DIR_WrtDate & 0x1f);
+ month = ((dir->DIR_WrtDate & 0x01E0) >> 5);
+ year = ((dir->DIR_WrtDate & 0xFE00) >> 9);
+
+ if(seconds < 29)
+ {
+ // Increment number of seconds by 2
+ // This clock method isn't intended to be accurate anyway
+ seconds++;
+ }
+ else
+ {
+ seconds = 0x00;
+
+ if(minutes < 59)
+ {
+ minutes++;
+ }
+ else
+ {
+ minutes = 0;
+
+ if(hours < 23)
+ {
+ hours++;
+ }
+ else
+ {
+ hours = 0;
+ if(day < 30)
+ {
+ day++;
+ }
+ else
+ {
+ day = 1;
+
+ if(month < 12)
+ {
+ month++;
+ }
+ else
+ {
+ month = 1;
+ // new year
+ year++;
+ // This is only valid until 2107
+ }
+ }
+ }
+ }
+ }
+
+ dir->DIR_WrtTime = (WORD)(seconds);
+ dir->DIR_WrtTime |= ((WORD)(minutes) << 5);
+ dir->DIR_WrtTime |= ((WORD)(hours) << 11);
+
+ dir->DIR_WrtDate = (WORD)(day);
+ dir->DIR_WrtDate |= ((WORD)(month) << 5);
+ dir->DIR_WrtDate |= ((WORD)(year) << 9);
+}
+#endif
+
+/*****************************************************************
+ Function:
+ BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Fill a file object with specified dir entry data
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Passed member's location
+ Return Values:
+ FOUND - Operation successful
+ NOT_FOUND - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then copy
+ the file information for that entry into the 'fo' FSFILE
+ object.
+ Remarks:
+ None.
+ *****************************************************************/
+
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE index, a;
+ BYTE character;
+ BYTE status;
+ BYTE test = 0;
+
+ // Get the entry
+ if (((*fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) && (*fHandle != 0)) // 4-bit mask because 16-root entries max per sector
+ {
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ }
+ else
+ {
+ dir = Cache_File_Entry (fo, fHandle, FALSE);
+ }
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Make sure there is a directory left
+ if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
+ {
+ status = NO_MORE;
+ }
+ else
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ status = NOT_FOUND;
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // print the file name and extension
+ for (index=0; index < DIR_NAMESIZE; index++)
+ {
+ character = dir->DIR_Name[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // its possible to have an extension in a directory
+ character = dir->DIR_Extension[0];
+
+ // Get the file extension if its there
+ for (index=0; index < DIR_EXTENSION; index++)
+ {
+ character = dir->DIR_Extension[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // done and done with the name
+ // fo->name[++test] = (BYTE)'\0';
+
+ // Now store the identifier
+ fo->entry = *fHandle;
+
+ // see if we are still a good file
+ a = dir->DIR_Name[0];
+
+ if(a == DIR_DEL)
+ status = NOT_FOUND;
+ else
+ status = FOUND;
+
+ // Now store the size
+ fo->size = (dir->DIR_FileSize);
+
+ fo->cluster = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ /// -Get and store the attributes
+ a = dir->DIR_Attr;
+ fo->attributes = a;
+
+ // get the date and time
+ if ((a & ATTR_DIRECTORY) != 0)
+ {
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ }
+ else
+ {
+ fo->time = dir->DIR_WrtTime;
+ fo->date = dir->DIR_WrtDate;
+ }
+
+ }// deleted directory
+ }// Ensure we are still good
+ return(status);
+} // Fill_File_Object
+
+
+/************************************************************************
+ Function:
+ DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Load file information from a directory entry and cache the entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Information location
+ Return Values:
+ DIRENTRY - Pointer to the directory entry
+ NULL - Directory entry could not be loaded
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then return a pointer
+ to the directory entry in the global data buffer.
+ Remarks:
+ None.
+ ************************************************************************/
+
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE a;
+
+ fo->dirccls = fo->dirclus;
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+ if (dir == NULL)
+ return NULL;
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Make sure there is a directory left
+ if(a == DIR_EMPTY)
+ dir = (DIRENTRY)NULL;
+
+ if(dir != (DIRENTRY)NULL)
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ dir = (DIRENTRY)NULL;
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // scan through all the long dir entries
+ while(a == ATTR_LONG_NAME)
+ {
+ (*fHandle)++;
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+ if (dir == NULL)
+ return NULL;
+ a = dir->DIR_Attr;
+ } // long file name while loop
+ } // deleted dir
+ }// Ensure we are still good
+
+ return(dir);
+} // LoadDirAttrib
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+ Summary:
+ Erase a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location of file information
+ EraseClusters - Remove cluster allocation from FAT?
+ Return Values:
+ CE_GOOD - File erased successfully
+ CE_FILE_NOT_FOUND - Could not find the file on the card
+ CE_ERASE_FAIL - Internal Card erase failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries in the directory
+ pointed to by the dirclus value in the FSFILE object 'fo' that contains
+ the entry that corresponds to the fHandle offset. It will then mark that
+ entry as deleted. If the EraseClusters argument is TRUE, the chain of
+ clusters for that file will be marked as unused in the FAT by the
+ FAT_erase_cluster_chain function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+{
+ DIRENTRY dir;
+ BYTE a;
+ CETYPE status = CE_GOOD;
+ DWORD clus;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ // reset the cluster
+ clus = fo->dirclus;
+ fo->dirccls = clus;
+
+ // load the sector
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return CE_BADCACHEREAD;
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ a = dir->DIR_Name[0];
+
+ // see if there is something in the dir
+ if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ /* 8.3 File Name - entry*/
+ dir->DIR_Name[0] = DIR_DEL; // mark as deleted
+
+ // Get the starting cluster
+ clus = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ // Now write it
+ if(status != CE_GOOD || !(Write_File_Entry( fo, fHandle)))
+ {
+ status = CE_ERASE_FAIL;
+ }
+ else
+ {
+ if (clus != FatRootDirClusterValue) //
+ {
+ if(EraseClusters)
+ {
+ /* Now remove the cluster allocation from the FAT */
+ status = ((FAT_erase_cluster_chain(clus, disk)) ? CE_GOOD : CE_ERASE_FAIL);
+ }
+ }
+ }
+ } // Not already deleted
+ }// Not existant
+
+ if (status == CE_GOOD)
+ FSerrno = CE_GOOD;
+ else
+ FSerrno = CE_ERASE_FAIL;
+
+ return (status);
+}
+#endif
+
+/***************************************************************
+ Function:
+ int FSrename (const rom char * fileName, FSFILE * fo)
+ Summary:
+ Change the name of a file or directory
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file
+ fo - The file to rename
+ Return Values:
+ 0 - File was renamed successfully
+ EOF - File was not renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrename function will rename a file. First, it will
+ search through the current working directory to ensure the
+ specified new filename is not already in use. If it isn't,
+ the new filename will be written to the file entry of the
+ file pointed to by 'fo.'
+ Remarks:
+ None
+ ***************************************************************/
+
+#ifdef ALLOW_WRITES
+
+int FSrename (const char * fileName, FSFILE * fo)
+{
+ unsigned char j, k = 0;
+ char string[12];
+ WORD fHandle = 1, goodHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ if (fo == NULL)
+ {
+ FSerrno = CE_FILENOTOPENED;
+ return -1;
+ }
+ // If fo != NULL, rename the file
+ if (FormatFileName (fileName, fo->name, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+ else
+ {
+ for (j = 0; j < 11; j++)
+ {
+ string[j] = fo->name[j];
+ }
+ goodHandle = fo->entry;
+
+ fHandle = 0;
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Check if the file name is already used
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+
+ nextClusterIsLast = FALSE;
+ while (1)
+ {
+ // Look through the entries until we get to the end
+ // to make sure the name isn't taken
+ dir = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dir == NULL)
+ {
+ if (nextClusterIsLast == TRUE)
+ {
+ break;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ if (dir->DIR_Name[0] == 0)
+ break;
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+ fHandle++;
+ }
+
+ fHandle = goodHandle;
+ fo->dirccls = fo->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ for (j = 0; j < 11; j++)
+ {
+ dir->DIR_Name[j] = fo->name[j];
+ }
+
+ // just write the last entry in
+ if(!Write_File_Entry(fo,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#endif // Allow writes
+
+
+
+/*********************************************************************
+ Function:
+ FSFILE * FSfopen (const char * fileName, const char *mode)
+ Summary:
+ Open a file
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to open
+ mode -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ - WRITEPLUS - Create a new file or replace an existing file (reads also enabled)
+ - READPLUS - Read data from an existing file (writes also enabled)
+ - APPENDPLUS - Append data to an existing file (reads also enabled)
+ Return Values:
+ FSFILE * - The pointer to the file object
+ NULL - The file could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will open a file or directory. First, RAM in the
+ dynamic heap or static array will be allocated to a new FSFILE object.
+ Then, the specified file name will be formatted to ensure that it's
+ in 8.3 format. Next, the FILEfind function will be used to search
+ for the specified file name. If the name is found, one of three
+ things will happen: if the file was opened in read mode, its file
+ info will be loaded using the FILEopen function; if it was opened in
+ write mode, it will be erased, and a new file will be constructed in
+ its place; if it was opened in append mode, its file info will be
+ loaded with FILEopen and the current location will be moved to the
+ end of the file using the FSfseek function. If the file was not
+ found by FILEfind, it will be created if the mode was specified as
+ a write or append mode. In these cases, a pointer to the heap or
+ static FSFILE object array will be returned. If the file was not
+ found and the mode was specified as a read mode, the memory
+ allocated to the file will be freed and the NULL pointer value
+ will be returned.
+ Remarks:
+ None.
+ *********************************************************************/
+
+FSFILE * FSfopen( const char * fileName, const char *mode )
+{
+ FILEOBJ filePtr;
+#ifndef FS_DYNAMIC_MEM
+ int fIndex;
+#endif
+ BYTE ModeC;
+ WORD fHandle;
+ CETYPE final;
+
+#ifdef FS_DYNAMIC_MEM
+ filePtr = (FILEOBJ) FS_malloc(sizeof(FSFILE));
+#else
+
+ filePtr = NULL;
+
+ //Pick available file structure
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( gFileSlotOpen[fIndex] ) //this slot is available
+ {
+ gFileSlotOpen[fIndex] = FALSE;
+ filePtr = &gFileArray[fIndex];
+ break;
+ }
+ }
+
+ if( filePtr == NULL )
+ {
+ FSerrno = CE_TOO_MANY_FILES_OPEN;
+ return NULL; //no file structure slot available
+ }
+#endif
+
+ //Format the source string.
+ if( !FormatFileName(fileName, filePtr->name, 0) )
+ {
+#ifdef FS_DYNAMIC_MEM
+ FS_free( (unsigned char *)filePtr );
+#else
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+#endif
+ FSerrno = CE_INVALID_FILENAME;
+ return NULL; //bad filename
+ }
+
+ //Read the mode character
+ ModeC = mode[0];
+
+ filePtr->dsk = &gDiskData;
+ filePtr->cluster = 0;
+ filePtr->ccls = 0;
+ filePtr->entry = 0;
+ filePtr->attributes = ATTR_ARCHIVE;
+
+ // start at the current directory
+#ifdef ALLOW_DIRS
+ filePtr->dirclus = cwdptr->dirclus;
+ filePtr->dirccls = cwdptr->dirccls;
+#else
+ filePtr->dirclus = FatRootDirClusterValue;
+ filePtr->dirccls = FatRootDirClusterValue;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, filePtr);
+
+ // See if the file is found
+ if(FILEfind (filePtr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0) == CE_GOOD)
+ {
+ // File is Found
+ switch(ModeC)
+ {
+#ifdef ALLOW_WRITES
+ case 'w':
+ case 'W':
+ {
+ // File exists, we want to create a new one, remove it first
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ break;
+ }
+
+ case 'A':
+ case 'a':
+ {
+ if(filePtr->size != 0)
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ else
+ {
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ }
+ break;
+ }
+#endif
+ case 'R':
+ case 'r':
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'r');
+#ifdef ALLOW_WRITES
+ if ((mode[1] == '+') && !(filePtr->attributes & ATTR_DIRECTORY))
+ filePtr->flags.write = 1;
+#endif
+ break;
+ }
+
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;; //indicate error condition
+ break;
+ }
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ // the file was not found, reset to the default asked
+ FileObjectCopy(filePtr, &gFileTemp);
+
+ // File is not Found
+ if(ModeC == 'w' || ModeC == 'W' || ModeC == 'a' || ModeC == 'A')
+ {
+ // use the user requested name
+ fHandle = 0;
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ else
+#endif
+ final = CE_FILE_NOT_FOUND;
+ }
+
+ if (MDD_WriteProtectState())
+ {
+ filePtr->flags.write = 0;;
+ }
+
+#ifdef FS_DYNAMIC_MEM
+ if( final != CE_GOOD )
+ {
+ FS_free( (unsigned char *)filePtr );
+ filePtr = NULL;
+ }
+#else
+ if( final != CE_GOOD )
+ {
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+ filePtr = NULL;
+ }
+#endif
+ else
+ {
+ FSerrno = CE_GOOD;
+ }
+
+ return filePtr;
+}
+
+/*******************************************************************
+ Function:
+ long FSftell (FSFILE * fo)
+ Summary:
+ Determine the current location in a file
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to file structure
+ Return: Current location in the file
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSftell function will return the current position in the
+ file pointed to by 'fo' by returning the 'seek' variable in the
+ FSFILE object, which is used to keep track of the absolute
+ location of the current position in the file.
+ Remarks:
+ None
+ *******************************************************************/
+
+long FSftell (FSFILE * fo)
+{
+ FSerrno = CE_GOOD;
+ return (fo->seek);
+}
+
+
+#ifdef ALLOW_WRITES
+
+/*********************************************************************
+ Function:
+ int FSremove (const char * fileName)
+ Summary:
+ Delete a file
+ Conditions:
+ File not opened, file exists
+ Input:
+ fileName - Name of the file to erase
+ Return Values:
+ 0 - File removed
+ EOF - File was not removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremove function will attempt to find the specified file with
+ the FILEfind function. If the file is found, it will be erased
+ using the FILEerase function.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSremove (const char * fileName)
+{
+ FILEOBJ fo = &tempCWDobj;
+ CETYPE result;
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+ //Format the source string
+ if( !FormatFileName(fileName, fo->name, 0) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = ATTR_ARCHIVE;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+
+ if (fo->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_DELETE_DIR;
+ return -1;
+ }
+
+ result = FILEerase(fo, &fo->entry, TRUE);
+ if( result == CE_GOOD )
+ return 0;
+ else
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+}
+#endif
+
+/*********************************************************
+ Function:
+ void FSrewind (FSFILE * fo)
+ Summary:
+ Set the current position in a file to the beginning
+ Conditions:
+ File opened.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ None
+ Side Effects:
+ None.
+ Description:
+ The FSrewind funciton will reset the position of the
+ specified file to the beginning of the file. This
+ functionality is faster than using FSfseek to reset
+ the position in the file.
+ Remarks:
+ None.
+ *********************************************************/
+
+void FSrewind (FSFILE * fo)
+{
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ flushData();
+#endif
+ fo->seek = 0;
+ fo->pos = 0;
+ fo->sec = 0;
+ fo->ccls = fo->cluster;
+ gBufferOwner = NULL;
+ return;
+}
+
+/**************************************************************************
+ Function:
+ int FSerror (void)
+ Summary:
+ Return an error code for the last function call
+ Conditions:
+ The return value depends on the last function called.
+ Input:
+ None
+ Side Effects:
+ None.
+ Return Values:
+ FSInit -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The physical media could not be initialized
+ - CE_BAD_SECTOR_READ � The MBR or the boot sector could not be
+ read correctly
+ - CE_BAD_PARITION � The MBR signature code was incorrect.
+ - CE_NOT_FORMATTED � The boot sector signature code was incorrect or
+ indicates an invalid number of bytes per sector.
+ - CE_CARDFAT32 � The physical media is FAT32 type (only an error
+ when FAT32 support is disabled).
+ - CE_UNSUPPORTED_FS � The device is formatted with an unsupported file
+ system (not FAT12 or 16).
+ FSfopen -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The device has not been initialized.
+ - CE_TOO_MANY_FILES_OPEN � The function could not allocate any
+ additional file information to the array
+ of FSFILE structures or the heap.
+ - CE_INVALID_FILENAME � The file name argument was invalid.
+ - CE_INVALID_ARGUMENT � The user attempted to open a directory in a
+ write mode or specified an invalid mode argument.
+ - CE_FILE_NOT_FOUND � The specified file (which was to be opened in read
+ mode) does not exist on the device.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_ERASE_FAIL � The existing file could not be erased (when opening
+ a file in WRITE mode).
+ - CE_DIR_FULL � The directory is full.
+ - CE_DISK_FULL� The data memory section is full.
+ - CE_WRITE_ERROR � A write to the device failed.
+ - CE_SEEK_ERROR � The current position in the file could not be set to
+ the end (when the file was opened in APPEND mode).
+ FSfclose -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer or the new file
+ entry information could not be written to the device.
+ - CE_BADCACHEREAD � The file entry information could not be cached
+ FSfread -
+ - CE_GOOD � No Error
+ - CE_WRITEONLY � The file was opened in a write-only mode.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_BAD_SECTOR_READ � The data sector could not be read.
+ - CE_EOF � The end of the file was reached.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be loaded.
+ FSfwrite -
+ - CE_GOOD � No Error
+ - CE_READONLY � The file was opened in a read-only mode.
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_WRITE_ERROR � There was an error writing data to the device.
+ - CE_BADCACHEREAD � The data sector to be modified could not be read from
+ the device.
+ - CE_DISK_FULL � All data clusters on the device are in use.
+ FSfseek -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_INVALID_ARGUMENT � The specified offset exceeds the size of the file.
+ - CE_BADCACHEREAD � The sector that contains the new current position
+ could not be loaded.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be
+ loaded/allocated.
+ FSftell -
+ - CE_GOOD � No Error
+ FSattrib -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The attribute argument was invalid.
+ - CE_BADCACHEREAD � The existing file entry information could not be
+ loaded.
+ - CE_WRITE_ERROR � The file entry information could not be written to
+ the device.
+ FSrename -
+ - CE_GOOD � No Error
+ - CE_FILENOTOPENED � A null file pointer was passed into the function.
+ - CE_INVALID_FILENAME � The file name passed into the function was invalid.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_FILENAME_EXISTS � A file with the specified name already exists.
+ - CE_WRITE_ERROR � The new file entry data could not be written to the
+ device.
+ FSfeof -
+ - CE_GOOD � No Error
+ FSformat -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The device could not be initialized.
+ - CE_BADCACHEREAD � The master boot record or boot sector could not be
+ loaded successfully.
+ - CE_INVALID_ARGUMENT � The user selected to create their own boot sector on
+ a device that has no master boot record, or the mode
+ argument was invalid.
+ - CE_WRITE_ERROR � The updated MBR/Boot sector could not be written to
+ the device.
+ - CE_BAD_PARTITION � The calculated number of sectors per clusters was
+ invalid.
+ - CE_NONSUPPORTED_SIZE � The card has too many sectors to be formatted as
+ FAT12 or FAT16.
+ FSremove -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � The specified file could not be found.
+ - CE_ERASE_FAIL � The file could not be erased.
+ FSchdir -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The path string was mis-formed or the user tried to
+ change to a non-directory file.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_FOUND � Could not find a directory in the path.
+ FSgetcwd -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The user passed a 0-length buffer into the function.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the current working directory.
+ FSmkdir -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_ARGUMENT � The path string was mis-formed.
+ - CE_BADCACHEREAD � Could not successfully change to a recently created
+ directory to store its dir entry information, or
+ could not cache directory entry information.
+ - CE_INVALID_FILENAME � One or more of the directory names has an invalid
+ format.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device or the dot/dotdot entries could
+ not be written to a newly created directory.
+ - CE_DIR_FULL � There are no available dir entries in the CWD.
+ - CE_DISK_FULL � There are no available clusters in the data region of
+ the device.
+ FSrmdir -
+ - CE_GOOD � No Error
+ - CE_DIR_NOT_FOUND � The directory specified could not be found or the
+ function could not change to a subdirectory within
+ the directory to be deleted (when recursive delete is
+ enabled).
+ - CE_INVALID_ARGUMENT � The user tried to remove the CWD or root directory.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_EMPTY � The directory to be deleted was not empty and
+ recursive subdirectory removal was disabled.
+ - CE_ERASE_FAIL � The directory or one of the directories or files
+ within it could not be deleted.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the CWD.
+ SetClockVars -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The time values passed into the function were
+ invalid.
+ FindFirst -
+ - CE_GOOD � No Error
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ - CE_BADCACHEREAD � The file information for the file that was found
+ could not be cached.
+ FindNext -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The SearchRec object was not initialized by a call to
+ FindFirst.
+ - CE_INVALID_ARGUMENT � The SearchRec object was initialized in a different
+ directory from the CWD.
+ - CE_INVALID_FILENAME � The filename is invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ FSfprintf -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � Characters could not be written to the file.
+ Description:
+ The FSerror function will return the FSerrno variable. This global
+ variable will have been set to an error value during the last call of a
+ library function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSerror (void)
+{
+ return FSerrno;
+}
+
+
+/**************************************************************
+ Function:
+ void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+ Summary:
+ Copy a file object
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - The destination
+ foSource - the source
+ Return:
+ None
+ Side Effects:
+ None
+ Description:
+ The FileObjectCopy function will make an exacy copy of
+ a specified FSFILE object.
+ Remarks:
+ None
+ **************************************************************/
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+{
+ BYTE size;
+ BYTE *dest;
+ BYTE *source;
+ BYTE Index;
+
+ dest = (BYTE *)foDest;
+ source = (BYTE *)foSource;
+
+ size = sizeof(FSFILE);
+
+ for(Index=0;Index< size; Index++)
+ {
+ dest[Index] = source[Index];
+ }
+}
+
+/*************************************************************************
+ Function:
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+ Summary:
+ Create the first cluster of a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ cluster - Cluster location
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ CE_DISK_FULL - All clusters in partition are taken
+ Side Effects:
+ None
+ Description:
+ The FILECreateHeadCluster function will create the first cluster
+ of a file. First, it will find an empty cluster with the
+ FATfindEmptyCluster function and mark it as the last cluster in the
+ file. It will then erase the cluster using the EraseCluster function.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+{
+ DISK * disk;
+ CETYPE error = CE_GOOD;
+
+ disk = fo->dsk;
+
+ // find the next empty cluster
+ *cluster = FATfindEmptyCluster(fo);
+
+ if(*cluster == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ {
+ error = CE_DISK_FULL;
+ }
+ else
+ {
+ // mark the cluster as taken, and last in chain
+ if(disk->type == FAT12)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT12, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+ else if(disk->type == FAT16)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT16, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+
+ #ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT32, FALSE) == CLUSTER_FAIL_FAT32)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+#endif
+
+ // lets erase this cluster
+ if(error == CE_GOOD)
+ {
+ error = EraseCluster(disk,*cluster);
+ }
+ }
+
+ return(error);
+} // allocate head cluster
+#endif
+
+/*************************************************************************
+ Function:
+ BYTE EraseCluster(DISK *disk, DWORD cluster)
+ Summary:
+ Erase a cluster
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - Disk structure
+ cluster - Cluster to be erased
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ Side Effects:
+ None
+ Description:
+ The EraseCluster function will write a 0 value into every byte of
+ the specified cluster.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE EraseCluster(DISK *disk, DWORD cluster)
+{
+ BYTE index;
+ DWORD SectorAddress;
+ BYTE error = CE_GOOD;
+
+ SectorAddress = Cluster2Sector(disk,cluster);
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+
+ gBufferOwner = NULL;
+
+ if (gBufferZeroed == FALSE)
+ {
+ // clear out the memory first
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+ gBufferZeroed = TRUE;
+ }
+
+ // Now clear them out
+ for(index = 0; index < disk->SecPerClus && error == CE_GOOD; index++)
+ {
+ if (MDD_SectorWrite( SectorAddress++, disk->buffer, FALSE) != TRUE)
+ error = CE_WRITE_ERROR;
+ }
+
+ return(error);
+}
+#endif
+
+
+#if defined (__C30__) || defined (__C32__)
+
+/***************************************************
+ Function:
+ BYTE ReadByte(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a byte from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ BYTE - the byte read
+ Side Effects:
+ None
+ Description:
+ Reads a byte from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+BYTE ReadByte( BYTE* pBuffer, WORD index )
+{
+ return( pBuffer[index] );
+}
+
+
+/***************************************************
+ Function:
+ BYTE ReadWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 16-bit word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ WORD - the word read
+ Side Effects:
+ None
+ Description:
+ Reads a 16-bit word from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+WORD ReadWord( BYTE* pBuffer, WORD index )
+{
+ BYTE loByte, hiByte;
+ WORD res;
+
+ loByte = pBuffer[index];
+ hiByte = pBuffer[index+1];
+ res = hiByte;
+ res *= 0x100;
+ res |= loByte;
+ return( res );
+}
+
+
+/****************************************************
+ Function:
+ BYTE ReadDWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 32-bit double word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ DWORD - the double word read
+ Side Effects:
+ None
+ Description:
+ Reads a 32-bit double word from a buffer
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD ReadDWord( BYTE* pBuffer, WORD index )
+{
+ WORD loWord, hiWord;
+ DWORD result;
+
+ loWord = ReadWord( pBuffer, index );
+ hiWord = ReadWord( pBuffer, index+2 );
+
+ result = hiWord;
+ result *= 0x10000;
+ result |= loWord;
+ return result;
+}
+
+#endif
+
+
+
+/****************************************************
+ Function:
+ DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+ Summary:
+ Convert a cluster number to the corresponding sector
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - Disk structure
+ cluster - Cluster to be converted
+ Return:
+ sector - Sector that corresponds to given cluster
+ Side Effects:
+ None
+ Description:
+ The Cluster2Sector function will calculate the
+ sector number that corresponds to the first sector
+ of the cluster whose value was passed into the
+ function.
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+{
+ DWORD sector;
+
+ /* Rt: Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ /* In FAT32, there is no separate ROOT region. It is as well stored in DATA region */
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // The root dir takes up cluster 0 and 1
+ if(cluster == 0 ||cluster == 1)
+ sector = dsk->root + cluster;
+ else
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+ }
+
+ return(sector);
+
+}
+
+
+/***************************************************************************
+ Function:
+ int FSattrib (FSFILE * file, unsigned char attributes)
+ Summary:
+ Change the attributes of a file
+ Conditions:
+ File opened
+ Input:
+ file - Pointer to file structure
+ attributes - The attributes to set for the file
+ - Attribute - Value - Indications
+ - ATTR_READ_ONLY - 0x01 - The read-only attribute
+ - ATTR_HIDDEN - 0x02 - The hidden attribute
+ - ATTR_SYSTEM - 0x04 - The system attribute
+ - ATTR_ARCHIVE - 0x20 - The archive attribute
+ Return Values:
+ 0 - Attribute change was successful
+ -1 - Attribute change was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSattrib funciton will set the attributes of the specified file
+ to the attributes passed in by the user. This function will load the
+ file entry, replace the attributes with the ones specified, and write
+ the attributes back. If the specified file is a directory, the
+ directory attribute will be preserved.
+ Remarks:
+ None
+ ***************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSattrib (FSFILE * file, unsigned char attributes)
+{
+ WORD fHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ // Check for valid attributes
+ if ((attributes & ~0x27) != 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ fHandle = file->entry;
+
+ file->dirccls = file->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(file, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Ensure that we aren't trying to change the
+ // attributes of a volume entry
+ if (dir->DIR_Attr & ATTR_VOLUME)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Don't remove the directory attribute from DIR files
+ if (file->attributes & ATTR_DIRECTORY)
+ dir->DIR_Attr = attributes | ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = attributes;
+
+ // just write the last entry in
+ if(!Write_File_Entry(file,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+
+/*********************************************************************************
+ Function:
+ size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Write data to a file
+ Conditions:
+ File opened in WRITE, APPEND, WRITE+, APPEND+, READ+ mode
+ Input:
+ ptr - Pointer to source buffer
+ size - Size of units in bytes
+ n - Number of units to transfer
+ stream - Pointer to file structure
+ Return:
+ size_t - number of units written
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfwrite function will write data to a file. First, the sector that
+ corresponds to the current position in the file will be loaded (if it hasn't
+ already been cached in the global data buffer). Data will then be written to
+ the device from the specified buffer until the specified amount has been written.
+ If the end of a cluster is reached, the next cluster will be loaded, unless
+ the end-of-file flag for the specified file has been set. If it has, a new
+ cluster will be allocated to the file. Finally, the new position and filezize
+ will be stored in the FSFILE object. The parameters 'size' and 'n' indicate how
+ much data to write. 'Size' refers to the size of one object to write (in bytes),
+ and 'n' will refer to the number of these objects to write. The value returned
+ will be equal to 'n' unless an error occured.
+ Remarks:
+ None.
+ *********************************************************************************/
+
+#ifdef ALLOW_WRITES
+size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD count = size * n;
+ BYTE * src = (BYTE *) ptr;
+ DISK * dsk; // pointer to disk structure
+ CETYPE error = CE_GOOD;
+ WORD pos;
+ DWORD l; // absolute lba of sector to load
+ DWORD seek, filesize;
+ WORD writeCount = 0;
+
+ // see if the file was opened in a write mode
+ if(!(stream->flags.write))
+ {
+ FSerrno = CE_READONLY;
+ error = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ if (count == 0)
+ return 0;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ error = CE_WRITE_PROTECTED;
+ return 0;
+ }
+
+ gBufferZeroed = FALSE;
+ dsk = stream->dsk;
+ // get the stated position
+ pos = stream->pos;
+ seek = stream->seek;
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ // Check if the current stream was the last one to use the
+ // buffer. If not, check if we need to write data from the
+ // old stream
+ if (gBufferOwner != stream)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+ gBufferOwner = stream;
+ }
+ if (gLastDataSectorRead != l)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+
+ gBufferZeroed = FALSE;
+ if(!MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ }
+ gLastDataSectorRead = l;
+ }
+ // exit loop if EOF reached
+ filesize = stream->size;
+
+ // Loop while writing bytes
+ while (error == CE_GOOD && count > 0)
+ {
+ if( seek == filesize )
+ stream->flags.FileWriteEOF = TRUE;
+
+ // load a new sector if necessary, multiples of sector
+ if (pos == MEDIA_SECTOR_SIZE)
+ {
+ BYTE needRead = TRUE;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ // reset position
+ pos = 0;
+
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if (stream->sec == dsk->SecPerClus)
+ {
+ stream->sec = 0;
+
+ if(stream->flags.FileWriteEOF)
+ {
+ error = FILEallocate_new_cluster(stream, 0); // add new cluster to the file
+ needRead = FALSE;
+ }
+ else
+ error = FILEget_next_cluster( stream, 1);
+ }
+
+ if (error == CE_DISK_FULL)
+ {
+ FSerrno = CE_DISK_FULL;
+ return 0;
+ }
+
+ if(error == CE_GOOD)
+ {
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+ gBufferOwner = stream;
+ // If we just allocated a new cluster, then the cluster will
+ // contain garbage data, so it doesn't matter what we write to it
+ // Whatever is in the buffer will work fine
+ if (needRead)
+ {
+ if( !MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = 0xFFFFFFFF;
+ return 0;
+ }
+ else
+ {
+ gLastDataSectorRead = l;
+ }
+ }
+ else
+ gLastDataSectorRead = l;
+ }
+ } // load new sector
+
+ if(error == CE_GOOD)
+ {
+ // Write one byte at a time
+ RAMwrite(dsk->buffer, pos++, *(char *)src);
+ src = src + 1; // compiler bug
+ seek++;
+ count--;
+ writeCount++;
+ // now increment the size of the part
+ if(stream->flags.FileWriteEOF)
+ filesize++;
+ gNeedDataWrite = TRUE;
+ }
+ } // while count
+
+ // save off the positon
+ stream->pos = pos;
+
+ // save off the seek
+ stream->seek = seek;
+
+ // now the new size
+ stream->size = filesize;
+
+ return(writeCount / size);
+} // fwrite
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE flushData (void)
+ Summary:
+ Flush unwritten data to a file
+ Conditions:
+ File opened in a write mode, data needs to be written
+ Return Values:
+ CE_GOOD - Data was updated successfully
+ CE_WRITE_ERROR - Data could not be updated
+ Side Effects:
+ None
+ Description:
+ The flushData function is called when it is necessary to
+ read new data into the global data buffer and the
+ gNeedDataWrite variable indicates that there is data
+ in the buffer that hasn't been written to the device.
+ The flushData function will write the data from the
+ buffer into the current cluster of the FSFILE object
+ that is stored in the gBufferOwner global variable.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE flushData (void)
+{
+ DWORD l;
+ DISK * dsk;
+
+ // This will either be the pointer to the last file, or the handle
+ FILEOBJ stream = gBufferOwner;
+
+ dsk = stream->dsk;
+
+ // figure out the lba
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ if(!MDD_SectorWrite( l, dsk->buffer, FALSE))
+ {
+ return CE_WRITE_ERROR;
+ }
+
+ gNeedDataWrite = FALSE;
+
+ return CE_GOOD;
+}
+#endif
+
+/****************************************************
+ Function:
+ int FSfeof( FSFILE * stream )
+ Summary:
+ Indicate whether the current file position is at the end
+ Conditions:
+ File is open in a read mode
+ Input:
+ stream - Pointer to the target file
+ Return Values:
+ Non-Zero - EOF reached
+ 0 - Not at end of File
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfeof function will indicate that the end-of-
+ file has been reached for the specified file by
+ comparing the absolute location in the file to the
+ size of the file.
+ Remarks:
+ None.
+ ****************************************************/
+
+int FSfeof( FSFILE * stream )
+{
+ FSerrno = CE_GOOD;
+ return( stream->seek == stream->size );
+}
+
+
+/**************************************************************************
+ Function:
+ size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Read data from a file
+ Conditions:
+ File is opened in a read mode
+ Input:
+ ptr - Destination buffer for read bytes
+ size - Size of units in bytes
+ n - Number of units to be read
+ stream - File to be read from
+ Return:
+ size_t - number of units read
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfread function will read data from the specified file. First,
+ the appropriate sector of the file is loaded. Then, data is read into
+ the specified buffer until the specified number of bytes have been read.
+ When a cluster boundary is reached, a new cluster will be loaded. The
+ parameters 'size' and 'n' indicate how much data to read. 'Size'
+ refers to the size of one object to read (in bytes), and 'n' will refer
+ to the number of these objects to read. The value returned will be equal
+ to 'n' unless an error occured or the user tried to read beyond the end
+ of the file.
+ Remarks:
+ None.
+ **************************************************************************/
+
+size_t FSfread (void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD len = size * n;
+ BYTE *pointer = (BYTE *) ptr;
+ DISK *dsk; // Disk structure
+ DWORD seek, sec_sel;
+ WORD pos; //position within sector
+ CETYPE error = CE_GOOD;
+ WORD readCount = 0;
+
+ FSerrno = CE_GOOD;
+
+ dsk = (DISK *)stream->dsk;
+ pos = stream->pos;
+ seek = stream->seek;
+
+ if( !stream->flags.read )
+ {
+ FSerrno = CE_WRITEONLY;
+ return 0; // CE_WRITEONLY
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+#endif
+
+ // if it not my buffer, then get it from the disk.
+ if( (gBufferOwner != stream) && (pos != MEDIA_SECTOR_SIZE ))
+ {
+ gBufferOwner = stream;
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ return 0;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ //loop reading (count) bytes
+ while( len )
+ {
+ if( seek == stream->size )
+ {
+ FSerrno = CE_EOF;
+ error = CE_EOF;
+ break;
+ }
+
+ // In fopen, pos is init to 0 and the sect is loaded
+ if( pos == MEDIA_SECTOR_SIZE )
+ {
+ // reset position
+ pos = 0;
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if( stream->sec == dsk->SecPerClus )
+ {
+ stream->sec = 0;
+ if( (error = FILEget_next_cluster( stream, 1)) != CE_GOOD )
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ break;
+ }
+ }
+
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+
+ gBufferOwner = stream;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ break;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ // copy one byte at a time
+ *pointer = RAMread( dsk->buffer, pos++ );
+ pointer++;
+ seek++;
+ readCount++;
+ len--;
+ }
+
+ // save off the positon
+ stream->pos = pos;
+ // save off the seek
+ stream->seek = seek;
+
+ return(readCount / size);
+} // fread
+
+
+/***************************************************************************
+ Function:
+ BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode )
+ Summary:
+ Format a file name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be formatted
+ fN2 - The location the formatted name will be stored
+ mode - Non-zero if parital string search chars are allowed
+ Return Values:
+ TRUE - Name formatted successfully
+ FALSE - File name could not be formatted
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into FSFILE structure format. If filename is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ filename are valid in this filesystem.
+ Remarks:
+ None.
+ ***************************************************************************/
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode)
+{
+ char * pExt;
+ WORD temp;
+ char szName[15];
+ BYTE count;
+
+ for (count = 0; count < 11; count++)
+ {
+ *(fN2 + count) = ' '; // Load destination filename to be space intially.
+ }
+
+ // Make sure we dont have an empty string or a name with only
+ // an extension
+ if (fileName[0] == '.' || fileName[0] == 0)
+ return FALSE;
+
+ temp = strlen( fileName );
+
+ if( temp <= TOTAL_FILE_SIZE ) // 8+3+1
+ strcpy( szName, fileName ); // copy to RAM in case fileName is located in flash
+ else
+ return FALSE; //long file name
+
+ // Make sure the characters are valid
+ if ( !ValidateChars(szName, mode) )
+ return FALSE;
+
+ //Look for '.' in the szName
+ if( (pExt = strchr( szName, '.' )) != 0 )
+ {
+ *pExt = 0; // Assigning NULL here makes the "szName" to be terminated and "pExt" pointer to hold only extn characters.
+ pExt++; // now pointing to extension
+
+ if( strlen( pExt ) > 3 ) // make sure the extension is 3 bytes or fewer
+ return FALSE;
+ }
+
+ if( strlen(szName) > 8 )
+ return FALSE;
+
+ //copy file name
+ for (count = 0; count < strlen(szName); count++)
+ {
+ *(fN2 + count) = * (szName + count); // Destination filename initially filled with SPACE. Now copy only available chars.
+ }
+
+ //copy extension
+ if(pExt && *pExt )
+ {
+ for (count = 0; count < strlen (pExt); count++)
+ {
+ *(fN2 + count + 8) = *(pExt + count); // Copy the extn to 8th position onwards. Ex: "FILE .Tx "
+ }
+ }
+
+ return TRUE;
+}
+
+#ifdef ALLOW_DIRS
+
+/*************************************************************************
+ Function:
+ BYTE FormatDirName (char * string, BYTE mode)
+ Summary:
+ Format a dir name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ string - The name to be formatted
+ mode -
+ - TRUE - Partial string search characters are allowed
+ - FALSE - Partial string search characters are forbidden
+ Return Values:
+ TRUE - The name was formatted correctly
+ FALSE - The name contained invalid characters
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into directory structure format. If the name is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ directory name are valid in this filesystem.
+ Remarks:
+ None.
+ *************************************************************************/
+
+BYTE FormatDirName (char * string, BYTE mode)
+{
+ unsigned char i, j;
+ char tempString [12];
+
+ if (ValidateChars (string, mode) == FALSE)
+ return FALSE;
+
+ for (i = 0; (i < 8) && (*(string + i) != '.') && (*(string + i) != 0); i++)
+ {
+ tempString[i] = *(string + i);
+ }
+
+ j = i;
+
+ while (i < 8)
+ {
+ tempString [i++] = 0x20;
+ }
+
+ if (*(string + j) == '.')
+ {
+ j++;
+ while (*(string + j) != 0)
+ {
+ tempString[i++] = *(string + j++);
+ }
+ }
+
+ while (i < 11)
+ {
+ tempString[i++] = 0x20;
+ }
+
+ tempString[11] = 0;
+
+ // Forbidden
+ if (tempString[0] == 0x20)
+ {
+ tempString[0] = '_';
+ }
+
+ for (i = 0; i < 12; i++)
+ {
+ *(string + i) = tempString[i];
+ }
+
+ return TRUE;
+}
+#endif
+
+
+/*************************************************************
+ Function:
+ BYTE ValidateChars( char * FileName, BYTE mode)
+ Summary:
+ Validate the characters in a given file name
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be validated
+ mode - Determines if partial string search is allowed
+ Return Values:
+ TRUE - Name was validated
+ FALSE - File name was not valid
+ Side Effects:
+ None
+ Description:
+ The ValidateChars function will compare characters in a
+ specified filename to determine if they're permissable
+ in the FAT file system. Lower-case characters will be
+ converted to upper-case. If the mode argument is specifed
+ to be 'TRUE,' partial string search characters are allowed.
+ Remarks:
+ None.
+ *************************************************************/
+BYTE ValidateChars( char * FileName , BYTE mode)
+{
+ int StrSz, index;
+ unsigned char radix = FALSE;
+
+ StrSz = strlen(FileName);
+
+ for( index = 0; index < StrSz; index++ )
+ {
+ if (((FileName[index] <= 0x20) && (FileName[index] != 0x05)) ||
+ (FileName[index] == 0x22) || (FileName[index] == 0x2B) ||
+ (FileName[index] == 0x2C) || (FileName[index] == 0x2F) ||
+ (FileName[index] == 0x3A) || (FileName[index] == 0x3B) ||
+ (FileName[index] == 0x3C) || (FileName[index] == 0x3D) ||
+ (FileName[index] == 0x3E) || (FileName[index] == 0x5B) ||
+ (FileName[index] == 0x5C) || (FileName[index] == 0x5D) ||
+ (FileName[index] == 0x7C) || ((FileName[index] == 0x2E) && radix == TRUE))
+ {
+ return FALSE;
+ }
+ else
+ {
+ // Check for partial string search chars
+ if (mode == FALSE)
+ {
+ if ((FileName[index] == '*') || (FileName[index] == '?'))
+ return FALSE;
+ }
+ // only one radix ('.') character is allowed
+ if (FileName[index] == 0x2E)
+ {
+ radix = TRUE;
+ }
+ // Convert lower-case to upper-case
+ if ((FileName[index] >= 0x61) && (FileName[index] <= 0x7A))
+ FileName[index] -= 0x20;
+ }
+ }
+ return TRUE;
+}
+
+
+/**********************************************************************
+ Function:
+ int FSfseek(FSFILE *stream, long offset, int whence)
+ Summary:
+ Change the current position in a file
+ Conditions:
+ File opened
+ Input:
+ stream - Pointer to file structure
+ offset - Offset from base location
+ whence -
+ - SEEK_SET - Seek from start of file
+ - SEEK_CUR - Seek from current location
+ - SEEK_END - Seek from end of file (subtract offset)
+ Return Values:
+ 0 - Operation successful
+ -1 - Operation unsuccesful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfseek function will change the current position in the file to
+ one specified by the user. First, an absolute offset is calculated
+ using the offset and base location passed in by the user. Then, the
+ position variables are updated, and the sector number that corresponds
+ to the new location. That sector is then loaded. If the offset
+ falls exactly on a cluster boundary, a new cluster will be allocated
+ to the file and the position will be set to the first byte of that
+ cluster.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSfseek(FSFILE *stream, long offset, int whence)
+{
+ DWORD numsector, temp; // lba of first sector of first cluster
+ DISK* dsk; // pointer to disk structure
+ BYTE test;
+ long offset2 = offset;
+
+ dsk = stream->dsk;
+
+ switch(whence)
+ {
+ case SEEK_CUR:
+ // Apply the offset to the current position
+ offset2 += stream->seek;
+ break;
+ case SEEK_END:
+ // Apply the offset to the end of the file
+ offset2 = stream->size - offset2;
+ break;
+ case SEEK_SET:
+ // automatically there
+ default:
+ break;
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+#endif
+
+ // start from the beginning
+ temp = stream->cluster;
+ stream->ccls = temp;
+
+ temp = stream->size;
+
+ if (offset2 > temp)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return (-1); // past the limits
+ }
+ else
+ {
+ // if we are writing we are no longer at the end
+ stream->flags.FileWriteEOF = FALSE;
+
+ // set the new postion
+ stream->seek = offset2;
+
+ // figure out how many sectors
+ numsector = offset2 / MEDIA_SECTOR_SIZE;
+
+ // figure out how many bytes off of the offset
+ offset2 = offset2 - (numsector * MEDIA_SECTOR_SIZE);
+ stream->pos = offset2;
+
+ // figure out how many clusters
+ temp = numsector / dsk->SecPerClus;
+
+ // figure out the stranded sectors
+ numsector = numsector - (dsk->SecPerClus * temp);
+ stream->sec = numsector;
+
+ // if we are in the current cluster stay there
+ if (temp > 0)
+ {
+ test = FILEget_next_cluster(stream, temp);
+ if (test != CE_GOOD)
+ {
+ if (test == CE_FAT_EOF)
+ {
+#ifdef ALLOW_WRITES
+ if (stream->flags.write)
+ {
+ // load the previous cluster
+ stream->ccls = stream->cluster;
+ // Don't perform this operation if there's only one cluster
+ if (temp != 1)
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (FILEallocate_new_cluster(stream, 0) != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return -1;
+ }
+ // sec and pos should already be zero
+ }
+ else
+ {
+#endif
+ stream->ccls = stream->cluster;
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (test != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1);
+ }
+ stream->pos = MEDIA_SECTOR_SIZE;
+ stream->sec = dsk->SecPerClus - 1;
+#ifdef ALLOW_WRITES
+ }
+#endif
+ }
+ else
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1); // past the limits
+ }
+ }
+ }
+
+ // Determine the lba of the selected sector and load
+ temp = Cluster2Sector(dsk,stream->ccls);
+
+ // now the extra sectors
+ numsector = stream->sec;
+ temp += numsector;
+
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead(temp, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return (-1); // Bad read
+ }
+ gLastDataSectorRead = temp;
+ }
+
+ FSerrno = CE_GOOD;
+
+ return (0);
+}
+
+
+// FSfopenpgm, FSremovepgm, and FSrenamepgm will only work on PIC18s
+#ifdef __18CXX
+#ifdef ALLOW_PGMFUNCTIONS
+
+#ifdef ALLOW_WRITES
+
+/*****************************************************************
+ Function:
+ int FSrenamepgm(const rom char * fileName, FSFILE * fo)
+ Summary:
+ Rename a file named with a ROM string on PIC18
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file (in ROM)
+ fo - The file to rename
+ Return Values:
+ 0 - File renamed successfully
+ -1 - File could not be renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The Fsrenamepgm function will copy the rom fileName specified
+ by the user into a RAM array and pass that array into the
+ FSrename function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *****************************************************************/
+
+int FSrenamepgm (const rom char * fileName, FSFILE * fo)
+{
+ char F[13];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+
+ return FSrename (F, fo);
+}
+#endif
+
+/******************************************************************************
+ Function:
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+ Summary:
+ Open a file named with a ROM string on PIC18
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to be opened (ROM)
+ mode - The mode the file will be opened in (ROM)
+ Return Values:
+ FSFILE * - A pointer to the file object
+ NULL - File could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfopenpgm function will copy a PIC18 ROM fileName and mode argument
+ into RAM arrays, and then pass those arrays to the FSfopen function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ ******************************************************************************/
+
+
+FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+{
+ char F[13];
+ char M[2];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+ for (count = 0; count < 2; count++)
+ {
+ M[count] = *(mode + count);
+ }
+
+ return FSfopen(F, M);
+}
+
+/*************************************************************
+ Function:
+ int FSremovepgm (const rom char * fileName)
+ Summary:
+ Delete a file named with a ROM string on PIC18
+ Conditions:
+ File not opened; file exists
+ Input:
+ fileName - The name of the file to be deleted (ROM)
+ Return Values:
+ 0 - File was removed successfully
+ -1 - File could not be removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremovepgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FSremove function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *************************************************************/
+#ifdef ALLOW_WRITES
+int FSremovepgm (const rom char * fileName)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for(...)
+
+ return FSremove (F);
+}
+#endif
+
+/**************************************************************************************
+ Function:
+ int FindFirstpgm (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Find a file named with a ROM string on PIC18
+ Conditions:
+ None
+ Input:
+ fileName - The name of the file to be found (ROM)
+ attr - The attributes of the file to be found
+ rec - Pointer to a search record to store the file info in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the given parameters was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object will be lost.
+ The FSerrno variable will be changed.
+ Description:
+ The FindFirstpgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FindFirst function.
+ Remarks:
+ Call FindFirstpgm or FindFirst before calling FindNext.
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************************/
+#ifdef ALLOW_FILESEARCH
+int FindFirstpgm (const rom char * fileName, unsigned int attr, SearchRec * rec)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for
+
+ return FindFirst (F,attr,rec);
+}
+#endif
+#endif
+#endif
+
+
+/***********************************************
+ Function:
+ DWORD ReadFAT (DISK *dsk, DWORD ccls)
+ Summary:
+ Read the next entry from the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ Return:
+ DWORD - The next cluster in a file chain
+ Side Effects:
+ None
+ Description:
+ The ReadFAT function will read the FAT and
+ determine the next cluster value after the
+ cluster specified by 'ccls.' Note that the
+ FAT sector that is read is stored in the
+ global FAT cache buffer.
+ Remarks:
+ None.
+ ***********************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls)
+{
+ BYTE q;
+ DWORD p, l; // "l" is the sector Address
+ DWORD c, d, ClusterFailValue,LastClusterLimit; // ClusterEntries
+
+ gBufferZeroed = FALSE;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls * 4;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls *3; // Mulby1.5 to find cluster pos in FAT
+ q = p&1;
+ p >>= 1;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT12;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD)ccls *2; // Mulby 2 to find cluster pos in FAT
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ l = dsk->fat + (p >> 9); // FAT buffer has 512 bytes of size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ // Check if the appropriate FAT sector is already loaded
+ if (gLastFATSectorRead == l)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if(dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ // Check if the MSB is across the sector boundry
+ p = (p +1) & 0x1FF;
+ if (p == 0)
+ {
+ // Start by writing the sector we just worked on to the card
+ // if we need to
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+#endif
+ if (!MDD_SectorRead (l+1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l +1;
+ }
+ }
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ else
+ {
+ // If there's a currently open FAT sector,
+ // write it back before reading into the buffer
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ {
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+ }
+#endif
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF; // Note: It is Sector not Cluster.
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if (dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ p = (p +1) & 0x1FF;
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ }
+
+ // Normalize it so 0xFFFF is an error
+ if (c >= LastClusterLimit)
+ c = LastClusterLimit;
+
+ return c;
+} // ReadFAT
+
+
+
+/****************************************************************************
+ Function:
+ WORD WriteFAT (DISK *dsk, DWORD ccls, WORD value, BYTE forceWrite)
+ Summary:
+ Write an entry to the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ value - The value to write in
+ forceWrite - Force the function to write the current FAT sector
+ Return:
+ 0 - The FAT write was successful
+ FAIL - The FAT could not be written
+ Side Effects:
+ None
+ Description:
+ The WriteFAT function writes an entry to the FAT. If the function
+ is called and the 'forceWrite' argument is TRUE, the function will
+ write the existing FAT data to the device. Otherwise, the function
+ will replace a single entry in the FAT buffer (indicated by 'ccls')
+ with a new value (indicated by 'value.')
+ Remarks:
+ None.
+ ****************************************************************************/
+
+#ifdef ALLOW_WRITES
+DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite)
+{
+ BYTE i, q, c;
+ DWORD p, li, l, ClusterFailValue;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type != FAT32 && dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT32;
+#else // If FAT32 support not enabled
+ if (dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT16;
+#endif
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ gBufferZeroed = FALSE;
+
+ // The only purpose for calling this function with forceWrite
+ // is to write the current FAT sector to the card
+ if (forceWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+
+ return 0;
+ }
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls *4; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls * 3; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ q = p & 1; // Odd or even?
+ p >>= 1;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD) ccls *2; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+ }
+
+ l = dsk->fat + (p >>9); // FAt Buffer is 512 bytes size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ if (gLastFATSectorRead != l)
+ {
+ // If we are loading a new sector then write
+ // the current one to the card if we need to
+ if (gNeedFATWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+ }
+
+ // Load the new sector
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l;
+ }
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32) // Refer page 16 of FAT requirement.
+ {
+ RAMwrite (gFATBuffer, p, ((value&0x000000ff))); // lsb,1st byte of cluster value
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8));
+ RAMwrite (gFATBuffer, p+2, ((value&0x00ff0000) >> 16));
+ RAMwrite (gFATBuffer, p+3, ((value&0x0f000000) >> 24)); // the MSB nibble is supposed to be "0" in FAT32. So mask it.
+ }
+ else
+#endif
+
+ if (dsk->type == FAT16)
+ {
+ RAMwrite (gFATBuffer, p, value); //lsB
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8)); // msB
+ }
+ else if (dsk->type == FAT12)
+ {
+ // Get the current byte from the FAT
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = ((value & 0x0F) << 4) | ( c & 0x0F);
+ }
+ else
+ {
+ c = (value & 0xFF);
+ }
+ // Write in those bits
+ RAMwrite (gFATBuffer, p, c);
+
+ // FAT12 entries can cross sector boundaries
+ // Check if we need to load a new sector
+ p = (p+1) & 0x1FF;
+ if (p == 0)
+ {
+ // call this function to update the FAT on the card
+ if (WriteFAT (dsk, 0,0,TRUE))
+ return ClusterFailValue;
+ // Load the next sector
+ if (!MDD_SectorRead (l +1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l + 1;
+ }
+
+ // Get the second byte of the table entry
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = (value >> 4);
+ }
+ else
+ {
+ c = ((value >> 8) & 0x0F) | (c & 0xF0);
+ }
+ RAMwrite (gFATBuffer, p, c);
+ }
+
+ gNeedFATWrite = TRUE;
+
+ return 0;
+}
+#endif
+
+
+#ifdef ALLOW_DIRS
+
+// This string is used by dir functions to hold dir names temporarily
+char defaultString [13];
+
+
+
+/**************************************************************************
+ Function:
+ int FSchdir (char * path)
+ Summary:
+ Change the current working directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to.
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdir function passes a RAM pointer to the path to the
+ chdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSchdir (char * path)
+{
+ return chdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSchdirpgm (const rom char * path)
+ Summary:
+ Changed the CWD with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to (ROM)
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdirpgm function passes a PIC18 ROM path pointer to the
+ chdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSchdirpgm (const rom char * path)
+{
+ return chdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+ // PIC18
+ int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ Summary:
+ Helper function for FSchdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was changed successfully.
+ EOF - Directory could not be changed.
+ Side Effects:
+ The current working directory will be changed. The FSerrno variable
+ will be changed. Any unwritten data in the data buffer will be written
+ to the device.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able to
+ parse it correctly. The function will loop through a switch statement
+ to process the tokens in the path string. Dot or dotdot entries are
+ handled in the first case statement. A backslash character is handled
+ in the second case statement (note that this case statement will only
+ be used if backslash is the first character in the path; backslash
+ token delimiters will automatically be skipped after each token in the
+ path is processed). The third case statement will handle actual
+ directory name strings.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int chdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ WORD curent = 1;
+ DIRENTRY entry;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ FSFILE tempCWDobj2;
+ char tempArray[12];
+ FILEOBJ tempCWD = &tempCWDobj2;
+ FileObjectCopy (tempCWD, cwdptr);
+
+ FSerrno = CE_GOOD;
+
+ // Check the first char of the path
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+ if (i == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ while(1)
+ {
+ switch (i)
+ {
+ // First case: dot or dotdot entry
+ case '.':
+ // Move past the dot
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if it's a dotdot entry
+ if (i == '.')
+ {
+ // Increment the path variable
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if we're in the root
+ if (tempCWD->dirclus == FatRootDirClusterValue)
+ {
+ // Fails if there's a dotdot chdir from the root
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ else
+ {
+ // Cache the dotdot entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ curent = 1;
+ entry = Cache_File_Entry (tempCWD, &curent, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ tempCWD->dirclus = GetFullClusterNumber(entry); // Get Complete Cluster number.
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // If we changed to root, record the name
+ if (tempCWD->dirclus == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT) // "0" is the value of Dotdot entry for Root in both FAT types.
+ {
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+
+ /* While moving to Root, get the Root cluster value */
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Otherwise set the name to ..
+ tempCWD->name[0] = '.';
+ tempCWD->name[1] = '.';
+ for (j = 2; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ // Cache the dot entry
+ curent = 0;
+ if (Cache_File_Entry(tempCWD, &curent, TRUE) == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Move past the next backslash, if necessary
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // Copy and return, if we're at the end
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ // If we ended with a . entry,
+ // just return what we have
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ else
+ {
+ // Anything else after a dot doesn't make sense
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ }
+
+ break;
+
+ // Second case: the first char is the root backslash
+ // We will ONLY switch to this case if the first char
+ // of the path is a backslash
+ case '\\':
+ // Increment pointer to second char
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Can't start the path with multiple backslashes
+ if (i == '\\')
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == 0)
+ {
+ // The user is changing directory to
+ // the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ cwdptr->name[j] = 0x20;
+ }
+ return 0;
+ }
+ else
+ {
+ // Our first char is the root dir switch
+ tempCWD->dirclus = FatRootDirClusterValue;
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ break;
+
+ default:
+ // We should be at the beginning of a string of letters/numbers
+ j = 0;
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath2);
+ }
+ }
+ else
+ {
+#endif
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath);
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // We got a whole 12 chars
+ // There could be more- truncate it
+ if (j == 12)
+ {
+ while ((i != 0) && (i != '\\'))
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ i = *(++temppath2);
+ }
+ else
+ {
+#endif
+ i = *(++temppath);
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ }
+
+ defaultString[j] = 0;
+
+ if (FormatDirName (defaultString, 0) == FALSE)
+ return -1;
+
+ for (j = 0; j < 11; j++)
+ {
+ tempArray[j] = tempCWD->name[j];
+ tempCWD->name[j] = defaultString[j];
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, tempCWD);
+
+ // See if the directory is there
+ if(FILEfind (&gFileTemp, tempCWD, LOOK_FOR_MATCHING_ENTRY, 0) != CE_GOOD)
+ {
+ // Couldn't find the DIR
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Found the file
+ // Check to make sure it's actually a directory
+ if (gFileTemp.attributes != ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Get the new name
+ for (j = 0; j < 11; j++)
+ {
+ tempCWD->name[j] = gFileTemp.name[j];
+ }
+ tempCWD->dirclus = gFileTemp.cluster;
+ tempCWD->dirccls = tempCWD->dirclus;
+ }
+
+ if (i == 0)
+ {
+ // If we're at the end of the string, we're done
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ while (i == '\\')
+ {
+ // If we get to another backslash, increment past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ break;
+ }
+ } // loop
+}
+
+
+
+// This string is used by FSgetcwd to return the cwd name if the path
+// passed into the function is NULL
+char defaultArray [10];
+
+
+/**************************************************************
+ Function:
+ char * FSgetcwd (char * path, int numchars)
+ Summary:
+ Get the current working directory name
+ Conditions:
+ None
+ Input:
+ path - Pointer to the array to return the cwd name in
+ numchars - Number of chars in the path
+ Return Values:
+ char * - The cwd name string pointer (path or defaultArray)
+ NULL - The current working directory name could not be loaded.
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSgetcwd function will get the name of the current
+ working directory and return it to the user. The name
+ will be copied into the buffer pointed to by 'path,'
+ starting at the root directory and copying as many chars
+ as possible before the end of the buffer. The buffer
+ size is indicated by the 'numchars' argument. The first
+ thing this function will do is load the name of the current
+ working directory, if it isn't already present. This could
+ occur if the user switched to the dotdot entry of a
+ subdirectory immediately before calling this function. The
+ function will then copy the current working directory name
+ into the buffer backwards, and insert a backslash character.
+ Next, the function will continuously switch to the previous
+ directories and copy their names backwards into the buffer
+ until it reaches the root. If the buffer overflows, it
+ will be treated as a circular buffer, and data will be
+ copied over existing characters, starting at the beginning.
+ Once the root directory is reached, the text in the buffer
+ will be swapped, so that the buffer contains as much of the
+ current working directory name as possible, starting at the
+ root.
+ Remarks:
+ None
+ **************************************************************/
+char * FSgetcwd (char * path, int numchars)
+{
+ // If path is passed in as null, set up a default
+ // array with 10 characters
+ char totalchars = (path == NULL) ? 10 : numchars;
+ char * returnPointer;
+ char * bufferEnd;
+ FILEOBJ tempCWD = &gFileTemp;
+ BYTE bufferOverflow = FALSE;
+ signed char j;
+ DWORD curclus;
+ WORD fHandle, tempindex;
+ signed int i, index = 0;
+ char aChar;
+ DIRENTRY entry;
+
+ FSerrno = CE_GOOD;
+
+ // Set up the return value
+ if (path == NULL)
+ returnPointer = defaultArray;
+ else
+ {
+ returnPointer = path;
+ if (numchars == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return NULL;
+ }
+ }
+
+ bufferEnd = returnPointer + totalchars - 1;
+
+ FileObjectCopy (tempCWD, cwdptr);
+
+ if ((tempCWD->name[0] == '.') &&
+ (tempCWD->name[1] == '.'))
+ {
+ // We last changed directory into a dotdot entry
+ // Save the value of the current directory
+ curclus = tempCWD->dirclus;
+ // Put this dir's dotdot entry into the dirclus
+ // Our cwd absolutely is not the root
+ fHandle = 1;
+ tempCWD->dirccls = tempCWD->dirclus;
+ entry = Cache_File_Entry (tempCWD,&fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ // For FAT32, if the .. entry is 0, the cluster won't be 0
+#ifdef SUPPORT_FAT32
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ tempCWD->dirclus = TempClusterCalc;
+
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // Find the direntry for the entry we were just in
+ fHandle = 0;
+ entry = Cache_File_Entry (tempCWD, &fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != curclus) ||
+ ((TempClusterCalc == curclus) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME) || (entry->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ fHandle++;
+ entry = Cache_File_Entry (tempCWD, &fHandle, FALSE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // We've found the entry for the dir we were in
+ for (i = 0; i < 11; i++)
+ {
+ tempCWD->name[i] = entry->DIR_Name[i];
+ cwdptr->name[i] = entry->DIR_Name[i];
+ }
+ // Reset our temp dir back to that cluster
+ tempCWD->dirclus = curclus;
+ tempCWD->dirccls = curclus;
+ // This will set us at the cwd, but it will actually
+ // have the name in the name field this time
+ }
+ // There's actually some kind of name value in the cwd
+ if (tempCWD->name[0] == '\\')
+ {
+ // Easy, our CWD is the root
+ *returnPointer = '\\';
+ *(returnPointer + 1) = 0;
+ return returnPointer;
+ }
+ else
+ {
+ // Loop until we get back to the root
+ while (tempCWD->dirclus != FatRootDirClusterValue)
+ {
+ j = 10;
+ while (tempCWD->name[j] == 0x20)
+ j--;
+ if (j >= 8)
+ {
+ while (j >= 8)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+ *(returnPointer + index++) = '.';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ while (tempCWD->name[j] == 0x20)
+ j--;
+
+ while (j >= 0)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ // Put a backslash delimiter in front of the dir name
+ *(returnPointer + index++) = '\\';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+
+ // Load the previous entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ if (GetPreviousEntry (tempCWD))
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ return NULL;
+ }
+ }
+ }
+
+ // Point the index back at the last char in the string
+ index--;
+
+ i = 0;
+ // Swap the chars in the buffer so they are in the right places
+ if (bufferOverflow)
+ {
+ tempindex = index;
+ // Swap the overflowed values in the buffer
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+
+ // Point at the non-overflowed values
+ i = tempindex + 1;
+ index = bufferEnd - returnPointer;
+
+ // Swap the non-overflowed values into the right places
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ // All the values should be in the right place now
+ // Null-terminate the string
+ *(bufferEnd) = 0;
+ }
+ else
+ {
+ // There was no overflow, just do one set of swaps
+ tempindex = index;
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ *(returnPointer + tempindex + 1) = 0;
+ }
+
+ return returnPointer;
+}
+
+
+/**************************************************************************
+ Function:
+ void GetPreviousEntry (FSFILE * fo)
+ Summary:
+ Get the file entry info for the parent dir of the specified dir
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - The file to get the previous entry of
+ Return Values:
+ 0 - The previous entry was successfully retrieved
+ -1 - The previous entry could not be retrieved
+ Side Effects:
+ None
+ Description:
+ The GetPreviousEntry function is used by the FSgetcwd function to
+ load the previous (parent) directory. This function will load the
+ parent directory and then search through the file entries in that
+ directory for one that matches the cluster number of the original
+ directory. When the matching entry is found, the name of the
+ original directory is copied into the 'fo' FSFILE object.
+ Remarks:
+ None.
+ **************************************************************************/
+
+BYTE GetPreviousEntry (FSFILE * fo)
+{
+ BYTE i;
+ WORD fHandle = 1;
+ DWORD dirclus;
+ DIRENTRY dirptr;
+
+ // Load the previous entry
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ // The previous directory is the root
+ fo->name[0] = '\\';
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = 0x20;
+ }
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Get the directory name
+ // Save the previous cluster value
+ // Get the cluster
+
+ dirclus = TempClusterCalc;
+ fo->dirclus = TempClusterCalc;
+ fo->dirccls = TempClusterCalc;
+
+
+ // Load the previous previous cluster
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+#ifdef SUPPORT_FAT32
+ // If we're using FAT32 and the previous previous cluster is the root, the
+ // value in the dotdot entry will be 0, but the actual cluster won't
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ fo->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ fo->dirclus = TempClusterCalc;
+
+ fo->dirccls = fo->dirclus;
+
+ fHandle = 0;
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+ // Look through it until we get the name
+ // of the previous cluster
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+ while ((TempClusterCalc != dirclus) ||
+ ((TempClusterCalc == dirclus) &&
+ (((unsigned char)dirptr->DIR_Name[0] == 0xE5) || (dirptr->DIR_Attr == ATTR_VOLUME) || (dirptr->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ // Look through the entries until we get the
+ // right one
+ dirptr = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dirptr == NULL)
+ return -1;
+ fHandle++;
+
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number in a loop.
+ }
+
+ // The name should be in the entry now
+ // Copy the actual directory location back
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = dirptr->DIR_Name[i];
+ }
+ fo->dirclus = dirclus;
+ fo->dirccls = dirclus;
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+ Function:
+ int FSmkdir (char * path)
+ Summary:
+ Create a directory
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create.
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdir function passes a RAM pointer to the path to the
+ mkdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSmkdir (char * path)
+{
+ return mkdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSmkdirpgm (const rom char * path)
+ Summary:
+ Create a directory with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create (ROM)
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdirpgm function passes a PIC18 ROM path pointer to the
+ mkdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arugments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSmkdirpgm (const rom char * path)
+{
+ return mkdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+ // PIC18
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+ Summary:
+ Helper function for FSmkdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was created
+ -1 - Directory could not be created
+ Side Effects:
+ Will create all non-existant directories in the path.
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first scan through the path
+ to ensure that any DIR names don't exceed 11 characters. It will then
+ backup the current working directory and begin changing directories
+ through the path until it reaches a directory than can't be changed to.
+ It will then create the specified directory and change directories to
+ the new directory. The function will continue creating and changing to
+ directories until the end of the path is reached. The function will
+ then restore the original current working directory.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ char tempArray[13];
+ FILEOBJ tempCWD = &tempCWDobj;
+
+#ifdef __18CXX
+ char dotdotPath[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath2 != 0) && (*temppath2 != '.')&& (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath2 == '.')
+ {
+ temppath2++;
+ i = 0;
+ while ((*temppath2 != 0) && (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath2 == '\\')
+ temppath2++;
+ if (*temppath2 == 0)
+ break;
+ }
+ }
+ else
+#endif
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath != 0) && (*temppath != '.')&& (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath == '.')
+ {
+ temppath++;
+ i = 0;
+ while ((*temppath != 0) && (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath == '\\')
+ temppath++;
+ if (*temppath == 0)
+ break;
+ }
+
+ temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ temppath2 = romptr;
+#endif
+
+ // We're going to be moving the CWD
+ // Back up the CWD
+ FileObjectCopy (tempCWD, cwdptr);
+
+ // get to the target directory
+ while (1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+
+ if (i == '.')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ if ((i != '.') && (i != 0) && (i != '\\'))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == '.')
+ {
+ if (cwdptr->dirclus == FatRootDirClusterValue)
+ {
+ // If we try to change to the .. from the
+ // root, operation fails
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if ((i != '\\') && (i != 0))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+// dotdot entry
+#ifndef __18CXX
+ FSchdir ("..");
+#else
+ FSchdir (dotdotPath);
+#endif
+ }
+ // Skip past any backslashes
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ // No point in creating a dot or dotdot entry directly
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ // Start at the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (i = 1; i < 11; i++)
+ {
+ cwdptr->name[i] = 0x20;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // If we just got two backslashes in a row at the
+ // beginning of the path, the function fails
+ if (i == '\\')
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (i == 0)
+ {
+ // We can't make the root dir
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ tempArray[12] = 0;
+ while (1)
+ {
+ while(1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Change directories as specified
+ i = *temppath2;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ // Change directories as specified
+ i = *temppath;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ tempArray[j] = 0;
+
+ if (tempArray[0] == '.')
+ {
+ if ((tempArray[1] != 0) && (tempArray[1] != '.'))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if ((tempArray[1] == '.') && (tempArray[2] != 0))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+
+ // Try to change to it
+ // If you can't we need to create it
+ if (FSchdir (tempArray))
+ {
+ break;
+ }
+ else
+ {
+ // We changed into the directory
+ while (i == '\\')
+ {
+ // Next char is a backslash
+ // Move past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // If it's the last one, return success
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+
+ // Create a dir here
+ if (!CreateDIR (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ // Try to change to that directory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Check for another backslash
+ while (*temppath2 == '\\')
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ while (*temppath == '\\')
+ {
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Check to see if we're at the end of the path string
+ if (i == 0)
+ {
+ // We already have one
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+}
+
+
+/**************************************************************************
+ Function:
+ int CreateDIR (char * path)
+ Summary:
+ FSmkdir helper function to create a directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the dir to create
+ Return Values:
+ TRUE - Directory was created successfully
+ FALSE - Directory could not be created.
+ Side Effects:
+ Any unwritten data in the data buffer or the FAT buffer will be written
+ to the device.
+ Description:
+ The CreateDIR function is a helper function for the mkdirhelper
+ function. The CreateDIR function will create a new file entry for
+ a directory and assign a cluster to it. It will erase the cluster
+ and write a dot and dotdot entry to it.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int CreateDIR (char * path)
+{
+ FSFILE * dirEntryPtr = &gFileTemp;
+ DIRENTRY dir;
+ WORD handle = 0;
+ DWORD dot, dotdot;
+ BYTE i;
+
+ for (i = 0; i < 12; i++)
+ {
+ defaultString[i] = *(path + i);
+ }
+
+ if (FormatDirName(defaultString, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return FALSE;
+ }
+
+ // Copy name into file object
+ for (i = 0; i < 11; i++)
+ {
+ dirEntryPtr->name[i] = defaultString[i];
+ }
+
+ dirEntryPtr->dirclus = cwdptr->dirclus;
+ dirEntryPtr->dirccls = cwdptr->dirccls;
+ dirEntryPtr->cluster = 0;
+ dirEntryPtr->ccls = 0;
+ dirEntryPtr->dsk = cwdptr->dsk;
+
+ // Create a directory entry
+ if(CreateFileEntry(dirEntryPtr, &handle, DIRECTORY) != CE_GOOD)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (gNeedFATWrite)
+ if(WriteFAT (dirEntryPtr->dsk, 0, 0, TRUE))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+ // Zero that cluster
+ if (dirEntryPtr->dirclus == FatRootDirClusterValue)
+ dotdot = 0;
+ else
+ dotdot = dirEntryPtr->dirclus;
+ dirEntryPtr->dirccls = dirEntryPtr->dirclus;
+ dir = Cache_File_Entry(dirEntryPtr, &handle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return FALSE;
+ }
+
+ // Get the cluster
+ dot = GetFullClusterNumber(dir); // Get complete cluster number.
+
+ if (writeDotEntries (dirEntryPtr->dsk, dot, dotdot))
+ return TRUE;
+ else
+ return FALSE;
+
+ }
+}
+
+
+/***********************************************************************************
+ Function:
+ BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+ Summary:
+ Create dot and dotdot entries in a non-root directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - The global disk structure
+ dotAddress - The cluster the current dir is in
+ dotdotAddress - The cluster the previous directory was in
+ Return Values:
+ TRUE - The dot and dotdot entries were created
+ FALSE - The dot and dotdot entries could not be created in the new directory
+ Side Effects:
+ None
+ Description:
+ The writeDotEntries function will create and write dot and dotdot entries
+ to a newly created directory.
+ Remarks:
+ None.
+ ***********************************************************************************/
+
+BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+{
+ WORD i;
+ WORD size;
+ _DIRENTRY entry;
+ DIRENTRY entryptr = &entry;
+ DWORD sector;
+
+ gBufferOwner = NULL;
+
+ size = sizeof (_DIRENTRY);
+
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ entry.DIR_Name[0] = '.';
+
+ for (i = 1; i < 11; i++)
+ {
+ entry.DIR_Name[i] = 0x20;
+ }
+ entry.DIR_Attr = ATTR_DIRECTORY;
+ entry.DIR_NTRes = 0x00;
+
+ entry.DIR_FstClusLO = (WORD)(dotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+ entry.DIR_FileSize = 0x00;
+
+// Times need to be the same as the times in the directory entry
+
+// Set dir date for uncontrolled clock source
+#ifdef INCREMENTTIMESTAMP
+ entry.DIR_CrtTimeTenth = 0xB2;
+ entry.DIR_CrtTime = 0x7278;
+ entry.DIR_CrtDate = 0x32B0;
+ entry.DIR_LstAccDate = 0x0000;
+ entry.DIR_WrtTime = 0x0000;
+ entry.DIR_WrtDate = 0x0000;
+#endif
+
+#ifdef USEREALTIMECLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i) = *((char *)entryptr + i);
+ }
+ entry.DIR_Name[1] = '.';
+
+ entry.DIR_FstClusLO = (WORD)(dotdotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotdotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i + size) = *((char *)entryptr + i);
+ }
+
+ sector = Cluster2Sector (disk, dotAddress);
+
+ if (MDD_SectorWrite(sector, disk->buffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// This array is used to prevent a stack frame error
+#ifdef __18CXX
+ char tempArray[13] = " ";
+#endif
+
+
+/**************************************************************************
+ Function:
+ int FSrmdir (char * path)
+ Summary:
+ Delete a directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to remove
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdir function passes a RAM pointer to the path to the
+ rmdirhelper function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int FSrmdir (char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (0, path, NULL, rmsubdirs);
+}
+
+/**************************************************************************
+ Function:
+ int FSrmdirpgm (const rom char * path)
+ Summary:
+ Delete a directory with a path in ROM on PIC18
+ Conditions:
+ None.
+ Input:
+ path - The path of the directory to remove (ROM)
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdirpgm function passes a PIC18 ROM path pointer to the
+ rmdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSrmdirpgm (const rom char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (1, NULL, path, rmsubdirs);
+}
+#endif
+
+/************************************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+ // PIC18
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+ Summary:
+ Helper function for FSrmdir
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The path of the dir to delete
+ rmsubdirs -
+ - TRUE - Remove all sub-directories and files in the directory
+ - FALSE - Non-empty directories can not be removed
+ Return Values:
+ 0 - The specified directory was successfully removed.
+ EOF - The specified directory could not be removed.
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSmkdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first change to the
+ specified directory. If the rmsubdirs argument is FALSE the function
+ will search through the directory to ensure that it is empty and then
+ remove it. If the rmsubdirs argument is TRUE the function will also
+ search through the directory for subdirectories or files. When the
+ function finds a file, the file will be erased. When the function
+ finds a subdirectory, it will switch to the subdirectory and begin
+ removing all of the files in that subdirectory. Once the subdirectory
+ is empty, the function will switch back to the original directory.
+ return to the original position in that directory, and continue removing
+ files. Once the specified directory is empty, the function will
+ change to the parent directory, search through it for the directory
+ to remove, and then erase that directory.
+ Remarks:
+ None.
+ ************************************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+#else
+int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+#endif
+{
+ FILEOBJ tempCWD = &tempCWDobj;
+ FILEOBJ fo = &gFileTemp;
+ DIRENTRY entry;
+ WORD handle = 0;
+ WORD handle2;
+ WORD subDirDepth;
+ BYTE Index, Index2;
+
+#ifndef __18CXX
+ char tempArray[13] = " ";
+#else
+ char dotdotname[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ // Back up the current working directory
+ FileObjectCopy (tempCWD, cwdptr);
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ if (chdirhelper (1, NULL, romptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ }
+ else
+ {
+#endif
+ if (FSchdir (ramptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Make sure we aren't trying to remove the root dir or the CWD
+ if ((cwdptr->dirclus == FatRootDirClusterValue) || (cwdptr->dirclus == tempCWD->dirclus))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Don't remove subdirectories and sub-files
+ if (!rmsubdirs)
+ {
+ while (entry->DIR_Name[0] != 0)
+ {
+ if ((unsigned char)entry->DIR_Name[0] != 0xE5)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_EMPTY;
+ return -1;
+ }
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if ((entry == NULL))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ // Do remove subdirectories and sub-files
+ dirCleared = FALSE;
+ subDirDepth = 0;
+
+ while (!dirCleared)
+ {
+ if (entry->DIR_Name[0] != 0)
+ {
+ if (((unsigned char)entry->DIR_Name[0] != 0xE5) && (entry->DIR_Attr != ATTR_VOLUME) && (entry->DIR_Attr != ATTR_LONG_NAME))
+ {
+ if ((entry->DIR_Attr & ATTR_DIRECTORY) == ATTR_DIRECTORY)
+ {
+ // We have a directory
+ subDirDepth++;
+ for (Index = 0; (Index < DIR_NAMESIZE) && (entry->DIR_Name[Index] != 0x20); Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (entry->DIR_Name[8] != 0x20)
+ {
+ tempArray[Index++] = '.';
+ for (Index2 = 0; (Index2 < DIR_EXTENSION) && (entry->DIR_Name[Index2 + DIR_NAMESIZE] != 0x20); Index2++)
+ {
+ tempArray[Index++] = entry->DIR_Name[Index2 + DIR_NAMESIZE];
+ }
+ }
+ tempArray[Index] = 0;
+ // Change to the subdirectory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Make sure we're not trying to delete the CWD
+ if (cwdptr->dirclus == tempCWD->dirclus)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ handle = 2;
+ recache = TRUE;
+ }
+ else
+ {
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ fo->name[Index] = entry->DIR_Name[Index];
+ }
+
+ fo->dsk = &gDiskData;
+
+ fo->entry = handle;
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+ fo->cluster = 0;
+ fo->ccls = 0;
+
+ if (FILEerase(fo, &handle, TRUE))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ }
+ } // Check to see if it's a DIR entry
+ }// Check non-dir entry to see if its a valid file
+ else
+ {
+ handle++;
+ }
+ if (recache)
+ {
+ recache = FALSE;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ }
+ else
+ {
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ }
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ else
+ {
+ // We have reached the end of the directory
+ if (subDirDepth != 0)
+ {
+ handle2 = 0;
+
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle2, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ handle2 = GetFullClusterNumber(entry); // Get complete cluster number.
+
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ // Return to our previous position in this directory
+ handle = 2;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != handle2) ||
+ ((TempClusterCalc == handle2) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME))))
+ {
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // Erase the directory that we just cleared the subdirectories out of
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+
+ // Decrease the subdirectory depth
+ subDirDepth--;
+ }
+ else
+ {
+ dirCleared = TRUE;
+ } // Check subdirectory depth
+ } // Check until we get an empty entry
+ } // Loop until the whole dir is cleared
+ }
+
+ // Cache the current directory name
+ // tempArray is used so we don't disturb the
+ // global getcwd buffer
+ if (FSgetcwd (tempArray, 12) == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ memset(tempArray, 0x00, 12);
+
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = cwdptr->name[Index];
+ }
+
+ // If we're here, this directory is empty
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+}
+
+
+/****************************************************************
+ Function:
+ int eraseDir (char * path)
+ Summary:
+ FSrmdir helper function to erase dirs
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the directory to delete
+ Return Values:
+ 0 - Dir was deleted successfully
+ -1 - Dir could not be deleted.
+ Side Effects:
+ None
+ Description:
+ The eraseDir function is a helper function for the rmdirhelper
+ function. The eraseDir function will search for the
+ directory that matches the specified path name and then erase
+ it with the FILEerase function.
+ Remarks:
+ None.
+ *****************************************************************/
+
+int eraseDir (char * path)
+{
+ CETYPE result;
+ BYTE Index;
+ FSFILE tempCWDobj2;
+
+ if (MDD_WriteProtectState())
+ {
+ return (-1);
+ }
+
+ // preserve CWD
+ FileObjectCopy(&tempCWDobj2, cwdptr);
+
+ for (Index = 0; Index <11; Index++)
+ {
+ cwdptr->name[Index] = *(path + Index);
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, cwdptr);
+
+ // See if the file is found
+ result = FILEfind (cwdptr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+ result = FILEerase(cwdptr, &cwdptr->entry, TRUE);
+ if( result == CE_GOOD )
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return 0;
+ }
+ else
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+}
+#endif
+
+
+
+#endif
+
+
+#ifdef ALLOW_FILESEARCH
+
+
+/***********************************************************************************
+ Function:
+ int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Initial search function
+ Conditions:
+ None
+ Input:
+ fileName - The name to search for
+ - Parital string search characters
+ - * - Indicates the rest of the filename or extension can vary (e.g. FILE.*)
+ - ? - Indicates that one character in a filename can vary (e.g. F?LE.T?T)
+ attr - The attributes that a found file may have
+ - ATTR_READ_ONLY - File may be read only
+ - ATTR_HIDDEN - File may be a hidden file
+ - ATTR_SYSTEM - File may be a system file
+ - ATTR_VOLUME - Entry may be a volume label
+ - ATTR_DIRECTORY - File may be a directory
+ - ATTR_ARCHIVE - File may have archive attribute
+ - ATTR_MASK - All attributes
+ rec - pointer to a structure to put the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the specified criteria was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object
+ will be lost. The FSerrno variable will be changed.
+ Description:
+ The FindFirst function will search for a file based on parameters passed in
+ by the user. This function will use the FILEfind function to parse through
+ the current working directory searching for entries that match the specified
+ parameters. If a file is found, its parameters are copied into the SearchRec
+ structure, as are the initial parameters passed in by the user and the position
+ of the file entry in the current working directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling FindNext
+ ***********************************************************************************/
+
+int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ WORD fHandle;
+ BYTE j;
+ BYTE Index;
+
+ FSerrno = CE_GOOD;
+
+ if( !FormatFileName(fileName, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ rec->initialized = FALSE;
+
+ for (Index = 0; (Index < 12) && (fileName[Index] != 0); Index++)
+ {
+ rec->searchname[Index] = fileName[Index];
+ }
+ rec->searchname[Index] = 0;
+ rec->searchattr = attr;
+#ifdef ALLOW_DIRS
+ rec->cwdclus = cwdptr->dirclus;
+#else
+ rec->cwdclus = FatRootDirClusterValue;
+#endif
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = attr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ fHandle = fo->entry;
+ result = FILEopen (fo, &fHandle, 'r');
+ }
+ if (result == CE_GOOD)
+ {
+ // Copy as much name as there is
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (Index = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[Index++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[Index] = 0;
+ }
+ else
+ {
+ for (Index = 0; Index < DIR_NAMECOMP; Index++)
+ {
+ rec->filename[Index] = fo->name[Index];
+ }
+ rec->filename[Index] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ rec->initialized = TRUE;
+ return 0;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+}
+
+
+/**********************************************************************
+ Function:
+ int FindNext (SearchRec * rec)
+ Summary:
+ Sequential search function
+ Conditions:
+ None
+ Input:
+ rec - The structure to store the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No additional files matching the specified criteria were found
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FindNext function performs the same function as the FindFirst
+ funciton, except it does not copy any search parameters into the
+ SearchRec structure (only info about found files) and it begins
+ searching at the last directory entry offset at which a file was
+ found, rather than at the beginning of the current working
+ directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling this function
+ **********************************************************************/
+
+int FindNext (SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ BYTE i, j;
+
+ FSerrno = CE_GOOD;
+
+ // Make sure we called FindFirst on this object
+ if (rec->initialized == FALSE)
+ {
+ FSerrno = CE_NOT_INIT;
+ return -1;
+ }
+
+ // Make sure we called FindFirst in the cwd
+#ifdef ALLOW_DIRS
+ if (rec->cwdclus != cwdptr->dirclus)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#endif
+
+ if( !FormatFileName(rec->searchname, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ /* Brn: Copy the formatted name to "fo" which is necesary before calling "FILEfind" function */
+ //strcpy(fo->name,rec->searchname);
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = rec->entry + 1;
+ fo->attributes = rec->searchattr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (i = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[i++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[i] = 0;
+ }
+ else
+ {
+ for (i = 0; i < DIR_NAMECOMP; i++)
+ {
+ rec->filename[i] = fo->name[i];
+ }
+ rec->filename[i] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ return 0;
+ }
+}
+
+
+#endif
+
+
+
+#ifdef ALLOW_FSFPRINTF
+
+
+
+/**********************************************************************
+ Function:
+ int FSputc (char c, FSFILE * file)
+ Summary:
+ FSfprintf helper function to write a char
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ c - The character to write to the file.
+ file - The file to write to.
+ Return Values:
+ 0 - The character was written successfully
+ EOF - The character was not written to the file.
+ Side Effects:
+ None
+ Description:
+ This is a helper function for FSfprintf. It will write one
+ character to a file.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSputc (char c, FSFILE * file)
+{
+ if (FSfwrite ((void *)&c, 1, 1, file) != 1)
+ return EOF;
+ else
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ int str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+ Summary:
+ FSfprintf helper function to write a char multiple times
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - The file to write to.
+ n - The number of times to write that character to a file.
+ c - The character to write to the file.
+ Return Values:
+ 0 - The characters were written successfully
+ EOF - The characters were not written to the file.
+ Side Effects:
+ None
+ Description:
+ This funciton is used by the FSfprintf function to write multiple
+ instances of a single character to a file (for example, when
+ padding a format specifier with leading spacez or zeros).
+ Remarks:
+ None.
+ **********************************************************************/
+
+
+unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+{
+ while (n--)
+ if (FSputc (c, handle) == EOF)
+ return 1;
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSfprintf (FSFILE * fptr, const char * fmt, ...)
+ // PIC18
+ int FSfpritnf (FSFILE * fptr, const rom char * fmt, ...)
+ Summary:
+ Function to write formatted strings to a file
+ Conditions:
+ For PIC18, integer promotion must be enabled in the project build
+ options menu. File opened in a write mode.
+ Input:
+ fptr - A pointer to the file to write to.
+ fmt - A string of characters and format specifiers to write to
+ the file
+ ... - Additional arguments inserted in the string by format
+ specifiers
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Writes a specially formatted string to a file.
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSfprintf (FSFILE *fptr, const rom char *fmt, ...)
+#else
+int FSfprintf (FSFILE *fptr, const char * fmt, ...)
+#endif
+{
+ va_list ap;
+ int n;
+
+ va_start (ap, fmt);
+ n = FSvfprintf (fptr, fmt, ap);
+ va_end (ap);
+ return n;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSvfprintf (FSFILE * handle, const char * formatString, va_list ap)
+ // PIC18
+ int FSvfpritnf (auto FSFILE * handle, auto const rom char * formatString, auto va_list ap)
+ Summary:
+ Helper function for FSfprintf
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - A pointer to the file to write to.
+ formatString - A string of characters and format specifiers to write to
+ the file
+ ap - A structure pointing to the arguments on the stack
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function will access the elements passed to FSfprintf
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSvfprintf (auto FSFILE *handle, auto const rom char * formatString, auto va_list ap)
+#else
+int FSvfprintf (FSFILE *handle, const char * formatString, va_list ap)
+#endif
+{
+ unsigned char c;
+ int count = 0;
+
+ for (c = *formatString; c; c = *++formatString)
+ {
+ if (c == '%')
+ {
+ unsigned char flags = 0;
+ unsigned char width = 0;
+ unsigned char precision = 0;
+ unsigned char have_precision = 0;
+ unsigned char size = 0;
+#ifndef __18CXX
+ unsigned char size2 = 0;
+#endif
+ unsigned char space_cnt;
+ unsigned char cval;
+#ifdef __18CXX
+ unsigned long larg;
+ far rom char * romstring;
+#else
+ unsigned long long larg;
+#endif
+ char * ramstring;
+ int n;
+
+ FSerrno = CE_GOOD;
+
+ c = *++formatString;
+
+ while (c == '-' || c == '+' || c == ' ' || c == '#'
+ || c == '0')
+ {
+ switch (c)
+ {
+ case '-':
+ flags |= _FLAG_MINUS;
+ break;
+ case '+':
+ flags |= _FLAG_PLUS;
+ break;
+ case ' ':
+ flags |= _FLAG_SPACE;
+ break;
+ case '#':
+ flags |= _FLAG_OCTO;
+ break;
+ case '0':
+ flags |= _FLAG_ZERO;
+ break;
+ }
+ c = *++formatString;
+ }
+ /* the optional width field is next */
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n < 0)
+ {
+ flags |= _FLAG_MINUS;
+ width = -n;
+ }
+ else
+ width = n;
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ width = cval;
+ }
+
+ /* if '-' is specified, '0' is ignored */
+ if (flags & _FLAG_MINUS)
+ flags &= ~_FLAG_ZERO;
+
+ /* the optional precision field is next */
+ if (c == '.')
+ {
+ c = *++formatString;
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n >= 0)
+ {
+ precision = n;
+ have_precision = 1;
+ }
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ precision = cval;
+ have_precision = 1;
+ }
+ }
+
+ /* the optional 'h' specifier. since int and short int are
+ the same size for MPLAB C18, this is a NOP for us. */
+ if (c == 'h')
+ {
+ c = *++formatString;
+ /* if 'c' is another 'h' character, this is an 'hh'
+ specifier and the size is 8 bits */
+ if (c == 'h')
+ {
+ size = _FMT_BYTE;
+ c = *++formatString;
+ }
+ }
+ else if (c == 't' || c == 'z')
+ c = *++formatString;
+#ifdef __18CXX
+ else if (c == 'H' || c == 'T' || c == 'Z')
+ {
+ size = _FMT_SHRTLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l' || c == 'j')
+#else
+ else if (c == 'q' || c == 'j')
+ {
+ size = _FMT_LONGLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l')
+#endif
+ {
+ size = _FMT_LONG;
+ c = *++formatString;
+ }
+
+ switch (c)
+ {
+ case '\0':
+ /* this is undefined behaviour. we have a trailing '%' character
+ in the string, perhaps with some flags, width, precision
+ stuff as well, but no format specifier. We'll, arbitrarily,
+ back up a character so that the loop will terminate
+ properly when it loops back and we'll output a '%'
+ character. */
+ --formatString;
+ /* fallthrough */
+ case '%':
+ if (FSputc ('%', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ break;
+ case 'c':
+ space_cnt = 0;
+ if (width > 1)
+ {
+ space_cnt = width - 1;
+ count += space_cnt;
+ }
+ if (space_cnt && !(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ c = va_arg (ap, int);
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'S':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ romstring = va_arg (ap, rom far char *);
+ else
+ romstring = (far rom char*)va_arg (ap, rom near char *);
+ n = strlenpgm (romstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the
+ string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *romstring; c && cval < width; c = *++romstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+#endif
+ case 's':
+ ramstring = va_arg (ap, char *);
+ n = strlen (ramstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *ramstring; c && cval < width; c = *++ramstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'd':
+ case 'i':
+ flags |= _FLAG_SIGNED;
+ /* fall through */
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'b':
+ case 'B':
+ /* This is a bit of a trick. The 'l' and 'hh' size
+ specifiers are valid only for the integer conversions,
+ not the 'p' or 'P' conversions, and are ignored for the
+ latter. By jumping over the additional size specifier
+ checks here we get the best code size since we can
+ limit the size checks in the remaining code. */
+ if (size == _FMT_LONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, long int);
+ else
+ larg = va_arg (ap, unsigned long int);
+ goto _do_integer_conversion;
+ }
+ else if (size == _FMT_BYTE)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed char) va_arg (ap, int);
+ else
+ larg = (unsigned char) va_arg (ap, unsigned int);
+ goto _do_integer_conversion;
+ }
+#ifndef __18CXX
+ else if (size == _FMT_LONGLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed long long)va_arg (ap, long long);
+ else
+ larg = (unsigned long long) va_arg (ap, unsigned long long);
+ goto _do_integer_conversion;
+ }
+#endif
+ /* fall trough */
+ case 'p':
+ case 'P':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, short long int);
+ else
+ larg = va_arg (ap, unsigned short long int);
+ }
+ else
+#endif
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, int);
+ else
+ larg = va_arg (ap, unsigned int);
+ _do_integer_conversion:
+ /* default precision is 1 */
+ if (!have_precision)
+ precision = 1;
+ {
+ unsigned char digit_cnt = 0;
+ unsigned char prefix_cnt = 0;
+ unsigned char sign_char;
+ /* A 32 bit number will require at most 32 digits in the
+ string representation (binary format). */
+#ifdef __18CXX
+ char buf[33];
+ /* Start storing digits least-significant first */
+ char *q = &buf[31];
+ /* null terminate the string */
+ buf[32] = '\0';
+#else
+ char buf[65];
+ char *q = &buf[63];
+ buf[64] = '\0';
+#endif
+ space_cnt = 0;
+ size = 10;
+
+ switch (c)
+ {
+ case 'b':
+ case 'B':
+ size = 2;
+#ifndef __18CXX
+ size2 = 1;
+#endif
+ break;
+ case 'o':
+ size = 8;
+#ifndef __18CXX
+ size2 = 3;
+#endif
+ break;
+ case 'p':
+ case 'P':
+ /* from here on out, treat 'p' conversions just
+ like 'x' conversions. */
+ c += 'x' - 'p';
+ /* fall through */
+ case 'x':
+ case 'X':
+ size = 16;
+#ifndef __18CXX
+ size2 = 4;
+#endif
+ break;
+ }// switch (c)
+
+ /* if it's an unsigned conversion, we should ignore the
+ ' ' and '+' flags */
+ if (!(flags & _FLAG_SIGNED))
+ flags &= ~(_FLAG_PLUS | _FLAG_SPACE);
+
+ /* if it's a negative value, we need to negate the
+ unsigned version before we convert to text. Using
+ unsigned for this allows us to (ab)use the 2's
+ complement system to avoid overflow and be able to
+ adequately handle LONG_MIN.
+
+ We'll figure out what sign character to print, if
+ any, here as well. */
+#ifdef __18CXX
+ if (flags & _FLAG_SIGNED && ((long) larg < 0))
+ {
+ larg = -(long) larg;
+#else
+ if (flags & _FLAG_SIGNED && ((long long) larg < 0))
+ {
+ larg = -(long long) larg;
+#endif
+ sign_char = '-';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_PLUS)
+ {
+ sign_char = '+';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_SPACE)
+ {
+ sign_char = ' ';
+ ++digit_cnt;
+ }
+ else
+ sign_char = '\0';
+ /* get the digits for the actual number. If the
+ precision is zero and the value is zero, the result
+ is no characters. */
+ if (precision || larg)
+ {
+ do
+ {
+#ifdef __18CXX
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ larg /= size;
+#else
+ // larg is congruent mod size2 to its lower 16 bits
+ // for size2 = 2^n, 0 <= n <= 4
+ if (size2 != 0)
+ cval = s_digits[(unsigned int) larg % size];
+ else
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ if (size2 != 0)
+ larg = larg >> size2;
+ else
+ larg /= size;
+#endif
+ *q-- = cval;
+ ++digit_cnt;
+ } while (larg);
+ /* if the '#' flag was specified and we're dealing
+ with an 'o', 'b', 'B', 'x', or 'X' conversion,
+ we need a bit more. */
+ if (flags & _FLAG_OCTO)
+ {
+ if (c == 'o')
+ {
+ /* per the standard, for octal, the '#' flag
+ makes the precision be at least one more
+ than the number of digits in the number */
+ if (precision <= digit_cnt)
+ precision = digit_cnt + 1;
+ }
+ else if (c == 'x' || c == 'X' || c == 'b' || c == 'B')
+ prefix_cnt = 2;
+ }
+ }
+ else
+ digit_cnt = 0;
+
+ /* The leading zero count depends on whether the '0'
+ flag was specified or not. If it was not, then the
+ count is the difference between the specified
+ precision and the number of digits (including the
+ sign character, if any) to be printed; otherwise,
+ it's as if the precision were equal to the max of
+ the specified precision and the field width. If a
+ precision was specified, the '0' flag is ignored,
+ however. */
+ if ((flags & _FLAG_ZERO) && (width > precision)
+ && !have_precision)
+ precision = width;
+ /* for the rest of the processing, precision contains
+ the leading zero count for the conversion. */
+ if (precision > digit_cnt)
+ precision -= digit_cnt;
+ else
+ precision = 0;
+ /* the space count is the difference between the field
+ width and the digit count plus the leading zero
+ count. If the width is less than the digit count
+ plus the leading zero count, the space count is
+ zero. */
+ if (width > precision + digit_cnt + prefix_cnt)
+ space_cnt = width - precision - digit_cnt - prefix_cnt;
+
+ /* for output, we check the justification, if it's
+ right justified and the space count is positive, we
+ emit the space characters first. */
+ if (!(flags & _FLAG_MINUS) && space_cnt)
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ count += space_cnt;
+ space_cnt = 0;
+ }
+ /* if we have a sign character to print, that comes
+ next */
+ if (sign_char)
+ if (FSputc (sign_char, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if we have a prefix (0b, 0B, 0x or 0X), that's next */
+ if (prefix_cnt)
+ {
+ if (FSputc ('0', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ }
+ /* if we have leading zeros, they follow. the prefix, if any
+ is included in the number of digits when determining how
+ many leading zeroes are needed. */
+// if (precision > prefix_cnt)
+ // precision -= prefix_cnt;
+ if (str_put_n_chars (handle, precision, '0'))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* print the actual number */
+ for (cval = *++q; cval; cval = *++q)
+ if (FSputc (cval, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if there are any spaces left, they go to right-pad
+ the field */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ count += precision + digit_cnt + space_cnt + prefix_cnt;
+ }
+ break;
+ case 'n':
+ switch (size)
+ {
+ case _FMT_LONG:
+ *(long *) va_arg (ap, long *) = count;
+ break;
+#ifdef __18CXX
+ case _FMT_SHRTLONG:
+ *(short long *) va_arg (ap, short long *) = count;
+ break;
+#else
+ case _FMT_LONGLONG:
+ *(long long *) va_arg (ap, long long *) = count;
+ break;
+#endif
+ case _FMT_BYTE:
+ *(signed char *) va_arg (ap, signed char *) = count;
+ break;
+ default:
+ *(int *) va_arg (ap, int *) = count;
+ break;
+ }
+ break;
+ default:
+ /* undefined behaviour. we do nothing */
+ break;
+ }
+ }
+ else
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ }
+ }
+ return count;
+}
+
+
+
+#endif
+
+
+
+
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/FSIO.d b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/FSIO.d new file mode 100644 index 00000000..1af7e8ce --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/FSIO.d @@ -0,0 +1,61 @@ +FSIO.o: FSIO.c FSIO.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h FSconfig.h \
+ C:/Microchip\ Solutions/Microchip/Include/Compiler.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/string.h \
+ HardwareProfile.h \
+ C:/Microchip\ Solutions/Microchip/Include/MDD\ File\ System\FSDefs.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h SD-SPI.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/ctype.h
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/FSIO.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/FSIO.h new file mode 100644 index 00000000..2a69957f --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/FSIO.h @@ -0,0 +1,1392 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: FSIO.h
+ * Dependencies: GenericTypeDefs.h
+ * FSconfig.h
+ * FSDefs.h
+ * stddef.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#ifndef FS_DOT_H
+#define FS_DOT_H
+
+#include "GenericTypeDefs.h"
+#include "FSconfig.h"
+#include "MDD File System\FSDefs.h"
+#include "stddef.h"
+
+#ifdef USE_SD_INTERFACE_WITH_SPI
+ #include "SD-SPI.h"
+#endif
+#ifdef USE_CF_INTERFACE_WITH_PMP
+ #include "MDD File System\CF-PMP.h"
+#endif
+#ifdef USE_MANUAL_CF_INTERFACE
+ #include "MDD File System\CF- Bit transaction.h"
+#endif
+#ifdef USE_USB_INTERFACE
+ #include "USB\usb_host_msd_scsi.h"
+#endif
+
+
+//#ifndef __C30__
+ #ifdef USE_MANUAL_CF_INTERFACE
+ #ifdef USE_SD_INTERFACE_WITH_SPI
+ #error This library only supports one physical layer
+ #endif
+ #ifdef USE_CF_INTERFACE_WITH_PMP
+ #error This library only supports one physical layer
+ #endif
+ #ifdef USE_USB_INTERFACE
+ #error This library only supports one physical layer
+ #endif
+ #endif
+ #ifdef USE_SD_INTERFACE_WITH_SPI
+ #ifdef USE_CF_INTERFACE_WITH_PMP
+ #error This library only supports one physical layer
+ #endif
+ #ifdef USE_USB_INTERFACE
+ #error This library only supports one physical layer
+ #endif
+ #endif
+ #ifdef USE_CF_INTERFACE_WITH_PMP
+ #ifdef USE_USB_INTERFACE
+ #error This library only supports one physical layer
+ #endif
+ #endif
+//#endif
+
+
+/*******************************************************************/
+/* Strunctures and defines */
+/*******************************************************************/
+
+#ifndef FALSE
+ // Summary: False value
+ // Description: This macro will indicate that a condition is false.
+ #define FALSE 0
+#endif
+#ifndef TRUE
+ // Summary: True value
+ // Description: This macro will indicate that a condition is true.
+ #define TRUE !FALSE // True value
+#endif
+
+
+
+
+#ifndef SEEK_SET
+ // Summary: Macro for the FSfseek SEEK_SET base location.
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the beginning of the file.
+ #define SEEK_SET 0
+
+#endif
+#ifndef SEEK_CUR
+
+ // Summary: Macro for the FSfseek SEEK_CUR base location.
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the current location of the file
+ #define SEEK_CUR 1
+
+#endif
+#ifndef SEEK_END
+
+ // Summary: Macro for the FSfseek SEEK_END base location
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the end of the file. For this macro, the offset value will be subtracted from
+ // the end location of the file by default.
+ #define SEEK_END 2
+
+#endif
+
+
+
+
+// Summary: Macro for the FSfopen APPEND mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it's file information will be loaded and the
+// current location in the file will be set to the end. The user will then be able to write to the file.
+#define APPEND "a"
+
+// Summary: Macro for the FSfopen WRITE mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it will be erased and replaced by an empty file
+// of the same name. The user will then be able to write to the file.
+#define WRITE "w"
+
+// Summary: Macro for the FSfopen READ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file information for the
+// specified file will be loaded. If the file does not exist, the FSfopen function will fail. The user
+// will then be able to read from the file.
+#define READ "r"
+
+// Summary: Macro for the FSfopen APPEND+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it's file information will be loaded and the
+// current location in the file will be set to the end. The user will then be able to write to the file
+// or read from the file.
+#define APPENDPLUS "a+"
+
+// Summary: Macro for the FSfopen WRITE+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it will be erased and replaced by an empty file
+// of the same name. The user will then be able to write to the file or read from the file.
+#define WRITEPLUS "w+"
+
+// Summary: Macro for the FSfopen READ+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file information for the
+// specified file will be loaded. If the file does not exist, the FSfopen function will fail. The user
+// will then be able to read from the file or write to the file.
+#define READPLUS "r+"
+
+
+
+#ifndef intmax_t
+ #ifdef __PIC24F__
+ // Summary: A data type indicating the maximum integer size in an architecture
+ // Description: The intmax_t data type refers to the maximum-sized data type on any given architecture. This
+ // data type can be specified as a format specifier size specification for the FSfprintf function.
+ #define intmax_t long long
+ #elif defined __PIC24H__
+ #define intmax_t long long
+ #elif defined __dsPIC30F__
+ #define intmax_t long long
+ #elif defined __dsPIC33F__
+ #define intmax_t long long
+ #endif
+#endif
+
+
+
+// Summary: Indicates flag conditions for a file object
+// Description: The FILEFLAGS structure is used to indicate conditions in a file. It contains three flags: 'write' indicates
+// that the file was opened in a mode that allows writes, 'read' indicates that the file was opened in a mode
+// that allows reads, and 'FileWriteEOF' indicates that additional data that is written to the file will increase
+// the file size.
+typedef struct
+{
+ unsigned write :1; // Indicates a file was opened in a mode that allows writes
+ unsigned read :1; // Indicates a file was opened in a mode that allows reads
+ unsigned FileWriteEOF :1; // Indicates the current position in a file is at the end of the file
+}FILEFLAGS;
+
+
+
+// Summary: Indicates how to search for file entries in the FILEfind function
+// Description: The values in the SEARCH_TYPE enumeration are used internally by the library to indicate how the FILEfind function
+// how to perform a search. The 'LOOK_FOR_EMPTY_ENTRY' value indicates that FILEfind should search for an empty file entry.
+// The 'LOOK_FOR_MATCHING_ENTRY' value indicates that FILEfind should search for an entry that matches the FSFILE object
+// that was passed into the FILEfind function.
+typedef enum{
+ LOOK_FOR_EMPTY_ENTRY = 0,
+ LOOK_FOR_MATCHING_ENTRY
+} SEARCH_TYPE;
+
+
+
+// Summary: Macro indicating the length of a 8.3 file name
+// Description: The TOTAL_FILE_SIZE macro indicates the maximum number of characters in an 8.3 file name. This value includes
+// 8 characters for the name, three for the extentsion, and 1 for the radix ('.')
+#define TOTAL_FILE_SIZE 8+3+1
+
+// Summary: A mask that indicates the limit of directory entries in a sector
+// Description: The MASK_MAX_FILE_ENTRY_LIMIT_BITS is used to indicate to the Cache_File_Entry function that a new sector needs to
+// be loaded.
+#define MASK_MAX_FILE_ENTRY_LIMIT_BITS 0x0f
+
+// Summary: Value used for shift operations to calculate the sector offset in a directory
+// Description: The VALUE_BASED_ON_ENTRIES_PER_CLUSTER macro is used to calculate sector offsets for directories. The position of the
+// entry is shifted by 4 bits (divided by 16, since there are 16 entries in a sector) to calculate how many sectors a
+// specified entry is offset from the beginning of the directory.
+#define VALUE_BASED_ON_ENTRIES_PER_CLUSTER 4
+
+// Summary: A value that will indicate that a dotdot directory entry points to the root.
+// Description: The VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT macro is used as an absolute address when writing information to a dotdot entry
+// in a newly created directory. If a dotdot entry points to the root directory, it's cluster value must be set to 0,
+// regardless of the actual cluster number of the root directory.
+#define VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT 0
+
+// Summary: MAcro indicating the length of an 8.3 file name in a directory entry
+// Description: The FILE_NAME_SIZE macro indicates the number of characters that an 8.3 file name will take up when packed in
+// a directory entry. This value includes 8 characters for the name and 3 for the extension. Note that the radix is not
+// stored in the directory entry.
+#define FILE_NAME_SIZE 11
+
+
+
+// Summary: Contains file information and is used to indicate which file to access.
+// Description: The FSFILE structure is used to hold file information for an open file as it's being modified or accessed. A pointer to
+// an open file's FSFILE structure will be passeed to any library function that will modify that file.
+typedef struct
+{
+ DISK * dsk; // Pointer to a DISK structure
+ DWORD cluster; // The first cluster of the file
+ DWORD ccls; // The current cluster of the file
+ WORD sec; // The current sector in the current cluster of the file
+ WORD pos; // The position in the current sector
+ DWORD seek; // The absolute position in the file
+ DWORD size; // The size of the file
+ FILEFLAGS flags; // A structure containing file flags
+ WORD time; // The file's last update time
+ WORD date; // The file's last update date
+ char name[FILE_NAME_SIZE]; // The name of the file
+ WORD entry; // The position of the file's directory entry in it's directory
+ WORD chk; // File structure checksum
+ WORD attributes; // The file attributes
+ DWORD dirclus; // The base cluster of the file's directory
+ DWORD dirccls; // The current cluster of the file's directory
+} FSFILE;
+
+
+
+// Summary: A structure used for searching for files on a device.
+// Description: The SearchRec structure is used when searching for file on a device. It contains parameters that will be loaded with
+// file information when a file is found. It also contains the parameters that the user searched for, allowing further
+// searches to be perfomed in the same directory for additional files that meet the specified criteria.
+typedef struct
+{
+ char filename[FILE_NAME_SIZE + 2]; // The name of the file that has been found
+ unsigned char attributes; // The attributes of the file that has been found
+ unsigned long filesize; // The size of the file that has been found
+ unsigned long timestamp; // The last modified time of the file that has been found (create time for directories)
+
+ unsigned int entry; // The directory entry of the last file found that matches the specified attributes. (Internal use only)
+ char searchname[FILE_NAME_SIZE + 2]; // The name specified when the user began the search. (Internal use only)
+ unsigned char searchattr; // The attributes specified when the user began the search. (Internal use only)
+ unsigned int cwdclus; // The directory that this search was performed in. (Internal use only)
+ unsigned char initialized; // Check to determine if the structure was initialized by FindFirst (Internal use only)
+} SearchRec;
+
+
+/***************************************************************************
+* Prototypes *
+***************************************************************************/
+
+
+
+
+/*************************************************************************
+ Function:
+ int FSInit(void)
+ Summary:
+ Function to initialize the device.
+ Conditions:
+ The physical device should be connected to the microcontroller.
+ Input:
+ None
+ Return Values:
+ TRUE - Initialization successful
+ FALSE - Initialization unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Initializes the static or dynamic memory slots for holding file
+ structures. Initializes the device with the DISKmount function. Loads
+ MBR and boot sector information. Initializes the current working
+ directory to the root directory for the device if directory support
+ is enabled.
+ Remarks:
+ None
+ *************************************************************************/
+
+int FSInit(void);
+
+
+/*********************************************************************
+ Function:
+ FSFILE * FSfopen (const char * fileName, const char *mode)
+ Summary:
+ Open a file
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to open
+ mode -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ - WRITEPLUS - Create a new file or replace an existing file (reads also enabled)
+ - READPLUS - Read data from an existing file (writes also enabled)
+ - APPENDPLUS - Append data to an existing file (reads also enabled)
+ Return Values:
+ FSFILE * - The pointer to the file object
+ NULL - The file could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will open a file or directory. First, RAM in the
+ dynamic heap or static array will be allocated to a new FSFILE object.
+ Then, the specified file name will be formatted to ensure that it's
+ in 8.3 format. Next, the FILEfind function will be used to search
+ for the specified file name. If the name is found, one of three
+ things will happen: if the file was opened in read mode, its file
+ info will be loaded using the FILEopen function; if it was opened in
+ write mode, it will be erased, and a new file will be constructed in
+ its place; if it was opened in append mode, its file info will be
+ loaded with FILEopen and the current location will be moved to the
+ end of the file using the FSfseek function. If the file was not
+ found by FILEfind, it will be created if the mode was specified as
+ a write or append mode. In these cases, a pointer to the heap or
+ static FSFILE object array will be returned. If the file was not
+ found and the mode was specified as a read mode, the memory
+ allocated to the file will be freed and the NULL pointer value
+ will be returned.
+ Remarks:
+ None.
+ *********************************************************************/
+
+FSFILE * FSfopen(const char * fileName, const char *mode);
+
+
+
+#ifdef ALLOW_PGMFUNCTIONS
+
+/******************************************************************************
+ Function:
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+ Summary:
+ Open a file named with a ROM string on PIC18
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to be opened (ROM)
+ mode - The mode the file will be opened in (ROM)
+ Return Values:
+ FSFILE * - A pointer to the file object
+ NULL - File could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfopenpgm function will copy a PIC18 ROM fileName and mode argument
+ into RAM arrays, and then pass those arrays to the FSfopen function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ ******************************************************************************/
+
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode);
+
+
+/**************************************************************************************
+ Function:
+ int FindFirstpgm (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Find a file named with a ROM string on PIC18
+ Conditions:
+ None
+ Input:
+ fileName - The name of the file to be found (ROM)
+ attr - The attributes of the file to be found
+ rec - Pointer to a search record to store the file info in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the given parameters was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object will be lost.
+ The FSerrno variable will be changed.
+ Description:
+ The FindFirstpgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FindFirst function.
+ Remarks:
+ Call FindFirstpgm or FindFirst before calling FindNext.
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************************/
+
+ int FindFirstpgm (const rom char * fileName, unsigned int attr, SearchRec * rec);
+
+
+/**************************************************************************
+ Function:
+ int FSchdirpgm (const rom char * path)
+ Summary:
+ Changed the CWD with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to (ROM)
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdirpgm function passes a PIC18 ROM path pointer to the
+ chdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM
+ **************************************************************************/
+
+ int FSchdirpgm (const rom char * path);
+
+ #ifdef ALLOW_WRITES
+
+
+/*************************************************************
+ Function:
+ int FSremovepgm (const rom char * fileName)
+ Summary:
+ Delete a file named with a ROM string on PIC18
+ Conditions:
+ File not opened; file exists
+ Input:
+ fileName - The name of the file to be deleted (ROM)
+ Return Values:
+ 0 - File was removed successfully
+ -1 - File could not be removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremovepgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FSremove function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *************************************************************/
+
+ int FSremovepgm (const rom char * fileName);
+
+
+/**************************************************************************
+ Function:
+ int FSmkdirpgm (const rom char * path)
+ Summary:
+ Create a directory with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create (ROM)
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdirpgm function passes a PIC18 ROM path pointer to the
+ mkdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arugments in ROM
+ **************************************************************************/
+
+ int FSmkdirpgm (const rom char * path);
+
+
+/**************************************************************************
+ Function:
+ int FSrmdirpgm (const rom char * path)
+ Summary:
+ Delete a directory with a path in ROM on PIC18
+ Conditions:
+ None.
+ Input:
+ path - The path of the directory to remove (ROM)
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdirpgm function passes a PIC18 ROM path pointer to the
+ rmdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************/
+
+ int FSrmdirpgm (const rom char * path, unsigned char rmsubdirs);
+
+
+/*****************************************************************
+ Function:
+ int FSrenamepgm(const rom char * fileName, FSFILE * fo)
+ Summary:
+ Rename a file named with a ROM string on PIC18
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file (in ROM)
+ fo - The file to rename
+ Return Values:
+ 0 - File renamed successfully
+ -1 - File could not be renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The Fsrenamepgm function will copy the rom fileName specified
+ by the user into a RAM array and pass that array into the
+ FSrename function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *****************************************************************/
+
+ int FSrenamepgm (const rom char * fileName, FSFILE * fo);
+ #endif
+#endif
+
+
+/************************************************************
+ Function:
+ int FSfclose(FSFILE *fo)
+ Summary:
+ Update file information and free FSFILE objects
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to the file to close
+ Return Values:
+ 0 - File closed successfully
+ EOF - Error closing the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will update the directory entry for the
+ file pointed to by 'fo' with the information contained
+ in 'fo,' including the new file size and attributes.
+ Timestamp information will also be loaded based on the
+ method selected by the user and written to the entry
+ as the last modified time and date. The file entry will
+ then be written to the device. Finally, the memory
+ used for the specified file object will be freed from
+ the dynamic heap or the array of FSFILE objects.
+ Remarks:
+ A function to flush data to the device without closing the
+ file can be created by removing the portion of this
+ function that frees the memory and the line that clears
+ the write flag.
+ ************************************************************/
+
+int FSfclose(FSFILE *fo);
+
+
+/*********************************************************
+ Function:
+ void FSrewind (FSFILE * fo)
+ Summary:
+ Set the current position in a file to the beginning
+ Conditions:
+ File opened.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ None
+ Side Effects:
+ None.
+ Description:
+ The FSrewind funciton will reset the position of the
+ specified file to the beginning of the file. This
+ functionality is faster than using FSfseek to reset
+ the position in the file.
+ Remarks:
+ None.
+ *********************************************************/
+
+void FSrewind (FSFILE *fo);
+
+
+/**************************************************************************
+ Function:
+ size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Read data from a file
+ Conditions:
+ File is opened in a read mode
+ Input:
+ ptr - Destination buffer for read bytes
+ size - Size of units in bytes
+ n - Number of units to be read
+ stream - File to be read from
+ Return:
+ size_t - number of units read
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfread function will read data from the specified file. First,
+ the appropriate sector of the file is loaded. Then, data is read into
+ the specified buffer until the specified number of bytes have been read.
+ When a cluster boundary is reached, a new cluster will be loaded. The
+ parameters 'size' and 'n' indicate how much data to read. 'Size'
+ refers to the size of one object to read (in bytes), and 'n' will refer
+ to the number of these objects to read. The value returned will be equal
+ to 'n' unless an error occured or the user tried to read beyond the end
+ of the file.
+ Remarks:
+ None.
+ **************************************************************************/
+
+size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream);
+
+
+/**********************************************************************
+ Function:
+ int FSfseek(FSFILE *stream, long offset, int whence)
+ Summary:
+ Change the current position in a file
+ Conditions:
+ File opened
+ Input:
+ stream - Pointer to file structure
+ offset - Offset from base location
+ whence -
+ - SEEK_SET - Seek from start of file
+ - SEEK_CUR - Seek from current location
+ - SEEK_END - Seek from end of file (subtract offset)
+ Return Values:
+ 0 - Operation successful
+ -1 - Operation unsuccesful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfseek function will change the current position in the file to
+ one specified by the user. First, an absolute offset is calculated
+ using the offset and base location passed in by the user. Then, the
+ position variables are updated, and the sector number that corresponds
+ to the new location. That sector is then loaded. If the offset
+ falls exactly on a cluster boundary, a new cluster will be allocated
+ to the file and the position will be set to the first byte of that
+ cluster.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSfseek(FSFILE *stream, long offset, int whence);
+
+
+/*******************************************************************
+ Function:
+ long FSftell (FSFILE * fo)
+ Summary:
+ Determine the current location in a file
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to file structure
+ Return: Current location in the file
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSftell function will return the current position in the
+ file pointed to by 'fo' by returning the 'seek' variable in the
+ FSFILE object, which is used to keep track of the absolute
+ location of the current position in the file.
+ Remarks:
+ None
+ *******************************************************************/
+
+long FSftell(FSFILE *fo);
+
+
+/****************************************************
+ Function:
+ int FSfeof( FSFILE * stream )
+ Summary:
+ Indicate whether the current file position is at the end
+ Conditions:
+ File is open in a read mode
+ Input:
+ stream - Pointer to the target file
+ Return Values:
+ Non-Zero - EOF reached
+ 0 - Not at end of File
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfeof function will indicate that the end-of-
+ file has been reached for the specified file by
+ comparing the absolute location in the file to the
+ size of the file.
+ Remarks:
+ None.
+ ****************************************************/
+
+int FSfeof( FSFILE * stream );
+
+
+#ifdef ALLOW_FORMATS
+/*******************************************************************
+ Function:
+ int FSformat (char mode, long int serialNumber, char * volumeID)
+ Summary:
+ Formats a device
+ Conditions:
+ The device must possess a valid master boot record.
+ Input:
+ mode - - 0 - Just erase the FAT and root
+ - 1 - Create a new boot sector
+ serialNumber - Serial number to write to the card
+ volumeID - Name of the card
+ Return Values:
+ 0 - Format was successful
+ EOF - Format was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSformat function can be used to create a new boot sector
+ on a device, based on the information in the master boot record.
+ This function will first initialize the I/O pins and the device,
+ and then attempts to read the master boot record. If the MBR
+ cannot be loaded successfully, the function will fail. Next, if
+ the 'mode' argument is specified as '0' the existing boot sector
+ information will be loaded. If the 'mode' argument is '1' an
+ entirely new boot sector will be constructed using the disk
+ values from the master boot record. Once the boot sector has
+ been successfully loaded/created, the locations of the FAT and
+ root will be loaded from it, and they will be completely
+ erased. If the user has specified a volumeID parameter, a
+ VOLUME attribute entry will be created in the root directory
+ to name the device.
+ Remarks:
+ FAT12 and FAT16 formatting is supported.
+ *******************************************************************/
+
+int FSformat (char mode, long int serialNumber, char * volumeID);
+#endif
+
+
+#ifdef ALLOW_WRITES
+/***************************************************************************
+ Function:
+ int FSattrib (FSFILE * file, unsigned char attributes)
+ Summary:
+ Change the attributes of a file
+ Conditions:
+ File opened
+ Input:
+ file - Pointer to file structure
+ attributes - The attributes to set for the file
+ - Attribute - Value - Indications
+ - ATTR_READ_ONLY - 0x01 - The read-only attribute
+ - ATTR_HIDDEN - 0x02 - The hidden attribute
+ - ATTR_SYSTEM - 0x04 - The system attribute
+ - ATTR_ARCHIVE - 0x20 - The archive attribute
+ Return Values:
+ 0 - Attribute change was successful
+ -1 - Attribute change was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSattrib funciton will set the attributes of the specified file
+ to the attributes passed in by the user. This function will load the
+ file entry, replace the attributes with the ones specified, and write
+ the attributes back. If the specified file is a directory, the
+ directory attribute will be preserved.
+ Remarks:
+ None
+ ***************************************************************************/
+
+int FSattrib (FSFILE * file, unsigned char attributes);
+
+
+/***************************************************************
+ Function:
+ int FSrename (const rom char * fileName, FSFILE * fo)
+ Summary:
+ Change the name of a file or directory
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file
+ fo - The file to rename
+ Return Values:
+ 0 - File was renamed successfully
+ EOF - File was not renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrename function will rename a file. First, it will
+ search through the current working directory to ensure the
+ specified new filename is not already in use. If it isn't,
+ the new filename will be written to the file entry of the
+ file pointed to by 'fo.'
+ Remarks:
+ None
+ ***************************************************************/
+
+int FSrename (const char * fileName, FSFILE * fo);
+
+
+/*********************************************************************
+ Function:
+ int FSremove (const char * fileName)
+ Summary:
+ Delete a file
+ Conditions:
+ File not opened, file exists
+ Input:
+ fileName - Name of the file to erase
+ Return Values:
+ 0 - File removed
+ EOF - File was not removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremove function will attempt to find the specified file with
+ the FILEfind function. If the file is found, it will be erased
+ using the FILEerase function.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSremove (const char * fileName);
+
+
+/*********************************************************************************
+ Function:
+ size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Write data to a file
+ Conditions:
+ File opened in WRITE, APPEND, WRITE+, APPEND+, READ+ mode
+ Input:
+ ptr - Pointer to source buffer
+ size - Size of units in bytes
+ n - Number of units to transfer
+ stream - Pointer to file structure
+ Return:
+ size_t - number of units written
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfwrite function will write data to a file. First, the sector that
+ corresponds to the current position in the file will be loaded (if it hasn't
+ already been cached in the global data buffer). Data will then be written to
+ the device from the specified buffer until the specified amount has been written.
+ If the end of a cluster is reached, the next cluster will be loaded, unless
+ the end-of-file flag for the specified file has been set. If it has, a new
+ cluster will be allocated to the file. Finally, the new position and filezize
+ will be stored in the FSFILE object. The parameters 'size' and 'n' indicate how
+ much data to write. 'Size' refers to the size of one object to write (in bytes),
+ and 'n' will refer to the number of these objects to write. The value returned
+ will be equal to 'n' unless an error occured.
+ Remarks:
+ None.
+ *********************************************************************************/
+
+size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream);
+
+#endif
+
+#ifdef ALLOW_DIRS
+
+
+/**************************************************************************
+ Function:
+ int FSchdir (char * path)
+ Summary:
+ Change the current working directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to.
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdir function passes a RAM pointer to the path to the
+ chdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSchdir (char * path);
+
+
+/**************************************************************
+ Function:
+ char * FSgetcwd (char * path, int numchars)
+ Summary:
+ Get the current working directory name
+ Conditions:
+ None
+ Input:
+ path - Pointer to the array to return the cwd name in
+ numchars - Number of chars in the path
+ Return Values:
+ char * - The cwd name string pointer (path or defaultArray)
+ NULL - The current working directory name could not be loaded.
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSgetcwd function will get the name of the current
+ working directory and return it to the user. The name
+ will be copied into the buffer pointed to by 'path,'
+ starting at the root directory and copying as many chars
+ as possible before the end of the buffer. The buffer
+ size is indicated by the 'numchars' argument. The first
+ thing this function will do is load the name of the current
+ working directory, if it isn't already present. This could
+ occur if the user switched to the dotdot entry of a
+ subdirectory immediately before calling this function. The
+ function will then copy the current working directory name
+ into the buffer backwards, and insert a backslash character.
+ Next, the function will continuously switch to the previous
+ directories and copy their names backwards into the buffer
+ until it reaches the root. If the buffer overflows, it
+ will be treated as a circular buffer, and data will be
+ copied over existing characters, starting at the beginning.
+ Once the root directory is reached, the text in the buffer
+ will be swapped, so that the buffer contains as much of the
+ current working directory name as possible, starting at the
+ root.
+ Remarks:
+ None
+ **************************************************************/
+
+char * FSgetcwd (char * path, int numbchars);
+
+
+#ifdef ALLOW_WRITES
+
+/**************************************************************************
+ Function:
+ int FSmkdir (char * path)
+ Summary:
+ Create a directory
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create.
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdir function passes a RAM pointer to the path to the
+ mkdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSmkdir (char * path);
+
+
+/**************************************************************************
+ Function:
+ int FSrmdir (char * path)
+ Summary:
+ Delete a directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to remove
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdir function passes a RAM pointer to the path to the
+ rmdirhelper function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int FSrmdir (char * path, unsigned char rmsubdirs);
+#endif
+
+#endif
+
+#ifdef USERDEFINEDCLOCK
+
+
+/***********************************************************************************************************
+ Function:
+ int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+ Summary:
+ Manually set timestamp variables
+ Conditions:
+ USERDEFINEDCLOCK macro defined in FSconfig.h.
+ Input:
+ year - The year (1980\-2107)
+ month - The month (1\-12)
+ day - The day of the month (1\-31)
+ hour - The hour (0\-23)
+ minute - The minute (0\-59)
+ second - The second (0\-59)
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ Lets the user manually set the timing variables. The values passed in will be converted to the format
+ used by the FAT timestamps.
+ Remarks:
+ Call this before creating a file or directory (set create time) and
+ before closing a file (set last access time, last modified time)
+ ***********************************************************************************************************/
+
+int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second);
+#endif
+
+
+#ifdef ALLOW_FILESEARCH
+
+/***********************************************************************************
+ Function:
+ int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Initial search function
+ Conditions:
+ None
+ Input:
+ fileName - The name to search for
+ - Parital string search characters
+ - * - Indicates the rest of the filename or extension can vary (e.g. FILE.*)
+ - ? - Indicates that one character in a filename can vary (e.g. F?LE.T?T)
+ attr - The attributes that a found file may have
+ - ATTR_READ_ONLY - File may be read only
+ - ATTR_HIDDEN - File may be a hidden file
+ - ATTR_SYSTEM - File may be a system file
+ - ATTR_VOLUME - Entry may be a volume label
+ - ATTR_DIRECTORY - File may be a directory
+ - ATTR_ARCHIVE - File may have archive attribute
+ - ATTR_MASK - All attributes
+ rec - pointer to a structure to put the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the specified criteria was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object
+ will be lost. The FSerrno variable will be changed.
+ Description:
+ The FindFirst function will search for a file based on parameters passed in
+ by the user. This function will use the FILEfind function to parse through
+ the current working directory searching for entries that match the specified
+ parameters. If a file is found, its parameters are copied into the SearchRec
+ structure, as are the initial parameters passed in by the user and the position
+ of the file entry in the current working directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling FindNext
+ ***********************************************************************************/
+
+int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec);
+
+
+/**********************************************************************
+ Function:
+ int FindNext (SearchRec * rec)
+ Summary:
+ Sequential search function
+ Conditions:
+ None
+ Input:
+ rec - The structure to store the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No additional files matching the specified criteria were found
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FindNext function performs the same function as the FindFirst
+ funciton, except it does not copy any search parameters into the
+ SearchRec structure (only info about found files) and it begins
+ searching at the last directory entry offset at which a file was
+ found, rather than at the beginning of the current working
+ directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling this function
+ **********************************************************************/
+
+int FindNext (SearchRec * rec);
+#endif
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSfprintf (FSFILE * fptr, const char * fmt, ...)
+ // PIC18
+ int FSfpritnf (FSFILE * fptr, const rom char * fmt, ...)
+ Summary:
+ Function to write formatted strings to a file
+ Conditions:
+ For PIC18, integer promotion must be enabled in the project build
+ options menu. File opened in a write mode.
+ Input:
+ fptr - A pointer to the file to write to.
+ fmt - A string of characters and format specifiers to write to
+ the file
+ ... - Additional arguments inserted in the string by format
+ specifiers
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Writes a specially formatted string to a file.
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef ALLOW_FSFPRINTF
+ #ifdef __18CXX
+ int FSfprintf (FSFILE *fptr, const rom char *fmt, ...);
+ #else
+ int FSfprintf (FSFILE *fptr, const char * fmt, ...);
+ #endif
+#endif
+
+
+/**************************************************************************
+ Function:
+ int FSerror (void)
+ Summary:
+ Return an error code for the last function call
+ Conditions:
+ The return value depends on the last function called.
+ Input:
+ None
+ Side Effects:
+ None.
+ Return Values:
+ FSInit -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The physical media could not be initialized
+ - CE_BAD_SECTOR_READ � The MBR or the boot sector could not be
+ read correctly
+ - CE_BAD_PARITION � The MBR signature code was incorrect.
+ - CE_NOT_FORMATTED � The boot sector signature code was incorrect or
+ indicates an invalid number of bytes per sector.
+ - CE_CARDFAT32 � The physical media is FAT32 type (only an error
+ when FAT32 support is disabled).
+ - CE_UNSUPPORTED_FS � The device is formatted with an unsupported file
+ system (not FAT12 or 16).
+ FSfopen -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The device has not been initialized.
+ - CE_TOO_MANY_FILES_OPEN � The function could not allocate any
+ additional file information to the array
+ of FSFILE structures or the heap.
+ - CE_INVALID_FILENAME � The file name argument was invalid.
+ - CE_INVALID_ARGUMENT � The user attempted to open a directory in a
+ write mode or specified an invalid mode argument.
+ - CE_FILE_NOT_FOUND � The specified file (which was to be opened in read
+ mode) does not exist on the device.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_ERASE_FAIL � The existing file could not be erased (when opening
+ a file in WRITE mode).
+ - CE_DIR_FULL � The directory is full.
+ - CE_DISK_FULL� The data memory section is full.
+ - CE_WRITE_ERROR � A write to the device failed.
+ - CE_SEEK_ERROR � The current position in the file could not be set to
+ the end (when the file was opened in APPEND mode).
+ FSfclose -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer or the new file
+ entry information could not be written to the device.
+ - CE_BADCACHEREAD � The file entry information could not be cached
+ FSfread -
+ - CE_GOOD � No Error
+ - CE_WRITEONLY � The file was opened in a write-only mode.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_BAD_SECTOR_READ � The data sector could not be read.
+ - CE_EOF � The end of the file was reached.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be loaded.
+ FSfwrite -
+ - CE_GOOD � No Error
+ - CE_READONLY � The file was opened in a read-only mode.
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_WRITE_ERROR � There was an error writing data to the device.
+ - CE_BADCACHEREAD � The data sector to be modified could not be read from
+ the device.
+ - CE_DISK_FULL � All data clusters on the device are in use.
+ FSfseek -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_INVALID_ARGUMENT � The specified offset exceeds the size of the file.
+ - CE_BADCACHEREAD � The sector that contains the new current position
+ could not be loaded.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be
+ loaded/allocated.
+ FSftell -
+ - CE_GOOD � No Error
+ FSattrib -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The attribute argument was invalid.
+ - CE_BADCACHEREAD � The existing file entry information could not be
+ loaded.
+ - CE_WRITE_ERROR � The file entry information could not be written to
+ the device.
+ FSrename -
+ - CE_GOOD � No Error
+ - CE_FILENOTOPENED � A null file pointer was passed into the function.
+ - CE_INVALID_FILENAME � The file name passed into the function was invalid.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_FILENAME_EXISTS � A file with the specified name already exists.
+ - CE_WRITE_ERROR � The new file entry data could not be written to the
+ device.
+ FSfeof -
+ - CE_GOOD � No Error
+ FSformat -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The device could not be initialized.
+ - CE_BADCACHEREAD � The master boot record or boot sector could not be
+ loaded successfully.
+ - CE_INVALID_ARGUMENT � The user selected to create their own boot sector on
+ a device that has no master boot record, or the mode
+ argument was invalid.
+ - CE_WRITE_ERROR � The updated MBR/Boot sector could not be written to
+ the device.
+ - CE_BAD_PARTITION � The calculated number of sectors per clusters was
+ invalid.
+ - CE_NONSUPPORTED_SIZE � The card has too many sectors to be formatted as
+ FAT12 or FAT16.
+ FSremove -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � The specified file could not be found.
+ - CE_ERASE_FAIL � The file could not be erased.
+ FSchdir -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The path string was mis-formed or the user tried to
+ change to a non-directory file.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_FOUND � Could not find a directory in the path.
+ FSgetcwd -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The user passed a 0-length buffer into the function.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the current working directory.
+ FSmkdir -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_ARGUMENT � The path string was mis-formed.
+ - CE_BADCACHEREAD � Could not successfully change to a recently created
+ directory to store its dir entry information, or
+ could not cache directory entry information.
+ - CE_INVALID_FILENAME � One or more of the directory names has an invalid
+ format.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device or the dot/dotdot entries could
+ not be written to a newly created directory.
+ - CE_DIR_FULL � There are no available dir entries in the CWD.
+ - CE_DISK_FULL � There are no available clusters in the data region of
+ the device.
+ FSrmdir -
+ - CE_GOOD � No Error
+ - CE_DIR_NOT_FOUND � The directory specified could not be found or the
+ function could not change to a subdirectory within
+ the directory to be deleted (when recursive delete is
+ enabled).
+ - CE_INVALID_ARGUMENT � The user tried to remove the CWD or root directory.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_EMPTY � The directory to be deleted was not empty and
+ recursive subdirectory removal was disabled.
+ - CE_ERASE_FAIL � The directory or one of the directories or files
+ within it could not be deleted.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the CWD.
+ SetClockVars -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The time values passed into the function were
+ invalid.
+ FindFirst -
+ - CE_GOOD � No Error
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ - CE_BADCACHEREAD � The file information for the file that was found
+ could not be cached.
+ FindNext -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The SearchRec object was not initialized by a call to
+ FindFirst.
+ - CE_INVALID_ARGUMENT � The SearchRec object was initialized in a different
+ directory from the CWD.
+ - CE_INVALID_FILENAME � The filename is invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ FSfprintf -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � Characters could not be written to the file.
+ Description:
+ The FSerror function will return the FSerrno variable. This global
+ variable will have been set to an error value during the last call of a
+ library function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSerror (void);
+
+
+/*********************************************************************************
+ Function:
+ int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+ Summary:
+ Creates a master boot record
+ Conditions:
+ The I/O pins for the device have been initialized by the InitIO function.
+ Input:
+ firstSector - The first sector of the partition on the device (cannot
+ be 0; that's the MBR)
+ numSectors - The number of sectors available in memory (including the
+ MBR)
+ Return Values:
+ 0 - MBR was created successfully
+ EOF - MBR could not be created
+ Side Effects:
+ None
+ Description:
+ This function can be used to create a master boot record for a device. Note
+ that this function should not be used on a device that is already formatted
+ with a master boot record (i.e. most SD cards, CF cards, USB keys). This
+ function will fill the global data buffer with appropriate partition information
+ for a FAT partition with a type determined by the number of sectors available
+ to the partition. It will then write the MBR information to the first sector
+ on the device. This function should be followed by a call to FSformat, which
+ will create a boot sector, root dir, and FAT appropriate the the information
+ contained in the new master boot record. Note that FSformat only supports
+ FAT12 and FAT16 formatting at this time, and so cannot be used to format a
+ device with more than 0x3FFD5F sectors.
+ Remarks:
+ This function can damage the device being used, and should not be called
+ unless the user is sure about the size of the device and the first sector value.
+ *********************************************************************************/
+
+int FSCreateMBR (unsigned long firstSector, unsigned long numSectors);
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/HardwareProfile-BfB.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/HardwareProfile-BfB.h new file mode 100644 index 00000000..01653540 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/HardwareProfile-BfB.h @@ -0,0 +1,622 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: HardwareProfile.h
+ * Dependencies: None
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+
+#ifndef _HARDWAREPROFILE_H_
+#define _HARDWAREPROFILE_H_
+
+// Define your clock speed here
+
+// Sample clock speed for PIC18
+#if defined (__18CXX)
+
+ #define GetSystemClock() 40000000 // System clock frequency (Hz)
+ #define GetPeripheralClock() GetSystemClock() // Peripheral clock freq.
+ #define GetInstructionClock() (GetSystemClock() / 4) // Instruction clock freq.
+
+// Sample clock speed for a 16-bit processor
+#elif defined (__C30__)
+
+ #define GetSystemClock() 32000000
+ #define GetPeripheralClock() GetSystemClock()
+ #define GetInstructionClock() (GetSystemClock() / 2)
+
+ // Clock values
+ #define MILLISECONDS_PER_TICK 10 // Definition for use with a tick timer
+ #define TIMER_PRESCALER TIMER_PRESCALER_8 // Definition for use with a tick timer
+ #define TIMER_PERIOD 20000 // Definition for use with a tick timer
+
+// Sample clock speed for a 32-bit processor
+#elif defined (__PIC32MX__)
+
+ // Indicates that the PIC32 clock is running at 48 MHz
+ //#define RUN_AT_48MHZ
+ // Indicates that the PIC32 clock is running at 24 MHz
+ //#define RUN_AT_24MHZ
+ // Indicates that the PIC32 clock is running at 60 MHz
+ //#define RUN_AT_60MHZ
+ // Indicates that the PIC32 clock is running at 60 MHz
+ #define RUN_AT_80MHZ
+
+ // Various clock values
+
+ #if defined(RUN_AT_48MHZ)
+ #define GetSystemClock() 48000000UL // System clock frequency (Hz)
+ #define GetPeripheralClock() 48000000UL // Peripheral clock frequency
+ #define GetInstructionClock() (GetSystemClock()) // Instruction clock frequency
+ #elif defined(RUN_AT_24MHZ)
+ #define GetSystemClock() 24000000UL
+ #define GetPeripheralClock() 24000000UL
+ #define GetInstructionClock() (GetSystemClock())
+ #elif defined(RUN_AT_60MHZ)
+ #define GetSystemClock() (60000000ul)
+ #define GetPeripheralClock() (GetSystemClock())
+ #define GetInstructionClock() (GetSystemClock())
+ #elif defined(RUN_AT_80MHZ)
+ #define GetSystemClock() (80000000ul)
+ #define GetPeripheralClock() (GetSystemClock()/8)
+ #define GetInstructionClock() (GetSystemClock())
+ #else
+ #error Choose a speed
+ #endif
+
+ // Clock values
+
+ #define MILLISECONDS_PER_TICK 10 // Definition for use with a tick timer
+ #define TIMER_PRESCALER TIMER_PRESCALER_8 // Definition for use with a tick timer
+ #define TIMER_PERIOD 37500 // Definition for use with a tick timer
+#endif
+
+
+
+
+
+// Select your interface type
+// This library currently only supports a single physical interface layer at a time
+
+
+// Description: Macro used to enable the SD-SPI physical layer (SD-SPI.c and .h)
+#define USE_SD_INTERFACE_WITH_SPI
+
+// Description: Macro used to enable the CF-PMP physical layer (CF-PMP.c and .h)
+//#define USE_CF_INTERFACE_WITH_PMP
+
+// Description: Macro used to enable the CF-Manual physical layer (CF-Bit transaction.c and .h)
+//#define USE_MANUAL_CF_INTERFACE
+
+// Description: Macro used to enable the USB Host physical layer (USB host MSD library)
+//#define USE_USB_INTERFACE
+
+
+/*********************************************************************/
+/******************* Pin and Register Definitions ********************/
+/*********************************************************************/
+
+/* SD Card definitions: Change these to fit your application when using
+ an SD-card-based physical layer */
+
+#ifdef USE_SD_INTERFACE_WITH_SPI
+ #ifdef __18CXX
+
+ // Sample definition for PIC18 (modify to fit your own project)
+
+ // Description: SD-SPI Chip Select Output bit
+ #define SD_CS PORTBbits.RB3
+ // Description: SD-SPI Chip Select TRIS bit
+ #define SD_CS_TRIS TRISBbits.TRISB3
+
+ // Description: SD-SPI Card Detect Input bit
+ #define SD_CD PORTBbits.RB4
+ // Description: SD-SPI Card Detect TRIS bit
+ #define SD_CD_TRIS TRISBbits.TRISB4
+
+ // Description: SD-SPI Write Protect Check Input bit
+ #define SD_WE PORTAbits.RA4
+ // Description: SD-SPI Write Protect Check TRIS bit
+ #define SD_WE_TRIS TRISAbits.TRISA4
+
+ // Registers for the SPI module you want to use
+
+ // Description: The main SPI control register
+ #define SPICON1 SSP1CON1
+ // Description: The SPI status register
+ #define SPISTAT SSP1STAT
+ // Description: The SPI buffer
+ #define SPIBUF SSP1BUF
+ // Description: The receive buffer full bit in the SPI status register
+ #define SPISTAT_RBF SSP1STATbits.BF
+ // Description: The bitwise define for the SPI control register (i.e. _____bits)
+ #define SPICON1bits SSP1CON1bits
+ // Description: The bitwise define for the SPI status register (i.e. _____bits)
+ #define SPISTATbits SSP1STATbits
+
+ // Description: The interrupt flag for the SPI module
+ #define SPI_INTERRUPT_FLAG PIR1bits.SSPIF
+ // Description: The enable bit for the SPI module
+ #define SPIENABLE SPICON1bits.SSPEN
+
+/*
+ // Defines for the FS-USB demo board
+
+ // Tris pins for SCK/SDI/SDO lines
+ #define SPICLOCK TRISBbits.TRISB1
+ #define SPIIN TRISBbits.TRISB0
+ #define SPIOUT TRISCbits.TRISC7
+
+ // Latch pins for SCK/SDI/SDO lines
+ #define SPICLOCKLAT LATBbits.LATB1
+ #define SPIINLAT LATBbits.LATB0
+ #define SPIOUTLAT LATCbits.LATC7
+
+ // Port pins for SCK/SDI/SDO lines
+ #define SPICLOCKPORT PORTBbits.RB1
+ #define SPIINPORT PORTBbits.RB0
+ #define SPIOUTPORT PORTCbits.RC7
+*/
+
+ // Defines for the HPC Explorer board
+
+ // Description: The TRIS bit for the SCK pin
+ #define SPICLOCK TRISCbits.TRISC3
+ // Description: The TRIS bit for the SDI pin
+ #define SPIIN TRISCbits.TRISC4
+ // Description: The TRIS bit for the SDO pin
+ #define SPIOUT TRISCbits.TRISC5
+
+ // Description: The output latch for the SCK pin
+ #define SPICLOCKLAT LATCbits.LATC3
+ // Description: The output latch for the SDI pin
+ #define SPIINLAT LATCbits.LATC4
+ // Description: The output latch for the SDO pin
+ #define SPIOUTLAT LATCbits.LATC5
+
+ // Description: The port for the SCK pin
+ #define SPICLOCKPORT PORTCbits.RC3
+ // Description: The port for the SDI pin
+ #define SPIINPORT PORTCbits.RC4
+ // Description: The port for the SDO pin
+ #define SPIOUTPORT PORTCbits.RC5
+
+
+ // Will generate an error if the clock speed is too low to interface to the card
+ #if (GetSystemClock() < 400000)
+ #error System clock speed must exceed 400 kHz
+ #endif
+
+ #elif defined __PIC24F__
+
+ // Description: SD-SPI Chip Select Output bit
+ #define SD_CS PORTBbits.RB1
+ // Description: SD-SPI Chip Select TRIS bit
+ #define SD_CS_TRIS TRISBbits.TRISB1
+
+ // Description: SD-SPI Card Detect Input bit
+ #define SD_CD PORTFbits.RF0
+ // Description: SD-SPI Card Detect TRIS bit
+ #define SD_CD_TRIS TRISFbits.TRISF0
+
+ // Description: SD-SPI Write Protect Check Input bit
+ #define SD_WE PORTFbits.RF1
+ // Description: SD-SPI Write Protect Check TRIS bit
+ #define SD_WE_TRIS TRISFbits.TRISF1
+
+ // Registers for the SPI module you want to use
+ // Description: The main SPI control register
+ #define SPICON1 SPI1CON1
+ // Description: The SPI status register
+ #define SPISTAT SPI1STAT
+ // Description: The SPI Buffer
+ #define SPIBUF SPI1BUF
+ // Description: The receive buffer full bit in the SPI status register
+ #define SPISTAT_RBF SPI1STATbits.SPIRBF
+ // Description: The bitwise define for the SPI control register (i.e. _____bits)
+ #define SPICON1bits SPI1CON1bits
+ // Description: The bitwise define for the SPI status register (i.e. _____bits)
+ #define SPISTATbits SPI1STATbits
+ // Description: The enable bit for the SPI module
+ #define SPIENABLE SPISTATbits.SPIEN
+
+ // Tris pins for SCK/SDI/SDO lines
+
+ // Description: The TRIS bit for the SCK pin
+ #define SPICLOCK TRISFbits.TRISF6
+ // Description: The TRIS bit for the SDI pin
+ #define SPIIN TRISFbits.TRISF7
+ // Description: The TRIS bit for the SDO pin
+ #define SPIOUT TRISFbits.TRISF8
+
+ // Will generate an error if the clock speed is too low to interface to the card
+ #if (GetSystemClock() < 100000)
+ #error Clock speed must exceed 100 kHz
+ #endif
+
+ #elif defined (__PIC32MX__)
+
+ // Description: SD-SPI Chip Select Output bit
+ #define SD_CS PORTBbits.RB1
+ // Description: SD-SPI Chip Select TRIS bit
+ #define SD_CS_TRIS TRISBbits.TRISB1
+
+ // Description: SD-SPI Card Detect Input bit
+ #define SD_CD PORTEbits.RE4
+ // Description: SD-SPI Card Detect TRIS bit
+ #define SD_CD_TRIS TRISEbits.TRISE4
+
+ // Description: SD-SPI Write Protect Check Input bit
+ #define SD_WE PORTEbits.RE3
+ // Description: SD-SPI Write Protect Check TRIS bit
+ #define SD_WE_TRIS TRISEbits.TRISE3
+
+ // Registers for the SPI module you want to use
+
+ // Description: The main SPI 1 control register
+ //#define SPICON1 SPI1CON
+ // Description: The SPI status register
+ //#define SPISTAT SPI1STAT
+ // Description: The SPI Buffer
+ //#define SPIBUF SPI1BUF
+ // Description: The receive buffer full bit in the SPI status register
+ //#define SPISTAT_RBF SPI1STATbits.SPIRBF
+ // Description: The bitwise define for the SPI control register (i.e. _____bits)
+ //#define SPICON1bits SPI1CONbits
+ // Description: The bitwise define for the SPI status register (i.e. _____bits)
+ //#define SPISTATbits SPI1STATbits
+ // Description: The enable bit for the SPI module
+ //#define SPIENABLE SPICON1bits.ON
+ // Description: The definition for the SPI baud rate generator register (PIC32)
+ //#define SPIBRG SPI1BRG
+
+ // Description: The main SPI 2 control register
+ #define SPICON2 SPI2CON
+ // Description: The SPI status register
+ #define SPISTAT SPI2STAT
+ // Description: The SPI Buffer
+ #define SPIBUF SPI2BUF
+ // Description: The receive buffer full bit in the SPI status register
+ #define SPISTAT_RBF SPI2STATbits.SPIRBF
+ // Description: The bitwise define for the SPI control register (i.e. _____bits)
+ #define SPICON2bits SPI2CONbits
+ // Description: The bitwise define for the SPI status register (i.e. _____bits)
+ #define SPISTATbits SPI2STATbits
+ // Description: The enable bit for the SPI module
+ #define SPIENABLE SPICON2bits.ON
+ // Description: The definition for the SPI baud rate generator register (PIC32)
+ #define SPIBRG SPI2BRG
+
+ // Tris pins for SCK/SDI/SDO lines
+
+ // Description: The TRIS bit for the SCK pin
+ #define SPICLOCK TRISGbits.TRISG6
+ // Description: The TRIS bit for the SDI pin
+ #define SPIIN TRISGbits.TRISG7
+ // Description: The TRIS bit for the SDO pin
+ #define SPIOUT TRISGbits.TRISG8
+
+ // Will generate an error if the clock speed is too low to interface to the card
+ #if (GetSystemClock() < 100000)
+ #error Clock speed must exceed 100 kHz
+ #endif
+
+ #endif
+
+#endif
+
+
+#ifdef USE_CF_INTERFACE_WITH_PMP
+
+ /* CompactFlash-PMP card definitions: change these to fit your application when
+ using the PMP module to interface with CF cards */
+
+ #ifdef __18CXX
+ #error The PIC18 architecture does not currently support PMP interface to CF cards
+ #elif defined __dsPIC30F__
+
+ // Sample dsPIC30 defines
+
+ // Description: The output latch for the CF Reset signal
+ #define CF_PMP_RST _RD0
+ // Description: The TRIS bit for the CF Reset signal
+ #define CF_PMP_RESETDIR _TRISD0
+ // Description: The input port for the CF Ready signal
+ #define CF_PMP_RDY _RD12
+ // Description: The TRIS bit for the CF Ready signal
+ #define CF_PMP_READYDIR _TRISD12
+ // Description: The input port for the CF card detect signal
+ #define CF_PMP_CD1 _RC4
+ // Description: The TRIS bit for the CF card detect signal
+ #define CF_PMP_CD1DIR _TRISC4
+
+ #elif defined __dsPIC33F__
+
+ // Sample dsPIC33 defines
+
+ // Description: The output latch for the CF Reset signal
+ #define CF_PMP_RST _RD0
+ // Description: The TRIS bit for the CF Reset signal
+ #define CF_PMP_RESETDIR _TRISD0
+ // Description: The input port for the CF Ready signal
+ #define CF_PMP_RDY _RD12
+ // Description: The TRIS bit for the CF Ready signal
+ #define CF_PMP_READYDIR _TRISD12
+ // Description: The input port for the CF card detect signal
+ #define CF_PMP_CD1 _RC4
+ // Description: The TRIS bit for the CF card detect signal
+ #define CF_PMP_CD1DIR _TRISC4
+
+ #elif defined __PIC24F__
+
+ // Default case for PIC24F
+
+ // Description: The output latch for the CF Reset signal
+ #define CF_PMP_RST PORTDbits.RD0
+ // Description: The TRIS bit for the CF Reset signal
+ #define CF_PMP_RESETDIR TRISDbits.TRISD0
+ // Description: The input port for the CF Ready signal
+ #define CF_PMP_RDY PORTDbits.RD12
+ // Description: The TRIS bit for the CF Ready signal
+ #define CF_PMP_READYDIR TRISDbits.TRISD12
+ // Description: The input port for the CF card detect signal
+ #define CF_PMP_CD1 PORTCbits.RC4
+ // Description: The TRIS bit for the CF card detect signal
+ #define CF_PMP_CD1DIR TRISCbits.TRISC4
+
+ #endif
+
+ // Description: Defines the PMP data bus direction register
+ #define MDD_CFPMP_DATADIR TRISE
+#endif
+
+
+#ifdef USE_MANUAL_CF_INTERFACE
+ // Use these definitions with CF-Bit transaction.c and .h
+ // This will manually perform parallel port transactions
+
+ #ifdef __18CXX
+
+ // Address lines
+
+ // Description: The CF address bus output latch register (for PIC18)
+ #define ADDBL LATA
+ // Description: The CF address bus TRIS register (for PIC18)
+ #define ADDDIR TRISA
+
+ // Data bus
+
+ // Description: The Manual CF data bus port register
+ #define MDD_CFBT_DATABIN PORTD
+ // Description: The Manual CF data bus output latch register
+ #define MDD_CFBT_DATABOUT LATD
+ // Description: The Manual CF data bus TRIS register
+ #define MDD_CFBT_DATADIR TRISD
+
+ // control bus lines
+
+ // Description: The CF card chip select output latch bit
+ #define CF_CE LATEbits.LATE1
+ // Description: The CF card chip select TRIS bit
+ #define CF_CEDIR TRISEbits.TRISE1
+ // Description: The CF card output enable strobe latch bit
+ #define CF_OE LATAbits.LATA5
+ // Description: The CF card output enable strobe TRIS bit
+ #define CF_OEDIR TRISAbits.TRISA5
+ // Description: The CF card write enable strobe latch bit
+ #define CF_WE LATAbits.LATA4
+ // Description: The CF card write enable strobe TRIS bit
+ #define CF_WEDIR TRISAbits.TRISA4
+ // Description: The CF card reset signal latch bit
+ #define CF_BT_RST LATEbits.LATE0
+ // Description: The CF card reset signal TRIS bit
+ #define CF_BT_RESETDIR TRISEbits.TRISE0
+ // Description: The CF card ready signal port bit
+ #define CF_BT_RDY PORTEbits.RE2
+ // Description: The CF card ready signal TRIS bit
+ #define CF_BT_READYDIR TRISEbits.TRISE2
+ // Description: The CF card detect signal port bit
+ #define CF_BT_CD1 PORTCbits.RC2
+ // Description: The CF card detect signal TRIS bit
+ #define CF_BT_CD1DIR TRISCbits.TRISC2
+
+ #elif defined __dsPIC30F__
+
+ // Address lines
+
+ // Description: The CF address bus bit 0 output latch definition (for PIC24/30/33/32)
+ #define ADDR0 _LATB15
+ // Description: The CF address bus bit 1 output latch definition (for PIC24/30/33/32)
+ #define ADDR1 _LATB14
+ // Description: The CF address bus bit 2 output latch definition (for PIC24/30/33/32)
+ #define ADDR2 _LATG9
+ // Description: The CF address bus bit 3 output latch definition (for PIC24/30/33/32)
+ #define ADDR3 _LATG8
+ // Description: The CF address bus bit 0 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS0 _TRISB15
+ // Description: The CF address bus bit 1 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS1 _TRISB14
+ // Description: The CF address bus bit 2 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS2 _TRISG9
+ // Description: The CF address bus bit 3 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS3 _TRISG8
+
+ // Data bus
+
+ // Description: The Manual CF data bus port register
+ #define MDD_CFBT_DATABIN PORTE
+ // Description: The Manual CF data bus output latch register
+ #define MDD_CFBT_DATABOUT PORTE
+ // Description: The Manual CF data bus TRIS register
+ #define MDD_CFBT_DATADIR TRISE
+
+ // control bus lines
+
+ // Description: The CF card chip select output latch bit
+ #define CF_CE _RD11
+ // Description: The CF card chip select TRIS bit
+ #define CF_CEDIR _TRISD11
+ // Description: The CF card output enable strobe latch bit
+ #define CF_OE _RD5
+ // Description: The CF card output enable strobe TRIS bit
+ #define CF_OEDIR _TRISD5
+ // Description: The CF card write enable strobe latch bit
+ #define CF_WE _RD4
+ // Description: The CF card write enable strobe TRIS bit
+ #define CF_WEDIR _TRISD4
+ // Description: The CF card reset signal latch bit
+ #define CF_BT_RST _RD0
+ // Description: The CF card reset signal TRIS bit
+ #define CF_BT_RESETDIR _TRISD0
+ // Description: The CF card ready signal port bit
+ #define CF_BT_RDY _RD12
+ // Description: The CF card ready signal TRIS bit
+ #define CF_BT_READYDIR _TRISD12
+ // Description: The CF card detect signal port bit
+ #define CF_BT_CD1 _RC4
+ // Description: The CF card detect signal TRIS bit
+ #define CF_BT_CD1DIR _TRISC4
+
+ #elif defined __dsPIC33F__
+
+ // Address lines
+
+ // Description: The CF address bus bit 0 output latch definition (for PIC24/30/33/32)
+ #define ADDR0 _LATB15
+ // Description: The CF address bus bit 1 output latch definition (for PIC24/30/33/32)
+ #define ADDR1 _LATB14
+ // Description: The CF address bus bit 2 output latch definition (for PIC24/30/33/32)
+ #define ADDR2 _LATG9
+ // Description: The CF address bus bit 3 output latch definition (for PIC24/30/33/32)
+ #define ADDR3 _LATG8
+ // Description: The CF address bus bit 0 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS0 _TRISB15
+ // Description: The CF address bus bit 1 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS1 _TRISB14
+ // Description: The CF address bus bit 2 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS2 _TRISG9
+ // Description: The CF address bus bit 3 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS3 _TRISG8
+
+ // Data bus
+
+ // Description: The Manual CF data bus port register
+ #define MDD_CFBT_DATABIN PORTE
+ // Description: The Manual CF data bus output latch register
+ #define MDD_CFBT_DATABOUT PORTE
+ // Description: The Manual CF data bus TRIS register
+ #define MDD_CFBT_DATADIR TRISE
+
+ // control bus lines
+
+ // Description: The CF card chip select output latch bit
+ #define CF_CE _RD11
+ // Description: The CF card chip select TRIS bit
+ #define CF_CEDIR _TRISD11
+ // Description: The CF card output enable strobe latch bit
+ #define CF_OE _RD5
+ // Description: The CF card output enable strobe TRIS bit
+ #define CF_OEDIR _TRISD5
+ // Description: The CF card write enable strobe latch bit
+ #define CF_WE _RD4
+ // Description: The CF card write enable strobe TRIS bit
+ #define CF_WEDIR _TRISD4
+ // Description: The CF card reset signal latch bit
+ #define CF_BT_RST _RD0
+ // Description: The CF card reset signal TRIS bit
+ #define CF_BT_RESETDIR _TRISD0
+ // Description: The CF card ready signal port bit
+ #define CF_BT_RDY _RD12
+ // Description: The CF card ready signal TRIS bit
+ #define CF_BT_READYDIR _TRISD12
+ // Description: The CF card detect signal port bit
+ #define CF_BT_CD1 _RC4
+ // Description: The CF card detect signal TRIS bit
+ #define CF_BT_CD1DIR _TRISC4
+
+ #elif defined __PIC24F__
+
+ // Address lines
+
+ // Description: The CF address bus bit 0 output latch definition (for PIC24/30/33/32)
+ #define ADDR0 LATBbits.LATB15
+ // Description: The CF address bus bit 1 output latch definition (for PIC24/30/33/32)
+ #define ADDR1 LATBbits.LATB14
+ // Description: The CF address bus bit 2 output latch definition (for PIC24/30/33/32)
+ #define ADDR2 LATGbits.LATG9
+ // Description: The CF address bus bit 3 output latch definition (for PIC24/30/33/32)
+ #define ADDR3 LATGbits.LATG8
+ // Description: The CF address bus bit 0 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS0 TRISBbits.TRISB15
+ // Description: The CF address bus bit 1 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS1 TRISBbits.TRISB14
+ // Description: The CF address bus bit 2 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS2 TRISGbits.TRISG9
+ // Description: The CF address bus bit 3 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS3 TRISGbits.TRISG8
+
+ // Data bus
+
+ // Description: The Manual CF data bus port register
+ #define MDD_CFBT_DATABIN PORTE
+ // Description: The Manual CF data bus output latch register
+ #define MDD_CFBT_DATABOUT PORTE
+ // Description: The Manual CF data bus TRIS register
+ #define MDD_CFBT_DATADIR TRISE
+
+ // control bus lines
+
+ // Description: The CF card chip select output latch bit
+ #define CF_CE PORTDbits.RD11
+ // Description: The CF card chip select TRIS bit
+ #define CF_CEDIR TRISDbits.TRISD11
+ // Description: The CF card output enable strobe latch bit
+ #define CF_OE PORTDbits.RD5
+ // Description: The CF card output enable strobe TRIS bit
+ #define CF_OEDIR TRISDbits.TRISD5
+ // Description: The CF card write enable strobe latch bit
+ #define CF_WE PORTDbits.RD4
+ // Description: The CF card write enable strobe TRIS bit
+ #define CF_WEDIR TRISDbits.TRISD4
+ // Description: The CF card reset signal latch bit
+ #define CF_BT_RST PORTDbits.RD0
+ // Description: The CF card reset signal TRIS bit
+ #define CF_BT_RESETDIR TRISDbits.TRISD0
+ // Description: The CF card ready signal port bit
+ #define CF_BT_RDY PORTDbits.RD12
+ // Description: The CF card ready signal TRIS bit
+ #define CF_BT_READYDIR TRISDbits.TRISD12
+ // Description: The CF card detect signal port bit
+ #define CF_BT_CD1 PORTCbits.RC4
+ // Description: The CF card detect signal TRIS bit
+ #define CF_BT_CD1DIR TRISCbits.TRISC4
+ #endif
+#endif
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/SD-SPI.d b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/SD-SPI.d new file mode 100644 index 00000000..5556b9b2 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/SD-SPI.d @@ -0,0 +1,61 @@ +SD-SPI.o: SD-SPI.c FSIO.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h FSconfig.h \
+ C:/Microchip\ Solutions/Microchip/Include/Compiler.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/string.h \
+ HardwareProfile.h \
+ C:/Microchip\ Solutions/Microchip/Include/MDD\ File\ System\FSDefs.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h SD-SPI.h \
+ FSConfig.h
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/SD-SPI.h b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/SD-SPI.h new file mode 100644 index 00000000..55084ad4 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/newer_fw/SD-SPI.h @@ -0,0 +1,432 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: SD-SPI.h
+ * Dependencies: GenericTypeDefs.h
+ * FSconfig.h
+ * FSDefs.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#ifndef SDMMC_H
+#define SDMMC_H
+
+#include "GenericTypeDefs.h"
+#include "FSconfig.h"
+#include "MDD File System\FSDefs.h"
+
+
+#ifdef __18CXX
+ // Description: This macro is used to initialize a PIC18 SPI module with a 4x prescale divider
+ #define SYNC_MODE_FAST 0x00
+ // Description: This macro is used to initialize a PIC18 SPI module with a 16x prescale divider
+ #define SYNC_MODE_MED 0x01
+ // Description: This macro is used to initialize a PIC18 SPI module with a 64x prescale divider
+ #define SYNC_MODE_SLOW 0x02
+#elif defined __PIC32MX__
+ // Description: This macro is used to initialize a PIC32 SPI module
+ #define SYNC_MODE_FAST 0x3E
+ // Description: This macro is used to initialize a PIC32 SPI module
+ #define SYNC_MODE_SLOW 0x3C
+#else
+ // Description: This macro indicates the SPI enable bit for 16-bit PICs
+ #define MASTER_ENABLE_ON 0x0020
+
+ // Description: This macro is used to initialize a 16-bit PIC SPI module
+ #define SYNC_MODE_FAST 0x3E
+ // Description: This macro is used to initialize a 16-bit PIC SPI module
+ #define SYNC_MODE_SLOW 0x3C
+
+ // Description: This macro is used to initialize a 16-bit PIC SPI module secondary prescaler
+ #define SEC_PRESCAL_1_1 0x001c
+ // Description: This macro is used to initialize a 16-bit PIC SPI module primary prescaler
+ #define PRI_PRESCAL_1_1 0x0003
+#endif
+
+
+
+/*****************************************************************/
+/* Strcutures and defines */
+/*****************************************************************/
+
+
+// Description: This macro represents an SD card start token
+#define DATA_START_TOKEN 0xFE
+
+// Description: This macro represents an SD card data accepted token
+#define DATA_ACCEPTED 0x05
+
+// Description: This macro indicates that the SD card expects to transmit or receive more data
+#define MOREDATA !0
+
+// Description: This macro indicates that the SD card does not expect to transmit or receive more data
+#define NODATA 0
+
+// Description: This macro represents a floating SPI bus condition
+#define MMC_FLOATING_BUS 0xFF
+
+// Description: This macro represents a bad SD card response byte
+#define MMC_BAD_RESPONSE MMC_FLOATING_BUS
+
+// The SDMMC Commands
+
+// Description: This macro defines the command code to reset the SD card
+#define cmdGO_IDLE_STATE 0
+// Description: This macro defines the command code to initialize the SD card
+#define cmdSEND_OP_COND 1
+// Description: This macro defines the command code to get the Card Specific Data
+#define cmdSEND_CSD 9
+// Description: This macro defines the command code to get the Card Information
+#define cmdSEND_CID 10
+// Description: This macro defines the command code to stop transmission during a multi-block read
+#define cmdSTOP_TRANSMISSION 12
+// Description: This macro defines the command code to get the card status information
+#define cmdSEND_STATUS 13
+// Description: This macro defines the command code to set the block length of the card
+#define cmdSET_BLOCKLEN 16
+// Description: This macro defines the command code to read one block from the card
+#define cmdREAD_SINGLE_BLOCK 17
+// Description: This macro defines the command code to read multiple blocks from the card
+#define cmdREAD_MULTI_BLOCK 18
+// Description: This macro defines the command code to write one block to the card
+#define cmdWRITE_SINGLE_BLOCK 24
+// Description: This macro defines the command code to write multiple blocks to the card
+#define cmdWRITE_MULTI_BLOCK 25
+// Description: This macro defines the command code to set the address of the start of an erase operation
+#define cmdTAG_SECTOR_START 32
+// Description: This macro defines the command code to set the address of the end of an erase operation
+#define cmdTAG_SECTOR_END 33
+// Description: This macro defines the command code to erase all previously selected blocks
+#define cmdERASE 38
+// Description: This macro defines the command code to begin application specific command inputs
+#define cmdAPP_CMD 55
+// Description: This macro defines the command code to get the OCR register information from the card
+#define cmdREAD_OCR 58
+// Description: This macro defines the command code to disable CRC checking
+#define cmdCRC_ON_OFF 59
+
+
+// Description: Enumeration of different SD response types
+typedef enum
+{
+ R1, // R1 type response
+ R1b, // R1b type response
+ R2, // R2 type response
+ R3 // R3 type response
+}RESP;
+
+// Summary: SD card command data structure
+// Description: The typMMC_CMD structure is used to create a command table of information needed for each relevant SD command
+typedef struct
+{
+ BYTE CmdCode; // The command code
+ BYTE CRC; // The CRC value for that command
+ RESP responsetype; // The response type
+ BYTE moredataexpected; // Set to MOREDATA or NODATA, depending on whether more data is expected or not
+} typMMC_CMD;
+
+
+// Summary: An SD command packet
+// Description: This union represents different ways to access an SD card command packet
+typedef union
+{
+ // This structure allows array-style access of command bytes
+ struct
+ {
+ #ifdef __18CXX
+ BYTE field[6]; // BYTE array
+ #else
+ BYTE field[7];
+ #endif
+ };
+ // This structure allows byte-wise access of packet command bytes
+ struct
+ {
+ BYTE crc; // The CRC byte
+ #if defined __C30__
+ BYTE c30filler; // Filler space (since bitwise declarations can't cross a WORD boundary)
+ #elif defined __C32__
+ BYTE c32filler[3]; // Filler space (since bitwise declarations can't cross a DWORD boundary)
+ #endif
+
+ BYTE addr0; // Address byte 0
+ BYTE addr1; // Address byte 1
+ BYTE addr2; // Address byte 2
+ BYTE addr3; // Address byte 3
+ BYTE cmd; // Command code byte
+ };
+ // This structure allows bitwise access to elements of the command bytes
+ struct
+ {
+ BYTE END_BIT:1; // Packet end bit
+ BYTE CRC7:7; // CRC value
+ DWORD address; // Address
+ BYTE CMD_INDEX:6; // Command code
+ BYTE TRANSMIT_BIT:1; // Transmit bit
+ BYTE START_BIT:1; // Packet start bit
+ };
+} CMD_PACKET;
+
+
+// Summary: The format of an R1 type response
+// Description: This union represents different ways to access an SD card R1 type response packet.
+typedef union
+{
+ BYTE _byte; // Byte-wise access
+ // This structure allows bitwise access of the response
+ struct
+ {
+ unsigned IN_IDLE_STATE:1; // Card is in idle state
+ unsigned ERASE_RESET:1; // Erase reset flag
+ unsigned ILLEGAL_CMD:1; // Illegal command flag
+ unsigned CRC_ERR:1; // CRC error flag
+ unsigned ERASE_SEQ_ERR:1; // Erase sequence error flag
+ unsigned ADDRESS_ERR:1; // Address error flag
+ unsigned PARAM_ERR:1; // Parameter flag
+ unsigned B7:1; // Unused bit 7
+ };
+} RESPONSE_1;
+
+// Summary: The format of an R2 type response
+// Description: This union represents different ways to access an SD card R2 type response packet
+typedef union
+{
+ WORD _word;
+ struct
+ {
+ BYTE _byte0;
+ BYTE _byte1;
+ };
+ struct
+ {
+ unsigned IN_IDLE_STATE:1;
+ unsigned ERASE_RESET:1;
+ unsigned ILLEGAL_CMD:1;
+ unsigned CRC_ERR:1;
+ unsigned ERASE_SEQ_ERR:1;
+ unsigned ADDRESS_ERR:1;
+ unsigned PARAM_ERR:1;
+ unsigned B7:1;
+ unsigned CARD_IS_LOCKED:1;
+ unsigned WP_ERASE_SKIP_LK_FAIL:1;
+ unsigned ERROR:1;
+ unsigned CC_ERROR:1;
+ unsigned CARD_ECC_FAIL:1;
+ unsigned WP_VIOLATION:1;
+ unsigned ERASE_PARAM:1;
+ unsigned OUTRANGE_CSD_OVERWRITE:1;
+ };
+} RESPONSE_2;
+
+// Summary: A union of responses from an SD card
+// Description: The MMC_RESPONSE union represents any of the possible responses that an SD card can return after
+// being issued a command.
+typedef union
+{
+ RESPONSE_1 r1;
+ RESPONSE_2 r2;
+}MMC_RESPONSE;
+
+
+// Summary: A description of the card specific data register
+// Description: This union represents different ways to access information in a packet with SD card CSD informaiton. For more
+// information on the CSD register, consult an SD card user's manual.
+typedef union
+{
+ struct
+ {
+ DWORD _u320;
+ DWORD _u321;
+ DWORD _u322;
+ DWORD _u323;
+ };
+ struct
+ {
+ BYTE _byte[16];
+ };
+ struct
+ {
+ unsigned NOT_USED :1;
+ unsigned CRC :7;
+ unsigned ECC :2;
+ unsigned FILE_FORMAT :2;
+ unsigned TMP_WRITE_PROTECT :1;
+ unsigned PERM_WRITE_PROTECT :1;
+ unsigned COPY :1;
+ unsigned FILE_FORMAT_GRP :1;
+ unsigned RESERVED_1 :5;
+ unsigned WRITE_BL_PARTIAL :1;
+ unsigned WRITE_BL_LEN_L :2;
+ unsigned WRITE_BL_LEN_H :2;
+ unsigned R2W_FACTOR :3;
+ unsigned DEFAULT_ECC :2;
+ unsigned WP_GRP_ENABLE :1;
+ unsigned WP_GRP_SIZE :5;
+ unsigned ERASE_GRP_SIZE_L :3;
+ unsigned ERASE_GRP_SIZE_H :2;
+ unsigned SECTOR_SIZE :5;
+ unsigned C_SIZE_MULT_L :1;
+ unsigned C_SIZE_MULT_H :2;
+ unsigned VDD_W_CURR_MAX :3;
+ unsigned VDD_W_CUR_MIN :3;
+ unsigned VDD_R_CURR_MAX :3;
+ unsigned VDD_R_CURR_MIN :3;
+ unsigned C_SIZE_L :2;
+ unsigned C_SIZE_H :8;
+ unsigned C_SIZE_U :2;
+ unsigned RESERVED_2 :2;
+ unsigned DSR_IMP :1;
+ unsigned READ_BLK_MISALIGN :1;
+ unsigned WRITE_BLK_MISALIGN :1;
+ unsigned READ_BL_PARTIAL :1;
+ unsigned READ_BL_LEN :4;
+ unsigned CCC_L :4;
+ unsigned CCC_H :8;
+ unsigned TRAN_SPEED :8;
+ unsigned NSAC :8;
+ unsigned TAAC :8;
+ unsigned RESERVED_3 :2;
+ unsigned SPEC_VERS :4;
+ unsigned CSD_STRUCTURE :2;
+ };
+} CSD;
+
+
+// Summary: A description of the card information register
+// Description: This union represents different ways to access information in a packet with SD card CID register informaiton. For more
+// information on the CID register, consult an SD card user's manual.
+typedef union
+{
+ struct
+ {
+ DWORD _u320;
+ DWORD _u321;
+ DWORD _u322;
+ DWORD _u323;
+ };
+ struct
+ {
+ BYTE _byte[16];
+ };
+ struct
+ {
+ unsigned NOT_USED :1;
+ unsigned CRC :7;
+ unsigned MDT :8;
+ DWORD PSN;
+ unsigned PRV :8;
+ char PNM[6];
+ WORD OID;
+ unsigned MID :8;
+ };
+} CID;
+
+#ifndef FALSE
+ #define FALSE 0
+#endif
+#ifndef TRUE
+ #define TRUE !FALSE
+#endif
+
+#define INPUT 1
+#define OUTPUT 0
+
+
+// Description: A delay prescaler
+#define DELAY_PRESCALER (BYTE) 8 //80MHz
+
+// Description: An approximation of the number of cycles per delay loop of overhead
+#define DELAY_OVERHEAD (BYTE) 5
+
+// Description: An approximate calculation of how many times to loop to delay 1 ms in the Delayms function
+#define MILLISECDELAY (WORD) ((GetInstructionClock()/DELAY_PRESCALER/(WORD)1000) - DELAY_OVERHEAD)
+
+// Summary: An enumeration of SD commands
+// Description: This enumeration corresponds to the position of each command in the sdmmc_cmdtable array
+// These macros indicate to the SendMMCCmd function which element of the sdmmc_cmdtable array
+// to retrieve command code information from.
+typedef enum
+{
+ GO_IDLE_STATE,
+ SEND_OP_COND,
+ SEND_CSD,
+ SEND_CID,
+ STOP_TRANSMISSION,
+ SEND_STATUS,
+ SET_BLOCKLEN,
+ READ_SINGLE_BLOCK,
+ READ_MULTI_BLOCK,
+ WRITE_SINGLE_BLOCK,
+ WRITE_MULTI_BLOCK,
+ TAG_SECTOR_START,
+ TAG_SECTOR_END,
+ ERASE,
+ APP_CMD,
+ READ_OCR,
+ CRC_ON_OFF
+}sdmmc_cmd;
+
+
+
+/***************************************************************************/
+/* Macros */
+/***************************************************************************/
+
+// Description: A macro to send clock cycles to dummy-read the CRC
+#define mReadCRC() WriteSPIM(0xFF);WriteSPIM(0xFF);
+
+// Description: A macro to send clock cycles to dummy-write the CRC
+#define mSendCRC() WriteSPIM(0xFF);WriteSPIM(0xFF);
+
+// Description: A macro to send 8 clock cycles for SD timing requirements
+#define mSend8ClkCycles() WriteSPIM(0xFF);
+
+/*****************************************************************************/
+/* Prototypes */
+/*****************************************************************************/
+
+DWORD MDD_SDSPI_ReadCapacity(void);
+WORD MDD_SDSPI_ReadSectorSize(void);
+void MDD_SDSPI_InitIO(void);
+
+BYTE MDD_SDSPI_MediaDetect(void);
+BYTE MDD_SDSPI_MediaInitialize(void);
+BYTE MDD_SDSPI_SectorRead(DWORD sector_addr, BYTE* buffer);
+BYTE MDD_SDSPI_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero);
+
+BYTE MDD_SDSPI_WriteProtectState(void);
+void MDD_SDSPI_ShutdownMedia(void);
+
+#if defined __C30__ || defined __C32__
+ extern BYTE ReadByte( BYTE* pBuffer, WORD index );
+ extern WORD ReadWord( BYTE* pBuffer, WORD index );
+ extern DWORD ReadDWord( BYTE* pBuffer, WORD index );
+#endif
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/procdefs.ld b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/procdefs.ld new file mode 100644 index 00000000..7f83fa41 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/EriksBranch/bfb-firmware-dev3/procdefs.ld @@ -0,0 +1,58 @@ +/* Special procdefs.ld for use with USB HID Bootloader.
+ Just copy to your build area where the .mcw file is located */
+/*************************************************************************
+ * Processor-specific object file. Contains SFR definitions.
+ *************************************************************************/
+INPUT("processor.o")
+
+/*************************************************************************
+ * For interrupt vector handling
+ *************************************************************************/
+PROVIDE(_vector_spacing = 0x00000001);
+_ebase_address = 0x9D005000;
+
+/*************************************************************************
+ * Memory Address Equates
+ *************************************************************************/
+_RESET_ADDR = 0x9D006000;
+_BEV_EXCPT_ADDR = 0x9D006380;
+_DBG_EXCPT_ADDR = 0x9D006480;
+_DBG_CODE_ADDR = 0xBFC02000;
+_GEN_EXCPT_ADDR = _ebase_address + 0x180;
+
+/*************************************************************************
+ * Memory Regions
+ *
+ * Memory regions without attributes cannot be used for orphaned sections.
+ * Only sections specifically assigned to these regions can be allocated
+ * into these regions.
+ *************************************************************************/
+MEMORY
+{
+ kseg0_program_mem (rx) : ORIGIN = 0x9D006A00, LENGTH = 0x7A600
+ kseg0_boot_mem : ORIGIN = 0x9D006490, LENGTH = 0x970
+ exception_mem : ORIGIN = 0x9D005000, LENGTH = 0x1000
+ kseg1_boot_mem : ORIGIN = 0x9D006000, LENGTH = 0x490
+ debug_exec_mem : ORIGIN = 0xBFC02000, LENGTH = 0xFF0
+ config3 : ORIGIN = 0xBFC02FF0, LENGTH = 0x4
+ config2 : ORIGIN = 0xBFC02FF4, LENGTH = 0x4
+ config1 : ORIGIN = 0xBFC02FF8, LENGTH = 0x4
+ config0 : ORIGIN = 0xBFC02FFC, LENGTH = 0x4
+ kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x8000
+ sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000
+}
+SECTIONS
+{
+ .config_BFC02FF0 : {
+ KEEP(*(.config_BFC02FF0))
+ } > config3
+ .config_BFC02FF4 : {
+ KEEP(*(.config_BFC02FF4))
+ } > config2
+ .config_BFC02FF8 : {
+ KEEP(*(.config_BFC02FF8))
+ } > config1
+ .config_BFC02FFC : {
+ KEEP(*(.config_BFC02FFC))
+ } > config0
+}
\ No newline at end of file diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Bits From Bytes Software Licence Agreement.pdf b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Bits From Bytes Software Licence Agreement.pdf Binary files differnew file mode 100644 index 00000000..33ac7f9c --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Bits From Bytes Software Licence Agreement.pdf diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/CreativeCommons-by-nc-sa-3.0-summary.pdf b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/CreativeCommons-by-nc-sa-3.0-summary.pdf Binary files differnew file mode 100644 index 00000000..bca9532f --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/CreativeCommons-by-nc-sa-3.0-summary.pdf diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/CreativeCommons-by-nc-sa-3.0.pdf b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/CreativeCommons-by-nc-sa-3.0.pdf Binary files differnew file mode 100644 index 00000000..95ea2819 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/CreativeCommons-by-nc-sa-3.0.pdf diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Enviroment.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Enviroment.h new file mode 100644 index 00000000..665c165d --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Enviroment.h @@ -0,0 +1,100 @@ +/**********************************************************************
+ ************************* Environment.h ****************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+//SPI2 pins for SD card see HardwareProfile
+#define OLED_CS PORTBbits.RB5 //Analog pin
+// Description: OLED-SPI Chip Select TRIS bit
+#define OLED_CS_TRIS TRISBbits.TRISB5
+#define DC PORTEbits.RE6 //Digital
+#define RES PORTEbits.RE7 //Digital
+
+
+//General Defines
+#define On 1
+#define OFF 0
+//#define TRUE 1
+//#define FALSE 0
+
+#define CLOCK_SPEED 80000000
+#define INPUT_PIN 1
+#define OUTPUT_PIN 0
+
+//Stepper Setup
+#define EXTRUDER_STEP_PER_REV 3200
+#define PR3_FREQUENCY 5e6 //=80MHz (sysclk) div_8 then div 2 for Pre-Scaler
+#define PR3_CONSTANT PR3_FREQUENCY*600/EXTRUDER_STEP_PER_REV //Use for 600 RPM * 10 to allow int maths
+
+//Interrupt defines
+#define _T3IE IEC0bits.T3IE
+#define _T3IF IFS0bits.T3IF
+
+//Buttons
+#define YPlusTop_Btn PORTBbits.RB15 //Analog pin
+#define YMinusBot_Btn PORTBbits.RB4 //Analog pin
+#define XPlusRight_Btn PORTBbits.RB3 //Analog pin
+#define XMinusLeft_Btn PORTBbits.RB2 //Analog pin
+#define ZPlus_up_Btn PORTFbits.RF5 //Digital pin
+#define ZMinus_down_Btn PORTFbits.RF4 //Digital pin
+#define Manual_Select PORTGbits.RG9 //Digital pin
+
+//Axis Limit switches
+#define X_HomeSwitch PORTDbits.RD4 //Digital pin
+#define Y_HomeSwitch PORTCbits.RC13 //Digital pin
+#define Z_HomeSwitch PORTCbits.RC14 //Digital pin
+
+//FETS
+#define HEATER PORTFbits.RF0 //Digital pin
+#define FAN PORTEbits.RE5 //Digital pin
+#define AUX PORTDbits.RD11 //Digital pin
+
+#define FILLAMENT_ERROR PORTBbits.RB0 //Analog pin
+
+//Analog
+#define THERMISTOR_ADC 11 //B11 Thermistor Analog Channel
+#define TOOL_ID 12 //B12 TOOL identification resistor
+
+//Display mode defines
+#define MANUAL_MOVE 0
+#define TEMPERATURE 1
+#define RPM 2
+#define AUTO_MODE 3
+
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Extruder.c b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Extruder.c new file mode 100644 index 00000000..19f8fd13 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Extruder.c @@ -0,0 +1,509 @@ +/**********************************************************************
+ *************************** Extruder.c *****************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+#include "Extruder.h"
+#include "Stepper.h"
+#include "Enviroment.h"
+#include "G_Code.h"
+#include "OLED.h"
+#include <plib.h> //required for interrupt handlers
+#include "stdlib.h"
+
+#define INPUT 1
+#define OUTPUT 0
+#define PRESSED 0
+#define NOT_PRESSED 1
+
+//default values for extruder reverse and prime steps
+#define STEPS_TO_REVERSE 1000
+#define STEPS_TO_PRIME 1000
+#define Z_HOP_STEPS 500
+
+//Variables
+int Thermistor_Failure_Counter = 0;
+int ADC_reading = 0;
+
+volatile int StepReady;
+//long Reverse_ms = 50;
+//long Prime_ms = 25;
+int SampleCountThermistor = 0;
+long AveSamplesThermistor = 0;
+long LowValue,HighValue,Range;
+float Fraction;
+long DataVal,TempVal;
+long raw_temperature;
+float temperature1;
+//char mode;
+int HeaterON = 0; //Heater Flag
+int temperature_OK = FALSE; //Motor flag
+short update_temp = FALSE;
+long SetTemperature = 0; //Value set from control board
+int RPM_Setting = 400;
+
+int PR3_Setting = 65525, Step_Cycle = 0, Direction = CCW;
+int RPM_Setting_Old = 0;
+int New_Data = FALSE;
+int UART_Counter = 0;
+char Message[20];
+
+int Reverse_Steps;
+int Prime_Steps;
+int Reverse_Step_Count;
+int Prime_Step_Count;
+
+int Temperature_Cycle = 0;
+extern int Operation_Mode;
+extern char FastMoveMotorEnable;//Flag to switch motor on/off during fast move
+
+//Thermistor 204GT 200K Ohms at ambient 600 ohm ref resister, 5V
+const long Therm_Table[31] = {
+1024,1023,1022,1020,1018,1015,1010,1004,995,984, //0-90
+969,950,927,899,865,827,784,737,687,635, //100-190
+583,531,480,433,388,346,309,275,244,217, //200-290
+193}; //300
+
+
+
+/***********************************************************/
+// Functions
+/***********************************************************/
+//low priority interrupt for running the temperature control loop
+void __ISR( _TIMER_2_VECTOR,ipl4) T2InterruptHandler(void)
+{
+ switch(Temperature_Cycle)
+ {
+ case 0: //maintains the ave. raw temp reading
+ ADC_reading = Read_Analog(THERMISTOR_ADC);
+
+ if (ADC_reading > 0)
+ {
+ AveSamplesThermistor += ADC_reading;
+ ++SampleCountThermistor;
+ if (SampleCountThermistor > 9)
+ {
+ raw_temperature = AveSamplesThermistor/10;
+ SampleCountThermistor = 0;
+ AveSamplesThermistor = 0;
+ Temperature_Cycle = 1;
+ break;
+ }
+ }
+ Temperature_Cycle = 0;
+ break;
+ case 1: //returns the temperature in DegC from raw_temperature
+ temperature1 = Thermistor_LookUp(raw_temperature);
+ Temperature_Cycle = 2;
+ break;
+ case 2: //changes settings
+ Control_Temperature();
+ Temperature_Cycle = 0;
+ if(HEATER)Thermistor_Failure_Counter++;
+ else Thermistor_Failure_Counter = 0;
+
+ if (!RPM_Change)
+ {
+ if (!XPlusRight_Btn){RPM_Change = 1;RPM_Setting += 10;}
+ if (!XMinusLeft_Btn){RPM_Change = 1;RPM_Setting -=10;}
+ }
+ if (!Temp_Change)
+ {
+ if (!YPlusTop_Btn) {Temp_Change = 1;SetTemperature++;}
+ if (!YMinusBot_Btn) {Temp_Change = 1;SetTemperature--;}
+ }
+ break;
+ }
+ TMR2 = 0; //Reset clock
+ mT2ClearIntFlag();
+
+}//ISR Timer2
+
+/***********************************************************/
+//Stepper Interrupt Control
+void __ISR( _TIMER_3_VECTOR,ipl7) T3InterruptHandler(void)
+{
+ switch(Step_Cycle){
+ case 0:
+ if (!StepReady)
+ {
+ if (Reverse_Step_Count>0)--Reverse_Step_Count; //decrement step count
+ if (Prime_Step_Count>0)--Prime_Step_Count;
+ StepReady = 1; //Step taken from count
+ }
+ EXTRUDER_DIR = Direction;
+ PR3 = 5;
+ Step_Cycle = 1;
+
+ break;
+ case 1:
+ if (StepReady)
+ {
+ EXTRUDER_STEP = On; //Step pin high
+ }
+ PR3 = 10;
+ Step_Cycle = 2;
+ break;
+ case 2:
+ if (StepReady)
+ {
+ EXTRUDER_STEP = OFF; //step pin low
+ }
+ PR3 = PR3_Setting;
+ Step_Cycle = 0;
+ StepReady = 0; //Step complete
+ break;
+ }
+ TMR3 = 0;
+ mT3ClearIntFlag();
+
+}//ISR Timer3
+
+/***********************************************************/
+void Control_Stepper_Motor(void)
+{
+ RPM_Setting_Old = RPM_Setting;
+
+ if (RPM_Setting < 15) RPM_Setting = 15; //Limit minimum to 1.5 RPM
+ if (RPM_Setting > 2000) RPM_Setting = 2000; //Limit maximum to 200 RPM
+ PR3_Setting=(PR3_CONSTANT/RPM_Setting)-25;
+
+ if(temperature_OK){
+ EXTRUDER_DISABLE = FALSE; //run motor
+ if(RPM_Setting <=15)EXTRUDER_DISABLE = TRUE; //If slower than 1.5RPM turn motor off
+ }
+ else EXTRUDER_DISABLE = TRUE;
+
+}//Control_Stepper_Motor
+
+/*************************************************/
+void Control_Temperature(void)
+{
+//Change_M104 flag to alter the heating method
+//Change_M104 == 1 temperature is changed by G_Code the new temp
+//must be achieved before it continues
+//Change_M104 == 0 is used during printing
+extern char Change_M104;
+extern char PauseFlag;
+
+ if(SetTemperature<0)SetTemperature = 0;
+ if(SetTemperature>300)SetTemperature = 300;
+
+ if (PauseFlag == 0)
+ {
+ if (temperature1 < SetTemperature)HEATER = On;
+ else HEATER = OFF;
+ }
+ else HEATER = OFF;
+
+ if (Change_M104 == 0) //Temperature control during print
+ {
+ if ((temperature1 < SetTemperature-10)||
+ (temperature1 > SetTemperature+10)||
+ (SetTemperature<100))
+ {
+ temperature_OK = FALSE; //To control motor
+ EXTRUDER_DISABLE = TRUE;
+ }
+ else temperature_OK = TRUE;
+ }
+
+ if (Change_M104 == 1) //Temperature change called for by G_Code
+ {
+ if ((temperature1 < SetTemperature-1)||
+ (temperature1 > SetTemperature+1)||
+ (SetTemperature<100)||
+ (temperature1 == 0))
+ {
+ temperature_OK = FALSE; //To control motor
+ EXTRUDER_DISABLE = TRUE;
+ }
+ else temperature_OK = TRUE;
+
+ }
+
+ if (EnableFanControl == TRUE)
+ {
+ if (temperature1 < SetTemperature-5) FAN = OFF; //Fan control
+ else FAN = On;
+ }
+
+ if (temperature1 == -1)Extruder_Status(OFF);//Error condition switch all off
+ if (temperature1 == 999)Extruder_Status(OFF);//Error condition switch all off
+
+}//Control_Temperature
+
+/*************************************************/
+float Thermistor_LookUp(long raw_temperature)
+{
+float temperature;
+int k;
+
+ if (raw_temperature < 28){temperature = 999;return temperature;} //Value over temp
+ if (raw_temperature >= 1023 && Thermistor_Failure_Counter > 50)
+ {temperature = -1;return temperature;}//Thermistor failure after 5 bad ave.readings
+
+ for(k=0; k<31; ++k){ // Loop through the Thermistor array
+ TempVal = Therm_Table[k];
+ if (raw_temperature > TempVal){
+ LowValue = TempVal;
+ HighValue = Therm_Table[k-1];
+ Range = HighValue - LowValue; //contains the range
+ DataVal = raw_temperature - LowValue;
+ Fraction = (float)DataVal/Range;
+ Fraction *= 10; //as the range is 10Degrees
+ temperature = (float)(k*10) - Fraction;
+ return temperature;
+ }
+ }
+}//Thermistor_LookUp
+
+/*************************************************/
+int Read_Analog(int Ch)
+{
+int i;
+ AD1CHSbits.CH0SA = Ch; //select analog +ve input
+ AD1CON1bits.SAMP = 1; //start sampling
+ for(i=0;i<200;i++); //delay
+ AD1CON1bits.SAMP = 0;
+ while (!AD1CON1bits.DONE); //wait for conversion to complete
+ return ADC1BUF0; //read the conversion result
+
+}//Read_Analog
+
+/*************************************************/
+void Extruder_Status(int on_off)
+{
+ switch(on_off == On){
+ case On:
+ EXTRUDER_DISABLE = !TRUE;
+ mT2IntEnable(TRUE); //Enable T2 interrputs Heater
+ mT3IntEnable(TRUE); //Enable T3 interrputs Stepper
+ //Delayms(1000); //Time to get first reading from Thermistor
+ Thermistor_Failure_Counter = 0;
+ break;
+ case OFF:
+ HEATER = OFF;
+ EXTRUDER_DISABLE = TRUE;
+ mT2IntEnable(!TRUE); //Disable T2 interrputs Heater
+ mT3IntEnable(!TRUE); //Disable T3 interrputs Stepper
+ break;
+ case NO_MOTOR:
+ EXTRUDER_DISABLE = TRUE;
+ mT3IntEnable(!TRUE);
+ break;
+ }
+}//Extruder_Status
+
+/*************************************************/
+void InitExtruder(void)
+{
+ //Initializations
+ TRISEbits.TRISE1 = OUTPUT; //Step
+ TRISEbits.TRISE2 = OUTPUT; //Dir
+ TRISEbits.TRISE0 = OUTPUT; //Enable
+
+ mOSCSetPBDIV(OSC_PB_DIV_8);
+
+ //Timer 2 is used to run the temperature control
+ //PB clk = 8MHz Post scaler = 2 to 1 tick every 25uS
+ T2CON = 0x0; //256 PS setting register
+ T2CONSET = 0x0070; //Set PS to 2
+ TMR2 = 0; //Reset clock
+ PR2 = 500; //Initialise PR2 value (when T2 matches PR2 it interrupts)
+ mT2SetIntPriority(4); //Set T2 interrupt to LOW priority
+ mT2ClearIntFlag(); //Clear interrupt flag
+ T2CONSET = 0x8000; //Turn on T2
+ mT2IntEnable(!TRUE); //Enable T2 interrputs
+
+ //Timer 3 is used to time the stepper motor steps
+ //PB clk = 8MHz Post scaler = 2 to 1 tick every 25uS
+ T3CON = 0x0; //Clear timer setting register
+ T3CONSET = 0x0010; //Set PS to 2
+ TMR3 = 0; //Reset clock
+ PR3 = 5000;//500; //Initialise PR3 value (when T3 matches PR3 it interrupts)
+ mT3SetIntPriority(7); //Set T3 interrupt to top priority
+ INTEnableSystemMultiVectoredInt();//Set T3 to vectored i.e. Fast
+ mT3ClearIntFlag(); //Clear interrupt flag
+ T3CONSET = 0x8000; //Turn on T3
+
+ mT3IntEnable(!TRUE); //Enable T3 interrputs
+ EXTRUDER_DISABLE = TRUE; //Disable Stepper
+ EnableFanControl = FALSE; //Default - Disable fan
+ FastMoveMotorEnable = FALSE; //Default - set extruder motor off
+
+}//InitExtruder
+
+/***********************************************************/
+void Manual_Extruder( void )
+{
+int i=0;
+ OLED_Fill_RAM(BLANK_SCREEN);
+ while(!XPlusRight_Btn); //Wait for menu selection key to be released
+ RPM_Setting = 0;
+ SetTemperature = 0;
+ OLED_Extruder_Screen();
+ Extruder_Status(On);
+ while (Manual_Select == NOT_PRESSED){
+ Control_Stepper_Motor();
+ i++;
+ if(i>1000)
+ {
+ OLED_Extruder_Screen();
+ if (!XPlusRight_Btn)RPM_Setting +=10;
+ if (!XMinusLeft_Btn)RPM_Setting -=10;
+ if (!YPlusTop_Btn) SetTemperature++;
+ if (!YMinusBot_Btn) SetTemperature--;
+ i=0;
+ }
+ }
+ Extruder_Status(OFF);
+
+}//Manual_Extruder
+
+/***********************************************************/
+// Delay uS
+//Max delay 21,000,000,000 i.e. 2,100 seconds = 35 Minutes
+//Calling has overhead of 260nS i.e. delay = 0 takes 260nS
+//delay = 1 takes 1.26uS
+void delay_us(long delayus)
+{
+int i_util;
+
+ for(i_util=0;i_util<delayus*4;i_util++)
+ {
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ }
+}//delay_us
+
+/***********************************************************/
+// Delay mS
+//See delay_us for limits
+void delay_ms(long delayms)
+{
+ delay_us(delayms*1000);
+
+}//delay_ms
+
+/***********************************************************/
+void Extruder_Reverse(void)
+{
+//StepData Bits 7 XDir, 6 X, 5 YDir, 4 Y, 3 ZDir, 2 Z, 1 & 0 Not used
+//unsigned char StepData = 0; //used for Z hop
+//unsigned int Z_Hop;
+
+ if((Ex_Reverse)&&(EXTRUDER_DISABLE == !TRUE))
+ {
+ /*
+ if (Do_Z_Hop == TRUE) //Gcode switch TODO
+ {
+ //Z Hop up
+ StepData |= 0x08; //Set Z Direction set bit 3 on
+ StepData |= 0x04; //z set step bit 2 on
+ Feed_Rate = 750;
+ Z_Hop = Z_HOP_STEPS;
+ do
+ {
+ AddToStepBuffer(StepData,0,0); //add step data to circular buffer
+ --Z_Hop;
+ }
+ while (Z_Hop>0);
+ Done_Hop_UP = TRUE; Not defined yet
+ }
+ */
+
+ Direction = CW;
+ if (Reverse_Step_Count == 0) //if not set in gCode then use default
+ {
+ if (Reverse_Steps == 0) Reverse_Step_Count = STEPS_TO_REVERSE; //Set number of steps to reverse
+ else Reverse_Step_Count = Reverse_Steps;
+ }
+
+ PR3_Setting=(PR3_CONSTANT/1000)-25; //set up step interrupt
+ while (Reverse_Step_Count >0);//wait for number of steps to complete
+ Direction = CCW; //reset normal direction
+ }
+}
+
+/***********************************************************/
+void Extruder_Prime(void)
+{
+//StepData Bits 7 XDir, 6 X, 5 YDir, 4 Y, 3 ZDir, 2 Z, 1 & 0 Not used
+//unsigned char StepData = 0; //used for Z hop
+//unsigned int Z_Hop;
+
+ if((Ex_Reverse)&&(EXTRUDER_DISABLE == !TRUE))
+ {
+ /*
+ if ((Do_Z_Hop == TRUE)&&(Done_Hop_UP == TRUE)) //GCode switch and there must have been a hop up
+ { //before we hop down.
+ //Z Hop down
+ StepData = StepData & ~0x08; //Set Z Direction set bit 3 off
+ StepData |= 0x04; //z set step bit 2 on
+ Feed_Rate = 750;
+ Z_Hop = Z_HOP_STEPS;
+ do
+ {
+ AddToStepBuffer(StepData,0,0); //add step data to circular buffer
+ --Z_Hop;
+ }
+ while (Z_Hop>0);
+ Done_Hop_UP = FALSE; Not defined yet
+ }
+ */
+ Direction = CCW;
+ if (Prime_Step_Count == 0)//if not set use default
+ {
+ if (Prime_Steps == 0) Prime_Step_Count = STEPS_TO_PRIME; //Set number of steps to reverse
+ else Prime_Step_Count = Prime_Steps;
+ }
+
+ PR3_Setting=(PR3_CONSTANT/1000)-25;//was1500
+ while (Prime_Step_Count >0);//wait for number of steps to complete
+ PR3_Setting=(PR3_CONSTANT/RPM_Setting)-25;
+ }
+}
+/***********************************************************/
+
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Extruder.d b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Extruder.d new file mode 100644 index 00000000..691be876 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Extruder.d @@ -0,0 +1,36 @@ +Extruder.o: Extruder.c Extruder.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h \
+ Enviroment.h Stepper.h G_Code.h OLED.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Extruder.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Extruder.h new file mode 100644 index 00000000..2e4f0c58 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Extruder.h @@ -0,0 +1,77 @@ +/**********************************************************************
+ *************************** Extruder.h *****************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+#include <p32xxxx.h>
+//#include <plib.h> //required for interrupt handlers
+#include "GenericTypeDefs.h"
+#include "Enviroment.h"
+//#include "stdlib.h"
+
+#define CW 0
+#define CCW 1
+#define NO_MOTOR 2
+
+#define EXTRUDER_DISABLE PORTEbits.RE0 //Digital
+#define EXTRUDER_STEP PORTEbits.RE1 //Digital
+#define EXTRUDER_DIR PORTEbits.RE2 //Digital
+
+extern char ExtruderStatus; //M103,M101 flag extruder off and on
+extern int Feed_Rate;
+
+int Ex_Reverse;
+
+//Functions
+int Read_Analog(int Ch);
+float Thermistor_LookUp(long raw_temperature);
+char RPM_Change; //set if RPM has changed
+char Temp_Change; //set if Temperature has changed
+char EnableFanControl; //Set if Fan is to be active
+
+void Control_Temperature(void);
+void InitExtruder(void);
+void delay_us(long delayus);
+void delay_ms(long delayms);
+void Control_Stepper_Motor(void);
+void Manual_Extruder(void);
+extern void Extruder_Status(int on_off);
+extern void Extruder_Reverse(void);
+extern void Extruder_Prime(void);
+
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSDefs.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSDefs.h new file mode 100644 index 00000000..5eabe7d0 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSDefs.h @@ -0,0 +1,532 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: FSDefs.h
+ * Dependencies: GenericTypeDefs.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#ifndef _FSDEF__H
+#define _FSDEF__H
+
+#include "GenericTypeDefs.h"
+
+// Summary: An enumeration used for various error codes.
+// Description: The CETYPE enumeration is used to indicate different error conditions during device operation.
+typedef enum _CETYPE
+{
+ CE_GOOD = 0, // No error
+ CE_ERASE_FAIL, // An erase failed
+ CE_NOT_PRESENT, // No device was present
+ CE_NOT_FORMATTED, // The disk is of an unsupported format
+ CE_BAD_PARTITION, // The boot record is bad
+ CE_UNSUPPORTED_FS, // The file system type is unsupported
+ CE_INIT_ERROR, // An initialization error has occured
+ CE_NOT_INIT, // An operation was performed on an uninitialized device
+ CE_BAD_SECTOR_READ, // A bad read of a sector occured
+ CE_WRITE_ERROR, // Could not write to a sector
+ CE_INVALID_CLUSTER, // Invalid cluster value > maxcls
+ CE_FILE_NOT_FOUND, // Could not find the file on the device
+ CE_DIR_NOT_FOUND, // Could not find the directory
+ CE_BAD_FILE, // File is corrupted
+ CE_DONE, // No more files in this directory
+ CE_COULD_NOT_GET_CLUSTER, // Could not load/allocate next cluster in file
+ CE_FILENAME_2_LONG, // A specified file name is too long to use
+ CE_FILENAME_EXISTS, // A specified filename already exists on the device
+ CE_INVALID_FILENAME, // Invalid file name
+ CE_DELETE_DIR, // The user tried to delete a directory with FSremove
+ CE_DIR_FULL, // All root dir entry are taken
+ CE_DISK_FULL, // All clusters in partition are taken
+ CE_DIR_NOT_EMPTY, // This directory is not empty yet, remove files before deleting
+ CE_NONSUPPORTED_SIZE, // The disk is too big to format as FAT16
+ CE_WRITE_PROTECTED, // Card is write protected
+ CE_FILENOTOPENED, // File not opened for the write
+ CE_SEEK_ERROR, // File location could not be changed successfully
+ CE_BADCACHEREAD, // Bad cache read
+ CE_CARDFAT32, // FAT 32 - card not supported
+ CE_READONLY, // The file is read-only
+ CE_WRITEONLY, // The file is write-only
+ CE_INVALID_ARGUMENT, // Invalid argument
+ CE_TOO_MANY_FILES_OPEN // Too many files are already open
+} CETYPE;
+
+
+// Summary: A macro indicating a dir entry was found
+// Description: The FOUND macro indicates that a directory entry was found in the specified position
+#define FOUND 0
+
+// Summary: A macro indicating no dir entry was found
+// Description: The NOT_FOUND macro indicates that the specified directory entry to load was deleted
+#define NOT_FOUND 1
+
+// Summary: A macro indicating that no more files were found
+// Description: The NO_MORE macro indicates that there are no more directory entries to search for
+#define NO_MORE 2
+
+
+
+// Summary: A macro indicating the device is formatted with FAT12
+// Description: The FAT12 macro is used to indicate that the file system on the device being accessed is a FAT12 file system.
+#define FAT12 1
+
+// Summary: A macro indicating the device is formatted with FAT16
+// Description: The FAT16 macro is used to indicate that the file system on the device being accessed is a FAT16 file system.
+#define FAT16 2
+
+// Summary: A macro indicating the device is formatted with FAT32
+// Description: The FAT32 macro is used to indicate that the file system on the device being accessed is a FAT32 file system.
+#define FAT32 3
+
+
+
+// Summary: A read-only attribute macro
+// Description: A macro for the read-only attribute. A file with this attribute should not be written to. Note that this
+// attribute will not actually prevent a write to the file; that functionality is operating-system dependant. The
+// user should take care not to write to a read-only file.
+#define ATTR_READ_ONLY 0x01
+
+// Summary: A hidden attribute macro
+// Description: A macro for the hidden attribute. A file with this attribute may be hidden from the user, depending on the
+// implementation of the operating system.
+#define ATTR_HIDDEN 0x02
+
+// Summary: A system attribute macro
+// Description: A macro for the system attribute. A file with this attribute is used by the operating system, and should not be
+// modified. Note that this attribute will not actually prevent a write to the file.
+#define ATTR_SYSTEM 0x04
+
+// Summary: A volume attribute macro
+// Description: A macro for the volume attribute. If the first directory entry in the root directory has the volume attribute set,
+// the device will use the name in that directory entry as the volume name.
+#define ATTR_VOLUME 0x08
+
+// Summary: A macro for the attributes for a long-file name entry
+// Description: A macro for the long-name attributes. If a directory entry is used in a long-file name implementation, it will have
+// all four lower bits set. This indicates that any software that does not support long file names should ignore that
+// entry.
+#define ATTR_LONG_NAME 0x0f
+
+// Summary: A directory attribute macro
+// Description: A macro for the directory attribute. If a directory entry has this attribute set, the file it points to is a directory-
+// type file, and will contain directory entries that point to additional directories or files.
+#define ATTR_DIRECTORY 0x10
+
+// Summary: An archive attribute macro
+// Description: A macro for the archive attribute. This attribute will indicate to some archiving programs that the file with this
+// attribute needs to be backed up. Most operating systems create files with the archive attribute set.
+#define ATTR_ARCHIVE 0x20
+
+// Summary: A macro for all attributes
+// Description: A macro for all attributes. The search functions in this library require an argument that determines which attributes
+// a file is allowed to have in order to be found. If ATTR_MASK is specified as this argument, any file may be found, regardless
+// of its attributes.
+#define ATTR_MASK 0x3f
+
+
+
+// Summary: A macro to indicate an empty FAT entry
+// Description: The CLUSTER_EMPTY value is used to indicate that a FAT entry and it's corresponding cluster are available.
+#define CLUSTER_EMPTY 0x0000
+
+// Summary: A macro to indicate the last cluster value for FAT12
+// Description: The LAST_CLUSTER_FAT12 macro is used when reading the FAT to indicate that the next FAT12 entry for a file contains
+// the end-of-file value.
+#define LAST_CLUSTER_FAT12 0xff8
+
+// Summary: A macro to indicate the last cluster value for FAT16
+// Description: The LAST_CLUSTER_FAT16 macro is used when reading the FAT to indicate that the next FAT16 entry for a file contains
+// the end-of-file value.
+#define LAST_CLUSTER_FAT16 0xfff8
+
+// Summary: A macro to indicate the last allocatable cluster for FAT12
+// Description: The END_CLUSTER_FAT12 value is used as a comparison in FAT12 to determine that the firmware has reached the end of
+// the range of allowed allocatable clusters.
+#define END_CLUSTER_FAT12 0xFF7
+
+// Summary: A macro to indicate the last allocatable cluster for FAT16
+// Description: The END_CLUSTER_FAT16 value is used as a comparison in FAT16 to determine that the firmware has reached the end of
+// the range of allowed allocatable clusters.
+#define END_CLUSTER_FAT16 0xFFF7
+
+// Summary: A macro to indicate the failure of the ReadFAT function
+// Description: The CLUSTER_FAIL_FAT16 macro is used by the ReadFAT function to indicate that an error occured reading a FAT12 or FAT16
+// file allocation table. Note that since '0xFFF8' is used for the last cluster return value in the FAT16 implementation
+// the end-of-file value '0xFFFF' can be used to indicate an error condition.
+#define CLUSTER_FAIL_FAT16 0xFFFF
+
+
+
+#ifdef SUPPORT_FAT32
+ // Summary: A macro to indicate the last cluster value for FAT32
+ // Description: The LAST_CLUSTER_FAT32 macro is used when reading the FAT to indicate that the next FAT32 entry for a file contains
+ // the end-of-file value.
+ #define LAST_CLUSTER_FAT32 0x0FFFFFF8
+
+ // Summary: A macro to indicate the last allocatable cluster for FAT32
+ // Description: The END_CLUSTER_FAT32 value is used as a comparison in FAT32 to determine that the firmware has reached the end of
+ // the range of allowed allocatable clusters.
+ #define END_CLUSTER_FAT32 0x0FFFFFF7
+
+ // Summary: A macro to indicate the failure of the ReadFAT function
+ // Description: The CLUSTER_FAIL_FAT32 macro is used by the ReadFAT function to indicate that an error occured reading a FAT32
+ // file allocation able.
+ #define CLUSTER_FAIL_FAT32 0x0FFFFFFF
+
+#endif
+
+// Summary: A macro indicating the number of bytes in a directory entry.
+// Description: The NUMBER_OF_BYTES_IN_DIR_ENTRY macro represents the number of bytes in one directory entry. It is used to calculate
+// the number of sectors in the root directory based on information in the boot sector.
+#define NUMBER_OF_BYTES_IN_DIR_ENTRY 32
+
+
+
+// Summary: A macro for a deleted dir entry marker.
+// Description: The DIR_DEL macro is used to mark a directory entry as deleted. When a file is deleted, this value will replace the
+// first character in the file name, and will indicate that the file the entry points to was deleted.
+#define DIR_DEL 0xE5
+
+// Summary: A macro for the last dir entry marker.
+// Description: The DIR_EMPTY macro is used to indicate the last entry in a directory. Since entries in use cannot start with a 0 and
+// deleted entries start with the DIR_DEL character, a 0 will mark the end of the in-use or previously used group of
+// entries in a directory
+#define DIR_EMPTY 0
+
+
+
+// Summary: A macro used to indicate the length of an 8.3 file name
+// Description: The DIR_NAMESIZE macro is used when validing the name portion of 8.3 filenames
+#define DIR_NAMESIZE 8
+
+// Summary: A macro used to indicate the length of an 8.3 file extension
+// Description: The DIR_EXTENSION macro is used when validating the extension portion of 8.3 filenames
+#define DIR_EXTENSION 3
+
+// Summary: A macro used to indicate the length of an 8.3 file name and extension
+// Description: The DIR_NAMECOMP macro is used when validating 8.3 filenames
+#define DIR_NAMECOMP (DIR_NAMESIZE+DIR_EXTENSION)
+
+
+
+// Summary: A macro to write a byte to RAM
+// Description: The RAMwrite macro is used to write a byte of data to a RAM array
+#define RAMwrite( a, f, d) *(a+f) = d
+
+// Summary: A macro to read a byte from RAM
+// Description: The RAMread macro is used to read a byte of data from a RAM array
+#define RAMread( a, f) *(a+f)
+
+// Summary: A macro to read a 16-bit word from RAM
+// Description: The RAMreadW macro is used to read two bytes of data from a RAM array
+#define RAMreadW( a, f) *(WORD *)(a+f)
+
+// Summary: A macro to read a 32-bit word from RAM
+// Description: The RAMreadD macro is used to read four bytes of data from a RAM array
+#define RAMreadD( a, f) *(DWORD *)(a+f)
+
+
+
+#ifndef EOF
+ // Summary: Indicates error conditions or end-of-file conditions
+ // Description: The EOF macro is used to indicate error conditions in some function calls. It is also used to indicate
+ // that the end-of-file has been reached.
+ #define EOF ((int)-1)
+#endif
+
+
+
+// Summary: A structure containing information about the device.
+// Description: The DISK structure contains information about the device being accessed.
+typedef struct
+{
+ BYTE * buffer; // Address of the global data buffer used to read and write file information
+ DWORD firsts; // Logical block address of the first sector of the FAT partition on the device
+ DWORD fat; // Logical block address of the FAT
+ DWORD root; // Logical block address of the root directory
+ DWORD data; // Logical block address of the data section of the device.
+ WORD maxroot; // The maximum number of entries in the root directory.
+ DWORD maxcls; // The maximum number of clusters in the partition.
+ WORD fatsize; // The number of sectors in the FAT
+ BYTE fatcopy; // The number of copies of the FAT in the partition
+ BYTE SecPerClus; // The number of sectors per cluster in the data region
+ BYTE type; // The file system type of the partition (FAT12, FAT16 or FAT32)
+ BYTE mount; // Device mount flag (TRUE if disk was mounted successfully, FALSE otherwise)
+#ifdef __PIC32MX__
+} __attribute__ ((packed)) DISK;
+#else
+} DISK;
+#endif
+
+
+#ifdef __18CXX
+ // Summary: A 24-bit data type
+ // Description: The SWORD macro is used to defined a 24-bit data type. For 16+ bit architectures, this must be represented as
+ // an array of three bytes.
+ typedef unsigned short long SWORD;
+#else
+ // Summary: A 24-bit data type
+ // Description: The SWORD macro is used to defined a 24-bit data type. For 16+ bit architectures, this must be represented as
+ // an array of three bytes.
+ typedef struct
+ {
+ unsigned char array[3];
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) SWORD;
+#else
+ } SWORD;
+#endif
+#endif
+
+
+
+// Summary: A structure containing the bios parameter block for a FAT12 file system (in the boot sector)
+// Description: The _BPB_FAT12 structure provides a layout of the "bios parameter block" in the boot sector of a FAT12 partition.
+typedef struct {
+ SWORD BootSec_JumpCmd; // Jump Command
+ BYTE BootSec_OEMName[8]; // OEM name
+ WORD BootSec_BPS; // Number of bytes per sector
+ BYTE BootSec_SPC; // Number of sectors per cluster
+ WORD BootSec_ResrvSec; // Number of reserved sectors at the beginning of the partition
+ BYTE BootSec_FATCount; // Number of FATs on the partition
+ WORD BootSec_RootDirEnts; // Number of root directory entries
+ WORD BootSec_TotSec16; // Total number of sectors
+ BYTE BootSec_MDesc; // Media descriptor
+ WORD BootSec_SPF; // Number of sectors per FAT
+ WORD BootSec_SPT; // Number of sectors per track
+ WORD BootSec_HeadCnt; // Number of heads
+ DWORD BootSec_HiddenSecCnt; // Number of hidden sectors
+ DWORD BootSec_Reserved; // Reserved space
+ BYTE BootSec_DriveNum; // Drive number
+ BYTE BootSec_Reserved2; // Reserved space
+ BYTE BootSec_BootSig; // Boot signature - equal to 0x29
+ BYTE BootSec_VolID[4]; // Volume ID
+ BYTE BootSec_VolLabel[11]; // Volume Label
+ BYTE BootSec_FSType[8]; // File system type in ASCII. Not used for determination
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) _BPB_FAT12;
+#else
+ } _BPB_FAT12;
+#endif
+
+// Summary: A structure containing the bios parameter block for a FAT16 file system (in the boot sector)
+// Description: The _BPB_FAT16 structure provides a layout of the "bios parameter block" in the boot sector of a FAT16 partition.
+typedef struct {
+ SWORD BootSec_JumpCmd; // Jump Command
+ BYTE BootSec_OEMName[8]; // OEM name
+ WORD BootSec_BPS; // Number of bytes per sector
+ BYTE BootSec_SPC; // Number of sectors per cluster
+ WORD BootSec_ResrvSec; // Number of reserved sectors at the beginning of the partition
+ BYTE BootSec_FATCount; // Number of FATs on the partition
+ WORD BootSec_RootDirEnts; // Number of root directory entries
+ WORD BootSec_TotSec16; // Total number of sectors
+ BYTE BootSec_MDesc; // Media descriptor
+ WORD BootSec_SPF; // Number of sectors per FAT
+ WORD BootSec_SPT; // Number of sectors per track
+ WORD BootSec_HeadCnt; // Number of heads
+ DWORD BootSec_HiddenSecCnt; // Number of hidden sectors
+ DWORD BootSec_TotSec32; // Total sector count (32 bits)
+ BYTE BootSec_DriveNum; // Drive number
+ BYTE BootSec_Reserved; // Reserved space
+ BYTE BootSec_BootSig; // Boot signature - equal to 0x29
+ BYTE BootSec_VolID[4]; // Volume ID
+ BYTE BootSec_VolLabel[11]; // Volume Label
+ BYTE BootSec_FSType[8]; // File system type in ASCII. Not used for determination
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) _BPB_FAT16;
+#else
+ } _BPB_FAT16;
+#endif
+
+// Summary: A structure containing the bios parameter block for a FAT32 file system (in the boot sector)
+// Description: The _BPB_FAT32 structure provides a layout of the "bios parameter block" in the boot sector of a FAT32 partition.
+typedef struct {
+ SWORD BootSec_jmpBoot; // Jump Command
+ BYTE BootSec_OEMName[8]; // OEM name
+ WORD BootSec_BytsPerSec; // Number of bytes per sector
+ BYTE BootSec_SecPerClus; // Number of sectors per cluster
+ WORD BootSec_RsvdSecCnt; // Number of reserved sectors at the beginning of the partition
+ BYTE BootSec_NumFATs; // Number of FATs on the partition
+ WORD BootSec_RootEntCnt; // Number of root directory entries
+ WORD BootSec_TotSec16; // Total number of sectors
+ BYTE BootSec_Media; // Media descriptor
+ WORD BootSec_FATSz16; // Number of sectors per FAT
+ WORD BootSec_SecPerTrk; // Number of sectors per track
+ WORD BootSec_NumHeads; // Number of heads
+ DWORD BootSec_HiddSec; // Number of hidden sectors
+ DWORD BootSec_TotSec32; // Total sector count (32 bits)
+ DWORD BootSec_FATSz32; // Sectors per FAT (32 bits)
+ WORD BootSec_ExtFlags; // Presently active FAT. Defined by bits 0-3 if bit 7 is 1.
+ WORD BootSec_FSVers; // FAT32 filesystem version. Should be 0:0
+ DWORD BootSec_RootClus; // Start cluster of the root directory (should be 2)
+ WORD BootSec_FSInfo; // File system information
+ WORD BootSec_BkBootSec; // Backup boot sector address.
+ BYTE BootSec_Reserved[12]; // Reserved space
+ BYTE BootSec_DrvNum; // Drive number
+ BYTE BootSec_Reserved1; // Reserved space
+ BYTE BootSec_BootSig; // Boot signature - 0x29
+ BYTE BootSec_VolID[4]; // Volume ID
+ BYTE BootSec_VolLab[11]; // Volume Label
+ BYTE BootSec_FilSysType[8]; // File system type in ASCII. Not used for determination
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) _BPB_FAT32;
+#else
+ } _BPB_FAT32;
+#endif
+
+
+// Description: A macro for the boot sector bytes per sector value offset
+#define BSI_BPS 11
+
+// Description: A macro for the boot sector sector per cluster value offset
+#define BSI_SPC 13
+
+// Description: A macro for the boot sector reserved sector count value offset
+#define BSI_RESRVSEC 14
+
+// Description: A macro for the boot sector FAT count value offset
+#define BSI_FATCOUNT 16
+
+// Description: A macro for the boot sector root directory entry count value offset
+#define BSI_ROOTDIRENTS 17
+
+// Description: A macro for the boot sector 16-bit total sector count value offset
+#define BSI_TOTSEC16 19
+
+// Description: A macro for the boot sector sectors per FAT value offset
+#define BSI_SPF 22
+
+// Description: A macro for the boot sector 32-bit total sector count value offset
+#define BSI_TOTSEC32 32
+
+// Description: A macro for the boot sector boot signature offset
+#define BSI_BOOTSIG 38
+
+// Description: A macro for the boot sector file system type string offset
+#define BSI_FSTYPE 54
+
+// Description: A macro for the boot sector 32-bit sector per FAT value offset
+#define BSI_FATSZ32 36
+
+// Description: A macro for the boot sector start cluster of root directory value offset
+#define BSI_ROOTCLUS 44
+
+// Description: A macro for the FAT32 boot sector boot signature offset
+#define BSI_FAT32_BOOTSIG 66
+
+// Description: A macro for the FAT32 boot sector file system type string offset
+#define BSI_FAT32_FSTYPE 82
+
+
+
+// Summary: A partition table entry structure.
+// Description: The PTE_MBR structure contains values found in a partition table entry in the MBR of a device.
+typedef struct
+{
+ BYTE PTE_BootDes; // The boot descriptor (should be 0x00 in a non-bootable device)
+ SWORD PTE_FrstPartSect; // The cylinder-head-sector address of the first sector of the partition
+ BYTE PTE_FSDesc; // The file system descriptor
+ SWORD PTE_LstPartSect; // The cylinder-head-sector address of the last sector of the partition
+ DWORD PTE_FrstSect; // The logical block address of the first sector of the partition
+ DWORD PTE_NumSect; // The number of sectors in a partition
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) PTE_MBR;
+#else
+ } PTE_MBR;
+#endif
+
+
+// Summary: A structure of the organization of a master boot record.
+// Description: The _PT_MBR structure has the same form as a master boot record. When the MBR is loaded from the device, it will
+// be cast as a _PT_MBR structure so the MBR elements can be accessed.
+typedef struct
+{
+ BYTE ConsChkRtn[446]; // Boot code
+ PTE_MBR Partition0; // The first partition table entry
+ PTE_MBR Partition1; // The second partition table entry
+ PTE_MBR Partition2; // The third partition table entry
+ PTE_MBR Partition3; // The fourth partition table entry
+ BYTE Signature0; // MBR signature code - equal to 0x55
+ BYTE Signature1; // MBR signature code - equal to 0xAA
+#ifdef __18CXX
+}_PT_MBR;
+#else
+}__attribute__((packed)) _PT_MBR;
+#endif
+
+// Summary: A pointer to a _PT_MBR structure
+// Description: The PT_MBR pointer points to a _PT_MBR structure.
+typedef _PT_MBR * PT_MBR;
+
+
+
+// Summary: A structure of the organization of a boot sector.
+// Description: The _BootSec structure has the same form as a boot sector. When the boot sector is loaded from the device, it will
+// be cast as a _BootSec structure so the boot sector elements can be accessed.
+typedef struct
+{
+ // A union of different bios parameter blocks
+ union
+ {
+ _BPB_FAT32 FAT_32;
+ _BPB_FAT16 FAT_16;
+ _BPB_FAT12 FAT_12;
+ }FAT;
+ BYTE Reserved[MEDIA_SECTOR_SIZE-sizeof(_BPB_FAT32)-2]; // Reserved space
+ BYTE Signature0; // Boot sector signature code - equal to 0x55
+ BYTE Signature1; // Boot sector signature code - equal to 0xAA
+#ifdef __PIC32MX__
+ } __attribute__ ((packed)) _BootSec;
+#else
+ } _BootSec;
+#endif
+
+// Summary: A pointer to a _BootSec structure
+// Description: The BootSec pointer points to a _BootSec structure.
+typedef _BootSec * BootSec;
+
+
+
+// Summary: A macro indicating the offset for the master boot record
+// Description: FO_MBR is a macro that indicates the addresss of the master boot record on the device. When the device is initialized
+// this sector will be read
+#define FO_MBR 0L
+
+
+
+// Summary: A macro for the first boot sector/MBR signature byte
+// Description: The FAT_GOOD_SIGN_0 macro is used to determine that the first byte of the MBR or boot sector signature code is correct
+#define FAT_GOOD_SIGN_0 0x55
+
+// Summary: A macro for the second boot sector/MBR signature byte
+// Description: The FAT_GOOD_SIGN_1 macro is used to determine that the second byte of the MBR or boot sector signature code is correct
+#define FAT_GOOD_SIGN_1 0xAA
+
+
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.c b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.c new file mode 100644 index 00000000..6a42c66b --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.c @@ -0,0 +1,8874 @@ +/******************************************************************************
+*
+* Microchip Memory Disk Drive File System
+*
+******************************************************************************
+* FileName: FSIO.c
+* Dependencies: GenericTypeDefs.h
+* FSIO.h
+* Physical interface include file (SD-SPI.h, CF-PMP.h, ...)
+* string.h
+* stdlib.h
+* FSDefs.h
+* ctype.h
+* salloc.h
+* Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+* Compiler: C18/C30/C32
+* Company: Microchip Technology, Inc.
+* Version: 1.2.0
+*
+* Software License Agreement
+*
+* The software supplied herewith by Microchip Technology Incorporated
+* (the �Company�) for its PICmicro� Microcontroller is intended and
+* supplied to you, the Company�s customer, for use solely and
+* exclusively on Microchip PICmicro Microcontroller products. The
+* software is owned by the Company and/or its supplier, and is
+* protected under applicable copyright laws. All rights are reserved.
+* Any use in violation of the foregoing restrictions may subject the
+* user to criminal sanctions under applicable laws, as well as to
+* civil liability for the breach of the terms and conditions of this
+* license.
+*
+* THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+*
+*****************************************************************************/
+
+#include "FSIO.h"
+#include "GenericTypeDefs.h"
+#include "string.h"
+#include "stdlib.h"
+#include "ctype.h"
+#include "MDD File System\FSDefs.h"
+
+#ifdef ALLOW_FSFPRINTF
+#include "stdarg.h"
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ #ifdef __18CXX
+ #include "salloc.h"
+ #endif
+#endif
+
+#ifndef ALLOW_WRITES
+ #ifdef ALLOW_FORMATS
+ #error Write functions must be enabled to use the format function
+ #endif
+ #ifdef ALLOW_FSFPRINTF
+ #error Write functions must be enabled to use the FSfprintf function
+ #endif
+#endif
+
+#ifdef USEREALTIMECLOCK
+ #ifdef USERDEFINEDCLOCK
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#elif defined USERDEFINEDCLOCK
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#endif
+/*****************************************************************************/
+/* Global Variables */
+/*****************************************************************************/
+
+#ifndef FS_DYNAMIC_MEM
+ FSFILE gFileArray[FS_MAX_FILES_OPEN]; // Array that contains file information (static allocation)
+ BYTE gFileSlotOpen[FS_MAX_FILES_OPEN]; // Array that indicates which elements of gFileArray are available for use
+#endif
+
+DWORD gLastFATSectorRead = 0xFFFF; // Global variable indicating which FAT sector was read last
+BYTE gNeedFATWrite = FALSE; // Global variable indicating that there is information that needs to be written to the FAT
+FSFILE * gBufferOwner = NULL; // Global variable indicating which file is using the data buffer
+DWORD gLastDataSectorRead = 0xFFFFFFFF; // Global variable indicating which data sector was read last
+BYTE gNeedDataWrite = FALSE; // Global variable indicating that there is information that needs to be written to the data section
+BYTE nextClusterIsLast = FALSE; // Global variable indicating that the entries in a directory align with a cluster boundary
+
+// Timing variables
+BYTE gTimeCrtMS; // Global time variable (for timestamps) used to indicate create time (milliseconds)
+WORD gTimeCrtTime; // Global time variable (for timestamps) used to indicate create time
+WORD gTimeCrtDate; // Global time variable (for timestamps) used to indicate create date
+WORD gTimeAccDate; // Global time variable (for timestamps) used to indicate last access date
+WORD gTimeWrtTime; // Global time variable (for timestamps) used to indicate last update time
+WORD gTimeWrtDate; // Global time variable (for timestamps) used to indicate last update date
+
+BYTE gBufferZeroed = FALSE; // Global variable indicating that the data buffer contains all zeros
+
+DWORD FatRootDirClusterValue; // Global variable containing the cluster number of the root dir (0 for FAT12/16)
+
+BYTE FSerrno; // Global error variable. Set to one of many error codes after each function call.
+
+DWORD TempClusterCalc; // Global variable used to store the calculated value of the cluster of a specified sector.
+BYTE dirCleared; // Global variable used by the "recursive" FSrmdir function to indicate that all subdirectories and files have been deleted from the target directory.
+BYTE recache = FALSE; // Global variable used by the "recursive" FSrmdir function to indicate that additional cache reads are needed.
+FSFILE tempCWDobj; // Global variable used to preserve the current working directory information.
+FSFILE gFileTemp; // Global variable used for file operations.
+
+#ifdef ALLOW_DIRS
+ FSFILE cwd; // Global current working directory
+ FSFILE * cwdptr = &cwd; // Pointer to the current working directory
+#endif
+
+
+#ifdef __18CXX
+ #pragma udata dataBuffer
+ BYTE gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ #pragma udata FATBuffer
+ BYTE gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE __attribute__ ((aligned(4))) gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ BYTE __attribute__ ((aligned(4))) gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+
+#pragma udata
+
+DISK gDiskData; // Global structure containing device information.
+
+
+
+/************************************************************************/
+/* Structures and defines */
+/************************************************************************/
+
+// Directory entry structure
+typedef struct
+{
+ char DIR_Name[DIR_NAMESIZE]; // File name
+ char DIR_Extension[DIR_EXTENSION]; // File extension
+ BYTE DIR_Attr; // File attributes
+ BYTE DIR_NTRes; // Reserved byte
+ BYTE DIR_CrtTimeTenth; // Create time (millisecond field)
+ WORD DIR_CrtTime; // Create time (second, minute, hour field)
+ WORD DIR_CrtDate; // Create date
+ WORD DIR_LstAccDate; // Last access date
+ WORD DIR_FstClusHI; // High word of the entry's first cluster number
+ WORD DIR_WrtTime; // Last update time
+ WORD DIR_WrtDate; // Last update date
+ WORD DIR_FstClusLO; // Low word of the entry's first cluster number
+ DWORD DIR_FileSize; // The 32-bit file size
+}_DIRENTRY;
+
+typedef _DIRENTRY * DIRENTRY; // A pointer to a directory entry structure
+
+#define DIRECTORY 0x12 // Value indicating that the CreateFileEntry function will be creating a directory
+
+#define DIRENTRIES_PER_SECTOR (MEDIA_SECTOR_SIZE / 32) // The number of directory entries in a sector
+
+// internal errors
+#define CE_FAT_EOF 60 // Error that indicates an attempt to read FAT entries beyond the end of the file
+#define CE_EOF 61 // Error that indicates that the end of the file has been reached
+
+typedef FSFILE * FILEOBJ; // Pointer to an FSFILE object
+
+#ifdef ALLOW_FSFPRINTF
+
+#define _FLAG_MINUS 0x1 // FSfprintf minus flag indicator
+#define _FLAG_PLUS 0x2 // FSfprintf plus flag indicator
+#define _FLAG_SPACE 0x4 // FSfprintf space flag indicator
+#define _FLAG_OCTO 0x8 // FSfprintf octothorpe (hash mark) flag indicator
+#define _FLAG_ZERO 0x10 // FSfprintf zero flag indicator
+#define _FLAG_SIGNED 0x80 // FSfprintf signed flag indicator
+
+#ifdef __18CXX
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONG 1 // FSfprintf 32-bit argument size flag
+ #define _FMT_SHRTLONG 2 // FSfprintf 24-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#else
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONGLONG 1 // FSfprintf 64-bit argument size flag
+ #define _FMT_LONG 2 // FSfprintf 32-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#endif
+
+#ifdef __18CXX
+ static const rom char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#else
+ static const char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#endif
+
+#endif
+
+/************************************************************************************/
+/* Prototypes */
+/************************************************************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls);
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead);
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle);
+DWORD Cluster2Sector(DISK * disk, DWORD cluster);
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle);
+#ifdef INCREMENTTIMESTAMP
+ void IncrementTimeStamp(DIRENTRY dir);
+#elif defined USEREALTIMECLOCK
+ void CacheTime (void);
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE ReadByte( BYTE* pBuffer, WORD index );
+ WORD ReadWord( BYTE* pBuffer, WORD index );
+ DWORD ReadDWord( BYTE* pBuffer, WORD index );
+#endif
+
+// Function pointer that points to a physical layer's MDD_xxxxx_WriteProtectState function
+extern BYTE MDD_WriteProtectState(void);
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource);
+BYTE ValidateChars (char * FileName, BYTE mode);
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode);
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode);
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n);
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type);
+
+// Write functions
+#ifdef ALLOW_WRITES
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry);
+ BYTE flushData (void);
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters);
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode);
+ BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk);
+ DWORD FATfindEmptyCluster(FILEOBJ fo);
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle);
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode);
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster);
+ BYTE EraseCluster(DISK *disk, DWORD cluster);
+ CETYPE CreateFirstCluster(FILEOBJ fo);
+ DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite);
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode);
+#endif
+
+// Directory functions
+#ifdef ALLOW_DIRS
+ BYTE GetPreviousEntry (FSFILE * fo);
+ BYTE FormatDirName (char * string, BYTE mode);
+ int CreateDIR (char * path);
+ BYTE writeDotEntries (DISK * dsk, DWORD dotAddress, DWORD dotdotAddress);
+ int eraseDir (char * path);
+#ifdef ALLOW_PGMFUNCTIONS
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs);
+ #endif
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+#else
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs);
+ #endif
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+#endif
+#endif
+
+#ifdef ALLOW_FSFPRINTF
+ #ifdef __18CXX
+ int FSvfprintf (auto FSFILE *handle, auto const rom char *formatString, auto va_list ap);
+ #else
+ int FSvfprintf (FSFILE *handle, const char *formatString, va_list ap);
+ #endif
+ int FSputc (char c, FSFILE * file);
+ unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c);
+#endif
+
+BYTE DISKmount( DISK *dsk);
+BYTE LoadMBR(DISK *dsk);
+BYTE LoadBootSector(DISK *dsk);
+DWORD GetFullClusterNumber(DIRENTRY entry);
+
+
+/*************************************************************************
+ Function:
+ int FSInit(void)
+ Summary:
+ Function to initialize the device.
+ Conditions:
+ The physical device should be connected to the microcontroller.
+ Input:
+ None
+ Return Values:
+ TRUE - Initialization successful
+ FALSE - Initialization unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Initializes the static or dynamic memory slots for holding file
+ structures. Initializes the device with the DISKmount function. Loads
+ MBR and boot sector information. Initializes the current working
+ directory to the root directory for the device if directory support
+ is enabled.
+ Remarks:
+ None
+ *************************************************************************/
+
+int FSInit(void)
+{
+ int fIndex;
+#ifndef FS_DYNAMIC_MEM
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ gFileSlotOpen[fIndex] = TRUE;
+#else
+ #ifdef __18CXX
+ SRAMInitHeap();
+ #endif
+#endif
+
+ gBufferZeroed = FALSE;
+
+ MDD_InitIO();
+
+ if(DISKmount(&gDiskData) == CE_GOOD)
+ {
+ // Initialize the current working directory to the root
+#ifdef ALLOW_DIRS
+ cwdptr->dsk = &gDiskData;
+ cwdptr->sec = 0;
+ cwdptr->pos = 0;
+ cwdptr->seek = 0;
+ cwdptr->size = 0;
+ cwdptr->name[0] = '\\';
+ for (fIndex = 1; fIndex < 11; fIndex++)
+ {
+ cwdptr->name[fIndex] = 0x20;
+ }
+ cwdptr->entry = 0;
+ cwdptr->attributes = ATTR_DIRECTORY;
+ // "FatRootDirClusterValue" indicates the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+#endif
+
+ FSerrno = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/********************************************************************************
+ Function:
+ CETYPE FILEfind (FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+ Summary
+ Finds a file on the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - FSFILE object containing information of the file found
+ foCompareTo - FSFILE object containing the name/attr of the file to be
+ found
+ cmd -
+ - LOOK_FOR_EMPTY_ENTRY: Search for empty entry.
+ - LOOK_FOR_MATCHING_ENTRY: Search for matching entry.
+ mode -
+ - 0: Match file exactly with default attributes.
+ - 1: Match file to user-specified attributes.
+ Return Values:
+ CE_GOOD - File found.
+ CE_FILE_NOT_FOUND - File not found.
+ Side Effects:
+ None.
+ Description:
+ The FILEfind function will sequentially cache directory entries within
+ the current working directory into the foDest FSFILE object. If the cmd
+ parameter is specified as LOOK_FOR_EMPTY_ENTRY the search will continue
+ until an empty directory entry is found. If the cmd parameter is specified
+ as LOOK_FOR_MATCHING_ENTRY these entries will be compared to the foCompareTo
+ object until a match is found or there are no more entries in the current
+ working directory. If the mode is specified a '0' the attributes of the FSFILE
+ entries are irrelevant. If the mode is specified as '1' the attributes of the
+ foDest entry must match the attributes specified in the foCompareTo file and
+ partial string search characters may bypass portions of the comparison.
+ Remarks:
+ None
+ ********************************************************************************/
+
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+{
+ WORD attrib, compareAttrib;
+ WORD fHandle = foDest->entry; // current entry counter
+ BYTE state,index; // state of the current object
+ CETYPE statusB = CE_FILE_NOT_FOUND;
+ BYTE character,test;
+
+ // reset the cluster
+ foDest->dirccls = foDest->dirclus;
+ compareAttrib = 0xFFFF ^ foCompareTo->attributes; // Attribute to be compared as per application layer request
+
+ if (fHandle == 0)
+ {
+ if (Cache_File_Entry(foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ if ((fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) != 0) // Maximum 16 entries possible
+ {
+ if (Cache_File_Entry (foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ if (statusB != CE_BADCACHEREAD)
+ {
+ // Loop until you reach the end or find the file
+ while(1)
+ {
+ if(statusB!=CE_GOOD) //First time entry always here
+ {
+ state = Fill_File_Object(foDest, &fHandle);
+ if(state == NO_MORE) // Reached the end of available files. Comparision over and file not found so quit.
+ {
+ break;
+ }
+ }
+ else // statusB == CE_GOOD then exit
+ {
+ break; // Code below intializes"statusB = CE_GOOD;" so, if no problem in the filled file, Exit the while loop.
+ }
+
+ if(state == FOUND) // Validate the correct matching of filled file data with the required(to be found) one.
+ {
+ /* We got something */
+ // get the attributes
+ attrib = foDest->attributes;
+
+ attrib &= ATTR_MASK;
+ switch (mode)
+ {
+ case 0:
+ // see if we are a volume id or hidden, ignore
+ if(attrib != ATTR_VOLUME)
+ {
+ statusB = CE_GOOD;
+ character = (BYTE)'m'; // random value
+
+ // search for one. if status = TRUE we found one
+ for(index = 0; index < DIR_NAMECOMP; index++)
+ {
+ // get the source character
+ character = foDest->name[index];
+ // get the destination character
+ test = foCompareTo->name[index];
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // Nope its not a match
+ break;
+ }
+ }// for loop
+ } // not dir nor vol
+ break;
+
+ case 1:
+ // Check for attribute match
+ if (((attrib & compareAttrib) == 0) && (attrib != ATTR_LONG_NAME))
+ {
+ statusB = CE_GOOD; // Indicate the already filled file data is correct and go back
+ character = (BYTE)'m'; // random value
+ if (foCompareTo->name[0] != '*') //If "*" is passed for comparion as 1st char then don't proceed. Go back, file alreay found.
+ {
+ for (index = 0; index < DIR_NAMESIZE; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ // Before calling this "FILEfind" fn, "formatfilename" must be called. Hence, extn always starts from position "8".
+ if ((foCompareTo->name[8] != '*') && (statusB == CE_GOOD))
+ {
+ for (index = 8; index < DIR_NAMECOMP; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ } // Attribute match
+
+ break;
+ }
+ } // not found
+ else
+ {
+ /*** looking for an empty/re-usable entry ***/
+ if ( cmd == LOOK_FOR_EMPTY_ENTRY)
+ statusB = CE_GOOD;
+ } // found or not
+
+ // increment it no matter what happened
+ fHandle++;
+
+ }// while
+ }
+
+ return(statusB);
+} // FILEFind
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+ Summary:
+ Loads file information from the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File to be opened
+ fHandle - Location of file
+ type -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ Return Values:
+ CE_GOOD - FILEopen successful
+ CE_NOT_INIT - Device is not yet initialized
+ CE_FILE_NOT_FOUND - Could not find the file on the device
+ CE_BAD_SECTOR_READ - A bad read of a sector occured
+ Side Effects:
+ None
+ Description:
+ This function will cache a directory entry in the directory specified
+ by the dirclus parameter of hte FSFILE object 'fo.' The offset of the
+ entry in the directory is specified by fHandle. Once the directory entry
+ has been loaded, the first sector of the file can be loaded using the
+ cluster value specified in the directory entry. The type argument will
+ specify the mode the files will be opened in. This will allow this
+ function to set the correct read/write flags for the file.
+ Remarks:
+ If the mode the file is being opened in is a plus mode (e.g. READ+) the
+ flags will be modified further in the FSfopen function.
+ **************************************************************************/
+
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+{
+ DISK *dsk; //Disk structure
+ BYTE r; //Result of search for file
+ DWORD l; //lba of first sector of first cluster
+ CETYPE error = CE_GOOD;
+
+ dsk = (DISK *)(fo->dsk);
+ if (dsk->mount == FALSE)
+ {
+ error = CE_NOT_INIT;
+ }
+ else
+ {
+ // load the sector
+ fo->dirccls = fo->dirclus;
+ // Cache no matter what if it's the first entry
+ if (*fHandle == 0)
+ {
+ if (Cache_File_Entry(fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ // If it's not the first, only cache it if it's
+ // not divisible by the number of entries per sector
+ // If it is, Fill_File_Object will cache it
+ if ((*fHandle & 0xf) != 0)
+ {
+ if (Cache_File_Entry (fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ r = Fill_File_Object(fo, fHandle);
+ if (r != FOUND)
+ error = CE_FILE_NOT_FOUND;
+ else
+ {
+ fo->seek = 0; // first byte in file
+ fo->ccls = fo->cluster; // first cluster
+ fo->sec = 0; // first sector in the cluster
+ fo->pos = 0; // first byte in sector/cluster
+
+ if ( r == NOT_FOUND)
+ {
+ error = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Determine the lba of the selected sector and load
+ l = Cluster2Sector(dsk,fo->ccls);
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+#endif
+ gBufferOwner = fo;
+ if (gLastDataSectorRead != l)
+ {
+ gBufferZeroed = FALSE;
+ if ( !MDD_SectorRead( l, dsk->buffer))
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = l;
+ }
+ } // -- found
+
+ fo->flags.FileWriteEOF = FALSE;
+ // Set flag for operation type
+#ifdef ALLOW_WRITES
+ if (type == 'w' || type == 'a')
+ {
+ fo->flags.write = 1; //write or append
+ fo->flags.read = 0;
+ }
+ else
+ {
+#endif
+ fo->flags.write = 0; //read
+ fo->flags.read = 1;
+#ifdef ALLOW_WRITES
+ } // -- flags
+#endif
+ } // -- r = Found
+ } // -- Mounted
+ return (error);
+} // -- FILEopen
+
+
+/*************************************************************************
+ Function:
+ BYTE FILEget_next_cluster(FILEOBJ fo, WORD n)
+ Summary:
+ Step through a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file to get the next cluster of
+ n - Number of links in the FAT cluster chain to jump through
+ Return Values:
+ CE_GOOD - Operation successful
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_INVALID_CLUSTER - Invalid cluster value \> maxcls
+ CE_FAT_EOF - Fat attempt to read beyond EOF
+ Side Effects:
+ None
+ Description:
+ This function will load 'n' proximate clusters for a file from
+ the FAT on the device. It will stop checking for clusters if the
+ ReadFAT function returns an error, if it reaches the last cluster in
+ a file, or if the device tries to read beyond the last cluster used
+ by the device.
+ Remarks:
+ None
+ *************************************************************************/
+
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n)
+{
+ DWORD c, c2, ClusterFailValue, LastClustervalue;
+ BYTE error = CE_GOOD;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ LastClustervalue = LAST_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT12:
+ LastClustervalue = LAST_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT16:
+ default:
+ LastClustervalue = LAST_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // loop n times
+ do
+ {
+ // get the next cluster link from FAT
+ c2 = fo->ccls;
+ if ( (c = ReadFAT( disk, c2)) == ClusterFailValue)
+ error = CE_BAD_SECTOR_READ;
+ else
+ {
+ // check if cluster value is valid
+ if ( c >= disk->maxcls)
+ {
+ error = CE_INVALID_CLUSTER;
+ }
+
+ // compare against max value of a cluster in FAT
+ // return if eof
+ if ( c >= LastClustervalue) // check against eof
+ {
+ error = CE_FAT_EOF;
+ }
+ }
+
+ // update the FSFILE structure
+ fo->ccls = c;
+
+ } while (--n > 0 && error == CE_GOOD);// loop end
+
+ return(error);
+} // get next cluster
+
+
+/**************************************************************************
+ Function:
+ BYTE DISKmount ( DISK *dsk)
+ Summary:
+ Initialies the device and loads MBR and boot sector information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure to be initialized.
+ Return Values:
+ CE_GOOD - Disk mounted
+ CE_INIT_ERROR - Initialization error has occured
+ Side Effects:
+ None
+ Description:
+ This function will use the function pointed to by the MDD_MediaInitialize
+ function pointer to initialize the device (if any initialization is
+ required). It then attempts to load the master boot record with the
+ LoadMBR function and the boot sector with the LoadBootSector function.
+ These two functions will be used to initialize a global DISK structure
+ that will be used when accessing file information in the future.
+ Remarks:
+ None
+ **************************************************************************/
+
+BYTE DISKmount( DISK *dsk)
+{
+ BYTE error = CE_GOOD;
+
+ dsk->mount = FALSE; // default invalid
+ dsk->buffer = gDataBuffer; // assign buffer
+
+ // Initialize the device
+ if(MDD_MediaInitialize() != TRUE)
+ {
+ error = CE_INIT_ERROR;
+ FSerrno = CE_INIT_ERROR;
+ }
+ else
+ {
+ // Load the Master Boot Record (partition)
+ if((error = LoadMBR(dsk)) == CE_GOOD)
+ {
+ // Now the boot sector
+ if((error = LoadBootSector(dsk)) == CE_GOOD)
+ dsk->mount = TRUE; // Mark that the DISK mounted successfully
+ }
+ } // -- Load file parameters
+
+ return(error);
+} // -- mount
+
+
+
+/********************************************************************
+ Function:
+ CETYPE LoadMBR ( DISK *dsk)
+ Summary:
+ Loads the MBR and extracts necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the master boot record to be loaded
+ Return Values:
+ CE_GOOD - MBR loaded successfully
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_BAD_PARTITION - The boot record is bad
+ Side Effects:
+ None
+ Description:
+ The LoadMBR function will use the function pointed to by the
+ MDD_SectorRead function pointer to read the 0 sector from the
+ device. If a valid boot signature is obtained, this function
+ will compare fields in that cached sector to the values that
+ would be present if that sector was a boot sector. If all of
+ those values match, it will be assumed that the device does not
+ have a master boot record and the 0 sector is actually the boot
+ sector. Otherwise, data about the partition and the actual
+ location of the boot sector will be loaded from the MBR into
+ the DISK structure pointed to by 'dsk.'
+ Remarks:
+ None
+ ********************************************************************/
+
+BYTE LoadMBR(DISK *dsk)
+{
+ PT_MBR Partition;
+ BYTE error = CE_GOOD;
+ BYTE type;
+ BootSec BSec;
+
+ // Get the partition table from the MBR
+ if ( MDD_SectorRead( FO_MBR, dsk->buffer) != TRUE)
+ {
+ error = CE_BAD_SECTOR_READ;
+ FSerrno = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ // Check if the card has no MBR
+ BSec = (BootSec) dsk->buffer;
+
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( dsk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT16;
+ return CE_GOOD;
+ }
+ else
+ {
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FAT32_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 3 ) == '3' && \
+ ReadByte( dsk->buffer, BSI_FAT32_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_32.BootSec_FilSysType[0] == 'F' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[1] == 'A' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[2] == 'T' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[3] == '3' && \
+ BSec->FAT.FAT_32.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT32;
+ return CE_GOOD;
+ }
+ }
+ }
+ // assign it the partition table strucutre
+ Partition = (PT_MBR)dsk->buffer;
+
+ // Ensure its good
+ if((Partition->Signature0 != FAT_GOOD_SIGN_0) || (Partition->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_BAD_PARTITION;
+ error = CE_BAD_PARTITION;
+ }
+ else
+ {
+ /* Valid Master Boot Record Loaded */
+
+ // Get the 32 bit offset to the first partition
+ dsk->firsts = Partition->Partition0.PTE_FrstSect;
+
+ // check if the partition type is acceptable
+ type = Partition->Partition0.PTE_FSDesc;
+
+ switch (type)
+ {
+ case 0x01:
+ dsk->type = FAT12;
+ break;
+
+ case 0x04:
+ case 0x06:
+ case 0x0E:
+ dsk->type = FAT16;
+ break;
+
+ case 0x0B:
+ case 0x0C:
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ dsk->type = FAT32; // FAT32 is supported too
+#else
+ FSerrno = CE_CARDFAT32;
+ error = CE_CARDFAT32;
+#endif
+ break;
+
+ default:
+ FSerrno = CE_UNSUPPORTED_FS;
+ error = CE_UNSUPPORTED_FS;
+ } // switch
+ }
+ }
+
+ return(error);
+}// -- LoadMBR
+
+
+/**************************************************************************
+ Function:
+ BYTE LoadBootSector (DISK *dsk)
+ Summary:
+ Load the boot sector and extract the necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the boot sector
+ Return Values:
+ CE_GOOD - Boot sector loaded
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_NOT_FORMATTED - The disk is of an unsupported format
+ CE_CARDFAT32 - FAT 32 device not supported
+ Side Effects:
+ None
+ Description:
+ LoadBootSector will use the function pointed to by the MDD_SectorWrite
+ function pointer to load the boot sector, whose location was obtained
+ by a previous call of LoadMBR. If the boot sector is loaded successfully,
+ partition information will be calcualted from it and copied into the DISK
+ structure pointed to by 'dsk.'
+ Remarks:
+ None
+ **************************************************************************/
+
+
+BYTE LoadBootSector(DISK *dsk)
+{
+ DWORD RootDirSectors;
+ DWORD TotSec,DataSec;
+ BYTE error = CE_GOOD;
+ BootSec BSec;
+ WORD BytesPerSec;
+ WORD ReservedSectorCount;
+
+ // Get the Boot sector
+ if ( MDD_SectorRead( dsk->firsts, dsk->buffer) != TRUE)
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ BSec = (BootSec)dsk->buffer;
+
+ //Verify the Boot Sector is valid
+ if((BSec->Signature0 != FAT_GOOD_SIGN_0) || (BSec->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ error = CE_NOT_FORMATTED;
+ }
+ else
+ {
+ #ifdef __18CXX
+
+ // Load count of sectors per cluster
+ dsk->SecPerClus = BSec->FAT.FAT_16.BootSec_SPC;
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + BSec->FAT.FAT_16.BootSec_ResrvSec;
+ // Load the count of FAT tables
+ dsk->fatcopy = BSec->FAT.FAT_16.BootSec_FATCount;
+ // Load the size of the FATs
+ dsk->fatsize = BSec->FAT.FAT_16.BootSec_SPF;
+ if(dsk->fatsize == 0)
+ dsk->fatsize = BSec->FAT.FAT_32.BootSec_FATSz32;
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = BSec->FAT.FAT_16.BootSec_RootDirEnts;
+
+ // Determine the total number of sectors in the partition
+ if(BSec->FAT.FAT_16.BootSec_TotSec16 != 0)
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec16;
+ }
+ else
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec32;
+ }
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = BSec->FAT.FAT_16.BootSec_BPS;
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((BSec->FAT.FAT_16.BootSec_RootDirEnts * 32) + (BSec->FAT.FAT_16.BootSec_BPS - 1)) / BSec->FAT.FAT_16.BootSec_BPS;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (dsk->root + RootDirSectors) + dsk->firsts + 2;
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #else // PIC24/30/33
+
+ // Read the count of reserved sectors
+ ReservedSectorCount = ReadWord( dsk->buffer, BSI_RESRVSEC );
+ // Load the count of sectors per cluster
+ dsk->SecPerClus = ReadByte( dsk->buffer, BSI_SPC );
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + ReservedSectorCount;
+ // Load the count of FAT tables
+ dsk->fatcopy = ReadByte( dsk->buffer, BSI_FATCOUNT );
+ // Load the size of the FATs
+ dsk->fatsize = ReadWord( dsk->buffer, BSI_SPF );
+ if(dsk->fatsize == 0)
+ dsk->fatsize = ReadDWord( dsk->buffer, BSI_FATSZ32 );
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = ReadWord( dsk->buffer, BSI_ROOTDIRENTS );
+
+ // Determine the total number of sectors in the partition
+ TotSec = ReadWord( dsk->buffer, BSI_TOTSEC16 );
+ if( TotSec == 0 )
+ TotSec = ReadDWord( dsk->buffer, BSI_TOTSEC32 );
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = ReadWord( dsk->buffer, BSI_BPS );
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((dsk->maxroot * NUMBER_OF_BYTES_IN_DIR_ENTRY) + (BytesPerSec - 1)) / BytesPerSec;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (ReservedSectorCount + (dsk->fatcopy * dsk->fatsize ) + RootDirSectors );
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #endif
+
+ // Determine the file system type based on the number of clusters used
+ if(dsk->maxcls < 4085)
+ {
+ dsk->type = FAT12;
+ }
+ else
+ {
+ if(dsk->maxcls < 65525)
+ {
+ dsk->type = FAT16;
+ }
+ else
+ {
+ #ifdef SUPPORT_FAT32
+ dsk->type = FAT32;
+ #else
+ error = CE_CARDFAT32;
+ FSerrno = CE_CARDFAT32;
+ #endif
+ }
+ }
+
+ #ifdef SUPPORT_FAT32
+ if (dsk->type == FAT32)
+ {
+ #ifdef __18CXX
+ FatRootDirClusterValue = BSec->FAT.FAT_32.BootSec_RootClus;
+ #else
+ FatRootDirClusterValue = ReadDWord( dsk->buffer, BSI_ROOTCLUS );
+ #endif
+ dsk->data = dsk->root + RootDirSectors;
+ }
+ else
+ #endif
+ {
+ FatRootDirClusterValue = 0;
+ dsk->data = dsk->root + ( dsk->maxroot >> 4);
+ }
+
+ #ifdef __18CXX
+ if(BSec->FAT.FAT_16.BootSec_BPS != MEDIA_SECTOR_SIZE)
+ #else
+ if(BytesPerSec != MEDIA_SECTOR_SIZE)
+ #endif
+ {
+ error = CE_NOT_FORMATTED;
+ FSerrno = CE_NOT_FORMATTED;
+ }
+ }
+ }
+ return(error);
+}
+
+
+
+/*************************************************************************
+ Function:
+ DWORD GetFullClusterNumber (DIRENTRY entry)
+ Summary:
+ Gets the cluster number from a directory entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ entry - The cached directory entry to get the cluster number from
+ Returns:
+ The cluster value from the passed directory entry
+ Side Effects:
+ None.
+ Description:
+ This function will load both the high and low 16-bit first cluster
+ values of a file from a directory entry and copy them into a 32-bit
+ cluster number variable, which will be returned.
+ Remarks:
+ None
+ *************************************************************************/
+
+DWORD GetFullClusterNumber(DIRENTRY entry)
+{
+
+ DWORD TempFullClusterCalc = 0;
+
+#ifndef SUPPORT_FAT32 // If FAT32 Not supported.
+ entry->DIR_FstClusHI = 0; // If FAT32 is not supported then Higher Word of the address is "0"
+#endif
+
+ // Get the cluster
+ TempFullClusterCalc = (entry->DIR_FstClusHI);
+ TempFullClusterCalc = TempFullClusterCalc << 16;
+ TempFullClusterCalc |= entry->DIR_FstClusLO;
+
+ return TempFullClusterCalc;
+}
+
+
+#ifdef ALLOW_FORMATS
+#ifdef ALLOW_WRITES
+
+
+/*********************************************************************************
+ Function:
+ int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+ Summary:
+ Creates a master boot record
+ Conditions:
+ The I/O pins for the device have been initialized by the InitIO function.
+ Input:
+ firstSector - The first sector of the partition on the device (cannot
+ be 0; that's the MBR)
+ numSectors - The number of sectors available in memory (including the
+ MBR)
+ Return Values:
+ 0 - MBR was created successfully
+ EOF - MBR could not be created
+ Side Effects:
+ None
+ Description:
+ This function can be used to create a master boot record for a device. Note
+ that this function should not be used on a device that is already formatted
+ with a master boot record (i.e. most SD cards, CF cards, USB keys). This
+ function will fill the global data buffer with appropriate partition information
+ for a FAT partition with a type determined by the number of sectors available
+ to the partition. It will then write the MBR information to the first sector
+ on the device. This function should be followed by a call to FSformat, which
+ will create a boot sector, root dir, and FAT appropriate the the information
+ contained in the new master boot record. Note that FSformat only supports
+ FAT12 and FAT16 formatting at this time, and so cannot be used to format a
+ device with more than 0x3FFD5F sectors.
+ Remarks:
+ This function can damage the device being used, and should not be called
+ unless the user is sure about the size of the device and the first sector value.
+ *********************************************************************************/
+
+int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+{
+ PT_MBR Partition;
+ DWORD CyHdSc = 0x00000000;
+ DWORD tempSector;
+
+ if ((firstSector == 0) || (numSectors <= 1))
+ return EOF;
+
+ if (firstSector > (numSectors - 1))
+ return EOF;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ return EOF;
+
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ Partition = (PT_MBR) gDataBuffer;
+
+ // Set Cylinder-head-sector address of the first sector
+ tempSector = firstSector;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[447] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[448] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[449] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the count of sectors
+ Partition->Partition0.PTE_NumSect = numSectors - firstSector;
+
+ // Set the partition type
+ // We only support creating FAT12 and FAT16 MBRs at this time
+ if (Partition->Partition0.PTE_NumSect < 0x1039)
+ {
+ // FAT12
+ Partition->Partition0.PTE_FSDesc = 0x01;
+ }
+ else if (Partition->Partition0.PTE_NumSect <= 0x3FFD5F)
+ {
+ // FAT16
+ Partition->Partition0.PTE_FSDesc = 0x06;
+ }
+ else
+ return EOF;
+
+ // Set the LBA of the first sector
+ Partition->Partition0.PTE_FrstSect = firstSector;
+
+ // Set the Cylinder-head-sector address of the last sector
+ tempSector = firstSector + numSectors - 1;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[451] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[452] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[453] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the boot descriptor. This will be 0, since we won't
+ // be booting anything from our device probably
+ Partition->Partition0.PTE_BootDes = 0x00;
+
+ // Set the signature codes
+ Partition->Signature0 = 0x55;
+ Partition->Signature1 = 0xAA;
+
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) != TRUE)
+ return EOF;
+ else
+ return 0;
+
+}
+
+
+
+/*******************************************************************
+ Function:
+ int FSformat (char mode, long int serialNumber, char * volumeID)
+ Summary:
+ Formats a device
+ Conditions:
+ The device must possess a valid master boot record.
+ Input:
+ mode - - 0 - Just erase the FAT and root
+ - 1 - Create a new boot sector
+ serialNumber - Serial number to write to the card
+ volumeID - Name of the card
+ Return Values:
+ 0 - Format was successful
+ EOF - Format was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSformat function can be used to create a new boot sector
+ on a device, based on the information in the master boot record.
+ This function will first initialize the I/O pins and the device,
+ and then attempts to read the master boot record. If the MBR
+ cannot be loaded successfully, the function will fail. Next, if
+ the 'mode' argument is specified as '0' the existing boot sector
+ information will be loaded. If the 'mode' argument is '1' an
+ entirely new boot sector will be constructed using the disk
+ values from the master boot record. Once the boot sector has
+ been successfully loaded/created, the locations of the FAT and
+ root will be loaded from it, and they will be completely
+ erased. If the user has specified a volumeID parameter, a
+ VOLUME attribute entry will be created in the root directory
+ to name the device.
+ Remarks:
+ FAT12 and FAT16 formatting is supported.
+ *******************************************************************/
+
+int FSformat (char mode, long int serialNumber, char * volumeID)
+{
+ PT_MBR masterBootRecord;
+ DWORD secCount, FAT16DataClusters, RootDirSectors;
+ BootSec BSec;
+ DISK d;
+ DISK * disk = &d;
+ WORD j;
+ DWORD fatsize, test;
+ BYTE Index;
+#ifdef __18CXX
+ // This is here because of a C18 compiler feature
+ BYTE * dataBufferPointer = gDataBuffer;
+#endif
+
+ FSerrno = CE_GOOD;
+
+ disk->buffer = gDataBuffer;
+
+ MDD_InitIO();
+
+ if (MDD_MediaInitialize() != TRUE)
+ {
+ FSerrno = CE_INIT_ERROR;
+ return EOF;
+ }
+
+ if (MDD_SectorRead (0x00, gDataBuffer) == FALSE)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+
+ // Check if the card has no MBR
+ BSec = (BootSec) disk->buffer;
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( disk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( disk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ switch (mode)
+ {
+ case 1:
+ // not enough info to construct our own boot sector
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ case 0:
+ // We have to determine the operating system, and the
+ // locations and sizes of the root dir and FAT, and the
+ // count of FATs
+ disk->firsts = 0;
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ default:
+ break;
+ }
+ }
+ else
+ {
+ masterBootRecord = (PT_MBR) &gDataBuffer;
+ disk->firsts = masterBootRecord->Partition0.PTE_FrstSect;
+ }
+ }
+
+ switch (mode)
+ {
+ // True: Rewrite the whole boot sector
+ case 1:
+ secCount = masterBootRecord->Partition0.PTE_NumSect;
+
+ if (secCount < 0x1039)
+ {
+ disk->type = FAT12;
+ // Format to FAT12 only if there are too few sectors to format
+ // as FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x01;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ if (secCount >= 0x1028)
+ {
+ // More than 0x18 sectors for FATs, 0x20 for root dir,
+ // 0x8 reserved, and 0xFED for data
+ // So double the number of sectors in a cluster to reduce
+ // the number of data clusters used
+ disk->SecPerClus = 2;
+ }
+ else
+ {
+ // One sector per cluster
+ disk->SecPerClus = 1;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT12 )
+ gDataBuffer[58] = '2';
+ }
+ else if (secCount <= 0x3FFD5F)
+ {
+ disk->type = FAT16;
+ // Format to FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x06;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ FAT16DataClusters = secCount - 0x218;
+ // Figure out how many sectors per cluster we need
+ disk->SecPerClus = 1;
+ while (FAT16DataClusters > 0xFFED)
+ {
+ disk->SecPerClus *= 2;
+ FAT16DataClusters /= 2;
+ }
+ // This shouldnt happen
+ if (disk->SecPerClus > 128)
+ {
+ FSerrno = CE_BAD_PARTITION;
+ return EOF;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT16 )
+ gDataBuffer[58] = '6';
+ }
+ else
+ {
+ // Cannot format; too many sectors
+ FSerrno = CE_NONSUPPORTED_SIZE;
+ return EOF;
+ }
+
+ // Calculate the size of the FAT
+ fatsize = (secCount - 0x21 + (2*disk->SecPerClus));
+ if (disk->type == FAT12)
+ test = (341 * disk->SecPerClus) + 2;
+ else
+ test = (256 * disk->SecPerClus) + 2;
+ fatsize = (fatsize + (test-1)) / test;
+ // Non-file system specific values
+ gDataBuffer[0] = 0xEB; //Jump instruction
+ gDataBuffer[1] = 0x3C;
+ gDataBuffer[2] = 0x90;
+ gDataBuffer[3] = 'M'; //OEM Name "MCHP FAT"
+ gDataBuffer[4] = 'C';
+ gDataBuffer[5] = 'H';
+ gDataBuffer[6] = 'P';
+ gDataBuffer[7] = ' ';
+ gDataBuffer[8] = 'F';
+ gDataBuffer[9] = 'A';
+ gDataBuffer[10] = 'T';
+ gDataBuffer[11] = 0x00; //Bytes per sector - 512
+ gDataBuffer[12] = 0x02;
+ gDataBuffer[13] = disk->SecPerClus; //Sectors per cluster
+ gDataBuffer[14] = 0x08; //Reserved sector count
+ gDataBuffer[15] = 0x00;
+ disk->fat = 0x08 + disk->firsts;
+ gDataBuffer[16] = 0x02; //number of FATs
+ disk->fatcopy = 0x02;
+ gDataBuffer[17] = 0x00; //Max number of root directory entries - 512 files allowed
+ gDataBuffer[18] = 0x02;
+ disk->maxroot = 0x200;
+ gDataBuffer[19] = 0x00; //total sectors
+ gDataBuffer[20] = 0x00;
+ gDataBuffer[21] = 0xF8; //Media Descriptor
+ gDataBuffer[22] = fatsize & 0xFF; //Sectors per FAT
+ gDataBuffer[23] = (fatsize >> 8) & 0xFF;
+ disk->fatsize = fatsize;
+ gDataBuffer[24] = 0x3F; //Sectors per track
+ gDataBuffer[25] = 0x00;
+ gDataBuffer[26] = 0xFF; //Number of heads
+ gDataBuffer[27] = 0x00;
+ // Hidden sectors = sectors between the MBR and the boot sector
+ gDataBuffer[28] = (BYTE)(disk->firsts & 0xFF);
+ gDataBuffer[29] = (BYTE)((disk->firsts / 0x100) & 0xFF);
+ gDataBuffer[30] = (BYTE)((disk->firsts / 0x10000) & 0xFF);
+ gDataBuffer[31] = (BYTE)((disk->firsts / 0x1000000) & 0xFF);
+ // Total Sectors = same as sectors in the partition from MBR
+ gDataBuffer[32] = (BYTE)(secCount & 0xFF);
+ gDataBuffer[33] = (BYTE)((secCount / 0x100) & 0xFF);
+ gDataBuffer[34] = (BYTE)((secCount / 0x10000) & 0xFF);
+ gDataBuffer[35] = (BYTE)((secCount / 0x1000000) & 0xFF);
+ gDataBuffer[36] = 0x00; // Physical drive number
+ gDataBuffer[37] = 0x00; // Reserved (current head)
+ gDataBuffer[38] = 0x29; // Signature code
+ gDataBuffer[39] = (BYTE)(serialNumber & 0xFF);
+ gDataBuffer[40] = (BYTE)((serialNumber / 0x100) & 0xFF);
+ gDataBuffer[41] = (BYTE)((serialNumber / 0x10000) & 0xFF);
+ gDataBuffer[42] = (BYTE)((serialNumber / 0x1000000) & 0xFF);
+ // Volume ID
+ if (volumeID != NULL)
+ {
+ for (Index = 0; (*(volumeID + Index) != 0) && (Index < 11); Index++)
+ {
+ gDataBuffer[Index + 43] = *(volumeID + Index);
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[43 + Index++] = 0x20;
+ }
+ }
+ else
+ {
+ for (Index = 0; Index < 11; Index++)
+ {
+ gDataBuffer[Index+43] = 0;
+ }
+ }
+ gDataBuffer[54] = 'F';
+ gDataBuffer[55] = 'A';
+ gDataBuffer[56] = 'T';
+ gDataBuffer[57] = '1';
+ gDataBuffer[59] = ' ';
+ gDataBuffer[60] = ' ';
+ gDataBuffer[61] = ' ';
+#ifdef __18CXX
+ // C18 can't reference a value greater than 256
+ // using an array name pointer
+ *(dataBufferPointer + 510) = 0x55;
+ *(dataBufferPointer + 511) = 0xAA;
+#else
+ gDataBuffer[510] = 0x55;
+ gDataBuffer[511] = 0xAA;
+#endif
+
+ disk->root = disk->fat + (disk->fatcopy * disk->fatsize);
+
+ if (MDD_SectorWrite (disk->firsts, gDataBuffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ break;
+ case 0:
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ break;
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ }
+
+ // Erase the FAT
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+ gDataBuffer[0] = 0xF8;
+ gDataBuffer[1] = 0xFF;
+ gDataBuffer[2] = 0xFF;
+ if (disk->type == FAT16)
+ gDataBuffer[3] = 0xFF;
+
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (disk->fat + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ memset (gDataBuffer, 0x00, 4);
+
+ for (Index = disk->fat + 1; Index < (disk->fat + disk->fatsize); Index++)
+ {
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (Index + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ }
+
+ // Erase the root directory
+ RootDirSectors = ((disk->maxroot * 32) + (0x200 - 1)) / 0x200;
+
+ for (Index = 1; Index < RootDirSectors; Index++)
+ {
+ if (MDD_SectorWrite (disk->root + Index, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ if (volumeID != NULL)
+ {
+ // Create a drive name entry in the root dir
+ Index = 0;
+ while ((*(volumeID + Index) != 0) && (Index < 11))
+ {
+ gDataBuffer[Index] = *(volumeID + Index);
+ Index++;
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[Index++] = ' ';
+ }
+ gDataBuffer[11] = 0x08;
+ gDataBuffer[17] = 0x11;
+ gDataBuffer[19] = 0x11;
+ gDataBuffer[23] = 0x11;
+
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ else
+ {
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ return 0;
+}
+#endif
+#endif
+
+
+/*******************************************************
+ Function:
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+ Summary:
+ Write dir entry info into a specified entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - \File structure
+ curEntry - Write destination
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will calculate the sector of the
+ directory (whose base sector is pointed to by the
+ dirccls value in the FSFILE object 'fo') that contains
+ a directory entry whose offset is indicated by the
+ curEntry parameter. It will then write the data
+ in the global data buffer (which should already
+ contain the entries for that sector) to the device.
+ Remarks:
+ None
+ *******************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+{
+ DISK *dsk;
+ BYTE status;
+ BYTE offset2;
+ DWORD sector;
+ DWORD ccls;
+
+ dsk = fo->dsk;
+
+ // get the cluster of this entry
+ ccls = fo->dirccls;
+
+ // if its not the root, it's cluster based
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // Root is always cluster-based in FAT32
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ if(ccls != FatRootDirClusterValue)
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+ }
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ // Now write it
+ // "Offset" ensures writing of data belonging to a file entry only. Hence it doesn't change other file entries.
+ if ( !MDD_SectorWrite( sector + offset2, dsk->buffer, FALSE))
+ status = FALSE;
+ else
+ status = TRUE;
+
+ return(status);
+} // Write_File_Entry
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE FAT_erase_cluster_chain (WORD cluster, DISK * dsk)
+ Summary:
+ Erase a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ cluster - The cluster number
+ dsk - The disk structure
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will parse through a cluster chain
+ starting with the cluster pointed to by 'cluster' and
+ mark all of the FAT entries as empty until the end of
+ the chain has been reached or an error occurs.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk)
+{
+ DWORD c,c2,ClusterFailValue;
+ enum _status {Good, Fail, Exit}status;
+
+ status = Good;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ c2 = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT16:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ c2 = LAST_CLUSTER_FAT16;
+ break;
+
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16; // FAT16 value itself
+ c2 = LAST_CLUSTER_FAT12;
+ break;
+ }
+
+ // Make sure there is actually a cluster assigned
+ if(cluster == 0 || cluster == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ while(status == Good)
+ {
+ // Get the FAT entry
+ if((c = ReadFAT( dsk, cluster)) == ClusterFailValue)
+ status = Fail;
+ else
+ {
+ if(c == 0 || c == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ // compare against max value of a cluster in FATxx
+ // look for the last cluster in the chain
+ if ( c >= c2)
+ status = Exit;
+
+ // Now erase this FAT entry
+ if(WriteFAT(dsk, cluster, CLUSTER_EMPTY, FALSE) == ClusterFailValue)
+ status = Fail;
+
+ // now update what the current cluster is
+ cluster = c;
+ }
+ }
+ }// while status
+ }// cluster == 0
+
+ WriteFAT (dsk, 0, 0, TRUE);
+
+ if(status == Exit)
+ return(TRUE);
+ else
+ return(FALSE);
+} // Erase cluster
+#endif
+
+/**************************************************************************
+ Function:
+ DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+ Summary:
+ Load a file entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File information
+ curEntry - Offset of the directory entry to load.
+ ForceRead - Forces loading of a new sector of the directory.
+ Return:
+ DIRENTRY - Pointer to the directory entry that was loaded.
+ Side Effects:
+ Any unwritten data in the data buffer will be written to the device.
+ Description:
+ Load the sector containing the file entry pointed to by 'curEntry'
+ from the directory pointed to by the variables in 'fo.'
+ Remarks:
+ Any modification of this function is extremely likely to
+ break something.
+ **************************************************************************/
+
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+{
+ DIRENTRY dir;
+ DISK *dsk;
+ DWORD sector;
+ DWORD cluster, LastClusterLimit;
+ DWORD ccls;
+ BYTE offset2;
+ BYTE numofclus;
+
+ dsk = fo->dsk;
+
+ // get the base sector of this directory
+ cluster = fo->dirclus;
+ ccls = fo->dirccls;
+
+ // figure out the offset from the base sector
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+ /* There are 16 entries per sector. SECTOR size is 512 bytes. Each entry in ROOT takes 32 bytes.
+ So, 512/32 = 16. So 16 file entries can be made in each sector. */
+
+ offset2 = offset2; // emulator issue
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // the ROOT is always cluster based in FAT32
+ /* In FAT32: There is no ROOT region. Root etries are made in DATA region only.
+ Every cluster of DATA which is accupied by ROOT is tracked by FAT table/entry so the ROOT can grow
+ to an amount which is restricted only by available free DATA region. */
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // if its the root its not cluster based
+ if(cluster != 0)
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ // check if a new sector of the root must be loaded
+ if (ForceRead || (*curEntry & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) // only 16 entries per sector
+ {
+ // see if we have to load a new cluster
+ if((offset2 == 0 && (*curEntry) >= DIRENTRIES_PER_SECTOR) || ForceRead)
+ {
+ if(cluster == 0)
+ {
+ ccls = 0;
+ }
+ else
+ {
+ // If ForceRead, read the number of sectors from 0
+ if(ForceRead)
+ numofclus = ((WORD)(*curEntry) / (WORD)(((WORD)DIRENTRIES_PER_SECTOR) * (WORD)dsk->SecPerClus));
+ // Otherwise just read the next sector
+ else
+ numofclus = 1;
+
+ // move to the correct cluster
+ while(numofclus)
+ {
+ ccls = ReadFAT(dsk, ccls);
+
+ if(ccls >= LastClusterLimit)
+ break;
+ else
+ numofclus--;
+ }
+ }
+ }
+
+ // see if that we have a valid cluster number
+ if(ccls < LastClusterLimit)
+ {
+ fo->dirccls = ccls; // write it back
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ /* see if we are root and about to go pass our boundaries
+ FAT32 stores the root directory in the Data Region along with files and other directories,
+ allowing it to grow without such a restraint */
+ if((ccls == FatRootDirClusterValue) && ((sector + offset2) >= dsk->data) && (FAT32 != dsk->type))
+ {
+ dir = ((DIRENTRY)NULL); // reached the end of the root
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return NULL;
+#endif
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+
+ if ( MDD_SectorRead( sector + offset2, dsk->buffer) != TRUE) // if FALSE: sector could not be read.
+ {
+ dir = ((DIRENTRY)NULL);
+ }
+ else // Sector has been read properly, Copy the root entry info of the file searched.
+ {
+ if(ForceRead) // Buffer holds all 16 root entry info. Point to the one required.
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+ else
+ dir = (DIRENTRY)dsk->buffer;
+ }
+ gLastDataSectorRead = 0xFFFFFFFF;
+ }
+ }
+ else
+ {
+ nextClusterIsLast = TRUE;
+ dir = ((DIRENTRY)NULL);
+ }
+ }
+ else
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+
+ return(dir);
+} // Cache_File_Entry
+
+
+/*************************************************************************
+ Function:
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Create a new file entry
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location to create file
+ Return Values:
+ CE_GOOD - File Creation successful
+ CE_DIR_FULL - All root directory entries are taken
+ CE_WRITE_ERROR - The head cluster of the file could not be created.
+ Side Effects:
+ Modifies the FSerrno variable.
+ Description:
+ With the data passed within fo, create a new file entry in the current
+ directory. This function will first search for empty file entries.
+ Once an empty entry is found, the entry will be populated with data
+ for a file or directory entry. Finally, the first cluster of the
+ new file will be located and allocated, and its value will be
+ written into the file entry.
+ Remarks:
+ None
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode)
+{
+ BYTE index;
+ CETYPE error = CE_GOOD;
+ char name[11];
+
+ FSerrno = CE_GOOD;
+
+ for (index = 0; index < FILE_NAME_SIZE; index ++)
+ {
+ name[index] = fo->name[index];
+ }
+
+ *fHandle = 0;
+
+ // figure out where to put this file in the directory stucture
+ if(FindEmptyEntries(fo, fHandle))
+ {
+ // found the entry, now populate it
+ if((error = PopulateEntries(fo, name ,fHandle, mode)) == CE_GOOD)
+ {
+ // if everything is ok, create a first cluster
+ error = CreateFirstCluster(fo);
+ }
+ }
+ else
+ {
+ error = CE_DIR_FULL;
+ }
+
+ FSerrno = error;
+
+ return(error);
+}
+#endif
+
+/******************************************************
+ Function:
+ CETYPE CreateFirstCluster(FILEOBJ fo)
+ Summary:
+ Create the first cluster for a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file that contains the first cluster
+ Return Values:
+ CE_GOOD - First cluster created successfully
+ CE_WRITE_ERROR - Cluster creation failed
+ Side Effects:
+ None
+ Description:
+ This function will find an unused cluster, link it to
+ a file's directory entry, and write the entry back
+ to the device.
+ Remarks:
+ None.
+ ******************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFirstCluster(FILEOBJ fo)
+{
+ CETYPE error;
+ DWORD cluster,TempMsbCluster;
+ WORD fHandle;
+ DIRENTRY dir;
+ fHandle = fo->entry;
+
+ // Now create the first cluster (head cluster)
+ if((error = FILECreateHeadCluster(fo,&cluster)) == CE_GOOD)
+ {
+ // load the file entry so the new cluster can be linked to it
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ // Now update the new cluster
+ dir->DIR_FstClusLO = (cluster & 0x0000FFFF);
+
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ // Get the higher part of cluster and store it in directory entry.
+ TempMsbCluster = (cluster & 0x0FFF0000); // Since only 28 bits usedin FAT32. Mask the higher MSB nibble.
+ TempMsbCluster = TempMsbCluster >> 16; // Get the date into Lsb place.
+ dir->DIR_FstClusHI = TempMsbCluster;
+#else // If FAT32 support not enabled
+ TempMsbCluster = 0; // Just to avoid compiler warnigng.
+ dir->DIR_FstClusHI = 0;
+#endif
+
+ // now write it
+ if(Write_File_Entry(fo, &fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+ } // Create Cluster
+
+ return(error);
+}// End of CreateFirstCluster
+#endif
+
+/**********************************************************
+ Function:
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Find an empty dir entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Start of entries
+ Return Values:
+ TRUE - One found
+ FALSE - None found
+ Side Effects:
+ None
+ Description:
+ This function will cache directory entries, starting
+ with the one pointed to by the fHandle argument. It will
+ then search through the entries until an unused one
+ is found. If the end of the cluster chain for the
+ directory is reached, a new cluster will be allocated
+ to the directory (unless it's a FAT12 or FAT16 root)
+ and the first entry of the new cluster will be used.
+ Remarks:
+ None.
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+{
+ BYTE status = NOT_FOUND;
+ BYTE amountfound;
+ BYTE a;
+ WORD bHandle;
+ DWORD b;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ if((dir = Cache_File_Entry( fo, fHandle, TRUE)) == NULL)
+ {
+ status = CE_BADCACHEREAD;
+ }
+ else
+ {
+ // while its still not found
+ while(status == NOT_FOUND)
+ {
+ amountfound = 0;
+ bHandle = *fHandle;
+
+ // find (number) continuous entries
+ do
+ {
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // increase number
+ (*fHandle)++;
+ }while((a == DIR_DEL || a == DIR_EMPTY) && (dir != (DIRENTRY)NULL) && (++amountfound < 1));
+
+ // --- now why did we exit?
+ if(dir == NULL) // Last entry of the cluster
+ {
+ //setup the current cluster
+ b = fo->dirccls; // write it back
+
+ // make sure we are not the root directory
+ if(b == FatRootDirClusterValue)
+ {
+ if (fo->dsk->type != FAT32)
+ status = NO_MORE;
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ if(amountfound == 1)
+ {
+ status = FOUND;
+ *fHandle = bHandle;
+ }
+ }
+ }// while
+
+ // copy the base handle over
+ *fHandle = bHandle;
+ }
+
+ if(status == FOUND)
+ return(TRUE);
+ else
+ return(FALSE);
+}
+#endif
+
+/**************************************************************************
+ Function:
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle)
+ Summary:
+ Populate a dir entry with data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ name - Name of the file
+ fHandle - Location of the file
+ Return Values:
+ CE_GOOD - Population successful
+ Side Effects:
+ None
+ Description:
+ This function will write data into a new file entry. It will also
+ load timestamp data (based on the method selected by the user) and
+ update the timestamp variables.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode)
+{
+ BYTE error = CE_GOOD;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+
+ if (dir == NULL)
+ return CE_BADCACHEREAD;
+
+ // copy the contents over
+ strncpy(dir->DIR_Name,name,DIR_NAMECOMP);
+
+ // setup no attributes
+ if (mode == DIRECTORY)
+ dir->DIR_Attr = ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = ATTR_ARCHIVE;
+
+ dir->DIR_NTRes = 0x00; // nt reserved
+ dir->DIR_FstClusHI = 0x0000; // high word of this enty's first cluster number
+ dir->DIR_FstClusLO = 0x0000; // low word of this entry's first cluster number
+ dir->DIR_FileSize = 0x0; // file size in DWORD
+
+ // Timing information for uncontrolled clock mode
+#ifdef INCREMENTTIMESTAMP
+ dir->DIR_CrtTimeTenth = 0xB2; // millisecond stamp
+ dir->DIR_CrtTime = 0x7278; // time created
+ dir->DIR_CrtDate = 0x32B0; // date created
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = 0x32B0; // Last Access date
+ dir->DIR_WrtTime = 0x7279; // last update time
+ dir->DIR_WrtDate = 0x32B0; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ dir->DIR_CrtTime = gTimeCrtTime; // time created //
+ dir->DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate; // Last Access date
+ dir->DIR_WrtTime = gTimeWrtTime; // last update time
+ dir->DIR_WrtDate = gTimeWrtDate; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ // The user will have set the time before this funciton is called
+ dir->DIR_CrtTimeTenth = gTimeCrtMS;
+ dir->DIR_CrtTime = gTimeCrtTime;
+ dir->DIR_CrtDate = gTimeCrtDate;
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate;
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+ fo->size = dir->DIR_FileSize;
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ fo->attributes = dir->DIR_Attr;
+ fo->entry = *fHandle;
+
+ // just write the last entry in
+ if (Write_File_Entry(fo,fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+
+ return(error);
+}
+
+#ifdef USEREALTIMECLOCK
+
+/*************************************************************************
+ Function:
+ void CacheTime (void)
+ Summary:
+ Automatically store timestamp information from the RTCC
+ Conditions:
+ RTCC module enabled. Should not be called by the user.
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ This function will automatically load information from an RTCC
+ module and use it to update the global timing variables. These can
+ then be used to update file timestamps.
+ Remarks:
+ None.
+ *************************************************************************/
+
+void CacheTime (void)
+{
+#ifdef __C30__
+ WORD year, monthday, weekhour, minsec, c, result;
+ BYTE ptr1, ptr0;
+
+ if(RCFGCALbits.RTCPTR0)
+ ptr0 = 1;
+ else
+ ptr0 = 0;
+ if (RCFGCALbits.RTCPTR1)
+ ptr1 = 1;
+ else
+ ptr1 = 0;
+
+ RCFGCALbits.RTCPTR0 = 1;
+ RCFGCALbits.RTCPTR1 = 1;
+ year = RTCVAL;
+ monthday = RTCVAL;
+ weekhour = RTCVAL;
+ minsec = RTCVAL;
+
+ if (ptr0 == 1)
+ RCFGCALbits.RTCPTR0 = 1;
+
+ if (ptr1 == 1)
+ RCFGCALbits.RTCPTR1 = 1;
+
+ c = 0;
+ c += (year & 0x0F);
+ c += ((year & 0xF0) >> 4) * 10;
+ // c equals the last 2 digits of the year from 2000 to 2099
+ // Add 20 to adjust it to FAT time (from 1980 to 2107)
+ c += 20;
+ // shift the result to bits
+ result = c << 9;
+
+ if ((monthday & 0x1000) == 0x1000)
+ {
+ c = 10;
+ }
+ else
+ {
+ c = 0;
+ }
+ c += ((monthday & 0x0F00) >> 8);
+ c <<= 5;
+ result |= c;
+
+ c = (monthday & 0x00F0) >> 4;
+ c *= 10;
+ c += (monthday & 0x000F);
+
+ result |= c;
+
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+ gTimeAccDate = result;
+
+ c = ((weekhour & 0x00F0) >> 4) * 10;
+ c += (weekhour & 0x000F);
+ result = c << 11;
+ c = ((minsec & 0xF000) >> 12) * 10;
+ c += (minsec & 0x0F00) >> 8;
+ result |= (c << 5);
+ c = ((minsec & 0x00F0) >> 4) * 10;
+ c += (minsec & 0x000F);
+
+ // If seconds mod 2 is 1, add 1000 ms
+ if (c % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ c >>= 1;
+ result |= c;
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+#elif defined __C32__
+ rtccTime tm; // time structure
+ rtccDate dt; // date structure
+ RtccGetTimeDate(&tm, &dt);
+ gTimeCrtTime = tm.w[1] | tm.w[0];
+ gTimeWrtDate = dt.w[1] | tm.w[0];
+#endif
+}
+#endif
+
+#ifdef USERDEFINEDCLOCK
+
+/***********************************************************************************************************
+ Function:
+ int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+ Summary:
+ Manually set timestamp variables
+ Conditions:
+ USERDEFINEDCLOCK macro defined in FSconfig.h.
+ Input:
+ year - The year (1980\-2107)
+ month - The month (1\-12)
+ day - The day of the month (1\-31)
+ hour - The hour (0\-23)
+ minute - The minute (0\-59)
+ second - The second (0\-59)
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ Lets the user manually set the timing variables. The values passed in will be converted to the format
+ used by the FAT timestamps.
+ Remarks:
+ Call this before creating a file or directory (set create time) and
+ before closing a file (set last access time, last modified time)
+ ***********************************************************************************************************/
+
+int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+{
+ unsigned int result;
+
+ if ((year < 1980) || (year > 2107) || (month < 1) || (month > 12) ||
+ (day < 1) || (day > 31) || (hour > 23) || (minute > 59) || (second > 59))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ result = (year - 1980) << 9;
+ result |= (unsigned int)((unsigned int)month << 5);
+ result |= (day);
+
+ gTimeAccDate = result;
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+
+ result = ((unsigned int)hour << 11);
+ result |= (unsigned int)((unsigned int)minute << 5);
+ result |= (second/2);
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+
+ if (second % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ FSerrno = CE_GOOD;
+ return 0;
+}
+#endif
+
+#endif
+
+/***********************************************************************
+ Function:
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+ Summary;
+ Allocate a new cluster to a file
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ mode -
+ - 0 - Allocate a cluster to a file
+ - 1 - Allocate a cluster to a directory
+ Return Values:
+ CE_GOOD - Cluster allocated
+ CE_DISK_FULL - No clusters available
+ Side Effects:
+ None
+ Description:
+ This function will find an empty cluster on the device using the
+ FATfindEmptyCluster function. It will then mark it as the last
+ cluster in the file in the FAT chain, and link the current last
+ cluster of the passed file to the new cluster. If the new
+ cluster is a directory cluster, it will be erased (so there are no
+ extraneous directory entries). If it's allocated to a non-directory
+ file, it doesn't need to be erased; extraneous data in the cluster
+ will be unviewable because of the file size parameter.
+ Remarks:
+ None.
+ ***********************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+{
+ DISK * dsk;
+ DWORD c,curcls;
+
+ dsk = fo->dsk;
+ c = fo->ccls;
+
+ // find the next empty cluster
+ c = FATfindEmptyCluster(fo);
+ if (c == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ return CE_DISK_FULL;
+
+
+ // mark the cluster as taken, and last in chain
+ if(dsk->type == FAT12)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT12, FALSE);
+ else if (dsk->type == FAT16)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT16, FALSE);
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT32, FALSE);
+#endif
+
+ // link current cluster to the new one
+ curcls = fo->ccls;
+
+ WriteFAT( dsk, curcls, c, FALSE);
+
+ // update the FILE structure
+ fo->ccls = c;
+
+ // IF this is a dir, we need to erase the cluster
+ // If it's a file, we can leave it- the file size
+ // will limit the data we see to the data that's been
+ // written
+ if (mode == 1)
+ return (EraseCluster(dsk, c));
+ else
+ return CE_GOOD;
+
+} // allocate new cluster
+#endif
+
+/***********************************************
+ Function:
+ DWORD FATfindEmptyCluster(FILEOBJ fo)
+ Summary:
+ Find the next available cluster on the device
+ Conditions:
+ This function should not be called by the
+ user.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ DWORD - Address of empty cluster
+ 0 - Could not find empty cluster
+ Side Effects:
+ None
+ Description:
+ This function will search through the FAT to
+ find the next available cluster on the device.
+ Remarks:
+ Should not be called by user
+ ***********************************************/
+
+#ifdef ALLOW_WRITES
+DWORD FATfindEmptyCluster(FILEOBJ fo)
+{
+ DISK * disk;
+ DWORD value = 0x0;
+ DWORD c,curcls, EndClusterLimit, ClusterFailValue;
+
+ disk = fo->dsk;
+ c = fo->ccls;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ EndClusterLimit = END_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ EndClusterLimit = END_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT12:
+ EndClusterLimit = END_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // just in case
+ if(c < 2)
+ c = 2;
+
+ curcls = c;
+ ReadFAT(disk, c);
+
+ // sequentially scan through the FAT looking for an empty cluster
+ while(c)
+ {
+ // look at its value
+ if ( (value = ReadFAT(disk, c)) == ClusterFailValue)
+ {
+ c = 0;
+ break;
+ }
+
+ // check if empty cluster found
+ if (value == CLUSTER_EMPTY)
+ break;
+
+ c++; // check next cluster in FAT
+ // check if reached last cluster in FAT, re-start from top
+ if (value == EndClusterLimit || c >= disk->maxcls)
+ c = 2;
+
+ // check if full circle done, disk full
+ if ( c == curcls)
+ {
+ c = 0;
+ break;
+ }
+ } // scanning for an empty cluster
+
+ return(c);
+}
+#endif
+
+/************************************************************
+ Function:
+ int FSfclose(FSFILE *fo)
+ Summary:
+ Update file information and free FSFILE objects
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to the file to close
+ Return Values:
+ 0 - File closed successfully
+ EOF - Error closing the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will update the directory entry for the
+ file pointed to by 'fo' with the information contained
+ in 'fo,' including the new file size and attributes.
+ Timestamp information will also be loaded based on the
+ method selected by the user and written to the entry
+ as the last modified time and date. The file entry will
+ then be written to the device. Finally, the memory
+ used for the specified file object will be freed from
+ the dynamic heap or the array of FSFILE objects.
+ Remarks:
+ A function to flush data to the device without closing the
+ file can be created by removing the portion of this
+ function that frees the memory and the line that clears
+ the write flag.
+ ************************************************************/
+
+int FSfclose(FSFILE *fo)
+{
+ WORD fHandle;
+#ifndef FS_DYNAMIC_MEM
+ WORD fIndex;
+#endif
+ int error = 72;
+#ifdef ALLOW_WRITES
+ DIRENTRY dir;
+#endif
+
+ FSerrno = CE_GOOD;
+ fHandle = fo->entry;
+
+#ifdef ALLOW_WRITES
+ if(fo->flags.write)
+ {
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ // Write the current FAT sector to the disk
+ WriteFAT (fo->dsk, 0, 0, TRUE);
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = EOF;
+ return error;
+ }
+
+ // update the time
+#ifdef INCREMENTTIMESTAMP
+ IncrementTimeStamp(dir);
+#elif defined USERDEFINEDCLOCK
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#elif defined USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#endif
+
+ Nop();
+
+ dir->DIR_FileSize = fo->size;
+
+ dir->DIR_Attr = fo->attributes;
+
+ // just write the last entry in
+ if(Write_File_Entry(fo,&fHandle))
+ error = 0;
+ else
+ {
+ FSerrno = CE_WRITE_ERROR;
+ error = EOF;
+ }
+
+ // it's now closed
+ fo->flags.write = FALSE;
+ }
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ FS_free((unsigned char *)fo);
+#else
+
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( fo == &gFileArray[fIndex] )
+ {
+ gFileSlotOpen[fIndex] = TRUE;
+ break;
+ }
+ }
+#endif
+
+ // File opened in read mode
+ if (error == 72)
+ error = 0;
+
+ return(error);
+} // FSfclose
+
+
+
+
+/*******************************************************
+ Function:
+ void IncrementTimeStamp(DIRENTRY dir)
+ Summary:
+ Automatically set the timestamp to "don't care" data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ dir - Pointer to directory structure
+ Return Values:
+ None
+ Side Effects:
+ None
+ Description:
+ This function will increment the timestamp variable in
+ the 'dir' directory entry. This is used for the
+ don't-care timing method.
+ Remarks:
+ None
+ *******************************************************/
+#ifdef INCREMENTTIMESTAMP
+void IncrementTimeStamp(DIRENTRY dir)
+{
+ BYTE seconds;
+ BYTE minutes;
+ BYTE hours;
+
+ BYTE day;
+ BYTE month;
+ BYTE year;
+
+ seconds = (dir->DIR_WrtTime & 0x1f);
+ minutes = ((dir->DIR_WrtTime & 0x07E0) >> 5);
+ hours = ((dir->DIR_WrtTime & 0xF800) >> 11);
+
+ day = (dir->DIR_WrtDate & 0x1f);
+ month = ((dir->DIR_WrtDate & 0x01E0) >> 5);
+ year = ((dir->DIR_WrtDate & 0xFE00) >> 9);
+
+ if(seconds < 29)
+ {
+ // Increment number of seconds by 2
+ // This clock method isn't intended to be accurate anyway
+ seconds++;
+ }
+ else
+ {
+ seconds = 0x00;
+
+ if(minutes < 59)
+ {
+ minutes++;
+ }
+ else
+ {
+ minutes = 0;
+
+ if(hours < 23)
+ {
+ hours++;
+ }
+ else
+ {
+ hours = 0;
+ if(day < 30)
+ {
+ day++;
+ }
+ else
+ {
+ day = 1;
+
+ if(month < 12)
+ {
+ month++;
+ }
+ else
+ {
+ month = 1;
+ // new year
+ year++;
+ // This is only valid until 2107
+ }
+ }
+ }
+ }
+ }
+
+ dir->DIR_WrtTime = (WORD)(seconds);
+ dir->DIR_WrtTime |= ((WORD)(minutes) << 5);
+ dir->DIR_WrtTime |= ((WORD)(hours) << 11);
+
+ dir->DIR_WrtDate = (WORD)(day);
+ dir->DIR_WrtDate |= ((WORD)(month) << 5);
+ dir->DIR_WrtDate |= ((WORD)(year) << 9);
+}
+#endif
+
+/*****************************************************************
+ Function:
+ BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Fill a file object with specified dir entry data
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Passed member's location
+ Return Values:
+ FOUND - Operation successful
+ NOT_FOUND - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then copy
+ the file information for that entry into the 'fo' FSFILE
+ object.
+ Remarks:
+ None.
+ *****************************************************************/
+
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE index, a;
+ BYTE character;
+ BYTE status;
+ BYTE test = 0;
+
+ // Get the entry
+ if (((*fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) && (*fHandle != 0)) // 4-bit mask because 16-root entries max per sector
+ {
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ }
+ else
+ {
+ dir = Cache_File_Entry (fo, fHandle, FALSE);
+ }
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Make sure there is a directory left
+ if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
+ {
+ status = NO_MORE;
+ }
+ else
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ status = NOT_FOUND;
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // print the file name and extension
+ for (index=0; index < DIR_NAMESIZE; index++)
+ {
+ character = dir->DIR_Name[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // its possible to have an extension in a directory
+ character = dir->DIR_Extension[0];
+
+ // Get the file extension if its there
+ for (index=0; index < DIR_EXTENSION; index++)
+ {
+ character = dir->DIR_Extension[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // done and done with the name
+ // fo->name[++test] = (BYTE)'\0';
+
+ // Now store the identifier
+ fo->entry = *fHandle;
+
+ // see if we are still a good file
+ a = dir->DIR_Name[0];
+
+ if(a == DIR_DEL)
+ status = NOT_FOUND;
+ else
+ status = FOUND;
+
+ // Now store the size
+ fo->size = (dir->DIR_FileSize);
+
+ fo->cluster = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ /// -Get and store the attributes
+ a = dir->DIR_Attr;
+ fo->attributes = a;
+
+ // get the date and time
+ if ((a & ATTR_DIRECTORY) != 0)
+ {
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ }
+ else
+ {
+ fo->time = dir->DIR_WrtTime;
+ fo->date = dir->DIR_WrtDate;
+ }
+
+ }// deleted directory
+ }// Ensure we are still good
+ return(status);
+} // Fill_File_Object
+
+
+/************************************************************************
+ Function:
+ DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Load file information from a directory entry and cache the entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Information location
+ Return Values:
+ DIRENTRY - Pointer to the directory entry
+ NULL - Directory entry could not be loaded
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then return a pointer
+ to the directory entry in the global data buffer.
+ Remarks:
+ None.
+ ************************************************************************/
+
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE a;
+
+ fo->dirccls = fo->dirclus;
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+ if (dir == NULL)
+ return NULL;
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Make sure there is a directory left
+ if(a == DIR_EMPTY)
+ dir = (DIRENTRY)NULL;
+
+ if(dir != (DIRENTRY)NULL)
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ dir = (DIRENTRY)NULL;
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // scan through all the long dir entries
+ while(a == ATTR_LONG_NAME)
+ {
+ (*fHandle)++;
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+ if (dir == NULL)
+ return NULL;
+ a = dir->DIR_Attr;
+ } // long file name while loop
+ } // deleted dir
+ }// Ensure we are still good
+
+ return(dir);
+} // LoadDirAttrib
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+ Summary:
+ Erase a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location of file information
+ EraseClusters - Remove cluster allocation from FAT?
+ Return Values:
+ CE_GOOD - File erased successfully
+ CE_FILE_NOT_FOUND - Could not find the file on the card
+ CE_ERASE_FAIL - Internal Card erase failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries in the directory
+ pointed to by the dirclus value in the FSFILE object 'fo' that contains
+ the entry that corresponds to the fHandle offset. It will then mark that
+ entry as deleted. If the EraseClusters argument is TRUE, the chain of
+ clusters for that file will be marked as unused in the FAT by the
+ FAT_erase_cluster_chain function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+{
+ DIRENTRY dir;
+ BYTE a;
+ CETYPE status = CE_GOOD;
+ DWORD clus;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ // reset the cluster
+ clus = fo->dirclus;
+ fo->dirccls = clus;
+
+ // load the sector
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return CE_BADCACHEREAD;
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ a = dir->DIR_Name[0];
+
+ // see if there is something in the dir
+ if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ /* 8.3 File Name - entry*/
+ dir->DIR_Name[0] = DIR_DEL; // mark as deleted
+
+ // Get the starting cluster
+ clus = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ // Now write it
+ if(status != CE_GOOD || !(Write_File_Entry( fo, fHandle)))
+ {
+ status = CE_ERASE_FAIL;
+ }
+ else
+ {
+ if (clus != FatRootDirClusterValue) //
+ {
+ if(EraseClusters)
+ {
+ /* Now remove the cluster allocation from the FAT */
+ status = ((FAT_erase_cluster_chain(clus, disk)) ? CE_GOOD : CE_ERASE_FAIL);
+ }
+ }
+ }
+ } // Not already deleted
+ }// Not existant
+
+ if (status == CE_GOOD)
+ FSerrno = CE_GOOD;
+ else
+ FSerrno = CE_ERASE_FAIL;
+
+ return (status);
+}
+#endif
+
+/***************************************************************
+ Function:
+ int FSrename (const rom char * fileName, FSFILE * fo)
+ Summary:
+ Change the name of a file or directory
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file
+ fo - The file to rename
+ Return Values:
+ 0 - File was renamed successfully
+ EOF - File was not renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrename function will rename a file. First, it will
+ search through the current working directory to ensure the
+ specified new filename is not already in use. If it isn't,
+ the new filename will be written to the file entry of the
+ file pointed to by 'fo.'
+ Remarks:
+ None
+ ***************************************************************/
+
+#ifdef ALLOW_WRITES
+
+int FSrename (const char * fileName, FSFILE * fo)
+{
+ unsigned char j, k = 0;
+ char string[12];
+ WORD fHandle = 1, goodHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ if (fo == NULL)
+ {
+ FSerrno = CE_FILENOTOPENED;
+ return -1;
+ }
+ // If fo != NULL, rename the file
+ if (FormatFileName (fileName, fo->name, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+ else
+ {
+ for (j = 0; j < 11; j++)
+ {
+ string[j] = fo->name[j];
+ }
+ goodHandle = fo->entry;
+
+ fHandle = 0;
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Check if the file name is already used
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+
+ nextClusterIsLast = FALSE;
+ while (1)
+ {
+ // Look through the entries until we get to the end
+ // to make sure the name isn't taken
+ dir = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dir == NULL)
+ {
+ if (nextClusterIsLast == TRUE)
+ {
+ break;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ if (dir->DIR_Name[0] == 0)
+ break;
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+ fHandle++;
+ }
+
+ fHandle = goodHandle;
+ fo->dirccls = fo->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ for (j = 0; j < 11; j++)
+ {
+ dir->DIR_Name[j] = fo->name[j];
+ }
+
+ // just write the last entry in
+ if(!Write_File_Entry(fo,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#endif // Allow writes
+
+
+
+/*********************************************************************
+ Function:
+ FSFILE * FSfopen (const char * fileName, const char *mode)
+ Summary:
+ Open a file
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to open
+ mode -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ - WRITEPLUS - Create a new file or replace an existing file (reads also enabled)
+ - READPLUS - Read data from an existing file (writes also enabled)
+ - APPENDPLUS - Append data to an existing file (reads also enabled)
+ Return Values:
+ FSFILE * - The pointer to the file object
+ NULL - The file could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will open a file or directory. First, RAM in the
+ dynamic heap or static array will be allocated to a new FSFILE object.
+ Then, the specified file name will be formatted to ensure that it's
+ in 8.3 format. Next, the FILEfind function will be used to search
+ for the specified file name. If the name is found, one of three
+ things will happen: if the file was opened in read mode, its file
+ info will be loaded using the FILEopen function; if it was opened in
+ write mode, it will be erased, and a new file will be constructed in
+ its place; if it was opened in append mode, its file info will be
+ loaded with FILEopen and the current location will be moved to the
+ end of the file using the FSfseek function. If the file was not
+ found by FILEfind, it will be created if the mode was specified as
+ a write or append mode. In these cases, a pointer to the heap or
+ static FSFILE object array will be returned. If the file was not
+ found and the mode was specified as a read mode, the memory
+ allocated to the file will be freed and the NULL pointer value
+ will be returned.
+ Remarks:
+ None.
+ *********************************************************************/
+
+FSFILE * FSfopen( const char * fileName, const char *mode )
+{
+ FILEOBJ filePtr;
+#ifndef FS_DYNAMIC_MEM
+ int fIndex;
+#endif
+ BYTE ModeC;
+ WORD fHandle;
+ CETYPE final;
+
+#ifdef FS_DYNAMIC_MEM
+ filePtr = (FILEOBJ) FS_malloc(sizeof(FSFILE));
+#else
+
+ filePtr = NULL;
+
+ //Pick available file structure
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( gFileSlotOpen[fIndex] ) //this slot is available
+ {
+ gFileSlotOpen[fIndex] = FALSE;
+ filePtr = &gFileArray[fIndex];
+ break;
+ }
+ }
+
+ if( filePtr == NULL )
+ {
+ FSerrno = CE_TOO_MANY_FILES_OPEN;
+ return NULL; //no file structure slot available
+ }
+#endif
+
+ //Format the source string.
+ if( !FormatFileName(fileName, filePtr->name, 0) )
+ {
+#ifdef FS_DYNAMIC_MEM
+ FS_free( (unsigned char *)filePtr );
+#else
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+#endif
+ FSerrno = CE_INVALID_FILENAME;
+ return NULL; //bad filename
+ }
+
+ //Read the mode character
+ ModeC = mode[0];
+
+ filePtr->dsk = &gDiskData;
+ filePtr->cluster = 0;
+ filePtr->ccls = 0;
+ filePtr->entry = 0;
+ filePtr->attributes = ATTR_ARCHIVE;
+
+ // start at the current directory
+#ifdef ALLOW_DIRS
+ filePtr->dirclus = cwdptr->dirclus;
+ filePtr->dirccls = cwdptr->dirccls;
+#else
+ filePtr->dirclus = FatRootDirClusterValue;
+ filePtr->dirccls = FatRootDirClusterValue;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, filePtr);
+
+ // See if the file is found
+ if(FILEfind (filePtr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0) == CE_GOOD)
+ {
+ // File is Found
+ switch(ModeC)
+ {
+#ifdef ALLOW_WRITES
+ case 'w':
+ case 'W':
+ {
+ // File exists, we want to create a new one, remove it first
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ break;
+ }
+
+ case 'A':
+ case 'a':
+ {
+ if(filePtr->size != 0)
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ else
+ {
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ }
+ break;
+ }
+#endif
+ case 'R':
+ case 'r':
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'r');
+#ifdef ALLOW_WRITES
+ if ((mode[1] == '+') && !(filePtr->attributes & ATTR_DIRECTORY))
+ filePtr->flags.write = 1;
+#endif
+ break;
+ }
+
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;; //indicate error condition
+ break;
+ }
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ // the file was not found, reset to the default asked
+ FileObjectCopy(filePtr, &gFileTemp);
+
+ // File is not Found
+ if(ModeC == 'w' || ModeC == 'W' || ModeC == 'a' || ModeC == 'A')
+ {
+ // use the user requested name
+ fHandle = 0;
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ else
+#endif
+ final = CE_FILE_NOT_FOUND;
+ }
+
+ if (MDD_WriteProtectState())
+ {
+ filePtr->flags.write = 0;;
+ }
+
+#ifdef FS_DYNAMIC_MEM
+ if( final != CE_GOOD )
+ {
+ FS_free( (unsigned char *)filePtr );
+ filePtr = NULL;
+ }
+#else
+ if( final != CE_GOOD )
+ {
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+ filePtr = NULL;
+ }
+#endif
+ else
+ {
+ FSerrno = CE_GOOD;
+ }
+
+ return filePtr;
+}
+
+/*******************************************************************
+ Function:
+ long FSftell (FSFILE * fo)
+ Summary:
+ Determine the current location in a file
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to file structure
+ Return: Current location in the file
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSftell function will return the current position in the
+ file pointed to by 'fo' by returning the 'seek' variable in the
+ FSFILE object, which is used to keep track of the absolute
+ location of the current position in the file.
+ Remarks:
+ None
+ *******************************************************************/
+
+long FSftell (FSFILE * fo)
+{
+ FSerrno = CE_GOOD;
+ return (fo->seek);
+}
+
+
+#ifdef ALLOW_WRITES
+
+/*********************************************************************
+ Function:
+ int FSremove (const char * fileName)
+ Summary:
+ Delete a file
+ Conditions:
+ File not opened, file exists
+ Input:
+ fileName - Name of the file to erase
+ Return Values:
+ 0 - File removed
+ EOF - File was not removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremove function will attempt to find the specified file with
+ the FILEfind function. If the file is found, it will be erased
+ using the FILEerase function.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSremove (const char * fileName)
+{
+ FILEOBJ fo = &tempCWDobj;
+ CETYPE result;
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+ //Format the source string
+ if( !FormatFileName(fileName, fo->name, 0) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = ATTR_ARCHIVE;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+
+ if (fo->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_DELETE_DIR;
+ return -1;
+ }
+
+ result = FILEerase(fo, &fo->entry, TRUE);
+ if( result == CE_GOOD )
+ return 0;
+ else
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+}
+#endif
+
+/*********************************************************
+ Function:
+ void FSrewind (FSFILE * fo)
+ Summary:
+ Set the current position in a file to the beginning
+ Conditions:
+ File opened.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ None
+ Side Effects:
+ None.
+ Description:
+ The FSrewind funciton will reset the position of the
+ specified file to the beginning of the file. This
+ functionality is faster than using FSfseek to reset
+ the position in the file.
+ Remarks:
+ None.
+ *********************************************************/
+
+void FSrewind (FSFILE * fo)
+{
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ flushData();
+#endif
+ fo->seek = 0;
+ fo->pos = 0;
+ fo->sec = 0;
+ fo->ccls = fo->cluster;
+ gBufferOwner = NULL;
+ return;
+}
+
+/**************************************************************************
+ Function:
+ int FSerror (void)
+ Summary:
+ Return an error code for the last function call
+ Conditions:
+ The return value depends on the last function called.
+ Input:
+ None
+ Side Effects:
+ None.
+ Return Values:
+ FSInit -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The physical media could not be initialized
+ - CE_BAD_SECTOR_READ � The MBR or the boot sector could not be
+ read correctly
+ - CE_BAD_PARITION � The MBR signature code was incorrect.
+ - CE_NOT_FORMATTED � The boot sector signature code was incorrect or
+ indicates an invalid number of bytes per sector.
+ - CE_CARDFAT32 � The physical media is FAT32 type (only an error
+ when FAT32 support is disabled).
+ - CE_UNSUPPORTED_FS � The device is formatted with an unsupported file
+ system (not FAT12 or 16).
+ FSfopen -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The device has not been initialized.
+ - CE_TOO_MANY_FILES_OPEN � The function could not allocate any
+ additional file information to the array
+ of FSFILE structures or the heap.
+ - CE_INVALID_FILENAME � The file name argument was invalid.
+ - CE_INVALID_ARGUMENT � The user attempted to open a directory in a
+ write mode or specified an invalid mode argument.
+ - CE_FILE_NOT_FOUND � The specified file (which was to be opened in read
+ mode) does not exist on the device.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_ERASE_FAIL � The existing file could not be erased (when opening
+ a file in WRITE mode).
+ - CE_DIR_FULL � The directory is full.
+ - CE_DISK_FULL� The data memory section is full.
+ - CE_WRITE_ERROR � A write to the device failed.
+ - CE_SEEK_ERROR � The current position in the file could not be set to
+ the end (when the file was opened in APPEND mode).
+ FSfclose -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer or the new file
+ entry information could not be written to the device.
+ - CE_BADCACHEREAD � The file entry information could not be cached
+ FSfread -
+ - CE_GOOD � No Error
+ - CE_WRITEONLY � The file was opened in a write-only mode.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_BAD_SECTOR_READ � The data sector could not be read.
+ - CE_EOF � The end of the file was reached.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be loaded.
+ FSfwrite -
+ - CE_GOOD � No Error
+ - CE_READONLY � The file was opened in a read-only mode.
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_WRITE_ERROR � There was an error writing data to the device.
+ - CE_BADCACHEREAD � The data sector to be modified could not be read from
+ the device.
+ - CE_DISK_FULL � All data clusters on the device are in use.
+ FSfseek -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_INVALID_ARGUMENT � The specified offset exceeds the size of the file.
+ - CE_BADCACHEREAD � The sector that contains the new current position
+ could not be loaded.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be
+ loaded/allocated.
+ FSftell -
+ - CE_GOOD � No Error
+ FSattrib -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The attribute argument was invalid.
+ - CE_BADCACHEREAD � The existing file entry information could not be
+ loaded.
+ - CE_WRITE_ERROR � The file entry information could not be written to
+ the device.
+ FSrename -
+ - CE_GOOD � No Error
+ - CE_FILENOTOPENED � A null file pointer was passed into the function.
+ - CE_INVALID_FILENAME � The file name passed into the function was invalid.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_FILENAME_EXISTS � A file with the specified name already exists.
+ - CE_WRITE_ERROR � The new file entry data could not be written to the
+ device.
+ FSfeof -
+ - CE_GOOD � No Error
+ FSformat -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The device could not be initialized.
+ - CE_BADCACHEREAD � The master boot record or boot sector could not be
+ loaded successfully.
+ - CE_INVALID_ARGUMENT � The user selected to create their own boot sector on
+ a device that has no master boot record, or the mode
+ argument was invalid.
+ - CE_WRITE_ERROR � The updated MBR/Boot sector could not be written to
+ the device.
+ - CE_BAD_PARTITION � The calculated number of sectors per clusters was
+ invalid.
+ - CE_NONSUPPORTED_SIZE � The card has too many sectors to be formatted as
+ FAT12 or FAT16.
+ FSremove -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � The specified file could not be found.
+ - CE_ERASE_FAIL � The file could not be erased.
+ FSchdir -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The path string was mis-formed or the user tried to
+ change to a non-directory file.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_FOUND � Could not find a directory in the path.
+ FSgetcwd -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The user passed a 0-length buffer into the function.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the current working directory.
+ FSmkdir -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_ARGUMENT � The path string was mis-formed.
+ - CE_BADCACHEREAD � Could not successfully change to a recently created
+ directory to store its dir entry information, or
+ could not cache directory entry information.
+ - CE_INVALID_FILENAME � One or more of the directory names has an invalid
+ format.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device or the dot/dotdot entries could
+ not be written to a newly created directory.
+ - CE_DIR_FULL � There are no available dir entries in the CWD.
+ - CE_DISK_FULL � There are no available clusters in the data region of
+ the device.
+ FSrmdir -
+ - CE_GOOD � No Error
+ - CE_DIR_NOT_FOUND � The directory specified could not be found or the
+ function could not change to a subdirectory within
+ the directory to be deleted (when recursive delete is
+ enabled).
+ - CE_INVALID_ARGUMENT � The user tried to remove the CWD or root directory.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_EMPTY � The directory to be deleted was not empty and
+ recursive subdirectory removal was disabled.
+ - CE_ERASE_FAIL � The directory or one of the directories or files
+ within it could not be deleted.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the CWD.
+ SetClockVars -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The time values passed into the function were
+ invalid.
+ FindFirst -
+ - CE_GOOD � No Error
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ - CE_BADCACHEREAD � The file information for the file that was found
+ could not be cached.
+ FindNext -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The SearchRec object was not initialized by a call to
+ FindFirst.
+ - CE_INVALID_ARGUMENT � The SearchRec object was initialized in a different
+ directory from the CWD.
+ - CE_INVALID_FILENAME � The filename is invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ FSfprintf -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � Characters could not be written to the file.
+ Description:
+ The FSerror function will return the FSerrno variable. This global
+ variable will have been set to an error value during the last call of a
+ library function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSerror (void)
+{
+ return FSerrno;
+}
+
+
+/**************************************************************
+ Function:
+ void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+ Summary:
+ Copy a file object
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - The destination
+ foSource - the source
+ Return:
+ None
+ Side Effects:
+ None
+ Description:
+ The FileObjectCopy function will make an exacy copy of
+ a specified FSFILE object.
+ Remarks:
+ None
+ **************************************************************/
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+{
+ BYTE size;
+ BYTE *dest;
+ BYTE *source;
+ BYTE Index;
+
+ dest = (BYTE *)foDest;
+ source = (BYTE *)foSource;
+
+ size = sizeof(FSFILE);
+
+ for(Index=0;Index< size; Index++)
+ {
+ dest[Index] = source[Index];
+ }
+}
+
+/*************************************************************************
+ Function:
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+ Summary:
+ Create the first cluster of a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ cluster - Cluster location
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ CE_DISK_FULL - All clusters in partition are taken
+ Side Effects:
+ None
+ Description:
+ The FILECreateHeadCluster function will create the first cluster
+ of a file. First, it will find an empty cluster with the
+ FATfindEmptyCluster function and mark it as the last cluster in the
+ file. It will then erase the cluster using the EraseCluster function.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+{
+ DISK * disk;
+ CETYPE error = CE_GOOD;
+
+ disk = fo->dsk;
+
+ // find the next empty cluster
+ *cluster = FATfindEmptyCluster(fo);
+
+ if(*cluster == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ {
+ error = CE_DISK_FULL;
+ }
+ else
+ {
+ // mark the cluster as taken, and last in chain
+ if(disk->type == FAT12)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT12, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+ else if(disk->type == FAT16)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT16, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+
+ #ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT32, FALSE) == CLUSTER_FAIL_FAT32)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+#endif
+
+ // lets erase this cluster
+ if(error == CE_GOOD)
+ {
+ error = EraseCluster(disk,*cluster);
+ }
+ }
+
+ return(error);
+} // allocate head cluster
+#endif
+
+/*************************************************************************
+ Function:
+ BYTE EraseCluster(DISK *disk, DWORD cluster)
+ Summary:
+ Erase a cluster
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - Disk structure
+ cluster - Cluster to be erased
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ Side Effects:
+ None
+ Description:
+ The EraseCluster function will write a 0 value into every byte of
+ the specified cluster.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE EraseCluster(DISK *disk, DWORD cluster)
+{
+ BYTE index;
+ DWORD SectorAddress;
+ BYTE error = CE_GOOD;
+
+ SectorAddress = Cluster2Sector(disk,cluster);
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+
+ gBufferOwner = NULL;
+
+ if (gBufferZeroed == FALSE)
+ {
+ // clear out the memory first
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+ gBufferZeroed = TRUE;
+ }
+
+ // Now clear them out
+ for(index = 0; index < disk->SecPerClus && error == CE_GOOD; index++)
+ {
+ if (MDD_SectorWrite( SectorAddress++, disk->buffer, FALSE) != TRUE)
+ error = CE_WRITE_ERROR;
+ }
+
+ return(error);
+}
+#endif
+
+
+#if defined (__C30__) || defined (__C32__)
+
+/***************************************************
+ Function:
+ BYTE ReadByte(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a byte from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ BYTE - the byte read
+ Side Effects:
+ None
+ Description:
+ Reads a byte from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+BYTE ReadByte( BYTE* pBuffer, WORD index )
+{
+ return( pBuffer[index] );
+}
+
+
+/***************************************************
+ Function:
+ BYTE ReadWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 16-bit word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ WORD - the word read
+ Side Effects:
+ None
+ Description:
+ Reads a 16-bit word from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+WORD ReadWord( BYTE* pBuffer, WORD index )
+{
+ BYTE loByte, hiByte;
+ WORD res;
+
+ loByte = pBuffer[index];
+ hiByte = pBuffer[index+1];
+ res = hiByte;
+ res *= 0x100;
+ res |= loByte;
+ return( res );
+}
+
+
+/****************************************************
+ Function:
+ BYTE ReadDWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 32-bit double word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ DWORD - the double word read
+ Side Effects:
+ None
+ Description:
+ Reads a 32-bit double word from a buffer
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD ReadDWord( BYTE* pBuffer, WORD index )
+{
+ WORD loWord, hiWord;
+ DWORD result;
+
+ loWord = ReadWord( pBuffer, index );
+ hiWord = ReadWord( pBuffer, index+2 );
+
+ result = hiWord;
+ result *= 0x10000;
+ result |= loWord;
+ return result;
+}
+
+#endif
+
+
+
+/****************************************************
+ Function:
+ DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+ Summary:
+ Convert a cluster number to the corresponding sector
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - Disk structure
+ cluster - Cluster to be converted
+ Return:
+ sector - Sector that corresponds to given cluster
+ Side Effects:
+ None
+ Description:
+ The Cluster2Sector function will calculate the
+ sector number that corresponds to the first sector
+ of the cluster whose value was passed into the
+ function.
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+{
+ DWORD sector;
+
+ /* Rt: Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ /* In FAT32, there is no separate ROOT region. It is as well stored in DATA region */
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // The root dir takes up cluster 0 and 1
+ if(cluster == 0 ||cluster == 1)
+ sector = dsk->root + cluster;
+ else
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+ }
+
+ return(sector);
+
+}
+
+
+/***************************************************************************
+ Function:
+ int FSattrib (FSFILE * file, unsigned char attributes)
+ Summary:
+ Change the attributes of a file
+ Conditions:
+ File opened
+ Input:
+ file - Pointer to file structure
+ attributes - The attributes to set for the file
+ - Attribute - Value - Indications
+ - ATTR_READ_ONLY - 0x01 - The read-only attribute
+ - ATTR_HIDDEN - 0x02 - The hidden attribute
+ - ATTR_SYSTEM - 0x04 - The system attribute
+ - ATTR_ARCHIVE - 0x20 - The archive attribute
+ Return Values:
+ 0 - Attribute change was successful
+ -1 - Attribute change was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSattrib funciton will set the attributes of the specified file
+ to the attributes passed in by the user. This function will load the
+ file entry, replace the attributes with the ones specified, and write
+ the attributes back. If the specified file is a directory, the
+ directory attribute will be preserved.
+ Remarks:
+ None
+ ***************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSattrib (FSFILE * file, unsigned char attributes)
+{
+ WORD fHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ // Check for valid attributes
+ if ((attributes & ~0x27) != 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ fHandle = file->entry;
+
+ file->dirccls = file->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(file, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Ensure that we aren't trying to change the
+ // attributes of a volume entry
+ if (dir->DIR_Attr & ATTR_VOLUME)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Don't remove the directory attribute from DIR files
+ if (file->attributes & ATTR_DIRECTORY)
+ dir->DIR_Attr = attributes | ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = attributes;
+
+ // just write the last entry in
+ if(!Write_File_Entry(file,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+
+/*********************************************************************************
+ Function:
+ size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Write data to a file
+ Conditions:
+ File opened in WRITE, APPEND, WRITE+, APPEND+, READ+ mode
+ Input:
+ ptr - Pointer to source buffer
+ size - Size of units in bytes
+ n - Number of units to transfer
+ stream - Pointer to file structure
+ Return:
+ size_t - number of units written
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfwrite function will write data to a file. First, the sector that
+ corresponds to the current position in the file will be loaded (if it hasn't
+ already been cached in the global data buffer). Data will then be written to
+ the device from the specified buffer until the specified amount has been written.
+ If the end of a cluster is reached, the next cluster will be loaded, unless
+ the end-of-file flag for the specified file has been set. If it has, a new
+ cluster will be allocated to the file. Finally, the new position and filezize
+ will be stored in the FSFILE object. The parameters 'size' and 'n' indicate how
+ much data to write. 'Size' refers to the size of one object to write (in bytes),
+ and 'n' will refer to the number of these objects to write. The value returned
+ will be equal to 'n' unless an error occured.
+ Remarks:
+ None.
+ *********************************************************************************/
+
+#ifdef ALLOW_WRITES
+size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD count = size * n;
+ BYTE * src = (BYTE *) ptr;
+ DISK * dsk; // pointer to disk structure
+ CETYPE error = CE_GOOD;
+ WORD pos;
+ DWORD l; // absolute lba of sector to load
+ DWORD seek, filesize;
+ WORD writeCount = 0;
+
+ // see if the file was opened in a write mode
+ if(!(stream->flags.write))
+ {
+ FSerrno = CE_READONLY;
+ error = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ if (count == 0)
+ return 0;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ error = CE_WRITE_PROTECTED;
+ return 0;
+ }
+
+ gBufferZeroed = FALSE;
+ dsk = stream->dsk;
+ // get the stated position
+ pos = stream->pos;
+ seek = stream->seek;
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ // Check if the current stream was the last one to use the
+ // buffer. If not, check if we need to write data from the
+ // old stream
+ if (gBufferOwner != stream)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+ gBufferOwner = stream;
+ }
+ if (gLastDataSectorRead != l)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+
+ gBufferZeroed = FALSE;
+ if(!MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ }
+ gLastDataSectorRead = l;
+ }
+ // exit loop if EOF reached
+ filesize = stream->size;
+
+ // Loop while writing bytes
+ while (error == CE_GOOD && count > 0)
+ {
+ if( seek == filesize )
+ stream->flags.FileWriteEOF = TRUE;
+
+ // load a new sector if necessary, multiples of sector
+ if (pos == MEDIA_SECTOR_SIZE)
+ {
+ BYTE needRead = TRUE;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ // reset position
+ pos = 0;
+
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if (stream->sec == dsk->SecPerClus)
+ {
+ stream->sec = 0;
+
+ if(stream->flags.FileWriteEOF)
+ {
+ error = FILEallocate_new_cluster(stream, 0); // add new cluster to the file
+ needRead = FALSE;
+ }
+ else
+ error = FILEget_next_cluster( stream, 1);
+ }
+
+ if (error == CE_DISK_FULL)
+ {
+ FSerrno = CE_DISK_FULL;
+ return 0;
+ }
+
+ if(error == CE_GOOD)
+ {
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+ gBufferOwner = stream;
+ // If we just allocated a new cluster, then the cluster will
+ // contain garbage data, so it doesn't matter what we write to it
+ // Whatever is in the buffer will work fine
+ if (needRead)
+ {
+ if( !MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = 0xFFFFFFFF;
+ return 0;
+ }
+ else
+ {
+ gLastDataSectorRead = l;
+ }
+ }
+ else
+ gLastDataSectorRead = l;
+ }
+ } // load new sector
+
+ if(error == CE_GOOD)
+ {
+ // Write one byte at a time
+ RAMwrite(dsk->buffer, pos++, *(char *)src);
+ src = src + 1; // compiler bug
+ seek++;
+ count--;
+ writeCount++;
+ // now increment the size of the part
+ if(stream->flags.FileWriteEOF)
+ filesize++;
+ gNeedDataWrite = TRUE;
+ }
+ } // while count
+
+ // save off the positon
+ stream->pos = pos;
+
+ // save off the seek
+ stream->seek = seek;
+
+ // now the new size
+ stream->size = filesize;
+
+ return(writeCount / size);
+} // fwrite
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE flushData (void)
+ Summary:
+ Flush unwritten data to a file
+ Conditions:
+ File opened in a write mode, data needs to be written
+ Return Values:
+ CE_GOOD - Data was updated successfully
+ CE_WRITE_ERROR - Data could not be updated
+ Side Effects:
+ None
+ Description:
+ The flushData function is called when it is necessary to
+ read new data into the global data buffer and the
+ gNeedDataWrite variable indicates that there is data
+ in the buffer that hasn't been written to the device.
+ The flushData function will write the data from the
+ buffer into the current cluster of the FSFILE object
+ that is stored in the gBufferOwner global variable.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE flushData (void)
+{
+ DWORD l;
+ DISK * dsk;
+
+ // This will either be the pointer to the last file, or the handle
+ FILEOBJ stream = gBufferOwner;
+
+ dsk = stream->dsk;
+
+ // figure out the lba
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ if(!MDD_SectorWrite( l, dsk->buffer, FALSE))
+ {
+ return CE_WRITE_ERROR;
+ }
+
+ gNeedDataWrite = FALSE;
+
+ return CE_GOOD;
+}
+#endif
+
+/****************************************************
+ Function:
+ int FSfeof( FSFILE * stream )
+ Summary:
+ Indicate whether the current file position is at the end
+ Conditions:
+ File is open in a read mode
+ Input:
+ stream - Pointer to the target file
+ Return Values:
+ Non-Zero - EOF reached
+ 0 - Not at end of File
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfeof function will indicate that the end-of-
+ file has been reached for the specified file by
+ comparing the absolute location in the file to the
+ size of the file.
+ Remarks:
+ None.
+ ****************************************************/
+
+int FSfeof( FSFILE * stream )
+{
+ FSerrno = CE_GOOD;
+ return( stream->seek == stream->size );
+}
+
+
+/**************************************************************************
+ Function:
+ size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Read data from a file
+ Conditions:
+ File is opened in a read mode
+ Input:
+ ptr - Destination buffer for read bytes
+ size - Size of units in bytes
+ n - Number of units to be read
+ stream - File to be read from
+ Return:
+ size_t - number of units read
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfread function will read data from the specified file. First,
+ the appropriate sector of the file is loaded. Then, data is read into
+ the specified buffer until the specified number of bytes have been read.
+ When a cluster boundary is reached, a new cluster will be loaded. The
+ parameters 'size' and 'n' indicate how much data to read. 'Size'
+ refers to the size of one object to read (in bytes), and 'n' will refer
+ to the number of these objects to read. The value returned will be equal
+ to 'n' unless an error occured or the user tried to read beyond the end
+ of the file.
+ Remarks:
+ None.
+ **************************************************************************/
+
+size_t FSfread (void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD len = size * n;
+ BYTE *pointer = (BYTE *) ptr;
+ DISK *dsk; // Disk structure
+ DWORD seek, sec_sel;
+ WORD pos; //position within sector
+ CETYPE error = CE_GOOD;
+ WORD readCount = 0;
+
+ FSerrno = CE_GOOD;
+
+ dsk = (DISK *)stream->dsk;
+ pos = stream->pos;
+ seek = stream->seek;
+
+ if( !stream->flags.read )
+ {
+ FSerrno = CE_WRITEONLY;
+ return 0; // CE_WRITEONLY
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+#endif
+
+ // if it not my buffer, then get it from the disk.
+ if( (gBufferOwner != stream) && (pos != MEDIA_SECTOR_SIZE ))
+ {
+ gBufferOwner = stream;
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ return 0;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ //loop reading (count) bytes
+ while( len )
+ {
+ if( seek == stream->size )
+ {
+ FSerrno = CE_EOF;
+ error = CE_EOF;
+ break;
+ }
+
+ // In fopen, pos is init to 0 and the sect is loaded
+ if( pos == MEDIA_SECTOR_SIZE )
+ {
+ // reset position
+ pos = 0;
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if( stream->sec == dsk->SecPerClus )
+ {
+ stream->sec = 0;
+ if( (error = FILEget_next_cluster( stream, 1)) != CE_GOOD )
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ break;
+ }
+ }
+
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+
+ gBufferOwner = stream;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ break;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ // copy one byte at a time
+ *pointer = RAMread( dsk->buffer, pos++ );
+ pointer++;
+ seek++;
+ readCount++;
+ len--;
+ }
+
+ // save off the positon
+ stream->pos = pos;
+ // save off the seek
+ stream->seek = seek;
+
+ return(readCount / size);
+} // fread
+
+
+/***************************************************************************
+ Function:
+ BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode )
+ Summary:
+ Format a file name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be formatted
+ fN2 - The location the formatted name will be stored
+ mode - Non-zero if parital string search chars are allowed
+ Return Values:
+ TRUE - Name formatted successfully
+ FALSE - File name could not be formatted
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into FSFILE structure format. If filename is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ filename are valid in this filesystem.
+ Remarks:
+ None.
+ ***************************************************************************/
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode)
+{
+ char * pExt;
+ WORD temp;
+ char szName[15];
+ BYTE count;
+
+ for (count = 0; count < 11; count++)
+ {
+ *(fN2 + count) = ' '; // Load destination filename to be space intially.
+ }
+
+ // Make sure we dont have an empty string or a name with only
+ // an extension
+ if (fileName[0] == '.' || fileName[0] == 0)
+ return FALSE;
+
+ temp = strlen( fileName );
+
+ if( temp <= TOTAL_FILE_SIZE ) // 8+3+1
+ strcpy( szName, fileName ); // copy to RAM in case fileName is located in flash
+ else
+ return FALSE; //long file name
+
+ // Make sure the characters are valid
+ if ( !ValidateChars(szName, mode) )
+ return FALSE;
+
+ //Look for '.' in the szName
+ if( (pExt = strchr( szName, '.' )) != 0 )
+ {
+ *pExt = 0; // Assigning NULL here makes the "szName" to be terminated and "pExt" pointer to hold only extn characters.
+ pExt++; // now pointing to extension
+
+ if( strlen( pExt ) > 3 ) // make sure the extension is 3 bytes or fewer
+ return FALSE;
+ }
+
+ if( strlen(szName) > 8 )
+ return FALSE;
+
+ //copy file name
+ for (count = 0; count < strlen(szName); count++)
+ {
+ *(fN2 + count) = * (szName + count); // Destination filename initially filled with SPACE. Now copy only available chars.
+ }
+
+ //copy extension
+ if(pExt && *pExt )
+ {
+ for (count = 0; count < strlen (pExt); count++)
+ {
+ *(fN2 + count + 8) = *(pExt + count); // Copy the extn to 8th position onwards. Ex: "FILE .Tx "
+ }
+ }
+
+ return TRUE;
+}
+
+#ifdef ALLOW_DIRS
+
+/*************************************************************************
+ Function:
+ BYTE FormatDirName (char * string, BYTE mode)
+ Summary:
+ Format a dir name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ string - The name to be formatted
+ mode -
+ - TRUE - Partial string search characters are allowed
+ - FALSE - Partial string search characters are forbidden
+ Return Values:
+ TRUE - The name was formatted correctly
+ FALSE - The name contained invalid characters
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into directory structure format. If the name is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ directory name are valid in this filesystem.
+ Remarks:
+ None.
+ *************************************************************************/
+
+BYTE FormatDirName (char * string, BYTE mode)
+{
+ unsigned char i, j;
+ char tempString [12];
+
+ if (ValidateChars (string, mode) == FALSE)
+ return FALSE;
+
+ for (i = 0; (i < 8) && (*(string + i) != '.') && (*(string + i) != 0); i++)
+ {
+ tempString[i] = *(string + i);
+ }
+
+ j = i;
+
+ while (i < 8)
+ {
+ tempString [i++] = 0x20;
+ }
+
+ if (*(string + j) == '.')
+ {
+ j++;
+ while (*(string + j) != 0)
+ {
+ tempString[i++] = *(string + j++);
+ }
+ }
+
+ while (i < 11)
+ {
+ tempString[i++] = 0x20;
+ }
+
+ tempString[11] = 0;
+
+ // Forbidden
+ if (tempString[0] == 0x20)
+ {
+ tempString[0] = '_';
+ }
+
+ for (i = 0; i < 12; i++)
+ {
+ *(string + i) = tempString[i];
+ }
+
+ return TRUE;
+}
+#endif
+
+
+/*************************************************************
+ Function:
+ BYTE ValidateChars( char * FileName, BYTE mode)
+ Summary:
+ Validate the characters in a given file name
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be validated
+ mode - Determines if partial string search is allowed
+ Return Values:
+ TRUE - Name was validated
+ FALSE - File name was not valid
+ Side Effects:
+ None
+ Description:
+ The ValidateChars function will compare characters in a
+ specified filename to determine if they're permissable
+ in the FAT file system. Lower-case characters will be
+ converted to upper-case. If the mode argument is specifed
+ to be 'TRUE,' partial string search characters are allowed.
+ Remarks:
+ None.
+ *************************************************************/
+BYTE ValidateChars( char * FileName , BYTE mode)
+{
+ int StrSz, index;
+ unsigned char radix = FALSE;
+
+ StrSz = strlen(FileName);
+
+ for( index = 0; index < StrSz; index++ )
+ {
+ if (((FileName[index] <= 0x20) && (FileName[index] != 0x05)) ||
+ (FileName[index] == 0x22) || (FileName[index] == 0x2B) ||
+ (FileName[index] == 0x2C) || (FileName[index] == 0x2F) ||
+ (FileName[index] == 0x3A) || (FileName[index] == 0x3B) ||
+ (FileName[index] == 0x3C) || (FileName[index] == 0x3D) ||
+ (FileName[index] == 0x3E) || (FileName[index] == 0x5B) ||
+ (FileName[index] == 0x5C) || (FileName[index] == 0x5D) ||
+ (FileName[index] == 0x7C) || ((FileName[index] == 0x2E) && radix == TRUE))
+ {
+ return FALSE;
+ }
+ else
+ {
+ // Check for partial string search chars
+ if (mode == FALSE)
+ {
+ if ((FileName[index] == '*') || (FileName[index] == '?'))
+ return FALSE;
+ }
+ // only one radix ('.') character is allowed
+ if (FileName[index] == 0x2E)
+ {
+ radix = TRUE;
+ }
+ // Convert lower-case to upper-case
+ if ((FileName[index] >= 0x61) && (FileName[index] <= 0x7A))
+ FileName[index] -= 0x20;
+ }
+ }
+ return TRUE;
+}
+
+
+/**********************************************************************
+ Function:
+ int FSfseek(FSFILE *stream, long offset, int whence)
+ Summary:
+ Change the current position in a file
+ Conditions:
+ File opened
+ Input:
+ stream - Pointer to file structure
+ offset - Offset from base location
+ whence -
+ - SEEK_SET - Seek from start of file
+ - SEEK_CUR - Seek from current location
+ - SEEK_END - Seek from end of file (subtract offset)
+ Return Values:
+ 0 - Operation successful
+ -1 - Operation unsuccesful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfseek function will change the current position in the file to
+ one specified by the user. First, an absolute offset is calculated
+ using the offset and base location passed in by the user. Then, the
+ position variables are updated, and the sector number that corresponds
+ to the new location. That sector is then loaded. If the offset
+ falls exactly on a cluster boundary, a new cluster will be allocated
+ to the file and the position will be set to the first byte of that
+ cluster.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSfseek(FSFILE *stream, long offset, int whence)
+{
+ DWORD numsector, temp; // lba of first sector of first cluster
+ DISK* dsk; // pointer to disk structure
+ BYTE test;
+ long offset2 = offset;
+
+ dsk = stream->dsk;
+
+ switch(whence)
+ {
+ case SEEK_CUR:
+ // Apply the offset to the current position
+ offset2 += stream->seek;
+ break;
+ case SEEK_END:
+ // Apply the offset to the end of the file
+ offset2 = stream->size - offset2;
+ break;
+ case SEEK_SET:
+ // automatically there
+ default:
+ break;
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+#endif
+
+ // start from the beginning
+ temp = stream->cluster;
+ stream->ccls = temp;
+
+ temp = stream->size;
+
+ if (offset2 > temp)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return (-1); // past the limits
+ }
+ else
+ {
+ // if we are writing we are no longer at the end
+ stream->flags.FileWriteEOF = FALSE;
+
+ // set the new postion
+ stream->seek = offset2;
+
+ // figure out how many sectors
+ numsector = offset2 / MEDIA_SECTOR_SIZE;
+
+ // figure out how many bytes off of the offset
+ offset2 = offset2 - (numsector * MEDIA_SECTOR_SIZE);
+ stream->pos = offset2;
+
+ // figure out how many clusters
+ temp = numsector / dsk->SecPerClus;
+
+ // figure out the stranded sectors
+ numsector = numsector - (dsk->SecPerClus * temp);
+ stream->sec = numsector;
+
+ // if we are in the current cluster stay there
+ if (temp > 0)
+ {
+ test = FILEget_next_cluster(stream, temp);
+ if (test != CE_GOOD)
+ {
+ if (test == CE_FAT_EOF)
+ {
+#ifdef ALLOW_WRITES
+ if (stream->flags.write)
+ {
+ // load the previous cluster
+ stream->ccls = stream->cluster;
+ // Don't perform this operation if there's only one cluster
+ if (temp != 1)
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (FILEallocate_new_cluster(stream, 0) != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return -1;
+ }
+ // sec and pos should already be zero
+ }
+ else
+ {
+#endif
+ stream->ccls = stream->cluster;
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (test != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1);
+ }
+ stream->pos = MEDIA_SECTOR_SIZE;
+ stream->sec = dsk->SecPerClus - 1;
+#ifdef ALLOW_WRITES
+ }
+#endif
+ }
+ else
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1); // past the limits
+ }
+ }
+ }
+
+ // Determine the lba of the selected sector and load
+ temp = Cluster2Sector(dsk,stream->ccls);
+
+ // now the extra sectors
+ numsector = stream->sec;
+ temp += numsector;
+
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead(temp, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return (-1); // Bad read
+ }
+ gLastDataSectorRead = temp;
+ }
+
+ FSerrno = CE_GOOD;
+
+ return (0);
+}
+
+
+// FSfopenpgm, FSremovepgm, and FSrenamepgm will only work on PIC18s
+#ifdef __18CXX
+#ifdef ALLOW_PGMFUNCTIONS
+
+#ifdef ALLOW_WRITES
+
+/*****************************************************************
+ Function:
+ int FSrenamepgm(const rom char * fileName, FSFILE * fo)
+ Summary:
+ Rename a file named with a ROM string on PIC18
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file (in ROM)
+ fo - The file to rename
+ Return Values:
+ 0 - File renamed successfully
+ -1 - File could not be renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The Fsrenamepgm function will copy the rom fileName specified
+ by the user into a RAM array and pass that array into the
+ FSrename function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *****************************************************************/
+
+int FSrenamepgm (const rom char * fileName, FSFILE * fo)
+{
+ char F[13];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+
+ return FSrename (F, fo);
+}
+#endif
+
+/******************************************************************************
+ Function:
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+ Summary:
+ Open a file named with a ROM string on PIC18
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to be opened (ROM)
+ mode - The mode the file will be opened in (ROM)
+ Return Values:
+ FSFILE * - A pointer to the file object
+ NULL - File could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfopenpgm function will copy a PIC18 ROM fileName and mode argument
+ into RAM arrays, and then pass those arrays to the FSfopen function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ ******************************************************************************/
+
+
+FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+{
+ char F[13];
+ char M[2];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+ for (count = 0; count < 2; count++)
+ {
+ M[count] = *(mode + count);
+ }
+
+ return FSfopen(F, M);
+}
+
+/*************************************************************
+ Function:
+ int FSremovepgm (const rom char * fileName)
+ Summary:
+ Delete a file named with a ROM string on PIC18
+ Conditions:
+ File not opened; file exists
+ Input:
+ fileName - The name of the file to be deleted (ROM)
+ Return Values:
+ 0 - File was removed successfully
+ -1 - File could not be removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremovepgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FSremove function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *************************************************************/
+#ifdef ALLOW_WRITES
+int FSremovepgm (const rom char * fileName)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for(...)
+
+ return FSremove (F);
+}
+#endif
+
+/**************************************************************************************
+ Function:
+ int FindFirstpgm (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Find a file named with a ROM string on PIC18
+ Conditions:
+ None
+ Input:
+ fileName - The name of the file to be found (ROM)
+ attr - The attributes of the file to be found
+ rec - Pointer to a search record to store the file info in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the given parameters was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object will be lost.
+ The FSerrno variable will be changed.
+ Description:
+ The FindFirstpgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FindFirst function.
+ Remarks:
+ Call FindFirstpgm or FindFirst before calling FindNext.
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************************/
+#ifdef ALLOW_FILESEARCH
+int FindFirstpgm (const rom char * fileName, unsigned int attr, SearchRec * rec)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for
+
+ return FindFirst (F,attr,rec);
+}
+#endif
+#endif
+#endif
+
+
+/***********************************************
+ Function:
+ DWORD ReadFAT (DISK *dsk, DWORD ccls)
+ Summary:
+ Read the next entry from the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ Return:
+ DWORD - The next cluster in a file chain
+ Side Effects:
+ None
+ Description:
+ The ReadFAT function will read the FAT and
+ determine the next cluster value after the
+ cluster specified by 'ccls.' Note that the
+ FAT sector that is read is stored in the
+ global FAT cache buffer.
+ Remarks:
+ None.
+ ***********************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls)
+{
+ BYTE q;
+ DWORD p, l; // "l" is the sector Address
+ DWORD c, d, ClusterFailValue,LastClusterLimit; // ClusterEntries
+
+ gBufferZeroed = FALSE;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls * 4;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls *3; // Mulby1.5 to find cluster pos in FAT
+ q = p&1;
+ p >>= 1;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT12;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD)ccls *2; // Mulby 2 to find cluster pos in FAT
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ l = dsk->fat + (p >> 9); // FAT buffer has 512 bytes of size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ // Check if the appropriate FAT sector is already loaded
+ if (gLastFATSectorRead == l)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if(dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ // Check if the MSB is across the sector boundry
+ p = (p +1) & 0x1FF;
+ if (p == 0)
+ {
+ // Start by writing the sector we just worked on to the card
+ // if we need to
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+#endif
+ if (!MDD_SectorRead (l+1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l +1;
+ }
+ }
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ else
+ {
+ // If there's a currently open FAT sector,
+ // write it back before reading into the buffer
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ {
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+ }
+#endif
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF; // Note: It is Sector not Cluster.
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if (dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ p = (p +1) & 0x1FF;
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ }
+
+ // Normalize it so 0xFFFF is an error
+ if (c >= LastClusterLimit)
+ c = LastClusterLimit;
+
+ return c;
+} // ReadFAT
+
+
+
+/****************************************************************************
+ Function:
+ WORD WriteFAT (DISK *dsk, DWORD ccls, WORD value, BYTE forceWrite)
+ Summary:
+ Write an entry to the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ value - The value to write in
+ forceWrite - Force the function to write the current FAT sector
+ Return:
+ 0 - The FAT write was successful
+ FAIL - The FAT could not be written
+ Side Effects:
+ None
+ Description:
+ The WriteFAT function writes an entry to the FAT. If the function
+ is called and the 'forceWrite' argument is TRUE, the function will
+ write the existing FAT data to the device. Otherwise, the function
+ will replace a single entry in the FAT buffer (indicated by 'ccls')
+ with a new value (indicated by 'value.')
+ Remarks:
+ None.
+ ****************************************************************************/
+
+#ifdef ALLOW_WRITES
+DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite)
+{
+ BYTE i, q, c;
+ DWORD p, li, l, ClusterFailValue;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type != FAT32 && dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT32;
+#else // If FAT32 support not enabled
+ if (dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT16;
+#endif
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ gBufferZeroed = FALSE;
+
+ // The only purpose for calling this function with forceWrite
+ // is to write the current FAT sector to the card
+ if (forceWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+
+ return 0;
+ }
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls *4; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls * 3; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ q = p & 1; // Odd or even?
+ p >>= 1;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD) ccls *2; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+ }
+
+ l = dsk->fat + (p >>9); // FAt Buffer is 512 bytes size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ if (gLastFATSectorRead != l)
+ {
+ // If we are loading a new sector then write
+ // the current one to the card if we need to
+ if (gNeedFATWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+ }
+
+ // Load the new sector
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l;
+ }
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32) // Refer page 16 of FAT requirement.
+ {
+ RAMwrite (gFATBuffer, p, ((value&0x000000ff))); // lsb,1st byte of cluster value
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8));
+ RAMwrite (gFATBuffer, p+2, ((value&0x00ff0000) >> 16));
+ RAMwrite (gFATBuffer, p+3, ((value&0x0f000000) >> 24)); // the MSB nibble is supposed to be "0" in FAT32. So mask it.
+ }
+ else
+#endif
+
+ if (dsk->type == FAT16)
+ {
+ RAMwrite (gFATBuffer, p, value); //lsB
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8)); // msB
+ }
+ else if (dsk->type == FAT12)
+ {
+ // Get the current byte from the FAT
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = ((value & 0x0F) << 4) | ( c & 0x0F);
+ }
+ else
+ {
+ c = (value & 0xFF);
+ }
+ // Write in those bits
+ RAMwrite (gFATBuffer, p, c);
+
+ // FAT12 entries can cross sector boundaries
+ // Check if we need to load a new sector
+ p = (p+1) & 0x1FF;
+ if (p == 0)
+ {
+ // call this function to update the FAT on the card
+ if (WriteFAT (dsk, 0,0,TRUE))
+ return ClusterFailValue;
+ // Load the next sector
+ if (!MDD_SectorRead (l +1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l + 1;
+ }
+
+ // Get the second byte of the table entry
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = (value >> 4);
+ }
+ else
+ {
+ c = ((value >> 8) & 0x0F) | (c & 0xF0);
+ }
+ RAMwrite (gFATBuffer, p, c);
+ }
+
+ gNeedFATWrite = TRUE;
+
+ return 0;
+}
+#endif
+
+
+#ifdef ALLOW_DIRS
+
+// This string is used by dir functions to hold dir names temporarily
+char defaultString [13];
+
+
+
+/**************************************************************************
+ Function:
+ int FSchdir (char * path)
+ Summary:
+ Change the current working directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to.
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdir function passes a RAM pointer to the path to the
+ chdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSchdir (char * path)
+{
+ return chdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSchdirpgm (const rom char * path)
+ Summary:
+ Changed the CWD with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to (ROM)
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdirpgm function passes a PIC18 ROM path pointer to the
+ chdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSchdirpgm (const rom char * path)
+{
+ return chdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+ // PIC18
+ int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ Summary:
+ Helper function for FSchdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was changed successfully.
+ EOF - Directory could not be changed.
+ Side Effects:
+ The current working directory will be changed. The FSerrno variable
+ will be changed. Any unwritten data in the data buffer will be written
+ to the device.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able to
+ parse it correctly. The function will loop through a switch statement
+ to process the tokens in the path string. Dot or dotdot entries are
+ handled in the first case statement. A backslash character is handled
+ in the second case statement (note that this case statement will only
+ be used if backslash is the first character in the path; backslash
+ token delimiters will automatically be skipped after each token in the
+ path is processed). The third case statement will handle actual
+ directory name strings.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int chdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ WORD curent = 1;
+ DIRENTRY entry;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ FSFILE tempCWDobj2;
+ char tempArray[12];
+ FILEOBJ tempCWD = &tempCWDobj2;
+ FileObjectCopy (tempCWD, cwdptr);
+
+ FSerrno = CE_GOOD;
+
+ // Check the first char of the path
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+ if (i == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ while(1)
+ {
+ switch (i)
+ {
+ // First case: dot or dotdot entry
+ case '.':
+ // Move past the dot
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if it's a dotdot entry
+ if (i == '.')
+ {
+ // Increment the path variable
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if we're in the root
+ if (tempCWD->dirclus == FatRootDirClusterValue)
+ {
+ // Fails if there's a dotdot chdir from the root
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ else
+ {
+ // Cache the dotdot entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ curent = 1;
+ entry = Cache_File_Entry (tempCWD, &curent, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ tempCWD->dirclus = GetFullClusterNumber(entry); // Get Complete Cluster number.
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // If we changed to root, record the name
+ if (tempCWD->dirclus == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT) // "0" is the value of Dotdot entry for Root in both FAT types.
+ {
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+
+ /* While moving to Root, get the Root cluster value */
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Otherwise set the name to ..
+ tempCWD->name[0] = '.';
+ tempCWD->name[1] = '.';
+ for (j = 2; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ // Cache the dot entry
+ curent = 0;
+ if (Cache_File_Entry(tempCWD, &curent, TRUE) == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Move past the next backslash, if necessary
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // Copy and return, if we're at the end
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ // If we ended with a . entry,
+ // just return what we have
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ else
+ {
+ // Anything else after a dot doesn't make sense
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ }
+
+ break;
+
+ // Second case: the first char is the root backslash
+ // We will ONLY switch to this case if the first char
+ // of the path is a backslash
+ case '\\':
+ // Increment pointer to second char
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Can't start the path with multiple backslashes
+ if (i == '\\')
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == 0)
+ {
+ // The user is changing directory to
+ // the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ cwdptr->name[j] = 0x20;
+ }
+ return 0;
+ }
+ else
+ {
+ // Our first char is the root dir switch
+ tempCWD->dirclus = FatRootDirClusterValue;
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ break;
+
+ default:
+ // We should be at the beginning of a string of letters/numbers
+ j = 0;
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath2);
+ }
+ }
+ else
+ {
+#endif
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath);
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // We got a whole 12 chars
+ // There could be more- truncate it
+ if (j == 12)
+ {
+ while ((i != 0) && (i != '\\'))
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ i = *(++temppath2);
+ }
+ else
+ {
+#endif
+ i = *(++temppath);
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ }
+
+ defaultString[j] = 0;
+
+ if (FormatDirName (defaultString, 0) == FALSE)
+ return -1;
+
+ for (j = 0; j < 11; j++)
+ {
+ tempArray[j] = tempCWD->name[j];
+ tempCWD->name[j] = defaultString[j];
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, tempCWD);
+
+ // See if the directory is there
+ if(FILEfind (&gFileTemp, tempCWD, LOOK_FOR_MATCHING_ENTRY, 0) != CE_GOOD)
+ {
+ // Couldn't find the DIR
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Found the file
+ // Check to make sure it's actually a directory
+ if (gFileTemp.attributes != ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Get the new name
+ for (j = 0; j < 11; j++)
+ {
+ tempCWD->name[j] = gFileTemp.name[j];
+ }
+ tempCWD->dirclus = gFileTemp.cluster;
+ tempCWD->dirccls = tempCWD->dirclus;
+ }
+
+ if (i == 0)
+ {
+ // If we're at the end of the string, we're done
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ while (i == '\\')
+ {
+ // If we get to another backslash, increment past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ break;
+ }
+ } // loop
+}
+
+
+
+// This string is used by FSgetcwd to return the cwd name if the path
+// passed into the function is NULL
+char defaultArray [10];
+
+
+/**************************************************************
+ Function:
+ char * FSgetcwd (char * path, int numchars)
+ Summary:
+ Get the current working directory name
+ Conditions:
+ None
+ Input:
+ path - Pointer to the array to return the cwd name in
+ numchars - Number of chars in the path
+ Return Values:
+ char * - The cwd name string pointer (path or defaultArray)
+ NULL - The current working directory name could not be loaded.
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSgetcwd function will get the name of the current
+ working directory and return it to the user. The name
+ will be copied into the buffer pointed to by 'path,'
+ starting at the root directory and copying as many chars
+ as possible before the end of the buffer. The buffer
+ size is indicated by the 'numchars' argument. The first
+ thing this function will do is load the name of the current
+ working directory, if it isn't already present. This could
+ occur if the user switched to the dotdot entry of a
+ subdirectory immediately before calling this function. The
+ function will then copy the current working directory name
+ into the buffer backwards, and insert a backslash character.
+ Next, the function will continuously switch to the previous
+ directories and copy their names backwards into the buffer
+ until it reaches the root. If the buffer overflows, it
+ will be treated as a circular buffer, and data will be
+ copied over existing characters, starting at the beginning.
+ Once the root directory is reached, the text in the buffer
+ will be swapped, so that the buffer contains as much of the
+ current working directory name as possible, starting at the
+ root.
+ Remarks:
+ None
+ **************************************************************/
+char * FSgetcwd (char * path, int numchars)
+{
+ // If path is passed in as null, set up a default
+ // array with 10 characters
+ char totalchars = (path == NULL) ? 10 : numchars;
+ char * returnPointer;
+ char * bufferEnd;
+ FILEOBJ tempCWD = &gFileTemp;
+ BYTE bufferOverflow = FALSE;
+ signed char j;
+ DWORD curclus;
+ WORD fHandle, tempindex;
+ signed int i, index = 0;
+ char aChar;
+ DIRENTRY entry;
+
+ FSerrno = CE_GOOD;
+
+ // Set up the return value
+ if (path == NULL)
+ returnPointer = defaultArray;
+ else
+ {
+ returnPointer = path;
+ if (numchars == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return NULL;
+ }
+ }
+
+ bufferEnd = returnPointer + totalchars - 1;
+
+ FileObjectCopy (tempCWD, cwdptr);
+
+ if ((tempCWD->name[0] == '.') &&
+ (tempCWD->name[1] == '.'))
+ {
+ // We last changed directory into a dotdot entry
+ // Save the value of the current directory
+ curclus = tempCWD->dirclus;
+ // Put this dir's dotdot entry into the dirclus
+ // Our cwd absolutely is not the root
+ fHandle = 1;
+ tempCWD->dirccls = tempCWD->dirclus;
+ entry = Cache_File_Entry (tempCWD,&fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ // For FAT32, if the .. entry is 0, the cluster won't be 0
+#ifdef SUPPORT_FAT32
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ tempCWD->dirclus = TempClusterCalc;
+
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // Find the direntry for the entry we were just in
+ fHandle = 0;
+ entry = Cache_File_Entry (tempCWD, &fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != curclus) ||
+ ((TempClusterCalc == curclus) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME) || (entry->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ fHandle++;
+ entry = Cache_File_Entry (tempCWD, &fHandle, FALSE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // We've found the entry for the dir we were in
+ for (i = 0; i < 11; i++)
+ {
+ tempCWD->name[i] = entry->DIR_Name[i];
+ cwdptr->name[i] = entry->DIR_Name[i];
+ }
+ // Reset our temp dir back to that cluster
+ tempCWD->dirclus = curclus;
+ tempCWD->dirccls = curclus;
+ // This will set us at the cwd, but it will actually
+ // have the name in the name field this time
+ }
+ // There's actually some kind of name value in the cwd
+ if (tempCWD->name[0] == '\\')
+ {
+ // Easy, our CWD is the root
+ *returnPointer = '\\';
+ *(returnPointer + 1) = 0;
+ return returnPointer;
+ }
+ else
+ {
+ // Loop until we get back to the root
+ while (tempCWD->dirclus != FatRootDirClusterValue)
+ {
+ j = 10;
+ while (tempCWD->name[j] == 0x20)
+ j--;
+ if (j >= 8)
+ {
+ while (j >= 8)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+ *(returnPointer + index++) = '.';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ while (tempCWD->name[j] == 0x20)
+ j--;
+
+ while (j >= 0)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ // Put a backslash delimiter in front of the dir name
+ *(returnPointer + index++) = '\\';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+
+ // Load the previous entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ if (GetPreviousEntry (tempCWD))
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ return NULL;
+ }
+ }
+ }
+
+ // Point the index back at the last char in the string
+ index--;
+
+ i = 0;
+ // Swap the chars in the buffer so they are in the right places
+ if (bufferOverflow)
+ {
+ tempindex = index;
+ // Swap the overflowed values in the buffer
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+
+ // Point at the non-overflowed values
+ i = tempindex + 1;
+ index = bufferEnd - returnPointer;
+
+ // Swap the non-overflowed values into the right places
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ // All the values should be in the right place now
+ // Null-terminate the string
+ *(bufferEnd) = 0;
+ }
+ else
+ {
+ // There was no overflow, just do one set of swaps
+ tempindex = index;
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ *(returnPointer + tempindex + 1) = 0;
+ }
+
+ return returnPointer;
+}
+
+
+/**************************************************************************
+ Function:
+ void GetPreviousEntry (FSFILE * fo)
+ Summary:
+ Get the file entry info for the parent dir of the specified dir
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - The file to get the previous entry of
+ Return Values:
+ 0 - The previous entry was successfully retrieved
+ -1 - The previous entry could not be retrieved
+ Side Effects:
+ None
+ Description:
+ The GetPreviousEntry function is used by the FSgetcwd function to
+ load the previous (parent) directory. This function will load the
+ parent directory and then search through the file entries in that
+ directory for one that matches the cluster number of the original
+ directory. When the matching entry is found, the name of the
+ original directory is copied into the 'fo' FSFILE object.
+ Remarks:
+ None.
+ **************************************************************************/
+
+BYTE GetPreviousEntry (FSFILE * fo)
+{
+ BYTE i;
+ WORD fHandle = 1;
+ DWORD dirclus;
+ DIRENTRY dirptr;
+
+ // Load the previous entry
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ // The previous directory is the root
+ fo->name[0] = '\\';
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = 0x20;
+ }
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Get the directory name
+ // Save the previous cluster value
+ // Get the cluster
+
+ dirclus = TempClusterCalc;
+ fo->dirclus = TempClusterCalc;
+ fo->dirccls = TempClusterCalc;
+
+
+ // Load the previous previous cluster
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+#ifdef SUPPORT_FAT32
+ // If we're using FAT32 and the previous previous cluster is the root, the
+ // value in the dotdot entry will be 0, but the actual cluster won't
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ fo->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ fo->dirclus = TempClusterCalc;
+
+ fo->dirccls = fo->dirclus;
+
+ fHandle = 0;
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+ // Look through it until we get the name
+ // of the previous cluster
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+ while ((TempClusterCalc != dirclus) ||
+ ((TempClusterCalc == dirclus) &&
+ (((unsigned char)dirptr->DIR_Name[0] == 0xE5) || (dirptr->DIR_Attr == ATTR_VOLUME) || (dirptr->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ // Look through the entries until we get the
+ // right one
+ dirptr = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dirptr == NULL)
+ return -1;
+ fHandle++;
+
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number in a loop.
+ }
+
+ // The name should be in the entry now
+ // Copy the actual directory location back
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = dirptr->DIR_Name[i];
+ }
+ fo->dirclus = dirclus;
+ fo->dirccls = dirclus;
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+ Function:
+ int FSmkdir (char * path)
+ Summary:
+ Create a directory
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create.
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdir function passes a RAM pointer to the path to the
+ mkdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSmkdir (char * path)
+{
+ return mkdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSmkdirpgm (const rom char * path)
+ Summary:
+ Create a directory with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create (ROM)
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdirpgm function passes a PIC18 ROM path pointer to the
+ mkdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arugments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSmkdirpgm (const rom char * path)
+{
+ return mkdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+ // PIC18
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+ Summary:
+ Helper function for FSmkdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was created
+ -1 - Directory could not be created
+ Side Effects:
+ Will create all non-existant directories in the path.
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first scan through the path
+ to ensure that any DIR names don't exceed 11 characters. It will then
+ backup the current working directory and begin changing directories
+ through the path until it reaches a directory than can't be changed to.
+ It will then create the specified directory and change directories to
+ the new directory. The function will continue creating and changing to
+ directories until the end of the path is reached. The function will
+ then restore the original current working directory.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ char tempArray[13];
+ FILEOBJ tempCWD = &tempCWDobj;
+
+#ifdef __18CXX
+ char dotdotPath[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath2 != 0) && (*temppath2 != '.')&& (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath2 == '.')
+ {
+ temppath2++;
+ i = 0;
+ while ((*temppath2 != 0) && (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath2 == '\\')
+ temppath2++;
+ if (*temppath2 == 0)
+ break;
+ }
+ }
+ else
+#endif
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath != 0) && (*temppath != '.')&& (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath == '.')
+ {
+ temppath++;
+ i = 0;
+ while ((*temppath != 0) && (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath == '\\')
+ temppath++;
+ if (*temppath == 0)
+ break;
+ }
+
+ temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ temppath2 = romptr;
+#endif
+
+ // We're going to be moving the CWD
+ // Back up the CWD
+ FileObjectCopy (tempCWD, cwdptr);
+
+ // get to the target directory
+ while (1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+
+ if (i == '.')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ if ((i != '.') && (i != 0) && (i != '\\'))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == '.')
+ {
+ if (cwdptr->dirclus == FatRootDirClusterValue)
+ {
+ // If we try to change to the .. from the
+ // root, operation fails
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if ((i != '\\') && (i != 0))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+// dotdot entry
+#ifndef __18CXX
+ FSchdir ("..");
+#else
+ FSchdir (dotdotPath);
+#endif
+ }
+ // Skip past any backslashes
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ // No point in creating a dot or dotdot entry directly
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ // Start at the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (i = 1; i < 11; i++)
+ {
+ cwdptr->name[i] = 0x20;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // If we just got two backslashes in a row at the
+ // beginning of the path, the function fails
+ if (i == '\\')
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (i == 0)
+ {
+ // We can't make the root dir
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ tempArray[12] = 0;
+ while (1)
+ {
+ while(1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Change directories as specified
+ i = *temppath2;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ // Change directories as specified
+ i = *temppath;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ tempArray[j] = 0;
+
+ if (tempArray[0] == '.')
+ {
+ if ((tempArray[1] != 0) && (tempArray[1] != '.'))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if ((tempArray[1] == '.') && (tempArray[2] != 0))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+
+ // Try to change to it
+ // If you can't we need to create it
+ if (FSchdir (tempArray))
+ {
+ break;
+ }
+ else
+ {
+ // We changed into the directory
+ while (i == '\\')
+ {
+ // Next char is a backslash
+ // Move past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // If it's the last one, return success
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+
+ // Create a dir here
+ if (!CreateDIR (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ // Try to change to that directory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Check for another backslash
+ while (*temppath2 == '\\')
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ while (*temppath == '\\')
+ {
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Check to see if we're at the end of the path string
+ if (i == 0)
+ {
+ // We already have one
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+}
+
+
+/**************************************************************************
+ Function:
+ int CreateDIR (char * path)
+ Summary:
+ FSmkdir helper function to create a directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the dir to create
+ Return Values:
+ TRUE - Directory was created successfully
+ FALSE - Directory could not be created.
+ Side Effects:
+ Any unwritten data in the data buffer or the FAT buffer will be written
+ to the device.
+ Description:
+ The CreateDIR function is a helper function for the mkdirhelper
+ function. The CreateDIR function will create a new file entry for
+ a directory and assign a cluster to it. It will erase the cluster
+ and write a dot and dotdot entry to it.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int CreateDIR (char * path)
+{
+ FSFILE * dirEntryPtr = &gFileTemp;
+ DIRENTRY dir;
+ WORD handle = 0;
+ DWORD dot, dotdot;
+ BYTE i;
+
+ for (i = 0; i < 12; i++)
+ {
+ defaultString[i] = *(path + i);
+ }
+
+ if (FormatDirName(defaultString, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return FALSE;
+ }
+
+ // Copy name into file object
+ for (i = 0; i < 11; i++)
+ {
+ dirEntryPtr->name[i] = defaultString[i];
+ }
+
+ dirEntryPtr->dirclus = cwdptr->dirclus;
+ dirEntryPtr->dirccls = cwdptr->dirccls;
+ dirEntryPtr->cluster = 0;
+ dirEntryPtr->ccls = 0;
+ dirEntryPtr->dsk = cwdptr->dsk;
+
+ // Create a directory entry
+ if(CreateFileEntry(dirEntryPtr, &handle, DIRECTORY) != CE_GOOD)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (gNeedFATWrite)
+ if(WriteFAT (dirEntryPtr->dsk, 0, 0, TRUE))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+ // Zero that cluster
+ if (dirEntryPtr->dirclus == FatRootDirClusterValue)
+ dotdot = 0;
+ else
+ dotdot = dirEntryPtr->dirclus;
+ dirEntryPtr->dirccls = dirEntryPtr->dirclus;
+ dir = Cache_File_Entry(dirEntryPtr, &handle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return FALSE;
+ }
+
+ // Get the cluster
+ dot = GetFullClusterNumber(dir); // Get complete cluster number.
+
+ if (writeDotEntries (dirEntryPtr->dsk, dot, dotdot))
+ return TRUE;
+ else
+ return FALSE;
+
+ }
+}
+
+
+/***********************************************************************************
+ Function:
+ BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+ Summary:
+ Create dot and dotdot entries in a non-root directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - The global disk structure
+ dotAddress - The cluster the current dir is in
+ dotdotAddress - The cluster the previous directory was in
+ Return Values:
+ TRUE - The dot and dotdot entries were created
+ FALSE - The dot and dotdot entries could not be created in the new directory
+ Side Effects:
+ None
+ Description:
+ The writeDotEntries function will create and write dot and dotdot entries
+ to a newly created directory.
+ Remarks:
+ None.
+ ***********************************************************************************/
+
+BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+{
+ WORD i;
+ WORD size;
+ _DIRENTRY entry;
+ DIRENTRY entryptr = &entry;
+ DWORD sector;
+
+ gBufferOwner = NULL;
+
+ size = sizeof (_DIRENTRY);
+
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ entry.DIR_Name[0] = '.';
+
+ for (i = 1; i < 11; i++)
+ {
+ entry.DIR_Name[i] = 0x20;
+ }
+ entry.DIR_Attr = ATTR_DIRECTORY;
+ entry.DIR_NTRes = 0x00;
+
+ entry.DIR_FstClusLO = (WORD)(dotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+ entry.DIR_FileSize = 0x00;
+
+// Times need to be the same as the times in the directory entry
+
+// Set dir date for uncontrolled clock source
+#ifdef INCREMENTTIMESTAMP
+ entry.DIR_CrtTimeTenth = 0xB2;
+ entry.DIR_CrtTime = 0x7278;
+ entry.DIR_CrtDate = 0x32B0;
+ entry.DIR_LstAccDate = 0x0000;
+ entry.DIR_WrtTime = 0x0000;
+ entry.DIR_WrtDate = 0x0000;
+#endif
+
+#ifdef USEREALTIMECLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i) = *((char *)entryptr + i);
+ }
+ entry.DIR_Name[1] = '.';
+
+ entry.DIR_FstClusLO = (WORD)(dotdotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotdotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i + size) = *((char *)entryptr + i);
+ }
+
+ sector = Cluster2Sector (disk, dotAddress);
+
+ if (MDD_SectorWrite(sector, disk->buffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// This array is used to prevent a stack frame error
+#ifdef __18CXX
+ char tempArray[13] = " ";
+#endif
+
+
+/**************************************************************************
+ Function:
+ int FSrmdir (char * path)
+ Summary:
+ Delete a directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to remove
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdir function passes a RAM pointer to the path to the
+ rmdirhelper function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int FSrmdir (char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (0, path, NULL, rmsubdirs);
+}
+
+/**************************************************************************
+ Function:
+ int FSrmdirpgm (const rom char * path)
+ Summary:
+ Delete a directory with a path in ROM on PIC18
+ Conditions:
+ None.
+ Input:
+ path - The path of the directory to remove (ROM)
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdirpgm function passes a PIC18 ROM path pointer to the
+ rmdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSrmdirpgm (const rom char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (1, NULL, path, rmsubdirs);
+}
+#endif
+
+/************************************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+ // PIC18
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+ Summary:
+ Helper function for FSrmdir
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The path of the dir to delete
+ rmsubdirs -
+ - TRUE - Remove all sub-directories and files in the directory
+ - FALSE - Non-empty directories can not be removed
+ Return Values:
+ 0 - The specified directory was successfully removed.
+ EOF - The specified directory could not be removed.
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSmkdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first change to the
+ specified directory. If the rmsubdirs argument is FALSE the function
+ will search through the directory to ensure that it is empty and then
+ remove it. If the rmsubdirs argument is TRUE the function will also
+ search through the directory for subdirectories or files. When the
+ function finds a file, the file will be erased. When the function
+ finds a subdirectory, it will switch to the subdirectory and begin
+ removing all of the files in that subdirectory. Once the subdirectory
+ is empty, the function will switch back to the original directory.
+ return to the original position in that directory, and continue removing
+ files. Once the specified directory is empty, the function will
+ change to the parent directory, search through it for the directory
+ to remove, and then erase that directory.
+ Remarks:
+ None.
+ ************************************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+#else
+int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+#endif
+{
+ FILEOBJ tempCWD = &tempCWDobj;
+ FILEOBJ fo = &gFileTemp;
+ DIRENTRY entry;
+ WORD handle = 0;
+ WORD handle2;
+ WORD subDirDepth;
+ BYTE Index, Index2;
+
+#ifndef __18CXX
+ char tempArray[13] = " ";
+#else
+ char dotdotname[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ // Back up the current working directory
+ FileObjectCopy (tempCWD, cwdptr);
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ if (chdirhelper (1, NULL, romptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ }
+ else
+ {
+#endif
+ if (FSchdir (ramptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Make sure we aren't trying to remove the root dir or the CWD
+ if ((cwdptr->dirclus == FatRootDirClusterValue) || (cwdptr->dirclus == tempCWD->dirclus))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Don't remove subdirectories and sub-files
+ if (!rmsubdirs)
+ {
+ while (entry->DIR_Name[0] != 0)
+ {
+ if ((unsigned char)entry->DIR_Name[0] != 0xE5)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_EMPTY;
+ return -1;
+ }
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if ((entry == NULL))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ // Do remove subdirectories and sub-files
+ dirCleared = FALSE;
+ subDirDepth = 0;
+
+ while (!dirCleared)
+ {
+ if (entry->DIR_Name[0] != 0)
+ {
+ if (((unsigned char)entry->DIR_Name[0] != 0xE5) && (entry->DIR_Attr != ATTR_VOLUME) && (entry->DIR_Attr != ATTR_LONG_NAME))
+ {
+ if ((entry->DIR_Attr & ATTR_DIRECTORY) == ATTR_DIRECTORY)
+ {
+ // We have a directory
+ subDirDepth++;
+ for (Index = 0; (Index < DIR_NAMESIZE) && (entry->DIR_Name[Index] != 0x20); Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (entry->DIR_Name[8] != 0x20)
+ {
+ tempArray[Index++] = '.';
+ for (Index2 = 0; (Index2 < DIR_EXTENSION) && (entry->DIR_Name[Index2 + DIR_NAMESIZE] != 0x20); Index2++)
+ {
+ tempArray[Index++] = entry->DIR_Name[Index2 + DIR_NAMESIZE];
+ }
+ }
+ tempArray[Index] = 0;
+ // Change to the subdirectory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Make sure we're not trying to delete the CWD
+ if (cwdptr->dirclus == tempCWD->dirclus)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ handle = 2;
+ recache = TRUE;
+ }
+ else
+ {
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ fo->name[Index] = entry->DIR_Name[Index];
+ }
+
+ fo->dsk = &gDiskData;
+
+ fo->entry = handle;
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+ fo->cluster = 0;
+ fo->ccls = 0;
+
+ if (FILEerase(fo, &handle, TRUE))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ }
+ } // Check to see if it's a DIR entry
+ }// Check non-dir entry to see if its a valid file
+ else
+ {
+ handle++;
+ }
+ if (recache)
+ {
+ recache = FALSE;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ }
+ else
+ {
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ }
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ else
+ {
+ // We have reached the end of the directory
+ if (subDirDepth != 0)
+ {
+ handle2 = 0;
+
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle2, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ handle2 = GetFullClusterNumber(entry); // Get complete cluster number.
+
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ // Return to our previous position in this directory
+ handle = 2;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != handle2) ||
+ ((TempClusterCalc == handle2) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME))))
+ {
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // Erase the directory that we just cleared the subdirectories out of
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+
+ // Decrease the subdirectory depth
+ subDirDepth--;
+ }
+ else
+ {
+ dirCleared = TRUE;
+ } // Check subdirectory depth
+ } // Check until we get an empty entry
+ } // Loop until the whole dir is cleared
+ }
+
+ // Cache the current directory name
+ // tempArray is used so we don't disturb the
+ // global getcwd buffer
+ if (FSgetcwd (tempArray, 12) == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ memset(tempArray, 0x00, 12);
+
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = cwdptr->name[Index];
+ }
+
+ // If we're here, this directory is empty
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+}
+
+
+/****************************************************************
+ Function:
+ int eraseDir (char * path)
+ Summary:
+ FSrmdir helper function to erase dirs
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the directory to delete
+ Return Values:
+ 0 - Dir was deleted successfully
+ -1 - Dir could not be deleted.
+ Side Effects:
+ None
+ Description:
+ The eraseDir function is a helper function for the rmdirhelper
+ function. The eraseDir function will search for the
+ directory that matches the specified path name and then erase
+ it with the FILEerase function.
+ Remarks:
+ None.
+ *****************************************************************/
+
+int eraseDir (char * path)
+{
+ CETYPE result;
+ BYTE Index;
+ FSFILE tempCWDobj2;
+
+ if (MDD_WriteProtectState())
+ {
+ return (-1);
+ }
+
+ // preserve CWD
+ FileObjectCopy(&tempCWDobj2, cwdptr);
+
+ for (Index = 0; Index <11; Index++)
+ {
+ cwdptr->name[Index] = *(path + Index);
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, cwdptr);
+
+ // See if the file is found
+ result = FILEfind (cwdptr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+ result = FILEerase(cwdptr, &cwdptr->entry, TRUE);
+ if( result == CE_GOOD )
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return 0;
+ }
+ else
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+}
+#endif
+
+
+
+#endif
+
+
+#ifdef ALLOW_FILESEARCH
+
+
+/***********************************************************************************
+ Function:
+ int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Initial search function
+ Conditions:
+ None
+ Input:
+ fileName - The name to search for
+ - Parital string search characters
+ - * - Indicates the rest of the filename or extension can vary (e.g. FILE.*)
+ - ? - Indicates that one character in a filename can vary (e.g. F?LE.T?T)
+ attr - The attributes that a found file may have
+ - ATTR_READ_ONLY - File may be read only
+ - ATTR_HIDDEN - File may be a hidden file
+ - ATTR_SYSTEM - File may be a system file
+ - ATTR_VOLUME - Entry may be a volume label
+ - ATTR_DIRECTORY - File may be a directory
+ - ATTR_ARCHIVE - File may have archive attribute
+ - ATTR_MASK - All attributes
+ rec - pointer to a structure to put the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the specified criteria was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object
+ will be lost. The FSerrno variable will be changed.
+ Description:
+ The FindFirst function will search for a file based on parameters passed in
+ by the user. This function will use the FILEfind function to parse through
+ the current working directory searching for entries that match the specified
+ parameters. If a file is found, its parameters are copied into the SearchRec
+ structure, as are the initial parameters passed in by the user and the position
+ of the file entry in the current working directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling FindNext
+ ***********************************************************************************/
+
+int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ WORD fHandle;
+ BYTE j;
+ BYTE Index;
+
+ FSerrno = CE_GOOD;
+
+ if( !FormatFileName(fileName, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ rec->initialized = FALSE;
+
+ for (Index = 0; (Index < 12) && (fileName[Index] != 0); Index++)
+ {
+ rec->searchname[Index] = fileName[Index];
+ }
+ rec->searchname[Index] = 0;
+ rec->searchattr = attr;
+#ifdef ALLOW_DIRS
+ rec->cwdclus = cwdptr->dirclus;
+#else
+ rec->cwdclus = FatRootDirClusterValue;
+#endif
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = attr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ fHandle = fo->entry;
+ result = FILEopen (fo, &fHandle, 'r');
+ }
+ if (result == CE_GOOD)
+ {
+ // Copy as much name as there is
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (Index = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[Index++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[Index] = 0;
+ }
+ else
+ {
+ for (Index = 0; Index < DIR_NAMECOMP; Index++)
+ {
+ rec->filename[Index] = fo->name[Index];
+ }
+ rec->filename[Index] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ rec->initialized = TRUE;
+ return 0;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+}
+
+
+/**********************************************************************
+ Function:
+ int FindNext (SearchRec * rec)
+ Summary:
+ Sequential search function
+ Conditions:
+ None
+ Input:
+ rec - The structure to store the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No additional files matching the specified criteria were found
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FindNext function performs the same function as the FindFirst
+ funciton, except it does not copy any search parameters into the
+ SearchRec structure (only info about found files) and it begins
+ searching at the last directory entry offset at which a file was
+ found, rather than at the beginning of the current working
+ directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling this function
+ **********************************************************************/
+
+int FindNext (SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ BYTE i, j;
+
+ FSerrno = CE_GOOD;
+
+ // Make sure we called FindFirst on this object
+ if (rec->initialized == FALSE)
+ {
+ FSerrno = CE_NOT_INIT;
+ return -1;
+ }
+
+ // Make sure we called FindFirst in the cwd
+#ifdef ALLOW_DIRS
+ if (rec->cwdclus != cwdptr->dirclus)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#endif
+
+ if( !FormatFileName(rec->searchname, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ /* Brn: Copy the formatted name to "fo" which is necesary before calling "FILEfind" function */
+ //strcpy(fo->name,rec->searchname);
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = rec->entry + 1;
+ fo->attributes = rec->searchattr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (i = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[i++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[i] = 0;
+ }
+ else
+ {
+ for (i = 0; i < DIR_NAMECOMP; i++)
+ {
+ rec->filename[i] = fo->name[i];
+ }
+ rec->filename[i] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ return 0;
+ }
+}
+
+
+#endif
+
+
+
+#ifdef ALLOW_FSFPRINTF
+
+
+
+/**********************************************************************
+ Function:
+ int FSputc (char c, FSFILE * file)
+ Summary:
+ FSfprintf helper function to write a char
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ c - The character to write to the file.
+ file - The file to write to.
+ Return Values:
+ 0 - The character was written successfully
+ EOF - The character was not written to the file.
+ Side Effects:
+ None
+ Description:
+ This is a helper function for FSfprintf. It will write one
+ character to a file.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSputc (char c, FSFILE * file)
+{
+ if (FSfwrite ((void *)&c, 1, 1, file) != 1)
+ return EOF;
+ else
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ int str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+ Summary:
+ FSfprintf helper function to write a char multiple times
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - The file to write to.
+ n - The number of times to write that character to a file.
+ c - The character to write to the file.
+ Return Values:
+ 0 - The characters were written successfully
+ EOF - The characters were not written to the file.
+ Side Effects:
+ None
+ Description:
+ This funciton is used by the FSfprintf function to write multiple
+ instances of a single character to a file (for example, when
+ padding a format specifier with leading spacez or zeros).
+ Remarks:
+ None.
+ **********************************************************************/
+
+
+unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+{
+ while (n--)
+ if (FSputc (c, handle) == EOF)
+ return 1;
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSfprintf (FSFILE * fptr, const char * fmt, ...)
+ // PIC18
+ int FSfpritnf (FSFILE * fptr, const rom char * fmt, ...)
+ Summary:
+ Function to write formatted strings to a file
+ Conditions:
+ For PIC18, integer promotion must be enabled in the project build
+ options menu. File opened in a write mode.
+ Input:
+ fptr - A pointer to the file to write to.
+ fmt - A string of characters and format specifiers to write to
+ the file
+ ... - Additional arguments inserted in the string by format
+ specifiers
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Writes a specially formatted string to a file.
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSfprintf (FSFILE *fptr, const rom char *fmt, ...)
+#else
+int FSfprintf (FSFILE *fptr, const char * fmt, ...)
+#endif
+{
+ va_list ap;
+ int n;
+
+ va_start (ap, fmt);
+ n = FSvfprintf (fptr, fmt, ap);
+ va_end (ap);
+ return n;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSvfprintf (FSFILE * handle, const char * formatString, va_list ap)
+ // PIC18
+ int FSvfpritnf (auto FSFILE * handle, auto const rom char * formatString, auto va_list ap)
+ Summary:
+ Helper function for FSfprintf
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - A pointer to the file to write to.
+ formatString - A string of characters and format specifiers to write to
+ the file
+ ap - A structure pointing to the arguments on the stack
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function will access the elements passed to FSfprintf
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSvfprintf (auto FSFILE *handle, auto const rom char * formatString, auto va_list ap)
+#else
+int FSvfprintf (FSFILE *handle, const char * formatString, va_list ap)
+#endif
+{
+ unsigned char c;
+ int count = 0;
+
+ for (c = *formatString; c; c = *++formatString)
+ {
+ if (c == '%')
+ {
+ unsigned char flags = 0;
+ unsigned char width = 0;
+ unsigned char precision = 0;
+ unsigned char have_precision = 0;
+ unsigned char size = 0;
+#ifndef __18CXX
+ unsigned char size2 = 0;
+#endif
+ unsigned char space_cnt;
+ unsigned char cval;
+#ifdef __18CXX
+ unsigned long larg;
+ far rom char * romstring;
+#else
+ unsigned long long larg;
+#endif
+ char * ramstring;
+ int n;
+
+ FSerrno = CE_GOOD;
+
+ c = *++formatString;
+
+ while (c == '-' || c == '+' || c == ' ' || c == '#'
+ || c == '0')
+ {
+ switch (c)
+ {
+ case '-':
+ flags |= _FLAG_MINUS;
+ break;
+ case '+':
+ flags |= _FLAG_PLUS;
+ break;
+ case ' ':
+ flags |= _FLAG_SPACE;
+ break;
+ case '#':
+ flags |= _FLAG_OCTO;
+ break;
+ case '0':
+ flags |= _FLAG_ZERO;
+ break;
+ }
+ c = *++formatString;
+ }
+ /* the optional width field is next */
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n < 0)
+ {
+ flags |= _FLAG_MINUS;
+ width = -n;
+ }
+ else
+ width = n;
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ width = cval;
+ }
+
+ /* if '-' is specified, '0' is ignored */
+ if (flags & _FLAG_MINUS)
+ flags &= ~_FLAG_ZERO;
+
+ /* the optional precision field is next */
+ if (c == '.')
+ {
+ c = *++formatString;
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n >= 0)
+ {
+ precision = n;
+ have_precision = 1;
+ }
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ precision = cval;
+ have_precision = 1;
+ }
+ }
+
+ /* the optional 'h' specifier. since int and short int are
+ the same size for MPLAB C18, this is a NOP for us. */
+ if (c == 'h')
+ {
+ c = *++formatString;
+ /* if 'c' is another 'h' character, this is an 'hh'
+ specifier and the size is 8 bits */
+ if (c == 'h')
+ {
+ size = _FMT_BYTE;
+ c = *++formatString;
+ }
+ }
+ else if (c == 't' || c == 'z')
+ c = *++formatString;
+#ifdef __18CXX
+ else if (c == 'H' || c == 'T' || c == 'Z')
+ {
+ size = _FMT_SHRTLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l' || c == 'j')
+#else
+ else if (c == 'q' || c == 'j')
+ {
+ size = _FMT_LONGLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l')
+#endif
+ {
+ size = _FMT_LONG;
+ c = *++formatString;
+ }
+
+ switch (c)
+ {
+ case '\0':
+ /* this is undefined behaviour. we have a trailing '%' character
+ in the string, perhaps with some flags, width, precision
+ stuff as well, but no format specifier. We'll, arbitrarily,
+ back up a character so that the loop will terminate
+ properly when it loops back and we'll output a '%'
+ character. */
+ --formatString;
+ /* fallthrough */
+ case '%':
+ if (FSputc ('%', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ break;
+ case 'c':
+ space_cnt = 0;
+ if (width > 1)
+ {
+ space_cnt = width - 1;
+ count += space_cnt;
+ }
+ if (space_cnt && !(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ c = va_arg (ap, int);
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'S':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ romstring = va_arg (ap, rom far char *);
+ else
+ romstring = (far rom char*)va_arg (ap, rom near char *);
+ n = strlenpgm (romstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the
+ string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *romstring; c && cval < width; c = *++romstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+#endif
+ case 's':
+ ramstring = va_arg (ap, char *);
+ n = strlen (ramstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *ramstring; c && cval < width; c = *++ramstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'd':
+ case 'i':
+ flags |= _FLAG_SIGNED;
+ /* fall through */
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'b':
+ case 'B':
+ /* This is a bit of a trick. The 'l' and 'hh' size
+ specifiers are valid only for the integer conversions,
+ not the 'p' or 'P' conversions, and are ignored for the
+ latter. By jumping over the additional size specifier
+ checks here we get the best code size since we can
+ limit the size checks in the remaining code. */
+ if (size == _FMT_LONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, long int);
+ else
+ larg = va_arg (ap, unsigned long int);
+ goto _do_integer_conversion;
+ }
+ else if (size == _FMT_BYTE)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed char) va_arg (ap, int);
+ else
+ larg = (unsigned char) va_arg (ap, unsigned int);
+ goto _do_integer_conversion;
+ }
+#ifndef __18CXX
+ else if (size == _FMT_LONGLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed long long)va_arg (ap, long long);
+ else
+ larg = (unsigned long long) va_arg (ap, unsigned long long);
+ goto _do_integer_conversion;
+ }
+#endif
+ /* fall trough */
+ case 'p':
+ case 'P':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, short long int);
+ else
+ larg = va_arg (ap, unsigned short long int);
+ }
+ else
+#endif
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, int);
+ else
+ larg = va_arg (ap, unsigned int);
+ _do_integer_conversion:
+ /* default precision is 1 */
+ if (!have_precision)
+ precision = 1;
+ {
+ unsigned char digit_cnt = 0;
+ unsigned char prefix_cnt = 0;
+ unsigned char sign_char;
+ /* A 32 bit number will require at most 32 digits in the
+ string representation (binary format). */
+#ifdef __18CXX
+ char buf[33];
+ /* Start storing digits least-significant first */
+ char *q = &buf[31];
+ /* null terminate the string */
+ buf[32] = '\0';
+#else
+ char buf[65];
+ char *q = &buf[63];
+ buf[64] = '\0';
+#endif
+ space_cnt = 0;
+ size = 10;
+
+ switch (c)
+ {
+ case 'b':
+ case 'B':
+ size = 2;
+#ifndef __18CXX
+ size2 = 1;
+#endif
+ break;
+ case 'o':
+ size = 8;
+#ifndef __18CXX
+ size2 = 3;
+#endif
+ break;
+ case 'p':
+ case 'P':
+ /* from here on out, treat 'p' conversions just
+ like 'x' conversions. */
+ c += 'x' - 'p';
+ /* fall through */
+ case 'x':
+ case 'X':
+ size = 16;
+#ifndef __18CXX
+ size2 = 4;
+#endif
+ break;
+ }// switch (c)
+
+ /* if it's an unsigned conversion, we should ignore the
+ ' ' and '+' flags */
+ if (!(flags & _FLAG_SIGNED))
+ flags &= ~(_FLAG_PLUS | _FLAG_SPACE);
+
+ /* if it's a negative value, we need to negate the
+ unsigned version before we convert to text. Using
+ unsigned for this allows us to (ab)use the 2's
+ complement system to avoid overflow and be able to
+ adequately handle LONG_MIN.
+
+ We'll figure out what sign character to print, if
+ any, here as well. */
+#ifdef __18CXX
+ if (flags & _FLAG_SIGNED && ((long) larg < 0))
+ {
+ larg = -(long) larg;
+#else
+ if (flags & _FLAG_SIGNED && ((long long) larg < 0))
+ {
+ larg = -(long long) larg;
+#endif
+ sign_char = '-';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_PLUS)
+ {
+ sign_char = '+';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_SPACE)
+ {
+ sign_char = ' ';
+ ++digit_cnt;
+ }
+ else
+ sign_char = '\0';
+ /* get the digits for the actual number. If the
+ precision is zero and the value is zero, the result
+ is no characters. */
+ if (precision || larg)
+ {
+ do
+ {
+#ifdef __18CXX
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ larg /= size;
+#else
+ // larg is congruent mod size2 to its lower 16 bits
+ // for size2 = 2^n, 0 <= n <= 4
+ if (size2 != 0)
+ cval = s_digits[(unsigned int) larg % size];
+ else
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ if (size2 != 0)
+ larg = larg >> size2;
+ else
+ larg /= size;
+#endif
+ *q-- = cval;
+ ++digit_cnt;
+ } while (larg);
+ /* if the '#' flag was specified and we're dealing
+ with an 'o', 'b', 'B', 'x', or 'X' conversion,
+ we need a bit more. */
+ if (flags & _FLAG_OCTO)
+ {
+ if (c == 'o')
+ {
+ /* per the standard, for octal, the '#' flag
+ makes the precision be at least one more
+ than the number of digits in the number */
+ if (precision <= digit_cnt)
+ precision = digit_cnt + 1;
+ }
+ else if (c == 'x' || c == 'X' || c == 'b' || c == 'B')
+ prefix_cnt = 2;
+ }
+ }
+ else
+ digit_cnt = 0;
+
+ /* The leading zero count depends on whether the '0'
+ flag was specified or not. If it was not, then the
+ count is the difference between the specified
+ precision and the number of digits (including the
+ sign character, if any) to be printed; otherwise,
+ it's as if the precision were equal to the max of
+ the specified precision and the field width. If a
+ precision was specified, the '0' flag is ignored,
+ however. */
+ if ((flags & _FLAG_ZERO) && (width > precision)
+ && !have_precision)
+ precision = width;
+ /* for the rest of the processing, precision contains
+ the leading zero count for the conversion. */
+ if (precision > digit_cnt)
+ precision -= digit_cnt;
+ else
+ precision = 0;
+ /* the space count is the difference between the field
+ width and the digit count plus the leading zero
+ count. If the width is less than the digit count
+ plus the leading zero count, the space count is
+ zero. */
+ if (width > precision + digit_cnt + prefix_cnt)
+ space_cnt = width - precision - digit_cnt - prefix_cnt;
+
+ /* for output, we check the justification, if it's
+ right justified and the space count is positive, we
+ emit the space characters first. */
+ if (!(flags & _FLAG_MINUS) && space_cnt)
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ count += space_cnt;
+ space_cnt = 0;
+ }
+ /* if we have a sign character to print, that comes
+ next */
+ if (sign_char)
+ if (FSputc (sign_char, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if we have a prefix (0b, 0B, 0x or 0X), that's next */
+ if (prefix_cnt)
+ {
+ if (FSputc ('0', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ }
+ /* if we have leading zeros, they follow. the prefix, if any
+ is included in the number of digits when determining how
+ many leading zeroes are needed. */
+// if (precision > prefix_cnt)
+ // precision -= prefix_cnt;
+ if (str_put_n_chars (handle, precision, '0'))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* print the actual number */
+ for (cval = *++q; cval; cval = *++q)
+ if (FSputc (cval, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if there are any spaces left, they go to right-pad
+ the field */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ count += precision + digit_cnt + space_cnt + prefix_cnt;
+ }
+ break;
+ case 'n':
+ switch (size)
+ {
+ case _FMT_LONG:
+ *(long *) va_arg (ap, long *) = count;
+ break;
+#ifdef __18CXX
+ case _FMT_SHRTLONG:
+ *(short long *) va_arg (ap, short long *) = count;
+ break;
+#else
+ case _FMT_LONGLONG:
+ *(long long *) va_arg (ap, long long *) = count;
+ break;
+#endif
+ case _FMT_BYTE:
+ *(signed char *) va_arg (ap, signed char *) = count;
+ break;
+ default:
+ *(int *) va_arg (ap, int *) = count;
+ break;
+ }
+ break;
+ default:
+ /* undefined behaviour. we do nothing */
+ break;
+ }
+ }
+ else
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ }
+ }
+ return count;
+}
+
+
+
+#endif
+
+
+
+
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.c.works b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.c.works new file mode 100644 index 00000000..bc8a1ad4 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.c.works @@ -0,0 +1,8878 @@ +/******************************************************************************
+*
+* Microchip Memory Disk Drive File System
+*
+******************************************************************************
+* FileName: FSIO.c
+* Dependencies: GenericTypeDefs.h
+* FSIO.h
+* Physical interface include file (SD-SPI.h, CF-PMP.h, ...)
+* string.h
+* stdlib.h
+* FSDefs.h
+* ctype.h
+* salloc.h
+* Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+* Compiler: C18/C30/C32
+* Company: Microchip Technology, Inc.
+* Version: 1.2.0
+*
+* Software License Agreement
+*
+* The software supplied herewith by Microchip Technology Incorporated
+* (the �Company�) for its PICmicro� Microcontroller is intended and
+* supplied to you, the Company�s customer, for use solely and
+* exclusively on Microchip PICmicro Microcontroller products. The
+* software is owned by the Company and/or its supplier, and is
+* protected under applicable copyright laws. All rights are reserved.
+* Any use in violation of the foregoing restrictions may subject the
+* user to criminal sanctions under applicable laws, as well as to
+* civil liability for the breach of the terms and conditions of this
+* license.
+*
+* THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+*
+*****************************************************************************/
+
+#include "FSIO.h"
+#include "GenericTypeDefs.h"
+#include "string.h"
+#include "stdlib.h"
+#include "ctype.h"
+#include "FSDefs.h"
+
+#ifdef ALLOW_FSFPRINTF
+#include "stdarg.h"
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ #ifdef __18CXX
+ #include "salloc.h"
+ #endif
+#endif
+
+#ifndef ALLOW_WRITES
+ #ifdef ALLOW_FORMATS
+ #error Write functions must be enabled to use the format function
+ #endif
+ #ifdef ALLOW_FSFPRINTF
+ #error Write functions must be enabled to use the FSfprintf function
+ #endif
+#endif
+
+#ifdef USEREALTIMECLOCK
+ #ifdef USERDEFINEDCLOCK
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#elif defined USERDEFINEDCLOCK
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#endif
+/*****************************************************************************/
+/* Global Variables */
+/*****************************************************************************/
+
+#ifndef FS_DYNAMIC_MEM
+ FSFILE gFileArray[FS_MAX_FILES_OPEN]; // Array that contains file information (static allocation)
+ BYTE gFileSlotOpen[FS_MAX_FILES_OPEN]; // Array that indicates which elements of gFileArray are available for use
+#endif
+
+#if defined(USEREALTIMECLOCK) || defined(USERDEFINEDCLOCK)
+// Timing variables
+BYTE gTimeCrtMS; // Global time variable (for timestamps) used to indicate create time (milliseconds)
+WORD gTimeCrtTime; // Global time variable (for timestamps) used to indicate create time
+WORD gTimeCrtDate; // Global time variable (for timestamps) used to indicate create date
+WORD gTimeAccDate; // Global time variable (for timestamps) used to indicate last access date
+WORD gTimeWrtTime; // Global time variable (for timestamps) used to indicate last update time
+WORD gTimeWrtDate; // Global time variable (for timestamps) used to indicate last update date
+#endif
+
+DWORD gLastFATSectorRead = 0xFFFF; // Global variable indicating which FAT sector was read last
+BYTE gNeedFATWrite = FALSE; // Global variable indicating that there is information that needs to be written to the FAT
+FSFILE * gBufferOwner = NULL; // Global variable indicating which file is using the data buffer
+DWORD gLastDataSectorRead = 0xFFFFFFFF; // Global variable indicating which data sector was read last
+BYTE gNeedDataWrite = FALSE; // Global variable indicating that there is information that needs to be written to the data section
+BYTE nextClusterIsLast = FALSE; // Global variable indicating that the entries in a directory align with a cluster boundary
+
+BYTE gBufferZeroed = FALSE; // Global variable indicating that the data buffer contains all zeros
+
+DWORD FatRootDirClusterValue; // Global variable containing the cluster number of the root dir (0 for FAT12/16)
+
+BYTE FSerrno; // Global error variable. Set to one of many error codes after each function call.
+
+DWORD TempClusterCalc; // Global variable used to store the calculated value of the cluster of a specified sector.
+BYTE dirCleared; // Global variable used by the "recursive" FSrmdir function to indicate that all subdirectories and files have been deleted from the target directory.
+BYTE recache = FALSE; // Global variable used by the "recursive" FSrmdir function to indicate that additional cache reads are needed.
+FSFILE tempCWDobj; // Global variable used to preserve the current working directory information.
+FSFILE gFileTemp; // Global variable used for file operations.
+
+#ifdef ALLOW_DIRS
+ FSFILE cwd; // Global current working directory
+ FSFILE * cwdptr = &cwd; // Pointer to the current working directory
+#endif
+
+
+#ifdef __18CXX
+ #pragma udata dataBuffer
+ BYTE gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ #pragma udata FATBuffer
+ BYTE gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE __attribute__ ((aligned(4))) gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ BYTE __attribute__ ((aligned(4))) gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+
+#pragma udata
+
+DISK gDiskData; // Global structure containing device information.
+
+
+
+/************************************************************************/
+/* Structures and defines */
+/************************************************************************/
+
+// Directory entry structure
+typedef struct
+{
+ char DIR_Name[DIR_NAMESIZE]; // File name
+ char DIR_Extension[DIR_EXTENSION]; // File extension
+ BYTE DIR_Attr; // File attributes
+ BYTE DIR_NTRes; // Reserved byte
+ BYTE DIR_CrtTimeTenth; // Create time (millisecond field)
+ WORD DIR_CrtTime; // Create time (second, minute, hour field)
+ WORD DIR_CrtDate; // Create date
+ WORD DIR_LstAccDate; // Last access date
+ WORD DIR_FstClusHI; // High word of the entry's first cluster number
+ WORD DIR_WrtTime; // Last update time
+ WORD DIR_WrtDate; // Last update date
+ WORD DIR_FstClusLO; // Low word of the entry's first cluster number
+ DWORD DIR_FileSize; // The 32-bit file size
+}_DIRENTRY;
+
+typedef _DIRENTRY * DIRENTRY; // A pointer to a directory entry structure
+
+#define DIRECTORY 0x12 // Value indicating that the CreateFileEntry function will be creating a directory
+
+#define DIRENTRIES_PER_SECTOR (MEDIA_SECTOR_SIZE / 32) // The number of directory entries in a sector
+
+// internal errors
+#define CE_FAT_EOF 60 // Error that indicates an attempt to read FAT entries beyond the end of the file
+#define CE_EOF 61 // Error that indicates that the end of the file has been reached
+
+typedef FSFILE * FILEOBJ; // Pointer to an FSFILE object
+
+#ifdef ALLOW_FSFPRINTF
+
+#define _FLAG_MINUS 0x1 // FSfprintf minus flag indicator
+#define _FLAG_PLUS 0x2 // FSfprintf plus flag indicator
+#define _FLAG_SPACE 0x4 // FSfprintf space flag indicator
+#define _FLAG_OCTO 0x8 // FSfprintf octothorpe (hash mark) flag indicator
+#define _FLAG_ZERO 0x10 // FSfprintf zero flag indicator
+#define _FLAG_SIGNED 0x80 // FSfprintf signed flag indicator
+
+#ifdef __18CXX
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONG 1 // FSfprintf 32-bit argument size flag
+ #define _FMT_SHRTLONG 2 // FSfprintf 24-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#else
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONGLONG 1 // FSfprintf 64-bit argument size flag
+ #define _FMT_LONG 2 // FSfprintf 32-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#endif
+
+#ifdef __18CXX
+ static const rom char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#else
+ static const char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#endif
+
+#endif
+
+/************************************************************************************/
+/* Prototypes */
+/************************************************************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls);
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead);
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle);
+DWORD Cluster2Sector(DISK * disk, DWORD cluster);
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle);
+#ifdef INCREMENTTIMESTAMP
+ void IncrementTimeStamp(DIRENTRY dir);
+#elif defined USEREALTIMECLOCK
+ void CacheTime (void);
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE ReadByte( BYTE* pBuffer, WORD index );
+ WORD ReadWord( BYTE* pBuffer, WORD index );
+ DWORD ReadDWord( BYTE* pBuffer, WORD index );
+#endif
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource);
+BYTE ValidateChars (char * FileName, BYTE mode);
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode);
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode);
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n);
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type);
+
+// Write functions
+#ifdef ALLOW_WRITES
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry);
+ BYTE flushData (void);
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters);
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode);
+ BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk);
+ DWORD FATfindEmptyCluster(FILEOBJ fo);
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle);
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode);
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster);
+ BYTE EraseCluster(DISK *disk, DWORD cluster);
+ CETYPE CreateFirstCluster(FILEOBJ fo);
+ DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite);
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode);
+#endif
+
+// Directory functions
+#ifdef ALLOW_DIRS
+ BYTE GetPreviousEntry (FSFILE * fo);
+ BYTE FormatDirName (char * string, BYTE mode);
+ int CreateDIR (char * path);
+ BYTE writeDotEntries (DISK * dsk, DWORD dotAddress, DWORD dotdotAddress);
+ int eraseDir (char * path);
+#ifdef ALLOW_PGMFUNCTIONS
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs);
+ #endif
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+#else
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs);
+ #endif
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+#endif
+#endif
+
+#ifdef ALLOW_FSFPRINTF
+ #ifdef __18CXX
+ int FSvfprintf (auto FSFILE *handle, auto const rom char *formatString, auto va_list ap);
+ #else
+ int FSvfprintf (FSFILE *handle, const char *formatString, va_list ap);
+ #endif
+ int FSputc (char c, FSFILE * file);
+ unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c);
+#endif
+
+BYTE DISKmount( DISK *dsk);
+BYTE LoadMBR(DISK *dsk);
+BYTE LoadBootSector(DISK *dsk);
+DWORD GetFullClusterNumber(DIRENTRY entry);
+
+
+/*************************************************************************
+ Function:
+ int FSInit(void)
+ Summary:
+ Function to initialize the device.
+ Conditions:
+ The physical device should be connected to the microcontroller.
+ Input:
+ None
+ Return Values:
+ TRUE - Initialization successful
+ FALSE - Initialization unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Initializes the static or dynamic memory slots for holding file
+ structures. Initializes the device with the DISKmount function. Loads
+ MBR and boot sector information. Initializes the current working
+ directory to the root directory for the device if directory support
+ is enabled.
+ Remarks:
+ None
+ *************************************************************************/
+
+int FSInit(void)
+{
+ int fIndex;
+#ifndef FS_DYNAMIC_MEM
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ gFileSlotOpen[fIndex] = TRUE;
+#else
+ #ifdef __18CXX
+ SRAMInitHeap();
+ #endif
+#endif
+
+ gBufferZeroed = FALSE;
+
+ MDD_InitIO();
+
+ if(DISKmount(&gDiskData) == CE_GOOD)
+ {
+ // Initialize the current working directory to the root
+#ifdef ALLOW_DIRS
+ cwdptr->dsk = &gDiskData;
+ cwdptr->sec = 0;
+ cwdptr->pos = 0;
+ cwdptr->seek = 0;
+ cwdptr->size = 0;
+ cwdptr->name[0] = '\\';
+ for (fIndex = 1; fIndex < 11; fIndex++)
+ {
+ cwdptr->name[fIndex] = 0x20;
+ }
+ cwdptr->entry = 0;
+ cwdptr->attributes = ATTR_DIRECTORY;
+ // "FatRootDirClusterValue" indicates the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+#endif
+
+ FSerrno = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/********************************************************************************
+ Function:
+ CETYPE FILEfind (FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+ Summary
+ Finds a file on the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - FSFILE object containing information of the file found
+ foCompareTo - FSFILE object containing the name/attr of the file to be
+ found
+ cmd -
+ - LOOK_FOR_EMPTY_ENTRY: Search for empty entry.
+ - LOOK_FOR_MATCHING_ENTRY: Search for matching entry.
+ mode -
+ - 0: Match file exactly with default attributes.
+ - 1: Match file to user-specified attributes.
+ Return Values:
+ CE_GOOD - File found.
+ CE_FILE_NOT_FOUND - File not found.
+ Side Effects:
+ None.
+ Description:
+ The FILEfind function will sequentially cache directory entries within
+ the current working directory into the foDest FSFILE object. If the cmd
+ parameter is specified as LOOK_FOR_EMPTY_ENTRY the search will continue
+ until an empty directory entry is found. If the cmd parameter is specified
+ as LOOK_FOR_MATCHING_ENTRY these entries will be compared to the foCompareTo
+ object until a match is found or there are no more entries in the current
+ working directory. If the mode is specified a '0' the attributes of the FSFILE
+ entries are irrelevant. If the mode is specified as '1' the attributes of the
+ foDest entry must match the attributes specified in the foCompareTo file and
+ partial string search characters may bypass portions of the comparison.
+ Remarks:
+ None
+ ********************************************************************************/
+
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+{
+ WORD attrib, compareAttrib;
+ WORD fHandle = foDest->entry; // current entry counter
+ BYTE state,index; // state of the current object
+ CETYPE statusB = CE_FILE_NOT_FOUND;
+ BYTE character,test;
+
+ // reset the cluster
+ foDest->dirccls = foDest->dirclus;
+ compareAttrib = 0xFFFF ^ foCompareTo->attributes; // Attribute to be compared as per application layer request
+
+ if (fHandle == 0)
+ {
+ if (Cache_File_Entry(foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ if ((fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) != 0) // Maximum 16 entries possible
+ {
+ if (Cache_File_Entry (foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ if (statusB != CE_BADCACHEREAD)
+ {
+ // Loop until you reach the end or find the file
+ while(1)
+ {
+ if(statusB!=CE_GOOD) //First time entry always here
+ {
+ state = Fill_File_Object(foDest, &fHandle);
+ if(state == NO_MORE) // Reached the end of available files. Comparision over and file not found so quit.
+ {
+ break;
+ }
+ }
+ else // statusB == CE_GOOD then exit
+ {
+ break; // Code below intializes"statusB = CE_GOOD;" so, if no problem in the filled file, Exit the while loop.
+ }
+
+ if(state == FOUND) // Validate the correct matching of filled file data with the required(to be found) one.
+ {
+ /* We got something */
+ // get the attributes
+ attrib = foDest->attributes;
+
+ attrib &= ATTR_MASK;
+ switch (mode)
+ {
+ case 0:
+ // see if we are a volume id or hidden, ignore
+ if(attrib != ATTR_VOLUME)
+ {
+ statusB = CE_GOOD;
+ character = (BYTE)'m'; // random value
+
+ // search for one. if status = TRUE we found one
+ for(index = 0; index < DIR_NAMECOMP; index++)
+ {
+ // get the source character
+ character = foDest->name[index];
+ // get the destination character
+ test = foCompareTo->name[index];
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // Nope its not a match
+ break;
+ }
+ }// for loop
+ } // not dir nor vol
+ break;
+
+ case 1:
+ // Check for attribute match
+ if (((attrib & compareAttrib) == 0) && (attrib != ATTR_LONG_NAME))
+ {
+ statusB = CE_GOOD; // Indicate the already filled file data is correct and go back
+ character = (BYTE)'m'; // random value
+ if (foCompareTo->name[0] != '*') //If "*" is passed for comparion as 1st char then don't proceed. Go back, file alreay found.
+ {
+ for (index = 0; index < DIR_NAMESIZE; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ // Before calling this "FILEfind" fn, "formatfilename" must be called. Hence, extn always starts from position "8".
+ if ((foCompareTo->name[8] != '*') && (statusB == CE_GOOD))
+ {
+ for (index = 8; index < DIR_NAMECOMP; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ } // Attribute match
+
+ break;
+ }
+ } // not found
+ else
+ {
+ /*** looking for an empty/re-usable entry ***/
+ if ( cmd == LOOK_FOR_EMPTY_ENTRY)
+ statusB = CE_GOOD;
+ } // found or not
+
+ // increment it no matter what happened
+ fHandle++;
+
+ }// while
+ }
+
+ return(statusB);
+} // FILEFind
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+ Summary:
+ Loads file information from the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File to be opened
+ fHandle - Location of file
+ type -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ Return Values:
+ CE_GOOD - FILEopen successful
+ CE_NOT_INIT - Device is not yet initialized
+ CE_FILE_NOT_FOUND - Could not find the file on the device
+ CE_BAD_SECTOR_READ - A bad read of a sector occured
+ Side Effects:
+ None
+ Description:
+ This function will cache a directory entry in the directory specified
+ by the dirclus parameter of hte FSFILE object 'fo.' The offset of the
+ entry in the directory is specified by fHandle. Once the directory entry
+ has been loaded, the first sector of the file can be loaded using the
+ cluster value specified in the directory entry. The type argument will
+ specify the mode the files will be opened in. This will allow this
+ function to set the correct read/write flags for the file.
+ Remarks:
+ If the mode the file is being opened in is a plus mode (e.g. READ+) the
+ flags will be modified further in the FSfopen function.
+ **************************************************************************/
+
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+{
+ DISK *dsk; //Disk structure
+ BYTE r; //Result of search for file
+ DWORD l; //lba of first sector of first cluster
+ CETYPE error = CE_GOOD;
+
+ dsk = (DISK *)(fo->dsk);
+ if (dsk->mount == FALSE)
+ {
+ error = CE_NOT_INIT;
+ }
+ else
+ {
+ // load the sector
+ fo->dirccls = fo->dirclus;
+ // Cache no matter what if it's the first entry
+ if (*fHandle == 0)
+ {
+ if (Cache_File_Entry(fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ // If it's not the first, only cache it if it's
+ // not divisible by the number of entries per sector
+ // If it is, Fill_File_Object will cache it
+ if ((*fHandle & 0xf) != 0)
+ {
+ if (Cache_File_Entry (fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ r = Fill_File_Object(fo, fHandle);
+ if (r != FOUND)
+ error = CE_FILE_NOT_FOUND;
+ else
+ {
+ fo->seek = 0; // first byte in file
+ fo->ccls = fo->cluster; // first cluster
+ fo->sec = 0; // first sector in the cluster
+ fo->pos = 0; // first byte in sector/cluster
+
+ if ( r == NOT_FOUND)
+ {
+ error = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Determine the lba of the selected sector and load
+ l = Cluster2Sector(dsk,fo->ccls);
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+#endif
+ gBufferOwner = fo;
+ if (gLastDataSectorRead != l)
+ {
+ gBufferZeroed = FALSE;
+ if ( !MDD_SectorRead( l, dsk->buffer))
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = l;
+ }
+ } // -- found
+
+ fo->flags.FileWriteEOF = FALSE;
+ // Set flag for operation type
+#ifdef ALLOW_WRITES
+ if (type == 'w' || type == 'a')
+ {
+ fo->flags.write = 1; //write or append
+ fo->flags.read = 0;
+ }
+ else
+ {
+#endif
+ fo->flags.write = 0; //read
+ fo->flags.read = 1;
+#ifdef ALLOW_WRITES
+ } // -- flags
+#endif
+ } // -- r = Found
+ } // -- Mounted
+ return (error);
+} // -- FILEopen
+
+
+/*************************************************************************
+ Function:
+ BYTE FILEget_next_cluster(FILEOBJ fo, WORD n)
+ Summary:
+ Step through a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file to get the next cluster of
+ n - Number of links in the FAT cluster chain to jump through
+ Return Values:
+ CE_GOOD - Operation successful
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_INVALID_CLUSTER - Invalid cluster value \> maxcls
+ CE_FAT_EOF - Fat attempt to read beyond EOF
+ Side Effects:
+ None
+ Description:
+ This function will load 'n' proximate clusters for a file from
+ the FAT on the device. It will stop checking for clusters if the
+ ReadFAT function returns an error, if it reaches the last cluster in
+ a file, or if the device tries to read beyond the last cluster used
+ by the device.
+ Remarks:
+ None
+ *************************************************************************/
+
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n)
+{
+ DWORD c, c2, ClusterFailValue, LastClustervalue;
+ BYTE error = CE_GOOD;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ LastClustervalue = LAST_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT12:
+ LastClustervalue = LAST_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT16:
+ default:
+ LastClustervalue = LAST_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // loop n times
+ do
+ {
+ // get the next cluster link from FAT
+ c2 = fo->ccls;
+ if ( (c = ReadFAT( disk, c2)) == ClusterFailValue)
+ error = CE_BAD_SECTOR_READ;
+ else
+ {
+ // check if cluster value is valid
+ if ( c >= disk->maxcls)
+ {
+ error = CE_INVALID_CLUSTER;
+ }
+
+ // compare against max value of a cluster in FAT
+ // return if eof
+ if ( c >= LastClustervalue) // check against eof
+ {
+ error = CE_FAT_EOF;
+ }
+ }
+
+ // update the FSFILE structure
+ fo->ccls = c;
+
+ } while (--n > 0 && error == CE_GOOD);// loop end
+
+ return(error);
+} // get next cluster
+
+
+/**************************************************************************
+ Function:
+ BYTE DISKmount ( DISK *dsk)
+ Summary:
+ Initialies the device and loads MBR and boot sector information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure to be initialized.
+ Return Values:
+ CE_GOOD - Disk mounted
+ CE_INIT_ERROR - Initialization error has occured
+ Side Effects:
+ None
+ Description:
+ This function will use the function pointed to by the MDD_MediaInitialize
+ function pointer to initialize the device (if any initialization is
+ required). It then attempts to load the master boot record with the
+ LoadMBR function and the boot sector with the LoadBootSector function.
+ These two functions will be used to initialize a global DISK structure
+ that will be used when accessing file information in the future.
+ Remarks:
+ None
+ **************************************************************************/
+
+BYTE DISKmount( DISK *dsk)
+{
+ BYTE error = CE_GOOD;
+
+ dsk->mount = FALSE; // default invalid
+ dsk->buffer = gDataBuffer; // assign buffer
+
+ // Initialize the device
+ if(MDD_MediaInitialize() != TRUE)
+ {
+ error = CE_INIT_ERROR;
+ FSerrno = CE_INIT_ERROR;
+ }
+ else
+ {
+ // Load the Master Boot Record (partition)
+ if((error = LoadMBR(dsk)) == CE_GOOD)
+ {
+ // Now the boot sector
+ if((error = LoadBootSector(dsk)) == CE_GOOD)
+ dsk->mount = TRUE; // Mark that the DISK mounted successfully
+ }
+ } // -- Load file parameters
+
+ return(error);
+} // -- mount
+
+
+
+/********************************************************************
+ Function:
+ CETYPE LoadMBR ( DISK *dsk)
+ Summary:
+ Loads the MBR and extracts necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the master boot record to be loaded
+ Return Values:
+ CE_GOOD - MBR loaded successfully
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_BAD_PARTITION - The boot record is bad
+ Side Effects:
+ None
+ Description:
+ The LoadMBR function will use the function pointed to by the
+ MDD_SectorRead function pointer to read the 0 sector from the
+ device. If a valid boot signature is obtained, this function
+ will compare fields in that cached sector to the values that
+ would be present if that sector was a boot sector. If all of
+ those values match, it will be assumed that the device does not
+ have a master boot record and the 0 sector is actually the boot
+ sector. Otherwise, data about the partition and the actual
+ location of the boot sector will be loaded from the MBR into
+ the DISK structure pointed to by 'dsk.'
+ Remarks:
+ None
+ ********************************************************************/
+
+BYTE LoadMBR(DISK *dsk)
+{
+ PT_MBR Partition;
+ BYTE error = CE_GOOD;
+ BYTE type;
+ BootSec BSec;
+
+ // Get the partition table from the MBR
+ if ( MDD_SectorRead( FO_MBR, dsk->buffer) != TRUE)
+ {
+ error = CE_BAD_SECTOR_READ;
+ FSerrno = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ // Check if the card has no MBR
+ BSec = (BootSec) dsk->buffer;
+
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( dsk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT16;
+ return CE_GOOD;
+ }
+ else
+ {
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FAT32_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 3 ) == '3' && \
+ ReadByte( dsk->buffer, BSI_FAT32_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_32.BootSec_FilSysType[0] == 'F' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[1] == 'A' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[2] == 'T' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[3] == '3' && \
+ BSec->FAT.FAT_32.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT32;
+ return CE_GOOD;
+ }
+ }
+ }
+ // assign it the partition table strucutre
+ Partition = (PT_MBR)dsk->buffer;
+
+ // Ensure its good
+ if((Partition->Signature0 != FAT_GOOD_SIGN_0) || (Partition->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_BAD_PARTITION;
+ error = CE_BAD_PARTITION;
+ }
+ else
+ {
+ /* Valid Master Boot Record Loaded */
+
+ // Get the 32 bit offset to the first partition
+ dsk->firsts = Partition->Partition0.PTE_FrstSect;
+
+ // check if the partition type is acceptable
+ type = Partition->Partition0.PTE_FSDesc;
+
+ switch (type)
+ {
+ case 0x01:
+ dsk->type = FAT12;
+ break;
+
+ case 0x04:
+ case 0x06:
+ case 0x0E:
+ dsk->type = FAT16;
+ break;
+
+ case 0x0B:
+ case 0x0C:
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ dsk->type = FAT32; // FAT32 is supported too
+#else
+ FSerrno = CE_CARDFAT32;
+ error = CE_CARDFAT32;
+#endif
+ break;
+
+ default:
+ FSerrno = CE_UNSUPPORTED_FS;
+ error = CE_UNSUPPORTED_FS;
+ } // switch
+ }
+ }
+
+ return(error);
+}// -- LoadMBR
+
+
+/**************************************************************************
+ Function:
+ BYTE LoadBootSector (DISK *dsk)
+ Summary:
+ Load the boot sector and extract the necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the boot sector
+ Return Values:
+ CE_GOOD - Boot sector loaded
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_NOT_FORMATTED - The disk is of an unsupported format
+ CE_CARDFAT32 - FAT 32 device not supported
+ Side Effects:
+ None
+ Description:
+ LoadBootSector will use the function pointed to by the MDD_SectorWrite
+ function pointer to load the boot sector, whose location was obtained
+ by a previous call of LoadMBR. If the boot sector is loaded successfully,
+ partition information will be calcualted from it and copied into the DISK
+ structure pointed to by 'dsk.'
+ Remarks:
+ None
+ **************************************************************************/
+
+
+BYTE LoadBootSector(DISK *dsk)
+{
+ DWORD RootDirSectors;
+ DWORD TotSec,DataSec;
+ BYTE error = CE_GOOD;
+ BootSec BSec;
+ WORD BytesPerSec;
+ WORD ReservedSectorCount;
+
+ // Get the Boot sector
+ if ( MDD_SectorRead( dsk->firsts, dsk->buffer) != TRUE)
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ BSec = (BootSec)dsk->buffer;
+
+ //Verify the Boot Sector is valid
+ if((BSec->Signature0 != FAT_GOOD_SIGN_0) || (BSec->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ error = CE_NOT_FORMATTED;
+ }
+ else
+ {
+ #ifdef __18CXX
+
+ // Load count of sectors per cluster
+ dsk->SecPerClus = BSec->FAT.FAT_16.BootSec_SPC;
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + BSec->FAT.FAT_16.BootSec_ResrvSec;
+ // Load the count of FAT tables
+ dsk->fatcopy = BSec->FAT.FAT_16.BootSec_FATCount;
+ // Load the size of the FATs
+ dsk->fatsize = BSec->FAT.FAT_16.BootSec_SPF;
+ if(dsk->fatsize == 0)
+ dsk->fatsize = BSec->FAT.FAT_32.BootSec_FATSz32;
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = BSec->FAT.FAT_16.BootSec_RootDirEnts;
+
+ // Determine the total number of sectors in the partition
+ if(BSec->FAT.FAT_16.BootSec_TotSec16 != 0)
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec16;
+ }
+ else
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec32;
+ }
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = BSec->FAT.FAT_16.BootSec_BPS;
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((BSec->FAT.FAT_16.BootSec_RootDirEnts * 32) + (BSec->FAT.FAT_16.BootSec_BPS - 1)) / BSec->FAT.FAT_16.BootSec_BPS;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (dsk->root + RootDirSectors) + dsk->firsts + 2;
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #else // PIC24/30/33
+
+ // Read the count of reserved sectors
+ ReservedSectorCount = ReadWord( dsk->buffer, BSI_RESRVSEC );
+ // Load the count of sectors per cluster
+ dsk->SecPerClus = ReadByte( dsk->buffer, BSI_SPC );
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + ReservedSectorCount;
+ // Load the count of FAT tables
+ dsk->fatcopy = ReadByte( dsk->buffer, BSI_FATCOUNT );
+ // Load the size of the FATs
+ dsk->fatsize = ReadWord( dsk->buffer, BSI_SPF );
+ if(dsk->fatsize == 0)
+ dsk->fatsize = ReadDWord( dsk->buffer, BSI_FATSZ32 );
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = ReadWord( dsk->buffer, BSI_ROOTDIRENTS );
+
+ // Determine the total number of sectors in the partition
+ TotSec = ReadWord( dsk->buffer, BSI_TOTSEC16 );
+ if( TotSec == 0 )
+ TotSec = ReadDWord( dsk->buffer, BSI_TOTSEC32 );
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = ReadWord( dsk->buffer, BSI_BPS );
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((dsk->maxroot * NUMBER_OF_BYTES_IN_DIR_ENTRY) + (BytesPerSec - 1)) / BytesPerSec;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (ReservedSectorCount + (dsk->fatcopy * dsk->fatsize ) + RootDirSectors );
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #endif
+
+ // Determine the file system type based on the number of clusters used
+ if(dsk->maxcls < 4085)
+ {
+ dsk->type = FAT12;
+ }
+ else
+ {
+ if(dsk->maxcls < 65525)
+ {
+ dsk->type = FAT16;
+ }
+ else
+ {
+ #ifdef SUPPORT_FAT32
+ dsk->type = FAT32;
+ #else
+ error = CE_CARDFAT32;
+ FSerrno = CE_CARDFAT32;
+ #endif
+ }
+ }
+
+ #ifdef SUPPORT_FAT32
+ if (dsk->type == FAT32)
+ {
+ #ifdef __18CXX
+ FatRootDirClusterValue = BSec->FAT.FAT_32.BootSec_RootClus;
+ #else
+ FatRootDirClusterValue = ReadDWord( dsk->buffer, BSI_ROOTCLUS );
+ #endif
+ dsk->data = dsk->root + RootDirSectors;
+ }
+ else
+ #endif
+ {
+ FatRootDirClusterValue = 0;
+ dsk->data = dsk->root + ( dsk->maxroot >> 4);
+ }
+
+ #ifdef __18CXX
+ if(BSec->FAT.FAT_16.BootSec_BPS != MEDIA_SECTOR_SIZE)
+ #else
+ if(BytesPerSec != MEDIA_SECTOR_SIZE)
+ #endif
+ {
+ error = CE_NOT_FORMATTED;
+ FSerrno = CE_NOT_FORMATTED;
+ }
+ }
+ }
+ return(error);
+}
+
+
+
+/*************************************************************************
+ Function:
+ DWORD GetFullClusterNumber (DIRENTRY entry)
+ Summary:
+ Gets the cluster number from a directory entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ entry - The cached directory entry to get the cluster number from
+ Returns:
+ The cluster value from the passed directory entry
+ Side Effects:
+ None.
+ Description:
+ This function will load both the high and low 16-bit first cluster
+ values of a file from a directory entry and copy them into a 32-bit
+ cluster number variable, which will be returned.
+ Remarks:
+ None
+ *************************************************************************/
+
+DWORD GetFullClusterNumber(DIRENTRY entry)
+{
+
+ DWORD TempFullClusterCalc = 0;
+
+#ifndef SUPPORT_FAT32 // If FAT32 Not supported.
+ entry->DIR_FstClusHI = 0; // If FAT32 is not supported then Higher Word of the address is "0"
+#endif
+
+ // Get the cluster
+ TempFullClusterCalc = (entry->DIR_FstClusHI);
+ TempFullClusterCalc = TempFullClusterCalc << 16;
+ TempFullClusterCalc |= entry->DIR_FstClusLO;
+
+ return TempFullClusterCalc;
+}
+
+
+#ifdef ALLOW_FORMATS
+#ifdef ALLOW_WRITES
+
+
+/*********************************************************************************
+ Function:
+ int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+ Summary:
+ Creates a master boot record
+ Conditions:
+ The I/O pins for the device have been initialized by the InitIO function.
+ Input:
+ firstSector - The first sector of the partition on the device (cannot
+ be 0; that's the MBR)
+ numSectors - The number of sectors available in memory (including the
+ MBR)
+ Return Values:
+ 0 - MBR was created successfully
+ EOF - MBR could not be created
+ Side Effects:
+ None
+ Description:
+ This function can be used to create a master boot record for a device. Note
+ that this function should not be used on a device that is already formatted
+ with a master boot record (i.e. most SD cards, CF cards, USB keys). This
+ function will fill the global data buffer with appropriate partition information
+ for a FAT partition with a type determined by the number of sectors available
+ to the partition. It will then write the MBR information to the first sector
+ on the device. This function should be followed by a call to FSformat, which
+ will create a boot sector, root dir, and FAT appropriate the the information
+ contained in the new master boot record. Note that FSformat only supports
+ FAT12 and FAT16 formatting at this time, and so cannot be used to format a
+ device with more than 0x3FFD5F sectors.
+ Remarks:
+ This function can damage the device being used, and should not be called
+ unless the user is sure about the size of the device and the first sector value.
+ *********************************************************************************/
+
+int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+{
+ PT_MBR Partition;
+ DWORD CyHdSc = 0x00000000;
+ DWORD tempSector;
+
+ if ((firstSector == 0) || (numSectors <= 1))
+ return EOF;
+
+ if (firstSector > (numSectors - 1))
+ return EOF;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ return EOF;
+
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ Partition = (PT_MBR) gDataBuffer;
+
+ // Set Cylinder-head-sector address of the first sector
+ tempSector = firstSector;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[447] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[448] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[449] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the count of sectors
+ Partition->Partition0.PTE_NumSect = numSectors - firstSector;
+
+ // Set the partition type
+ // We only support creating FAT12 and FAT16 MBRs at this time
+ if (Partition->Partition0.PTE_NumSect < 0x1039)
+ {
+ // FAT12
+ Partition->Partition0.PTE_FSDesc = 0x01;
+ }
+ else if (Partition->Partition0.PTE_NumSect <= 0x3FFD5F)
+ {
+ // FAT16
+ Partition->Partition0.PTE_FSDesc = 0x06;
+ }
+ else
+ return EOF;
+
+ // Set the LBA of the first sector
+ Partition->Partition0.PTE_FrstSect = firstSector;
+
+ // Set the Cylinder-head-sector address of the last sector
+ tempSector = firstSector + numSectors - 1;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[451] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[452] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[453] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the boot descriptor. This will be 0, since we won't
+ // be booting anything from our device probably
+ Partition->Partition0.PTE_BootDes = 0x00;
+
+ // Set the signature codes
+ Partition->Signature0 = 0x55;
+ Partition->Signature1 = 0xAA;
+
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) != TRUE)
+ return EOF;
+ else
+ return 0;
+
+}
+
+
+
+/*******************************************************************
+ Function:
+ int FSformat (char mode, long int serialNumber, char * volumeID)
+ Summary:
+ Formats a device
+ Conditions:
+ The device must possess a valid master boot record.
+ Input:
+ mode - - 0 - Just erase the FAT and root
+ - 1 - Create a new boot sector
+ serialNumber - Serial number to write to the card
+ volumeID - Name of the card
+ Return Values:
+ 0 - Format was successful
+ EOF - Format was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSformat function can be used to create a new boot sector
+ on a device, based on the information in the master boot record.
+ This function will first initialize the I/O pins and the device,
+ and then attempts to read the master boot record. If the MBR
+ cannot be loaded successfully, the function will fail. Next, if
+ the 'mode' argument is specified as '0' the existing boot sector
+ information will be loaded. If the 'mode' argument is '1' an
+ entirely new boot sector will be constructed using the disk
+ values from the master boot record. Once the boot sector has
+ been successfully loaded/created, the locations of the FAT and
+ root will be loaded from it, and they will be completely
+ erased. If the user has specified a volumeID parameter, a
+ VOLUME attribute entry will be created in the root directory
+ to name the device.
+ Remarks:
+ FAT12 and FAT16 formatting is supported.
+ *******************************************************************/
+
+int FSformat (char mode, long int serialNumber, char * volumeID)
+{
+ PT_MBR masterBootRecord;
+ DWORD secCount, FAT16DataClusters, RootDirSectors;
+ BootSec BSec;
+ DISK d;
+ DISK * disk = &d;
+ WORD j;
+ DWORD fatsize, test;
+ BYTE Index;
+#ifdef __18CXX
+ // This is here because of a C18 compiler feature
+ BYTE * dataBufferPointer = gDataBuffer;
+#endif
+
+ FSerrno = CE_GOOD;
+
+ disk->buffer = gDataBuffer;
+
+ MDD_InitIO();
+
+ if (MDD_MediaInitialize() != TRUE)
+ {
+ FSerrno = CE_INIT_ERROR;
+ return EOF;
+ }
+
+ if (MDD_SectorRead (0x00, gDataBuffer) == FALSE)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+
+ // Check if the card has no MBR
+ BSec = (BootSec) disk->buffer;
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( disk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( disk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ switch (mode)
+ {
+ case 1:
+ // not enough info to construct our own boot sector
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ case 0:
+ // We have to determine the operating system, and the
+ // locations and sizes of the root dir and FAT, and the
+ // count of FATs
+ disk->firsts = 0;
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ default:
+ break;
+ }
+ }
+ else
+ {
+ masterBootRecord = (PT_MBR) &gDataBuffer;
+ disk->firsts = masterBootRecord->Partition0.PTE_FrstSect;
+ }
+ }
+
+ switch (mode)
+ {
+ // True: Rewrite the whole boot sector
+ case 1:
+ secCount = masterBootRecord->Partition0.PTE_NumSect;
+
+ if (secCount < 0x1039)
+ {
+ disk->type = FAT12;
+ // Format to FAT12 only if there are too few sectors to format
+ // as FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x01;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ if (secCount >= 0x1028)
+ {
+ // More than 0x18 sectors for FATs, 0x20 for root dir,
+ // 0x8 reserved, and 0xFED for data
+ // So double the number of sectors in a cluster to reduce
+ // the number of data clusters used
+ disk->SecPerClus = 2;
+ }
+ else
+ {
+ // One sector per cluster
+ disk->SecPerClus = 1;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT12 )
+ gDataBuffer[58] = '2';
+ }
+ else if (secCount <= 0x3FFD5F)
+ {
+ disk->type = FAT16;
+ // Format to FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x06;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ FAT16DataClusters = secCount - 0x218;
+ // Figure out how many sectors per cluster we need
+ disk->SecPerClus = 1;
+ while (FAT16DataClusters > 0xFFED)
+ {
+ disk->SecPerClus *= 2;
+ FAT16DataClusters /= 2;
+ }
+ // This shouldnt happen
+ if (disk->SecPerClus > 128)
+ {
+ FSerrno = CE_BAD_PARTITION;
+ return EOF;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT16 )
+ gDataBuffer[58] = '6';
+ }
+ else
+ {
+ // Cannot format; too many sectors
+ FSerrno = CE_NONSUPPORTED_SIZE;
+ return EOF;
+ }
+
+ // Calculate the size of the FAT
+ fatsize = (secCount - 0x21 + (2*disk->SecPerClus));
+ if (disk->type == FAT12)
+ test = (341 * disk->SecPerClus) + 2;
+ else
+ test = (256 * disk->SecPerClus) + 2;
+ fatsize = (fatsize + (test-1)) / test;
+ // Non-file system specific values
+ gDataBuffer[0] = 0xEB; //Jump instruction
+ gDataBuffer[1] = 0x3C;
+ gDataBuffer[2] = 0x90;
+ gDataBuffer[3] = 'M'; //OEM Name "MCHP FAT"
+ gDataBuffer[4] = 'C';
+ gDataBuffer[5] = 'H';
+ gDataBuffer[6] = 'P';
+ gDataBuffer[7] = ' ';
+ gDataBuffer[8] = 'F';
+ gDataBuffer[9] = 'A';
+ gDataBuffer[10] = 'T';
+ gDataBuffer[11] = 0x00; //Bytes per sector - 512
+ gDataBuffer[12] = 0x02;
+ gDataBuffer[13] = disk->SecPerClus; //Sectors per cluster
+ gDataBuffer[14] = 0x08; //Reserved sector count
+ gDataBuffer[15] = 0x00;
+ disk->fat = 0x08 + disk->firsts;
+ gDataBuffer[16] = 0x02; //number of FATs
+ disk->fatcopy = 0x02;
+ gDataBuffer[17] = 0x00; //Max number of root directory entries - 512 files allowed
+ gDataBuffer[18] = 0x02;
+ disk->maxroot = 0x200;
+ gDataBuffer[19] = 0x00; //total sectors
+ gDataBuffer[20] = 0x00;
+ gDataBuffer[21] = 0xF8; //Media Descriptor
+ gDataBuffer[22] = fatsize & 0xFF; //Sectors per FAT
+ gDataBuffer[23] = (fatsize >> 8) & 0xFF;
+ disk->fatsize = fatsize;
+ gDataBuffer[24] = 0x3F; //Sectors per track
+ gDataBuffer[25] = 0x00;
+ gDataBuffer[26] = 0xFF; //Number of heads
+ gDataBuffer[27] = 0x00;
+ // Hidden sectors = sectors between the MBR and the boot sector
+ gDataBuffer[28] = (BYTE)(disk->firsts & 0xFF);
+ gDataBuffer[29] = (BYTE)((disk->firsts / 0x100) & 0xFF);
+ gDataBuffer[30] = (BYTE)((disk->firsts / 0x10000) & 0xFF);
+ gDataBuffer[31] = (BYTE)((disk->firsts / 0x1000000) & 0xFF);
+ // Total Sectors = same as sectors in the partition from MBR
+ gDataBuffer[32] = (BYTE)(secCount & 0xFF);
+ gDataBuffer[33] = (BYTE)((secCount / 0x100) & 0xFF);
+ gDataBuffer[34] = (BYTE)((secCount / 0x10000) & 0xFF);
+ gDataBuffer[35] = (BYTE)((secCount / 0x1000000) & 0xFF);
+ gDataBuffer[36] = 0x00; // Physical drive number
+ gDataBuffer[37] = 0x00; // Reserved (current head)
+ gDataBuffer[38] = 0x29; // Signature code
+ gDataBuffer[39] = (BYTE)(serialNumber & 0xFF);
+ gDataBuffer[40] = (BYTE)((serialNumber / 0x100) & 0xFF);
+ gDataBuffer[41] = (BYTE)((serialNumber / 0x10000) & 0xFF);
+ gDataBuffer[42] = (BYTE)((serialNumber / 0x1000000) & 0xFF);
+ // Volume ID
+ if (volumeID != NULL)
+ {
+ for (Index = 0; (*(volumeID + Index) != 0) && (Index < 11); Index++)
+ {
+ gDataBuffer[Index + 43] = *(volumeID + Index);
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[43 + Index++] = 0x20;
+ }
+ }
+ else
+ {
+ for (Index = 0; Index < 11; Index++)
+ {
+ gDataBuffer[Index+43] = 0;
+ }
+ }
+ gDataBuffer[54] = 'F';
+ gDataBuffer[55] = 'A';
+ gDataBuffer[56] = 'T';
+ gDataBuffer[57] = '1';
+ gDataBuffer[59] = ' ';
+ gDataBuffer[60] = ' ';
+ gDataBuffer[61] = ' ';
+#ifdef __18CXX
+ // C18 can't reference a value greater than 256
+ // using an array name pointer
+ *(dataBufferPointer + 510) = 0x55;
+ *(dataBufferPointer + 511) = 0xAA;
+#else
+ gDataBuffer[510] = 0x55;
+ gDataBuffer[511] = 0xAA;
+#endif
+
+ disk->root = disk->fat + (disk->fatcopy * disk->fatsize);
+
+ if (MDD_SectorWrite (disk->firsts, gDataBuffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ break;
+ case 0:
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ break;
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ }
+
+ // Erase the FAT
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+ gDataBuffer[0] = 0xF8;
+ gDataBuffer[1] = 0xFF;
+ gDataBuffer[2] = 0xFF;
+ if (disk->type == FAT16)
+ gDataBuffer[3] = 0xFF;
+
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (disk->fat + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ memset (gDataBuffer, 0x00, 4);
+
+ for (Index = disk->fat + 1; Index < (disk->fat + disk->fatsize); Index++)
+ {
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (Index + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ }
+
+ // Erase the root directory
+ RootDirSectors = ((disk->maxroot * 32) + (0x200 - 1)) / 0x200;
+
+ for (Index = 1; Index < RootDirSectors; Index++)
+ {
+ if (MDD_SectorWrite (disk->root + Index, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ if (volumeID != NULL)
+ {
+ // Create a drive name entry in the root dir
+ Index = 0;
+ while ((*(volumeID + Index) != 0) && (Index < 11))
+ {
+ gDataBuffer[Index] = *(volumeID + Index);
+ Index++;
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[Index++] = ' ';
+ }
+ gDataBuffer[11] = 0x08;
+ gDataBuffer[17] = 0x11;
+ gDataBuffer[19] = 0x11;
+ gDataBuffer[23] = 0x11;
+
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ else
+ {
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ return 0;
+}
+#endif
+#endif
+
+
+/*******************************************************
+ Function:
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+ Summary:
+ Write dir entry info into a specified entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - \File structure
+ curEntry - Write destination
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will calculate the sector of the
+ directory (whose base sector is pointed to by the
+ dirccls value in the FSFILE object 'fo') that contains
+ a directory entry whose offset is indicated by the
+ curEntry parameter. It will then write the data
+ in the global data buffer (which should already
+ contain the entries for that sector) to the device.
+ Remarks:
+ None
+ *******************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+{
+ DISK *dsk;
+ BYTE status;
+ BYTE offset2;
+ DWORD sector;
+ DWORD ccls;
+
+ dsk = fo->dsk;
+
+ // get the cluster of this entry
+ ccls = fo->dirccls;
+
+ // if its not the root, it's cluster based
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // Root is always cluster-based in FAT32
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ if(ccls != FatRootDirClusterValue)
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+ }
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ // Now write it
+ // "Offset" ensures writing of data belonging to a file entry only. Hence it doesn't change other file entries.
+ if ( !MDD_SectorWrite( sector + offset2, dsk->buffer, FALSE))
+ status = FALSE;
+ else
+ status = TRUE;
+
+ return(status);
+} // Write_File_Entry
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE FAT_erase_cluster_chain (WORD cluster, DISK * dsk)
+ Summary:
+ Erase a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ cluster - The cluster number
+ dsk - The disk structure
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will parse through a cluster chain
+ starting with the cluster pointed to by 'cluster' and
+ mark all of the FAT entries as empty until the end of
+ the chain has been reached or an error occurs.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk)
+{
+ DWORD c,c2,ClusterFailValue;
+ enum _status {Good, Fail, Exit}status;
+
+ status = Good;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ c2 = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT16:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ c2 = LAST_CLUSTER_FAT16;
+ break;
+
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16; // FAT16 value itself
+ c2 = LAST_CLUSTER_FAT12;
+ break;
+ }
+
+ // Make sure there is actually a cluster assigned
+ if(cluster == 0 || cluster == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ while(status == Good)
+ {
+ // Get the FAT entry
+ if((c = ReadFAT( dsk, cluster)) == ClusterFailValue)
+ status = Fail;
+ else
+ {
+ if(c == 0 || c == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ // compare against max value of a cluster in FATxx
+ // look for the last cluster in the chain
+ if ( c >= c2)
+ status = Exit;
+
+ // Now erase this FAT entry
+ if(WriteFAT(dsk, cluster, CLUSTER_EMPTY, FALSE) == ClusterFailValue)
+ status = Fail;
+
+ // now update what the current cluster is
+ cluster = c;
+ }
+ }
+ }// while status
+ }// cluster == 0
+
+ WriteFAT (dsk, 0, 0, TRUE);
+
+ if(status == Exit)
+ return(TRUE);
+ else
+ return(FALSE);
+} // Erase cluster
+#endif
+
+/**************************************************************************
+ Function:
+ DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+ Summary:
+ Load a file entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File information
+ curEntry - Offset of the directory entry to load.
+ ForceRead - Forces loading of a new sector of the directory.
+ Return:
+ DIRENTRY - Pointer to the directory entry that was loaded.
+ Side Effects:
+ Any unwritten data in the data buffer will be written to the device.
+ Description:
+ Load the sector containing the file entry pointed to by 'curEntry'
+ from the directory pointed to by the variables in 'fo.'
+ Remarks:
+ Any modification of this function is extremely likely to
+ break something.
+ **************************************************************************/
+
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+{
+ DIRENTRY dir;
+ DISK *dsk;
+ DWORD sector;
+ DWORD cluster, LastClusterLimit;
+ DWORD ccls;
+ BYTE offset2;
+ BYTE numofclus;
+
+ dsk = fo->dsk;
+
+ // get the base sector of this directory
+ cluster = fo->dirclus;
+ ccls = fo->dirccls;
+
+ // figure out the offset from the base sector
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+ /* There are 16 entries per sector. SECTOR size is 512 bytes. Each entry in ROOT takes 32 bytes.
+ So, 512/32 = 16. So 16 file entries can be made in each sector. */
+
+ offset2 = offset2; // emulator issue
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // the ROOT is always cluster based in FAT32
+ /* In FAT32: There is no ROOT region. Root etries are made in DATA region only.
+ Every cluster of DATA which is accupied by ROOT is tracked by FAT table/entry so the ROOT can grow
+ to an amount which is restricted only by available free DATA region. */
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // if its the root its not cluster based
+ if(cluster != 0)
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ // check if a new sector of the root must be loaded
+ if (ForceRead || (*curEntry & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) // only 16 entries per sector
+ {
+ // see if we have to load a new cluster
+ if((offset2 == 0 && (*curEntry) >= DIRENTRIES_PER_SECTOR) || ForceRead)
+ {
+ if(cluster == 0)
+ {
+ ccls = 0;
+ }
+ else
+ {
+ // If ForceRead, read the number of sectors from 0
+ if(ForceRead)
+ numofclus = ((WORD)(*curEntry) / (WORD)(((WORD)DIRENTRIES_PER_SECTOR) * (WORD)dsk->SecPerClus));
+ // Otherwise just read the next sector
+ else
+ numofclus = 1;
+
+ // move to the correct cluster
+ while(numofclus)
+ {
+ ccls = ReadFAT(dsk, ccls);
+
+ if(ccls >= LastClusterLimit)
+ break;
+ else
+ numofclus--;
+ }
+ }
+ }
+
+ // see if that we have a valid cluster number
+ if(ccls < LastClusterLimit)
+ {
+ fo->dirccls = ccls; // write it back
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ /* see if we are root and about to go pass our boundaries
+ FAT32 stores the root directory in the Data Region along with files and other directories,
+ allowing it to grow without such a restraint */
+ if((ccls == FatRootDirClusterValue) && ((sector + offset2) >= dsk->data) && (FAT32 != dsk->type))
+ {
+ dir = ((DIRENTRY)NULL); // reached the end of the root
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return NULL;
+#endif
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+
+ if ( MDD_SectorRead( sector + offset2, dsk->buffer) != TRUE) // if FALSE: sector could not be read.
+ {
+ dir = ((DIRENTRY)NULL);
+ }
+ else // Sector has been read properly, Copy the root entry info of the file searched.
+ {
+ if(ForceRead) // Buffer holds all 16 root entry info. Point to the one required.
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+ else
+ dir = (DIRENTRY)dsk->buffer;
+ }
+ gLastDataSectorRead = 0xFFFFFFFF;
+ }
+ }
+ else
+ {
+ nextClusterIsLast = TRUE;
+ dir = ((DIRENTRY)NULL);
+ }
+ }
+ else
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+
+ return(dir);
+} // Cache_File_Entry
+
+
+/*************************************************************************
+ Function:
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Create a new file entry
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location to create file
+ Return Values:
+ CE_GOOD - File Creation successful
+ CE_DIR_FULL - All root directory entries are taken
+ CE_WRITE_ERROR - The head cluster of the file could not be created.
+ Side Effects:
+ Modifies the FSerrno variable.
+ Description:
+ With the data passed within fo, create a new file entry in the current
+ directory. This function will first search for empty file entries.
+ Once an empty entry is found, the entry will be populated with data
+ for a file or directory entry. Finally, the first cluster of the
+ new file will be located and allocated, and its value will be
+ written into the file entry.
+ Remarks:
+ None
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode)
+{
+ BYTE index;
+ CETYPE error = CE_GOOD;
+ char name[11];
+
+ FSerrno = CE_GOOD;
+
+ for (index = 0; index < FILE_NAME_SIZE; index ++)
+ {
+ name[index] = fo->name[index];
+ }
+
+ *fHandle = 0;
+
+ // figure out where to put this file in the directory stucture
+ if(FindEmptyEntries(fo, fHandle))
+ {
+ // found the entry, now populate it
+ if((error = PopulateEntries(fo, name ,fHandle, mode)) == CE_GOOD)
+ {
+ // if everything is ok, create a first cluster
+ error = CreateFirstCluster(fo);
+ }
+ }
+ else
+ {
+ error = CE_DIR_FULL;
+ }
+
+ FSerrno = error;
+
+ return(error);
+}
+#endif
+
+/******************************************************
+ Function:
+ CETYPE CreateFirstCluster(FILEOBJ fo)
+ Summary:
+ Create the first cluster for a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file that contains the first cluster
+ Return Values:
+ CE_GOOD - First cluster created successfully
+ CE_WRITE_ERROR - Cluster creation failed
+ Side Effects:
+ None
+ Description:
+ This function will find an unused cluster, link it to
+ a file's directory entry, and write the entry back
+ to the device.
+ Remarks:
+ None.
+ ******************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFirstCluster(FILEOBJ fo)
+{
+ CETYPE error;
+ DWORD cluster,TempMsbCluster;
+ WORD fHandle;
+ DIRENTRY dir;
+ fHandle = fo->entry;
+
+ // Now create the first cluster (head cluster)
+ if((error = FILECreateHeadCluster(fo,&cluster)) == CE_GOOD)
+ {
+ // load the file entry so the new cluster can be linked to it
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ // Now update the new cluster
+ dir->DIR_FstClusLO = (cluster & 0x0000FFFF);
+
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ // Get the higher part of cluster and store it in directory entry.
+ TempMsbCluster = (cluster & 0x0FFF0000); // Since only 28 bits usedin FAT32. Mask the higher MSB nibble.
+ TempMsbCluster = TempMsbCluster >> 16; // Get the date into Lsb place.
+ dir->DIR_FstClusHI = TempMsbCluster;
+#else // If FAT32 support not enabled
+ TempMsbCluster = 0; // Just to avoid compiler warnigng.
+ dir->DIR_FstClusHI = 0;
+#endif
+
+ // now write it
+ if(Write_File_Entry(fo, &fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+ } // Create Cluster
+
+ return(error);
+}// End of CreateFirstCluster
+#endif
+
+/**********************************************************
+ Function:
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Find an empty dir entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Start of entries
+ Return Values:
+ TRUE - One found
+ FALSE - None found
+ Side Effects:
+ None
+ Description:
+ This function will cache directory entries, starting
+ with the one pointed to by the fHandle argument. It will
+ then search through the entries until an unused one
+ is found. If the end of the cluster chain for the
+ directory is reached, a new cluster will be allocated
+ to the directory (unless it's a FAT12 or FAT16 root)
+ and the first entry of the new cluster will be used.
+ Remarks:
+ None.
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+{
+ BYTE status = NOT_FOUND;
+ BYTE amountfound;
+ BYTE a;
+ WORD bHandle;
+ DWORD b;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ if((dir = Cache_File_Entry( fo, fHandle, TRUE)) == NULL)
+ {
+ status = CE_BADCACHEREAD;
+ }
+ else
+ {
+ // while its still not found
+ while(status == NOT_FOUND)
+ {
+ amountfound = 0;
+ bHandle = *fHandle;
+
+ // find (number) continuous entries
+ do
+ {
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // increase number
+ (*fHandle)++;
+ }while((a == DIR_DEL || a == DIR_EMPTY) && (dir != (DIRENTRY)NULL) && (++amountfound < 1));
+
+ // --- now why did we exit?
+ if(dir == NULL) // Last entry of the cluster
+ {
+ //setup the current cluster
+ b = fo->dirccls; // write it back
+
+ // make sure we are not the root directory
+ if(b == FatRootDirClusterValue)
+ {
+ if (fo->dsk->type != FAT32)
+ status = NO_MORE;
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ if(amountfound == 1)
+ {
+ status = FOUND;
+ *fHandle = bHandle;
+ }
+ }
+ }// while
+
+ // copy the base handle over
+ *fHandle = bHandle;
+ }
+
+ if(status == FOUND)
+ return(TRUE);
+ else
+ return(FALSE);
+}
+#endif
+
+/**************************************************************************
+ Function:
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle)
+ Summary:
+ Populate a dir entry with data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ name - Name of the file
+ fHandle - Location of the file
+ Return Values:
+ CE_GOOD - Population successful
+ Side Effects:
+ None
+ Description:
+ This function will write data into a new file entry. It will also
+ load timestamp data (based on the method selected by the user) and
+ update the timestamp variables.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode)
+{
+ BYTE error = CE_GOOD;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+
+ if (dir == NULL)
+ return CE_BADCACHEREAD;
+
+ // copy the contents over
+ strncpy(dir->DIR_Name,name,DIR_NAMECOMP);
+
+ // setup no attributes
+ if (mode == DIRECTORY)
+ dir->DIR_Attr = ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = ATTR_ARCHIVE;
+
+ dir->DIR_NTRes = 0x00; // nt reserved
+ dir->DIR_FstClusHI = 0x0000; // high word of this enty's first cluster number
+ dir->DIR_FstClusLO = 0x0000; // low word of this entry's first cluster number
+ dir->DIR_FileSize = 0x0; // file size in DWORD
+
+ // Timing information for uncontrolled clock mode
+#ifdef INCREMENTTIMESTAMP
+ dir->DIR_CrtTimeTenth = 0xB2; // millisecond stamp
+ dir->DIR_CrtTime = 0x7278; // time created
+ dir->DIR_CrtDate = 0x32B0; // date created
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = 0x32B0; // Last Access date
+ dir->DIR_WrtTime = 0x7279; // last update time
+ dir->DIR_WrtDate = 0x32B0; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ dir->DIR_CrtTime = gTimeCrtTime; // time created //
+ dir->DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate; // Last Access date
+ dir->DIR_WrtTime = gTimeWrtTime; // last update time
+ dir->DIR_WrtDate = gTimeWrtDate; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ // The user will have set the time before this funciton is called
+ dir->DIR_CrtTimeTenth = gTimeCrtMS;
+ dir->DIR_CrtTime = gTimeCrtTime;
+ dir->DIR_CrtDate = gTimeCrtDate;
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate;
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+ fo->size = dir->DIR_FileSize;
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ fo->attributes = dir->DIR_Attr;
+ fo->entry = *fHandle;
+
+ // just write the last entry in
+ if (Write_File_Entry(fo,fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+
+ return(error);
+}
+
+#ifdef USEREALTIMECLOCK
+
+/*************************************************************************
+ Function:
+ void CacheTime (void)
+ Summary:
+ Automatically store timestamp information from the RTCC
+ Conditions:
+ RTCC module enabled. Should not be called by the user.
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ This function will automatically load information from an RTCC
+ module and use it to update the global timing variables. These can
+ then be used to update file timestamps.
+ Remarks:
+ None.
+ *************************************************************************/
+
+void CacheTime (void)
+{
+#ifdef __C30__
+ WORD year, monthday, weekhour, minsec, c, result;
+ BYTE ptr1, ptr0;
+
+ if(RCFGCALbits.RTCPTR0)
+ ptr0 = 1;
+ else
+ ptr0 = 0;
+ if (RCFGCALbits.RTCPTR1)
+ ptr1 = 1;
+ else
+ ptr1 = 0;
+
+ RCFGCALbits.RTCPTR0 = 1;
+ RCFGCALbits.RTCPTR1 = 1;
+ year = RTCVAL;
+ monthday = RTCVAL;
+ weekhour = RTCVAL;
+ minsec = RTCVAL;
+
+ if (ptr0 == 1)
+ RCFGCALbits.RTCPTR0 = 1;
+
+ if (ptr1 == 1)
+ RCFGCALbits.RTCPTR1 = 1;
+
+ c = 0;
+ c += (year & 0x0F);
+ c += ((year & 0xF0) >> 4) * 10;
+ // c equals the last 2 digits of the year from 2000 to 2099
+ // Add 20 to adjust it to FAT time (from 1980 to 2107)
+ c += 20;
+ // shift the result to bits
+ result = c << 9;
+
+ if ((monthday & 0x1000) == 0x1000)
+ {
+ c = 10;
+ }
+ else
+ {
+ c = 0;
+ }
+ c += ((monthday & 0x0F00) >> 8);
+ c <<= 5;
+ result |= c;
+
+ c = (monthday & 0x00F0) >> 4;
+ c *= 10;
+ c += (monthday & 0x000F);
+
+ result |= c;
+
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+ gTimeAccDate = result;
+
+ c = ((weekhour & 0x00F0) >> 4) * 10;
+ c += (weekhour & 0x000F);
+ result = c << 11;
+ c = ((minsec & 0xF000) >> 12) * 10;
+ c += (minsec & 0x0F00) >> 8;
+ result |= (c << 5);
+ c = ((minsec & 0x00F0) >> 4) * 10;
+ c += (minsec & 0x000F);
+
+ // If seconds mod 2 is 1, add 1000 ms
+ if (c % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ c >>= 1;
+ result |= c;
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+#elif defined __C32__
+ rtccTime tm; // time structure
+ rtccDate dt; // date structure
+ RtccGetTimeDate(&tm, &dt);
+ gTimeCrtTime = tm.w[1] | tm.w[0];
+ gTimeWrtDate = dt.w[1] | tm.w[0];
+#endif
+}
+#endif
+
+#ifdef USERDEFINEDCLOCK
+
+/***********************************************************************************************************
+ Function:
+ int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+ Summary:
+ Manually set timestamp variables
+ Conditions:
+ USERDEFINEDCLOCK macro defined in FSconfig.h.
+ Input:
+ year - The year (1980\-2107)
+ month - The month (1\-12)
+ day - The day of the month (1\-31)
+ hour - The hour (0\-23)
+ minute - The minute (0\-59)
+ second - The second (0\-59)
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ Lets the user manually set the timing variables. The values passed in will be converted to the format
+ used by the FAT timestamps.
+ Remarks:
+ Call this before creating a file or directory (set create time) and
+ before closing a file (set last access time, last modified time)
+ ***********************************************************************************************************/
+
+int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+{
+ unsigned int result;
+
+ if ((year < 1980) || (year > 2107) || (month < 1) || (month > 12) ||
+ (day < 1) || (day > 31) || (hour > 23) || (minute > 59) || (second > 59))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ result = (year - 1980) << 9;
+ result |= (unsigned int)((unsigned int)month << 5);
+ result |= (day);
+
+ gTimeAccDate = result;
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+
+ result = ((unsigned int)hour << 11);
+ result |= (unsigned int)((unsigned int)minute << 5);
+ result |= (second/2);
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+
+ if (second % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ FSerrno = CE_GOOD;
+ return 0;
+}
+#endif
+
+#endif
+
+/***********************************************************************
+ Function:
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+ Summary;
+ Allocate a new cluster to a file
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ mode -
+ - 0 - Allocate a cluster to a file
+ - 1 - Allocate a cluster to a directory
+ Return Values:
+ CE_GOOD - Cluster allocated
+ CE_DISK_FULL - No clusters available
+ Side Effects:
+ None
+ Description:
+ This function will find an empty cluster on the device using the
+ FATfindEmptyCluster function. It will then mark it as the last
+ cluster in the file in the FAT chain, and link the current last
+ cluster of the passed file to the new cluster. If the new
+ cluster is a directory cluster, it will be erased (so there are no
+ extraneous directory entries). If it's allocated to a non-directory
+ file, it doesn't need to be erased; extraneous data in the cluster
+ will be unviewable because of the file size parameter.
+ Remarks:
+ None.
+ ***********************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+{
+ DISK * dsk;
+ DWORD c,curcls;
+
+ dsk = fo->dsk;
+ c = fo->ccls;
+
+ // find the next empty cluster
+ c = FATfindEmptyCluster(fo);
+ if (c == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ return CE_DISK_FULL;
+
+
+ // mark the cluster as taken, and last in chain
+ if(dsk->type == FAT12)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT12, FALSE);
+ else if (dsk->type == FAT16)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT16, FALSE);
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT32, FALSE);
+#endif
+
+ // link current cluster to the new one
+ curcls = fo->ccls;
+
+ WriteFAT( dsk, curcls, c, FALSE);
+
+ // update the FILE structure
+ fo->ccls = c;
+
+ // IF this is a dir, we need to erase the cluster
+ // If it's a file, we can leave it- the file size
+ // will limit the data we see to the data that's been
+ // written
+ if (mode == 1)
+ return (EraseCluster(dsk, c));
+ else
+ return CE_GOOD;
+
+} // allocate new cluster
+#endif
+
+/***********************************************
+ Function:
+ DWORD FATfindEmptyCluster(FILEOBJ fo)
+ Summary:
+ Find the next available cluster on the device
+ Conditions:
+ This function should not be called by the
+ user.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ DWORD - Address of empty cluster
+ 0 - Could not find empty cluster
+ Side Effects:
+ None
+ Description:
+ This function will search through the FAT to
+ find the next available cluster on the device.
+ Remarks:
+ Should not be called by user
+ ***********************************************/
+
+#ifdef ALLOW_WRITES
+DWORD FATfindEmptyCluster(FILEOBJ fo)
+{
+ DISK * disk;
+ DWORD value = 0x0;
+ DWORD c,curcls, EndClusterLimit, ClusterFailValue;
+
+ disk = fo->dsk;
+ c = fo->ccls;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ EndClusterLimit = END_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ EndClusterLimit = END_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT12:
+ EndClusterLimit = END_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // just in case
+ if(c < 2)
+ c = 2;
+
+ curcls = c;
+ ReadFAT(disk, c);
+
+ // sequentially scan through the FAT looking for an empty cluster
+ while(c)
+ {
+ // look at its value
+ if ( (value = ReadFAT(disk, c)) == ClusterFailValue)
+ {
+ c = 0;
+ break;
+ }
+
+ // check if empty cluster found
+ if (value == CLUSTER_EMPTY)
+ break;
+
+ c++; // check next cluster in FAT
+ // check if reached last cluster in FAT, re-start from top
+ if (value == EndClusterLimit || c >= disk->maxcls)
+ c = 2;
+
+ // check if full circle done, disk full
+ if ( c == curcls)
+ {
+ c = 0;
+ break;
+ }
+ } // scanning for an empty cluster
+
+ return(c);
+}
+#endif
+
+/************************************************************
+ Function:
+ int FSfclose(FSFILE *fo)
+ Summary:
+ Update file information and free FSFILE objects
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to the file to close
+ Return Values:
+ 0 - File closed successfully
+ EOF - Error closing the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will update the directory entry for the
+ file pointed to by 'fo' with the information contained
+ in 'fo,' including the new file size and attributes.
+ Timestamp information will also be loaded based on the
+ method selected by the user and written to the entry
+ as the last modified time and date. The file entry will
+ then be written to the device. Finally, the memory
+ used for the specified file object will be freed from
+ the dynamic heap or the array of FSFILE objects.
+ Remarks:
+ A function to flush data to the device without closing the
+ file can be created by removing the portion of this
+ function that frees the memory and the line that clears
+ the write flag.
+ ************************************************************/
+
+int FSfclose(FSFILE *fo)
+{
+ WORD fHandle;
+#ifndef FS_DYNAMIC_MEM
+ WORD fIndex;
+#endif
+ int error = 72;
+#ifdef ALLOW_WRITES
+ DIRENTRY dir;
+#endif
+
+ FSerrno = CE_GOOD;
+ fHandle = fo->entry;
+
+#ifdef ALLOW_WRITES
+ if(fo->flags.write)
+ {
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ // Write the current FAT sector to the disk
+ WriteFAT (fo->dsk, 0, 0, TRUE);
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = EOF;
+ return error;
+ }
+
+ // update the time
+#ifdef INCREMENTTIMESTAMP
+ IncrementTimeStamp(dir);
+#elif defined USERDEFINEDCLOCK
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#elif defined USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#endif
+
+ dir->DIR_FileSize = fo->size;
+
+ dir->DIR_Attr = fo->attributes;
+
+ // just write the last entry in
+ if(Write_File_Entry(fo,&fHandle))
+ error = 0;
+ else
+ {
+ FSerrno = CE_WRITE_ERROR;
+ error = EOF;
+ }
+
+ // it's now closed
+ fo->flags.write = FALSE;
+ }
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ FS_free((unsigned char *)fo);
+#else
+
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( fo == &gFileArray[fIndex] )
+ {
+ gFileSlotOpen[fIndex] = TRUE;
+ break;
+ }
+ }
+#endif
+
+ // File opened in read mode
+ if (error == 72)
+ error = 0;
+
+ return(error);
+} // FSfclose
+
+
+
+
+/*******************************************************
+ Function:
+ void IncrementTimeStamp(DIRENTRY dir)
+ Summary:
+ Automatically set the timestamp to "don't care" data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ dir - Pointer to directory structure
+ Return Values:
+ None
+ Side Effects:
+ None
+ Description:
+ This function will increment the timestamp variable in
+ the 'dir' directory entry. This is used for the
+ don't-care timing method.
+ Remarks:
+ None
+ *******************************************************/
+#ifdef INCREMENTTIMESTAMP
+void IncrementTimeStamp(DIRENTRY dir)
+{
+ BYTE seconds;
+ BYTE minutes;
+ BYTE hours;
+
+ BYTE day;
+ BYTE month;
+ BYTE year;
+
+ seconds = (dir->DIR_WrtTime & 0x1f);
+ minutes = ((dir->DIR_WrtTime & 0x07E0) >> 5);
+ hours = ((dir->DIR_WrtTime & 0xF800) >> 11);
+
+ day = (dir->DIR_WrtDate & 0x1f);
+ month = ((dir->DIR_WrtDate & 0x01E0) >> 5);
+ year = ((dir->DIR_WrtDate & 0xFE00) >> 9);
+
+ if(seconds < 29)
+ {
+ // Increment number of seconds by 2
+ // This clock method isn't intended to be accurate anyway
+ seconds++;
+ }
+ else
+ {
+ seconds = 0x00;
+
+ if(minutes < 59)
+ {
+ minutes++;
+ }
+ else
+ {
+ minutes = 0;
+
+ if(hours < 23)
+ {
+ hours++;
+ }
+ else
+ {
+ hours = 0;
+ if(day < 30)
+ {
+ day++;
+ }
+ else
+ {
+ day = 1;
+
+ if(month < 12)
+ {
+ month++;
+ }
+ else
+ {
+ month = 1;
+ // new year
+ year++;
+ // This is only valid until 2107
+ }
+ }
+ }
+ }
+ }
+
+ dir->DIR_WrtTime = (WORD)(seconds);
+ dir->DIR_WrtTime |= ((WORD)(minutes) << 5);
+ dir->DIR_WrtTime |= ((WORD)(hours) << 11);
+
+ dir->DIR_WrtDate = (WORD)(day);
+ dir->DIR_WrtDate |= ((WORD)(month) << 5);
+ dir->DIR_WrtDate |= ((WORD)(year) << 9);
+}
+#endif
+
+/*****************************************************************
+ Function:
+ BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Fill a file object with specified dir entry data
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Passed member's location
+ Return Values:
+ FOUND - Operation successful
+ NOT_FOUND - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then copy
+ the file information for that entry into the 'fo' FSFILE
+ object.
+ Remarks:
+ None.
+ *****************************************************************/
+
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE index, a;
+ BYTE character;
+ BYTE status;
+ BYTE test = 0;
+
+ // Get the entry
+ if (((*fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) && (*fHandle != 0)) // 4-bit mask because 16-root entries max per sector
+ {
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ }
+ else
+ {
+ dir = Cache_File_Entry (fo, fHandle, FALSE);
+ }
+
+
+ // Make sure there is a directory left
+ if(dir == (DIRENTRY)NULL)
+ {
+ status = NO_MORE;
+ }
+ else
+ {
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ {
+ status = NOT_FOUND;
+ }
+ else if ( a == DIR_EMPTY)
+ {
+ status = NO_MORE;
+ }
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // print the file name and extension
+ for (index=0; index < DIR_NAMESIZE; index++)
+ {
+ character = dir->DIR_Name[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // its possible to have an extension in a directory
+ character = dir->DIR_Extension[0];
+
+ // Get the file extension if its there
+ for (index=0; index < DIR_EXTENSION; index++)
+ {
+ character = dir->DIR_Extension[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // done and done with the name
+ // fo->name[++test] = (BYTE)'\0';
+
+ // Now store the identifier
+ fo->entry = *fHandle;
+
+ // see if we are still a good file
+ a = dir->DIR_Name[0];
+
+ if(a == DIR_DEL)
+ status = NOT_FOUND;
+ else
+ status = FOUND;
+
+ // Now store the size
+ fo->size = (dir->DIR_FileSize);
+
+ fo->cluster = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ /// -Get and store the attributes
+ a = dir->DIR_Attr;
+ fo->attributes = a;
+
+ // get the date and time
+ if ((a & ATTR_DIRECTORY) != 0)
+ {
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ }
+ else
+ {
+ fo->time = dir->DIR_WrtTime;
+ fo->date = dir->DIR_WrtDate;
+ }
+
+ }// deleted directory
+ }// Ensure we are still good
+ return(status);
+} // Fill_File_Object
+
+
+/************************************************************************
+ Function:
+ DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Load file information from a directory entry and cache the entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Information location
+ Return Values:
+ DIRENTRY - Pointer to the directory entry
+ NULL - Directory entry could not be loaded
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then return a pointer
+ to the directory entry in the global data buffer.
+ Remarks:
+ None.
+ ************************************************************************/
+
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE a;
+
+ fo->dirccls = fo->dirclus;
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+ if (dir == NULL)
+ return NULL;
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Make sure there is a directory left
+ if(a == DIR_EMPTY)
+ dir = (DIRENTRY)NULL;
+
+ if(dir != (DIRENTRY)NULL)
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ dir = (DIRENTRY)NULL;
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // scan through all the long dir entries
+ while(a == ATTR_LONG_NAME)
+ {
+ (*fHandle)++;
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+ if (dir == NULL)
+ return NULL;
+ a = dir->DIR_Attr;
+ } // long file name while loop
+ } // deleted dir
+ }// Ensure we are still good
+
+ return(dir);
+} // LoadDirAttrib
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+ Summary:
+ Erase a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location of file information
+ EraseClusters - Remove cluster allocation from FAT?
+ Return Values:
+ CE_GOOD - File erased successfully
+ CE_FILE_NOT_FOUND - Could not find the file on the card
+ CE_ERASE_FAIL - Internal Card erase failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries in the directory
+ pointed to by the dirclus value in the FSFILE object 'fo' that contains
+ the entry that corresponds to the fHandle offset. It will then mark that
+ entry as deleted. If the EraseClusters argument is TRUE, the chain of
+ clusters for that file will be marked as unused in the FAT by the
+ FAT_erase_cluster_chain function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+{
+ DIRENTRY dir;
+ BYTE a;
+ CETYPE status = CE_GOOD;
+ DWORD clus;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ // reset the cluster
+ clus = fo->dirclus;
+ fo->dirccls = clus;
+
+ // load the sector
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return CE_BADCACHEREAD;
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ a = dir->DIR_Name[0];
+
+ // see if there is something in the dir
+ if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ /* 8.3 File Name - entry*/
+ dir->DIR_Name[0] = DIR_DEL; // mark as deleted
+
+ // Get the starting cluster
+ clus = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ // Now write it
+ if(status != CE_GOOD || !(Write_File_Entry( fo, fHandle)))
+ {
+ status = CE_ERASE_FAIL;
+ }
+ else
+ {
+ if (clus != FatRootDirClusterValue) //
+ {
+ if(EraseClusters)
+ {
+ /* Now remove the cluster allocation from the FAT */
+ status = ((FAT_erase_cluster_chain(clus, disk)) ? CE_GOOD : CE_ERASE_FAIL);
+ }
+ }
+ }
+ } // Not already deleted
+ }// Not existant
+
+ if (status == CE_GOOD)
+ FSerrno = CE_GOOD;
+ else
+ FSerrno = CE_ERASE_FAIL;
+
+ return (status);
+}
+#endif
+
+/***************************************************************
+ Function:
+ int FSrename (const rom char * fileName, FSFILE * fo)
+ Summary:
+ Change the name of a file or directory
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file
+ fo - The file to rename
+ Return Values:
+ 0 - File was renamed successfully
+ EOF - File was not renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrename function will rename a file. First, it will
+ search through the current working directory to ensure the
+ specified new filename is not already in use. If it isn't,
+ the new filename will be written to the file entry of the
+ file pointed to by 'fo.'
+ Remarks:
+ None
+ ***************************************************************/
+
+#ifdef ALLOW_WRITES
+
+int FSrename (const char * fileName, FSFILE * fo)
+{
+ unsigned char j, k = 0;
+ char string[12];
+ WORD fHandle = 1, goodHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ if (fo == NULL)
+ {
+ FSerrno = CE_FILENOTOPENED;
+ return -1;
+ }
+ // If fo != NULL, rename the file
+ if (FormatFileName (fileName, fo->name, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+ else
+ {
+ for (j = 0; j < 11; j++)
+ {
+ string[j] = fo->name[j];
+ }
+ goodHandle = fo->entry;
+
+ fHandle = 0;
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Check if the file name is already used
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+
+ nextClusterIsLast = FALSE;
+ while (1)
+ {
+ // Look through the entries until we get to the end
+ // to make sure the name isn't taken
+ dir = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dir == NULL)
+ {
+ if (nextClusterIsLast == TRUE)
+ {
+ break;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ if (dir->DIR_Name[0] == 0)
+ break;
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+ fHandle++;
+ }
+
+ fHandle = goodHandle;
+ fo->dirccls = fo->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ for (j = 0; j < 11; j++)
+ {
+ dir->DIR_Name[j] = fo->name[j];
+ }
+
+ // just write the last entry in
+ if(!Write_File_Entry(fo,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#endif // Allow writes
+
+
+
+/*********************************************************************
+ Function:
+ FSFILE * FSfopen (const char * fileName, const char *mode)
+ Summary:
+ Open a file
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to open
+ mode -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ - WRITEPLUS - Create a new file or replace an existing file (reads also enabled)
+ - READPLUS - Read data from an existing file (writes also enabled)
+ - APPENDPLUS - Append data to an existing file (reads also enabled)
+ Return Values:
+ FSFILE * - The pointer to the file object
+ NULL - The file could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will open a file or directory. First, RAM in the
+ dynamic heap or static array will be allocated to a new FSFILE object.
+ Then, the specified file name will be formatted to ensure that it's
+ in 8.3 format. Next, the FILEfind function will be used to search
+ for the specified file name. If the name is found, one of three
+ things will happen: if the file was opened in read mode, its file
+ info will be loaded using the FILEopen function; if it was opened in
+ write mode, it will be erased, and a new file will be constructed in
+ its place; if it was opened in append mode, its file info will be
+ loaded with FILEopen and the current location will be moved to the
+ end of the file using the FSfseek function. If the file was not
+ found by FILEfind, it will be created if the mode was specified as
+ a write or append mode. In these cases, a pointer to the heap or
+ static FSFILE object array will be returned. If the file was not
+ found and the mode was specified as a read mode, the memory
+ allocated to the file will be freed and the NULL pointer value
+ will be returned.
+ Remarks:
+ None.
+ *********************************************************************/
+
+FSFILE * FSfopen( const char * fileName, const char *mode )
+{
+ FILEOBJ filePtr;
+#ifndef FS_DYNAMIC_MEM
+ int fIndex;
+#endif
+ BYTE ModeC;
+ WORD fHandle;
+ CETYPE final;
+
+#ifdef FS_DYNAMIC_MEM
+ filePtr = (FILEOBJ) FS_malloc(sizeof(FSFILE));
+#else
+
+ filePtr = NULL;
+
+ //Pick available file structure
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( gFileSlotOpen[fIndex] ) //this slot is available
+ {
+ gFileSlotOpen[fIndex] = FALSE;
+ filePtr = &gFileArray[fIndex];
+ break;
+ }
+ }
+
+ if( filePtr == NULL )
+ {
+ FSerrno = CE_TOO_MANY_FILES_OPEN;
+ return NULL; //no file structure slot available
+ }
+#endif
+
+ //Format the source string.
+ if( !FormatFileName(fileName, filePtr->name, 0) )
+ {
+#ifdef FS_DYNAMIC_MEM
+ FS_free( (unsigned char *)filePtr );
+#else
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+#endif
+ FSerrno = CE_INVALID_FILENAME;
+ return NULL; //bad filename
+ }
+
+ //Read the mode character
+ ModeC = mode[0];
+
+ filePtr->dsk = &gDiskData;
+ filePtr->cluster = 0;
+ filePtr->ccls = 0;
+ filePtr->entry = 0;
+ filePtr->attributes = ATTR_ARCHIVE;
+
+ // start at the current directory
+#ifdef ALLOW_DIRS
+ filePtr->dirclus = cwdptr->dirclus;
+ filePtr->dirccls = cwdptr->dirccls;
+#else
+ filePtr->dirclus = FatRootDirClusterValue;
+ filePtr->dirccls = FatRootDirClusterValue;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, filePtr);
+
+ // See if the file is found
+ if(FILEfind (filePtr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0) == CE_GOOD)
+ {
+ // File is Found
+ switch(ModeC)
+ {
+#ifdef ALLOW_WRITES
+ case 'w':
+ case 'W':
+ {
+ // File exists, we want to create a new one, remove it first
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ break;
+ }
+
+ case 'A':
+ case 'a':
+ {
+ if(filePtr->size != 0)
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ else
+ {
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ }
+ break;
+ }
+#endif
+ case 'R':
+ case 'r':
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'r');
+#ifdef ALLOW_WRITES
+ if ((mode[1] == '+') && !(filePtr->attributes & ATTR_DIRECTORY))
+ filePtr->flags.write = 1;
+#endif
+ break;
+ }
+
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;; //indicate error condition
+ break;
+ }
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ // the file was not found, reset to the default asked
+ FileObjectCopy(filePtr, &gFileTemp);
+
+ // File is not Found
+ if(ModeC == 'w' || ModeC == 'W' || ModeC == 'a' || ModeC == 'A')
+ {
+ // use the user requested name
+ fHandle = 0;
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ else
+#endif
+ final = CE_FILE_NOT_FOUND;
+ }
+
+ if (MDD_WriteProtectState())
+ {
+ filePtr->flags.write = 0;;
+ }
+
+#ifdef FS_DYNAMIC_MEM
+ if( final != CE_GOOD )
+ {
+ FS_free( (unsigned char *)filePtr );
+ filePtr = NULL;
+ }
+#else
+ if( final != CE_GOOD )
+ {
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+ filePtr = NULL;
+ }
+#endif
+ else
+ {
+ FSerrno = CE_GOOD;
+ }
+
+ return filePtr;
+}
+
+/*******************************************************************
+ Function:
+ long FSftell (FSFILE * fo)
+ Summary:
+ Determine the current location in a file
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to file structure
+ Return: Current location in the file
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSftell function will return the current position in the
+ file pointed to by 'fo' by returning the 'seek' variable in the
+ FSFILE object, which is used to keep track of the absolute
+ location of the current position in the file.
+ Remarks:
+ None
+ *******************************************************************/
+
+long FSftell (FSFILE * fo)
+{
+ FSerrno = CE_GOOD;
+ return (fo->seek);
+}
+
+
+#ifdef ALLOW_WRITES
+
+/*********************************************************************
+ Function:
+ int FSremove (const char * fileName)
+ Summary:
+ Delete a file
+ Conditions:
+ File not opened, file exists
+ Input:
+ fileName - Name of the file to erase
+ Return Values:
+ 0 - File removed
+ EOF - File was not removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremove function will attempt to find the specified file with
+ the FILEfind function. If the file is found, it will be erased
+ using the FILEerase function.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSremove (const char * fileName)
+{
+ FILEOBJ fo = &tempCWDobj;
+ CETYPE result;
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+ //Format the source string
+ if( !FormatFileName(fileName, fo->name, 0) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = ATTR_ARCHIVE;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+
+ if (fo->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_DELETE_DIR;
+ return -1;
+ }
+
+ result = FILEerase(fo, &fo->entry, TRUE);
+ if( result == CE_GOOD )
+ return 0;
+ else
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+}
+#endif
+
+/*********************************************************
+ Function:
+ void FSrewind (FSFILE * fo)
+ Summary:
+ Set the current position in a file to the beginning
+ Conditions:
+ File opened.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ None
+ Side Effects:
+ None.
+ Description:
+ The FSrewind funciton will reset the position of the
+ specified file to the beginning of the file. This
+ functionality is faster than using FSfseek to reset
+ the position in the file.
+ Remarks:
+ None.
+ *********************************************************/
+
+void FSrewind (FSFILE * fo)
+{
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ flushData();
+#endif
+ fo->seek = 0;
+ fo->pos = 0;
+ fo->sec = 0;
+ fo->ccls = fo->cluster;
+ gBufferOwner = NULL;
+ return;
+}
+
+/**************************************************************************
+ Function:
+ int FSerror (void)
+ Summary:
+ Return an error code for the last function call
+ Conditions:
+ The return value depends on the last function called.
+ Input:
+ None
+ Side Effects:
+ None.
+ Return Values:
+ FSInit -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The physical media could not be initialized
+ - CE_BAD_SECTOR_READ � The MBR or the boot sector could not be
+ read correctly
+ - CE_BAD_PARITION � The MBR signature code was incorrect.
+ - CE_NOT_FORMATTED � The boot sector signature code was incorrect or
+ indicates an invalid number of bytes per sector.
+ - CE_CARDFAT32 � The physical media is FAT32 type (only an error
+ when FAT32 support is disabled).
+ - CE_UNSUPPORTED_FS � The device is formatted with an unsupported file
+ system (not FAT12 or 16).
+ FSfopen -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The device has not been initialized.
+ - CE_TOO_MANY_FILES_OPEN � The function could not allocate any
+ additional file information to the array
+ of FSFILE structures or the heap.
+ - CE_INVALID_FILENAME � The file name argument was invalid.
+ - CE_INVALID_ARGUMENT � The user attempted to open a directory in a
+ write mode or specified an invalid mode argument.
+ - CE_FILE_NOT_FOUND � The specified file (which was to be opened in read
+ mode) does not exist on the device.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_ERASE_FAIL � The existing file could not be erased (when opening
+ a file in WRITE mode).
+ - CE_DIR_FULL � The directory is full.
+ - CE_DISK_FULL� The data memory section is full.
+ - CE_WRITE_ERROR � A write to the device failed.
+ - CE_SEEK_ERROR � The current position in the file could not be set to
+ the end (when the file was opened in APPEND mode).
+ FSfclose -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer or the new file
+ entry information could not be written to the device.
+ - CE_BADCACHEREAD � The file entry information could not be cached
+ FSfread -
+ - CE_GOOD � No Error
+ - CE_WRITEONLY � The file was opened in a write-only mode.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_BAD_SECTOR_READ � The data sector could not be read.
+ - CE_EOF � The end of the file was reached.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be loaded.
+ FSfwrite -
+ - CE_GOOD � No Error
+ - CE_READONLY � The file was opened in a read-only mode.
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_WRITE_ERROR � There was an error writing data to the device.
+ - CE_BADCACHEREAD � The data sector to be modified could not be read from
+ the device.
+ - CE_DISK_FULL � All data clusters on the device are in use.
+ FSfseek -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_INVALID_ARGUMENT � The specified offset exceeds the size of the file.
+ - CE_BADCACHEREAD � The sector that contains the new current position
+ could not be loaded.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be
+ loaded/allocated.
+ FSftell -
+ - CE_GOOD � No Error
+ FSattrib -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The attribute argument was invalid.
+ - CE_BADCACHEREAD � The existing file entry information could not be
+ loaded.
+ - CE_WRITE_ERROR � The file entry information could not be written to
+ the device.
+ FSrename -
+ - CE_GOOD � No Error
+ - CE_FILENOTOPENED � A null file pointer was passed into the function.
+ - CE_INVALID_FILENAME � The file name passed into the function was invalid.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_FILENAME_EXISTS � A file with the specified name already exists.
+ - CE_WRITE_ERROR � The new file entry data could not be written to the
+ device.
+ FSfeof -
+ - CE_GOOD � No Error
+ FSformat -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The device could not be initialized.
+ - CE_BADCACHEREAD � The master boot record or boot sector could not be
+ loaded successfully.
+ - CE_INVALID_ARGUMENT � The user selected to create their own boot sector on
+ a device that has no master boot record, or the mode
+ argument was invalid.
+ - CE_WRITE_ERROR � The updated MBR/Boot sector could not be written to
+ the device.
+ - CE_BAD_PARTITION � The calculated number of sectors per clusters was
+ invalid.
+ - CE_NONSUPPORTED_SIZE � The card has too many sectors to be formatted as
+ FAT12 or FAT16.
+ FSremove -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � The specified file could not be found.
+ - CE_ERASE_FAIL � The file could not be erased.
+ FSchdir -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The path string was mis-formed or the user tried to
+ change to a non-directory file.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_FOUND � Could not find a directory in the path.
+ FSgetcwd -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The user passed a 0-length buffer into the function.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the current working directory.
+ FSmkdir -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_ARGUMENT � The path string was mis-formed.
+ - CE_BADCACHEREAD � Could not successfully change to a recently created
+ directory to store its dir entry information, or
+ could not cache directory entry information.
+ - CE_INVALID_FILENAME � One or more of the directory names has an invalid
+ format.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device or the dot/dotdot entries could
+ not be written to a newly created directory.
+ - CE_DIR_FULL � There are no available dir entries in the CWD.
+ - CE_DISK_FULL � There are no available clusters in the data region of
+ the device.
+ FSrmdir -
+ - CE_GOOD � No Error
+ - CE_DIR_NOT_FOUND � The directory specified could not be found or the
+ function could not change to a subdirectory within
+ the directory to be deleted (when recursive delete is
+ enabled).
+ - CE_INVALID_ARGUMENT � The user tried to remove the CWD or root directory.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_EMPTY � The directory to be deleted was not empty and
+ recursive subdirectory removal was disabled.
+ - CE_ERASE_FAIL � The directory or one of the directories or files
+ within it could not be deleted.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the CWD.
+ SetClockVars -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The time values passed into the function were
+ invalid.
+ FindFirst -
+ - CE_GOOD � No Error
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ - CE_BADCACHEREAD � The file information for the file that was found
+ could not be cached.
+ FindNext -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The SearchRec object was not initialized by a call to
+ FindFirst.
+ - CE_INVALID_ARGUMENT � The SearchRec object was initialized in a different
+ directory from the CWD.
+ - CE_INVALID_FILENAME � The filename is invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ FSfprintf -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � Characters could not be written to the file.
+ Description:
+ The FSerror function will return the FSerrno variable. This global
+ variable will have been set to an error value during the last call of a
+ library function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSerror (void)
+{
+ return FSerrno;
+}
+
+
+/**************************************************************
+ Function:
+ void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+ Summary:
+ Copy a file object
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - The destination
+ foSource - the source
+ Return:
+ None
+ Side Effects:
+ None
+ Description:
+ The FileObjectCopy function will make an exacy copy of
+ a specified FSFILE object.
+ Remarks:
+ None
+ **************************************************************/
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+{
+ BYTE size;
+ BYTE *dest;
+ BYTE *source;
+ BYTE Index;
+
+ dest = (BYTE *)foDest;
+ source = (BYTE *)foSource;
+
+ size = sizeof(FSFILE);
+
+ for(Index=0;Index< size; Index++)
+ {
+ dest[Index] = source[Index];
+ }
+}
+
+/*************************************************************************
+ Function:
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+ Summary:
+ Create the first cluster of a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ cluster - Cluster location
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ CE_DISK_FULL - All clusters in partition are taken
+ Side Effects:
+ None
+ Description:
+ The FILECreateHeadCluster function will create the first cluster
+ of a file. First, it will find an empty cluster with the
+ FATfindEmptyCluster function and mark it as the last cluster in the
+ file. It will then erase the cluster using the EraseCluster function.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+{
+ DISK * disk;
+ CETYPE error = CE_GOOD;
+
+ disk = fo->dsk;
+
+ // find the next empty cluster
+ *cluster = FATfindEmptyCluster(fo);
+
+ if(*cluster == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ {
+ error = CE_DISK_FULL;
+ }
+ else
+ {
+ // mark the cluster as taken, and last in chain
+ if(disk->type == FAT12)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT12, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+ else if(disk->type == FAT16)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT16, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+
+ #ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT32, FALSE) == CLUSTER_FAIL_FAT32)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+#endif
+
+ // lets erase this cluster
+ if(error == CE_GOOD)
+ {
+ error = EraseCluster(disk,*cluster);
+ }
+ }
+
+ return(error);
+} // allocate head cluster
+#endif
+
+/*************************************************************************
+ Function:
+ BYTE EraseCluster(DISK *disk, DWORD cluster)
+ Summary:
+ Erase a cluster
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - Disk structure
+ cluster - Cluster to be erased
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ Side Effects:
+ None
+ Description:
+ The EraseCluster function will write a 0 value into every byte of
+ the specified cluster.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE EraseCluster(DISK *disk, DWORD cluster)
+{
+ BYTE index;
+ DWORD SectorAddress;
+ BYTE error = CE_GOOD;
+
+ SectorAddress = Cluster2Sector(disk,cluster);
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+
+ gBufferOwner = NULL;
+
+ if (gBufferZeroed == FALSE)
+ {
+ // clear out the memory first
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+ gBufferZeroed = TRUE;
+ }
+
+ // Now clear them out
+ for(index = 0; index < disk->SecPerClus && error == CE_GOOD; index++)
+ {
+ if (MDD_SectorWrite( SectorAddress++, disk->buffer, FALSE) != TRUE)
+ error = CE_WRITE_ERROR;
+ }
+
+ return(error);
+}
+#endif
+
+
+#if defined (__C30__) || defined (__C32__)
+
+/***************************************************
+ Function:
+ BYTE ReadByte(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a byte from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ BYTE - the byte read
+ Side Effects:
+ None
+ Description:
+ Reads a byte from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+BYTE ReadByte( BYTE* pBuffer, WORD index )
+{
+ return( pBuffer[index] );
+}
+
+
+/***************************************************
+ Function:
+ BYTE ReadWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 16-bit word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ WORD - the word read
+ Side Effects:
+ None
+ Description:
+ Reads a 16-bit word from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+WORD ReadWord( BYTE* pBuffer, WORD index )
+{
+ BYTE loByte, hiByte;
+ WORD res;
+
+ loByte = pBuffer[index];
+ hiByte = pBuffer[index+1];
+ res = hiByte;
+ res *= 0x100;
+ res |= loByte;
+ return( res );
+}
+
+
+/****************************************************
+ Function:
+ BYTE ReadDWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 32-bit double word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ DWORD - the double word read
+ Side Effects:
+ None
+ Description:
+ Reads a 32-bit double word from a buffer
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD ReadDWord( BYTE* pBuffer, WORD index )
+{
+ WORD loWord, hiWord;
+ DWORD result;
+
+ loWord = ReadWord( pBuffer, index );
+ hiWord = ReadWord( pBuffer, index+2 );
+
+ result = hiWord;
+ result *= 0x10000;
+ result |= loWord;
+ return result;
+}
+
+#endif
+
+
+
+/****************************************************
+ Function:
+ DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+ Summary:
+ Convert a cluster number to the corresponding sector
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - Disk structure
+ cluster - Cluster to be converted
+ Return:
+ sector - Sector that corresponds to given cluster
+ Side Effects:
+ None
+ Description:
+ The Cluster2Sector function will calculate the
+ sector number that corresponds to the first sector
+ of the cluster whose value was passed into the
+ function.
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+{
+ DWORD sector;
+
+ /* Rt: Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ /* In FAT32, there is no separate ROOT region. It is as well stored in DATA region */
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // The root dir takes up cluster 0 and 1
+ if(cluster == 0 ||cluster == 1)
+ sector = dsk->root + cluster;
+ else
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+ }
+
+ return(sector);
+
+}
+
+
+/***************************************************************************
+ Function:
+ int FSattrib (FSFILE * file, unsigned char attributes)
+ Summary:
+ Change the attributes of a file
+ Conditions:
+ File opened
+ Input:
+ file - Pointer to file structure
+ attributes - The attributes to set for the file
+ - Attribute - Value - Indications
+ - ATTR_READ_ONLY - 0x01 - The read-only attribute
+ - ATTR_HIDDEN - 0x02 - The hidden attribute
+ - ATTR_SYSTEM - 0x04 - The system attribute
+ - ATTR_ARCHIVE - 0x20 - The archive attribute
+ Return Values:
+ 0 - Attribute change was successful
+ -1 - Attribute change was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSattrib funciton will set the attributes of the specified file
+ to the attributes passed in by the user. This function will load the
+ file entry, replace the attributes with the ones specified, and write
+ the attributes back. If the specified file is a directory, the
+ directory attribute will be preserved.
+ Remarks:
+ None
+ ***************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSattrib (FSFILE * file, unsigned char attributes)
+{
+ WORD fHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ // Check for valid attributes
+ if ((attributes & ~0x27) != 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ fHandle = file->entry;
+
+ file->dirccls = file->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(file, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Ensure that we aren't trying to change the
+ // attributes of a volume entry
+ if (dir->DIR_Attr & ATTR_VOLUME)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Don't remove the directory attribute from DIR files
+ if (file->attributes & ATTR_DIRECTORY)
+ dir->DIR_Attr = attributes | ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = attributes;
+
+ // just write the last entry in
+ if(!Write_File_Entry(file,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+
+/*********************************************************************************
+ Function:
+ size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Write data to a file
+ Conditions:
+ File opened in WRITE, APPEND, WRITE+, APPEND+, READ+ mode
+ Input:
+ ptr - Pointer to source buffer
+ size - Size of units in bytes
+ n - Number of units to transfer
+ stream - Pointer to file structure
+ Return:
+ size_t - number of units written
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfwrite function will write data to a file. First, the sector that
+ corresponds to the current position in the file will be loaded (if it hasn't
+ already been cached in the global data buffer). Data will then be written to
+ the device from the specified buffer until the specified amount has been written.
+ If the end of a cluster is reached, the next cluster will be loaded, unless
+ the end-of-file flag for the specified file has been set. If it has, a new
+ cluster will be allocated to the file. Finally, the new position and filezize
+ will be stored in the FSFILE object. The parameters 'size' and 'n' indicate how
+ much data to write. 'Size' refers to the size of one object to write (in bytes),
+ and 'n' will refer to the number of these objects to write. The value returned
+ will be equal to 'n' unless an error occured.
+ Remarks:
+ None.
+ *********************************************************************************/
+
+#ifdef ALLOW_WRITES
+size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD count = size * n;
+ BYTE * src = (BYTE *) ptr;
+ DISK * dsk; // pointer to disk structure
+ CETYPE error = CE_GOOD;
+ WORD pos;
+ DWORD l; // absolute lba of sector to load
+ DWORD seek, filesize;
+ WORD writeCount = 0;
+
+ // see if the file was opened in a write mode
+ if(!(stream->flags.write))
+ {
+ FSerrno = CE_READONLY;
+ error = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ if (count == 0)
+ return 0;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ error = CE_WRITE_PROTECTED;
+ return 0;
+ }
+
+ gBufferZeroed = FALSE;
+ dsk = stream->dsk;
+ // get the stated position
+ pos = stream->pos;
+ seek = stream->seek;
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ // Check if the current stream was the last one to use the
+ // buffer. If not, check if we need to write data from the
+ // old stream
+ if (gBufferOwner != stream)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+ gBufferOwner = stream;
+ }
+ if (gLastDataSectorRead != l)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+
+ gBufferZeroed = FALSE;
+ if(!MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ }
+ gLastDataSectorRead = l;
+ }
+ // exit loop if EOF reached
+ filesize = stream->size;
+
+ // Loop while writing bytes
+ while (error == CE_GOOD && count > 0)
+ {
+ if( seek == filesize )
+ stream->flags.FileWriteEOF = TRUE;
+
+ // load a new sector if necessary, multiples of sector
+ if (pos == MEDIA_SECTOR_SIZE)
+ {
+ BYTE needRead = TRUE;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ // reset position
+ pos = 0;
+
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if (stream->sec == dsk->SecPerClus)
+ {
+ stream->sec = 0;
+
+ if(stream->flags.FileWriteEOF)
+ {
+ error = FILEallocate_new_cluster(stream, 0); // add new cluster to the file
+ needRead = FALSE;
+ }
+ else
+ error = FILEget_next_cluster( stream, 1);
+ }
+
+ if (error == CE_DISK_FULL)
+ {
+ FSerrno = CE_DISK_FULL;
+ return 0;
+ }
+
+ if(error == CE_GOOD)
+ {
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+ gBufferOwner = stream;
+ // If we just allocated a new cluster, then the cluster will
+ // contain garbage data, so it doesn't matter what we write to it
+ // Whatever is in the buffer will work fine
+ if (needRead)
+ {
+ if( !MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = 0xFFFFFFFF;
+ return 0;
+ }
+ else
+ {
+ gLastDataSectorRead = l;
+ }
+ }
+ else
+ gLastDataSectorRead = l;
+ }
+ } // load new sector
+
+ if(error == CE_GOOD)
+ {
+ // Write one byte at a time
+ RAMwrite(dsk->buffer, pos++, *(char *)src);
+ src = src + 1; // compiler bug
+ seek++;
+ count--;
+ writeCount++;
+ // now increment the size of the part
+ if(stream->flags.FileWriteEOF)
+ filesize++;
+ gNeedDataWrite = TRUE;
+ }
+ } // while count
+
+ // save off the positon
+ stream->pos = pos;
+
+ // save off the seek
+ stream->seek = seek;
+
+ // now the new size
+ stream->size = filesize;
+
+ return(writeCount / size);
+} // fwrite
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE flushData (void)
+ Summary:
+ Flush unwritten data to a file
+ Conditions:
+ File opened in a write mode, data needs to be written
+ Return Values:
+ CE_GOOD - Data was updated successfully
+ CE_WRITE_ERROR - Data could not be updated
+ Side Effects:
+ None
+ Description:
+ The flushData function is called when it is necessary to
+ read new data into the global data buffer and the
+ gNeedDataWrite variable indicates that there is data
+ in the buffer that hasn't been written to the device.
+ The flushData function will write the data from the
+ buffer into the current cluster of the FSFILE object
+ that is stored in the gBufferOwner global variable.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE flushData (void)
+{
+ DWORD l;
+ DISK * dsk;
+
+ // This will either be the pointer to the last file, or the handle
+ FILEOBJ stream = gBufferOwner;
+
+ dsk = stream->dsk;
+
+ // figure out the lba
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ if(!MDD_SectorWrite( l, dsk->buffer, FALSE))
+ {
+ return CE_WRITE_ERROR;
+ }
+
+ gNeedDataWrite = FALSE;
+
+ return CE_GOOD;
+}
+#endif
+
+/****************************************************
+ Function:
+ int FSfeof( FSFILE * stream )
+ Summary:
+ Indicate whether the current file position is at the end
+ Conditions:
+ File is open in a read mode
+ Input:
+ stream - Pointer to the target file
+ Return Values:
+ Non-Zero - EOF reached
+ 0 - Not at end of File
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfeof function will indicate that the end-of-
+ file has been reached for the specified file by
+ comparing the absolute location in the file to the
+ size of the file.
+ Remarks:
+ None.
+ ****************************************************/
+
+int FSfeof( FSFILE * stream )
+{
+ FSerrno = CE_GOOD;
+ return( stream->seek == stream->size );
+}
+
+
+/**************************************************************************
+ Function:
+ size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Read data from a file
+ Conditions:
+ File is opened in a read mode
+ Input:
+ ptr - Destination buffer for read bytes
+ size - Size of units in bytes
+ n - Number of units to be read
+ stream - File to be read from
+ Return:
+ size_t - number of units read
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfread function will read data from the specified file. First,
+ the appropriate sector of the file is loaded. Then, data is read into
+ the specified buffer until the specified number of bytes have been read.
+ When a cluster boundary is reached, a new cluster will be loaded. The
+ parameters 'size' and 'n' indicate how much data to read. 'Size'
+ refers to the size of one object to read (in bytes), and 'n' will refer
+ to the number of these objects to read. The value returned will be equal
+ to 'n' unless an error occured or the user tried to read beyond the end
+ of the file.
+ Remarks:
+ None.
+ **************************************************************************/
+
+size_t FSfread (void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD len = size * n;
+ BYTE *pointer = (BYTE *) ptr;
+ DISK *dsk; // Disk structure
+ DWORD seek, sec_sel;
+ WORD pos; //position within sector
+ CETYPE error = CE_GOOD;
+ WORD readCount = 0;
+
+ FSerrno = CE_GOOD;
+
+ dsk = (DISK *)stream->dsk;
+ pos = stream->pos;
+ seek = stream->seek;
+
+ if( !stream->flags.read )
+ {
+ FSerrno = CE_WRITEONLY;
+ return 0; // CE_WRITEONLY
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+#endif
+
+ // if it not my buffer, then get it from the disk.
+ if( (gBufferOwner != stream) && (pos != MEDIA_SECTOR_SIZE ))
+ {
+ gBufferOwner = stream;
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ return 0;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ //loop reading (count) bytes
+ while( len )
+ {
+ if( seek == stream->size )
+ {
+ FSerrno = CE_EOF;
+ error = CE_EOF;
+ break;
+ }
+
+ // In fopen, pos is init to 0 and the sect is loaded
+ if( pos == MEDIA_SECTOR_SIZE )
+ {
+ // reset position
+ pos = 0;
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if( stream->sec == dsk->SecPerClus )
+ {
+ stream->sec = 0;
+ if( (error = FILEget_next_cluster( stream, 1)) != CE_GOOD )
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ break;
+ }
+ }
+
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+
+ gBufferOwner = stream;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ break;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ // copy one byte at a time
+ *pointer = RAMread( dsk->buffer, pos++ );
+ pointer++;
+ seek++;
+ readCount++;
+ len--;
+ }
+
+ // save off the positon
+ stream->pos = pos;
+ // save off the seek
+ stream->seek = seek;
+
+ return(readCount / size);
+} // fread
+
+
+/***************************************************************************
+ Function:
+ BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode )
+ Summary:
+ Format a file name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be formatted
+ fN2 - The location the formatted name will be stored
+ mode - Non-zero if parital string search chars are allowed
+ Return Values:
+ TRUE - Name formatted successfully
+ FALSE - File name could not be formatted
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into FSFILE structure format. If filename is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ filename are valid in this filesystem.
+ Remarks:
+ None.
+ ***************************************************************************/
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode)
+{
+ char * pExt;
+ WORD temp;
+ char szName[15];
+ BYTE count;
+
+ for (count = 0; count < 11; count++)
+ {
+ *(fN2 + count) = ' '; // Load destination filename to be space intially.
+ }
+
+ // Make sure we dont have an empty string or a name with only
+ // an extension
+ if (fileName[0] == '.' || fileName[0] == 0)
+ return FALSE;
+
+ temp = strlen( fileName );
+
+ if( temp <= TOTAL_FILE_SIZE ) // 8+3+1
+ strcpy( szName, fileName ); // copy to RAM in case fileName is located in flash
+ else
+ return FALSE; //long file name
+
+ // Make sure the characters are valid
+ if ( !ValidateChars(szName, mode) )
+ return FALSE;
+
+ //Look for '.' in the szName
+ if( (pExt = strchr( szName, '.' )) != 0 )
+ {
+ *pExt = 0; // Assigning NULL here makes the "szName" to be terminated and "pExt" pointer to hold only extn characters.
+ pExt++; // now pointing to extension
+
+ if( strlen( pExt ) > 3 ) // make sure the extension is 3 bytes or fewer
+ return FALSE;
+ }
+
+ if( strlen(szName) > 8 )
+ return FALSE;
+
+ //copy file name
+ for (count = 0; count < strlen(szName); count++)
+ {
+ *(fN2 + count) = * (szName + count); // Destination filename initially filled with SPACE. Now copy only available chars.
+ }
+
+ //copy extension
+ if(pExt && *pExt )
+ {
+ for (count = 0; count < strlen (pExt); count++)
+ {
+ *(fN2 + count + 8) = *(pExt + count); // Copy the extn to 8th position onwards. Ex: "FILE .Tx "
+ }
+ }
+
+ return TRUE;
+}
+
+#ifdef ALLOW_DIRS
+
+/*************************************************************************
+ Function:
+ BYTE FormatDirName (char * string, BYTE mode)
+ Summary:
+ Format a dir name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ string - The name to be formatted
+ mode -
+ - TRUE - Partial string search characters are allowed
+ - FALSE - Partial string search characters are forbidden
+ Return Values:
+ TRUE - The name was formatted correctly
+ FALSE - The name contained invalid characters
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into directory structure format. If the name is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ directory name are valid in this filesystem.
+ Remarks:
+ None.
+ *************************************************************************/
+
+BYTE FormatDirName (char * string, BYTE mode)
+{
+ unsigned char i, j;
+ char tempString [12];
+
+ if (ValidateChars (string, mode) == FALSE)
+ return FALSE;
+
+ for (i = 0; (i < 8) && (*(string + i) != '.') && (*(string + i) != 0); i++)
+ {
+ tempString[i] = *(string + i);
+ }
+
+ j = i;
+
+ while (i < 8)
+ {
+ tempString [i++] = 0x20;
+ }
+
+ if (*(string + j) == '.')
+ {
+ j++;
+ while (*(string + j) != 0)
+ {
+ tempString[i++] = *(string + j++);
+ }
+ }
+
+ while (i < 11)
+ {
+ tempString[i++] = 0x20;
+ }
+
+ tempString[11] = 0;
+
+ // Forbidden
+ if (tempString[0] == 0x20)
+ {
+ tempString[0] = '_';
+ }
+
+ for (i = 0; i < 12; i++)
+ {
+ *(string + i) = tempString[i];
+ }
+
+ return TRUE;
+}
+#endif
+
+
+/*************************************************************
+ Function:
+ BYTE ValidateChars( char * FileName, BYTE mode)
+ Summary:
+ Validate the characters in a given file name
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be validated
+ mode - Determines if partial string search is allowed
+ Return Values:
+ TRUE - Name was validated
+ FALSE - File name was not valid
+ Side Effects:
+ None
+ Description:
+ The ValidateChars function will compare characters in a
+ specified filename to determine if they're permissable
+ in the FAT file system. Lower-case characters will be
+ converted to upper-case. If the mode argument is specifed
+ to be 'TRUE,' partial string search characters are allowed.
+ Remarks:
+ None.
+ *************************************************************/
+BYTE ValidateChars( char * FileName , BYTE mode)
+{
+ int StrSz, index;
+ unsigned char radix = FALSE;
+
+ StrSz = strlen(FileName);
+
+ for( index = 0; index < StrSz; index++ )
+ {
+ if (((FileName[index] <= 0x20) && (FileName[index] != 0x05)) ||
+ (FileName[index] == 0x22) || (FileName[index] == 0x2B) ||
+ (FileName[index] == 0x2C) || (FileName[index] == 0x2F) ||
+ (FileName[index] == 0x3A) || (FileName[index] == 0x3B) ||
+ (FileName[index] == 0x3C) || (FileName[index] == 0x3D) ||
+ (FileName[index] == 0x3E) || (FileName[index] == 0x5B) ||
+ (FileName[index] == 0x5C) || (FileName[index] == 0x5D) ||
+ (FileName[index] == 0x7C) || ((FileName[index] == 0x2E) && radix == TRUE))
+ {
+ return FALSE;
+ }
+ else
+ {
+ // Check for partial string search chars
+ if (mode == FALSE)
+ {
+ if ((FileName[index] == '*') || (FileName[index] == '?'))
+ return FALSE;
+ }
+ // only one radix ('.') character is allowed
+ if (FileName[index] == 0x2E)
+ {
+ radix = TRUE;
+ }
+ // Convert lower-case to upper-case
+ if ((FileName[index] >= 0x61) && (FileName[index] <= 0x7A))
+ FileName[index] -= 0x20;
+ }
+ }
+ return TRUE;
+}
+
+
+/**********************************************************************
+ Function:
+ int FSfseek(FSFILE *stream, long offset, int whence)
+ Summary:
+ Change the current position in a file
+ Conditions:
+ File opened
+ Input:
+ stream - Pointer to file structure
+ offset - Offset from base location
+ whence -
+ - SEEK_SET - Seek from start of file
+ - SEEK_CUR - Seek from current location
+ - SEEK_END - Seek from end of file (subtract offset)
+ Return Values:
+ 0 - Operation successful
+ -1 - Operation unsuccesful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfseek function will change the current position in the file to
+ one specified by the user. First, an absolute offset is calculated
+ using the offset and base location passed in by the user. Then, the
+ position variables are updated, and the sector number that corresponds
+ to the new location. That sector is then loaded. If the offset
+ falls exactly on a cluster boundary, a new cluster will be allocated
+ to the file and the position will be set to the first byte of that
+ cluster.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSfseek(FSFILE *stream, long offset, int whence)
+{
+ DWORD numsector, temp; // lba of first sector of first cluster
+ DISK* dsk; // pointer to disk structure
+ BYTE test;
+ long offset2 = offset;
+
+ dsk = stream->dsk;
+
+ switch(whence)
+ {
+ case SEEK_CUR:
+ // Apply the offset to the current position
+ offset2 += stream->seek;
+ break;
+ case SEEK_END:
+ // Apply the offset to the end of the file
+ offset2 = stream->size - offset2;
+ break;
+ case SEEK_SET:
+ // automatically there
+ default:
+ break;
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+#endif
+
+ // start from the beginning
+ temp = stream->cluster;
+ stream->ccls = temp;
+
+ temp = stream->size;
+
+ if (offset2 > temp)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return (-1); // past the limits
+ }
+ else
+ {
+ // if we are writing we are no longer at the end
+ stream->flags.FileWriteEOF = FALSE;
+
+ // set the new postion
+ stream->seek = offset2;
+
+ // figure out how many sectors
+ numsector = offset2 / MEDIA_SECTOR_SIZE;
+
+ // figure out how many bytes off of the offset
+ offset2 = offset2 - (numsector * MEDIA_SECTOR_SIZE);
+ stream->pos = offset2;
+
+ // figure out how many clusters
+ temp = numsector / dsk->SecPerClus;
+
+ // figure out the stranded sectors
+ numsector = numsector - (dsk->SecPerClus * temp);
+ stream->sec = numsector;
+
+ // if we are in the current cluster stay there
+ if (temp > 0)
+ {
+ test = FILEget_next_cluster(stream, temp);
+ if (test != CE_GOOD)
+ {
+ if (test == CE_FAT_EOF)
+ {
+#ifdef ALLOW_WRITES
+ if (stream->flags.write)
+ {
+ // load the previous cluster
+ stream->ccls = stream->cluster;
+ // Don't perform this operation if there's only one cluster
+ if (temp != 1)
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (FILEallocate_new_cluster(stream, 0) != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return -1;
+ }
+ // sec and pos should already be zero
+ }
+ else
+ {
+#endif
+ stream->ccls = stream->cluster;
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (test != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1);
+ }
+ stream->pos = MEDIA_SECTOR_SIZE;
+ stream->sec = dsk->SecPerClus - 1;
+#ifdef ALLOW_WRITES
+ }
+#endif
+ }
+ else
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1); // past the limits
+ }
+ }
+ }
+
+ // Determine the lba of the selected sector and load
+ temp = Cluster2Sector(dsk,stream->ccls);
+
+ // now the extra sectors
+ numsector = stream->sec;
+ temp += numsector;
+
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead(temp, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return (-1); // Bad read
+ }
+ gLastDataSectorRead = temp;
+ }
+
+ FSerrno = CE_GOOD;
+
+ return (0);
+}
+
+
+// FSfopenpgm, FSremovepgm, and FSrenamepgm will only work on PIC18s
+#ifdef __18CXX
+#ifdef ALLOW_PGMFUNCTIONS
+
+#ifdef ALLOW_WRITES
+
+/*****************************************************************
+ Function:
+ int FSrenamepgm(const rom char * fileName, FSFILE * fo)
+ Summary:
+ Rename a file named with a ROM string on PIC18
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file (in ROM)
+ fo - The file to rename
+ Return Values:
+ 0 - File renamed successfully
+ -1 - File could not be renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The Fsrenamepgm function will copy the rom fileName specified
+ by the user into a RAM array and pass that array into the
+ FSrename function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *****************************************************************/
+
+int FSrenamepgm (const rom char * fileName, FSFILE * fo)
+{
+ char F[13];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+
+ return FSrename (F, fo);
+}
+#endif
+
+/******************************************************************************
+ Function:
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+ Summary:
+ Open a file named with a ROM string on PIC18
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to be opened (ROM)
+ mode - The mode the file will be opened in (ROM)
+ Return Values:
+ FSFILE * - A pointer to the file object
+ NULL - File could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfopenpgm function will copy a PIC18 ROM fileName and mode argument
+ into RAM arrays, and then pass those arrays to the FSfopen function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ ******************************************************************************/
+
+
+FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+{
+ char F[13];
+ char M[2];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+ for (count = 0; count < 2; count++)
+ {
+ M[count] = *(mode + count);
+ }
+
+ return FSfopen(F, M);
+}
+
+/*************************************************************
+ Function:
+ int FSremovepgm (const rom char * fileName)
+ Summary:
+ Delete a file named with a ROM string on PIC18
+ Conditions:
+ File not opened; file exists
+ Input:
+ fileName - The name of the file to be deleted (ROM)
+ Return Values:
+ 0 - File was removed successfully
+ -1 - File could not be removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremovepgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FSremove function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *************************************************************/
+#ifdef ALLOW_WRITES
+int FSremovepgm (const rom char * fileName)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for(...)
+
+ return FSremove (F);
+}
+#endif
+
+/**************************************************************************************
+ Function:
+ int FindFirstpgm (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Find a file named with a ROM string on PIC18
+ Conditions:
+ None
+ Input:
+ fileName - The name of the file to be found (ROM)
+ attr - The attributes of the file to be found
+ rec - Pointer to a search record to store the file info in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the given parameters was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object will be lost.
+ The FSerrno variable will be changed.
+ Description:
+ The FindFirstpgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FindFirst function.
+ Remarks:
+ Call FindFirstpgm or FindFirst before calling FindNext.
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************************/
+#ifdef ALLOW_FILESEARCH
+int FindFirstpgm (const rom char * fileName, unsigned int attr, SearchRec * rec)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for
+
+ return FindFirst (F,attr,rec);
+}
+#endif
+#endif
+#endif
+
+
+/***********************************************
+ Function:
+ DWORD ReadFAT (DISK *dsk, DWORD ccls)
+ Summary:
+ Read the next entry from the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ Return:
+ DWORD - The next cluster in a file chain
+ Side Effects:
+ None
+ Description:
+ The ReadFAT function will read the FAT and
+ determine the next cluster value after the
+ cluster specified by 'ccls.' Note that the
+ FAT sector that is read is stored in the
+ global FAT cache buffer.
+ Remarks:
+ None.
+ ***********************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls)
+{
+ BYTE q;
+ DWORD p, l; // "l" is the sector Address
+ DWORD c, d, ClusterFailValue,LastClusterLimit; // ClusterEntries
+
+ gBufferZeroed = FALSE;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls * 4;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls *3; // Mulby1.5 to find cluster pos in FAT
+ q = p&1;
+ p >>= 1;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT12;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD)ccls *2; // Mulby 2 to find cluster pos in FAT
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ l = dsk->fat + (p >> 9); // FAT buffer has 512 bytes of size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ // Check if the appropriate FAT sector is already loaded
+ if (gLastFATSectorRead == l)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if(dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ // Check if the MSB is across the sector boundry
+ p = (p +1) & 0x1FF;
+ if (p == 0)
+ {
+ // Start by writing the sector we just worked on to the card
+ // if we need to
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+#endif
+ if (!MDD_SectorRead (l+1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l +1;
+ }
+ }
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ else
+ {
+ // If there's a currently open FAT sector,
+ // write it back before reading into the buffer
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ {
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+ }
+#endif
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF; // Note: It is Sector not Cluster.
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if (dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ p = (p +1) & 0x1FF;
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ }
+
+ // Normalize it so 0xFFFF is an error
+ if (c >= LastClusterLimit)
+ c = LastClusterLimit;
+
+ return c;
+} // ReadFAT
+
+
+
+/****************************************************************************
+ Function:
+ WORD WriteFAT (DISK *dsk, DWORD ccls, WORD value, BYTE forceWrite)
+ Summary:
+ Write an entry to the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ value - The value to write in
+ forceWrite - Force the function to write the current FAT sector
+ Return:
+ 0 - The FAT write was successful
+ FAIL - The FAT could not be written
+ Side Effects:
+ None
+ Description:
+ The WriteFAT function writes an entry to the FAT. If the function
+ is called and the 'forceWrite' argument is TRUE, the function will
+ write the existing FAT data to the device. Otherwise, the function
+ will replace a single entry in the FAT buffer (indicated by 'ccls')
+ with a new value (indicated by 'value.')
+ Remarks:
+ None.
+ ****************************************************************************/
+
+#ifdef ALLOW_WRITES
+DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite)
+{
+ BYTE i, q, c;
+ DWORD p, li, l, ClusterFailValue;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type != FAT32 && dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT32;
+#else // If FAT32 support not enabled
+ if (dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT16;
+#endif
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ gBufferZeroed = FALSE;
+
+ // The only purpose for calling this function with forceWrite
+ // is to write the current FAT sector to the card
+ if (forceWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+
+ return 0;
+ }
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls *4; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls * 3; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ q = p & 1; // Odd or even?
+ p >>= 1;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD) ccls *2; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+ }
+
+ l = dsk->fat + (p >>9); // FAt Buffer is 512 bytes size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ if (gLastFATSectorRead != l)
+ {
+ // If we are loading a new sector then write
+ // the current one to the card if we need to
+ if (gNeedFATWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+ }
+
+ // Load the new sector
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l;
+ }
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32) // Refer page 16 of FAT requirement.
+ {
+ RAMwrite (gFATBuffer, p, ((value&0x000000ff))); // lsb,1st byte of cluster value
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8));
+ RAMwrite (gFATBuffer, p+2, ((value&0x00ff0000) >> 16));
+ RAMwrite (gFATBuffer, p+3, ((value&0x0f000000) >> 24)); // the MSB nibble is supposed to be "0" in FAT32. So mask it.
+ }
+ else
+#endif
+
+ if (dsk->type == FAT16)
+ {
+ RAMwrite (gFATBuffer, p, value); //lsB
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8)); // msB
+ }
+ else if (dsk->type == FAT12)
+ {
+ // Get the current byte from the FAT
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = ((value & 0x0F) << 4) | ( c & 0x0F);
+ }
+ else
+ {
+ c = (value & 0xFF);
+ }
+ // Write in those bits
+ RAMwrite (gFATBuffer, p, c);
+
+ // FAT12 entries can cross sector boundaries
+ // Check if we need to load a new sector
+ p = (p+1) & 0x1FF;
+ if (p == 0)
+ {
+ // call this function to update the FAT on the card
+ if (WriteFAT (dsk, 0,0,TRUE))
+ return ClusterFailValue;
+ // Load the next sector
+ if (!MDD_SectorRead (l +1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l + 1;
+ }
+
+ // Get the second byte of the table entry
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = (value >> 4);
+ }
+ else
+ {
+ c = ((value >> 8) & 0x0F) | (c & 0xF0);
+ }
+ RAMwrite (gFATBuffer, p, c);
+ }
+
+ gNeedFATWrite = TRUE;
+
+ return 0;
+}
+#endif
+
+
+#ifdef ALLOW_DIRS
+
+// This string is used by dir functions to hold dir names temporarily
+char defaultString [13];
+
+
+
+/**************************************************************************
+ Function:
+ int FSchdir (char * path)
+ Summary:
+ Change the current working directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to.
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdir function passes a RAM pointer to the path to the
+ chdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSchdir (char * path)
+{
+ return chdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSchdirpgm (const rom char * path)
+ Summary:
+ Changed the CWD with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to (ROM)
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdirpgm function passes a PIC18 ROM path pointer to the
+ chdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSchdirpgm (const rom char * path)
+{
+ return chdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+ // PIC18
+ int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ Summary:
+ Helper function for FSchdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was changed successfully.
+ EOF - Directory could not be changed.
+ Side Effects:
+ The current working directory will be changed. The FSerrno variable
+ will be changed. Any unwritten data in the data buffer will be written
+ to the device.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able to
+ parse it correctly. The function will loop through a switch statement
+ to process the tokens in the path string. Dot or dotdot entries are
+ handled in the first case statement. A backslash character is handled
+ in the second case statement (note that this case statement will only
+ be used if backslash is the first character in the path; backslash
+ token delimiters will automatically be skipped after each token in the
+ path is processed). The third case statement will handle actual
+ directory name strings.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int chdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ WORD curent = 1;
+ DIRENTRY entry;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ FSFILE tempCWDobj2;
+ char tempArray[12];
+ FILEOBJ tempCWD = &tempCWDobj2;
+ FileObjectCopy (tempCWD, cwdptr);
+
+ FSerrno = CE_GOOD;
+
+ // Check the first char of the path
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+ if (i == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ while(1)
+ {
+ switch (i)
+ {
+ // First case: dot or dotdot entry
+ case '.':
+ // Move past the dot
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if it's a dotdot entry
+ if (i == '.')
+ {
+ // Increment the path variable
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if we're in the root
+ if (tempCWD->dirclus == FatRootDirClusterValue)
+ {
+ // Fails if there's a dotdot chdir from the root
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ else
+ {
+ // Cache the dotdot entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ curent = 1;
+ entry = Cache_File_Entry (tempCWD, &curent, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ tempCWD->dirclus = GetFullClusterNumber(entry); // Get Complete Cluster number.
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // If we changed to root, record the name
+ if (tempCWD->dirclus == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT) // "0" is the value of Dotdot entry for Root in both FAT types.
+ {
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+
+ /* While moving to Root, get the Root cluster value */
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Otherwise set the name to ..
+ tempCWD->name[0] = '.';
+ tempCWD->name[1] = '.';
+ for (j = 2; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ // Cache the dot entry
+ curent = 0;
+ if (Cache_File_Entry(tempCWD, &curent, TRUE) == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Move past the next backslash, if necessary
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // Copy and return, if we're at the end
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ // If we ended with a . entry,
+ // just return what we have
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ else
+ {
+ // Anything else after a dot doesn't make sense
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ }
+
+ break;
+
+ // Second case: the first char is the root backslash
+ // We will ONLY switch to this case if the first char
+ // of the path is a backslash
+ case '\\':
+ // Increment pointer to second char
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Can't start the path with multiple backslashes
+ if (i == '\\')
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == 0)
+ {
+ // The user is changing directory to
+ // the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ cwdptr->name[j] = 0x20;
+ }
+ return 0;
+ }
+ else
+ {
+ // Our first char is the root dir switch
+ tempCWD->dirclus = FatRootDirClusterValue;
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ break;
+
+ default:
+ // We should be at the beginning of a string of letters/numbers
+ j = 0;
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath2);
+ }
+ }
+ else
+ {
+#endif
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath);
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // We got a whole 12 chars
+ // There could be more- truncate it
+ if (j == 12)
+ {
+ while ((i != 0) && (i != '\\'))
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ i = *(++temppath2);
+ }
+ else
+ {
+#endif
+ i = *(++temppath);
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ }
+
+ defaultString[j] = 0;
+
+ if (FormatDirName (defaultString, 0) == FALSE)
+ return -1;
+
+ for (j = 0; j < 11; j++)
+ {
+ tempArray[j] = tempCWD->name[j];
+ tempCWD->name[j] = defaultString[j];
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, tempCWD);
+
+ // See if the directory is there
+ if(FILEfind (&gFileTemp, tempCWD, LOOK_FOR_MATCHING_ENTRY, 0) != CE_GOOD)
+ {
+ // Couldn't find the DIR
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Found the file
+ // Check to make sure it's actually a directory
+ if (gFileTemp.attributes != ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Get the new name
+ for (j = 0; j < 11; j++)
+ {
+ tempCWD->name[j] = gFileTemp.name[j];
+ }
+ tempCWD->dirclus = gFileTemp.cluster;
+ tempCWD->dirccls = tempCWD->dirclus;
+ }
+
+ if (i == 0)
+ {
+ // If we're at the end of the string, we're done
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ while (i == '\\')
+ {
+ // If we get to another backslash, increment past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ break;
+ }
+ } // loop
+}
+
+
+
+// This string is used by FSgetcwd to return the cwd name if the path
+// passed into the function is NULL
+char defaultArray [10];
+
+
+/**************************************************************
+ Function:
+ char * FSgetcwd (char * path, int numchars)
+ Summary:
+ Get the current working directory name
+ Conditions:
+ None
+ Input:
+ path - Pointer to the array to return the cwd name in
+ numchars - Number of chars in the path
+ Return Values:
+ char * - The cwd name string pointer (path or defaultArray)
+ NULL - The current working directory name could not be loaded.
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSgetcwd function will get the name of the current
+ working directory and return it to the user. The name
+ will be copied into the buffer pointed to by 'path,'
+ starting at the root directory and copying as many chars
+ as possible before the end of the buffer. The buffer
+ size is indicated by the 'numchars' argument. The first
+ thing this function will do is load the name of the current
+ working directory, if it isn't already present. This could
+ occur if the user switched to the dotdot entry of a
+ subdirectory immediately before calling this function. The
+ function will then copy the current working directory name
+ into the buffer backwards, and insert a backslash character.
+ Next, the function will continuously switch to the previous
+ directories and copy their names backwards into the buffer
+ until it reaches the root. If the buffer overflows, it
+ will be treated as a circular buffer, and data will be
+ copied over existing characters, starting at the beginning.
+ Once the root directory is reached, the text in the buffer
+ will be swapped, so that the buffer contains as much of the
+ current working directory name as possible, starting at the
+ root.
+ Remarks:
+ None
+ **************************************************************/
+char * FSgetcwd (char * path, int numchars)
+{
+ // If path is passed in as null, set up a default
+ // array with 10 characters
+ char totalchars = (path == NULL) ? 10 : numchars;
+ char * returnPointer;
+ char * bufferEnd;
+ FILEOBJ tempCWD = &gFileTemp;
+ BYTE bufferOverflow = FALSE;
+ signed char j;
+ DWORD curclus;
+ WORD fHandle, tempindex;
+ signed int i, index = 0;
+ char aChar;
+ DIRENTRY entry;
+
+ FSerrno = CE_GOOD;
+
+ // Set up the return value
+ if (path == NULL)
+ returnPointer = defaultArray;
+ else
+ {
+ returnPointer = path;
+ if (numchars == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return NULL;
+ }
+ }
+
+ bufferEnd = returnPointer + totalchars - 1;
+
+ FileObjectCopy (tempCWD, cwdptr);
+
+ if ((tempCWD->name[0] == '.') &&
+ (tempCWD->name[1] == '.'))
+ {
+ // We last changed directory into a dotdot entry
+ // Save the value of the current directory
+ curclus = tempCWD->dirclus;
+ // Put this dir's dotdot entry into the dirclus
+ // Our cwd absolutely is not the root
+ fHandle = 1;
+ tempCWD->dirccls = tempCWD->dirclus;
+ entry = Cache_File_Entry (tempCWD,&fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ // For FAT32, if the .. entry is 0, the cluster won't be 0
+#ifdef SUPPORT_FAT32
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ tempCWD->dirclus = TempClusterCalc;
+
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // Find the direntry for the entry we were just in
+ fHandle = 0;
+ entry = Cache_File_Entry (tempCWD, &fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != curclus) ||
+ ((TempClusterCalc == curclus) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME) || (entry->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ fHandle++;
+ entry = Cache_File_Entry (tempCWD, &fHandle, FALSE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // We've found the entry for the dir we were in
+ for (i = 0; i < 11; i++)
+ {
+ tempCWD->name[i] = entry->DIR_Name[i];
+ cwdptr->name[i] = entry->DIR_Name[i];
+ }
+ // Reset our temp dir back to that cluster
+ tempCWD->dirclus = curclus;
+ tempCWD->dirccls = curclus;
+ // This will set us at the cwd, but it will actually
+ // have the name in the name field this time
+ }
+ // There's actually some kind of name value in the cwd
+ if (tempCWD->name[0] == '\\')
+ {
+ // Easy, our CWD is the root
+ *returnPointer = '\\';
+ *(returnPointer + 1) = 0;
+ return returnPointer;
+ }
+ else
+ {
+ // Loop until we get back to the root
+ while (tempCWD->dirclus != FatRootDirClusterValue)
+ {
+ j = 10;
+ while (tempCWD->name[j] == 0x20)
+ j--;
+ if (j >= 8)
+ {
+ while (j >= 8)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+ *(returnPointer + index++) = '.';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ while (tempCWD->name[j] == 0x20)
+ j--;
+
+ while (j >= 0)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ // Put a backslash delimiter in front of the dir name
+ *(returnPointer + index++) = '\\';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+
+ // Load the previous entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ if (GetPreviousEntry (tempCWD))
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ return NULL;
+ }
+ }
+ }
+
+ // Point the index back at the last char in the string
+ index--;
+
+ i = 0;
+ // Swap the chars in the buffer so they are in the right places
+ if (bufferOverflow)
+ {
+ tempindex = index;
+ // Swap the overflowed values in the buffer
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+
+ // Point at the non-overflowed values
+ i = tempindex + 1;
+ index = bufferEnd - returnPointer;
+
+ // Swap the non-overflowed values into the right places
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ // All the values should be in the right place now
+ // Null-terminate the string
+ *(bufferEnd) = 0;
+ }
+ else
+ {
+ // There was no overflow, just do one set of swaps
+ tempindex = index;
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ *(returnPointer + tempindex + 1) = 0;
+ }
+
+ return returnPointer;
+}
+
+
+/**************************************************************************
+ Function:
+ void GetPreviousEntry (FSFILE * fo)
+ Summary:
+ Get the file entry info for the parent dir of the specified dir
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - The file to get the previous entry of
+ Return Values:
+ 0 - The previous entry was successfully retrieved
+ -1 - The previous entry could not be retrieved
+ Side Effects:
+ None
+ Description:
+ The GetPreviousEntry function is used by the FSgetcwd function to
+ load the previous (parent) directory. This function will load the
+ parent directory and then search through the file entries in that
+ directory for one that matches the cluster number of the original
+ directory. When the matching entry is found, the name of the
+ original directory is copied into the 'fo' FSFILE object.
+ Remarks:
+ None.
+ **************************************************************************/
+
+BYTE GetPreviousEntry (FSFILE * fo)
+{
+ BYTE i;
+ WORD fHandle = 1;
+ DWORD dirclus;
+ DIRENTRY dirptr;
+
+ // Load the previous entry
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ // The previous directory is the root
+ fo->name[0] = '\\';
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = 0x20;
+ }
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Get the directory name
+ // Save the previous cluster value
+ // Get the cluster
+
+ dirclus = TempClusterCalc;
+ fo->dirclus = TempClusterCalc;
+ fo->dirccls = TempClusterCalc;
+
+
+ // Load the previous previous cluster
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+#ifdef SUPPORT_FAT32
+ // If we're using FAT32 and the previous previous cluster is the root, the
+ // value in the dotdot entry will be 0, but the actual cluster won't
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ fo->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ fo->dirclus = TempClusterCalc;
+
+ fo->dirccls = fo->dirclus;
+
+ fHandle = 0;
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+ // Look through it until we get the name
+ // of the previous cluster
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+ while ((TempClusterCalc != dirclus) ||
+ ((TempClusterCalc == dirclus) &&
+ (((unsigned char)dirptr->DIR_Name[0] == 0xE5) || (dirptr->DIR_Attr == ATTR_VOLUME) || (dirptr->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ // Look through the entries until we get the
+ // right one
+ dirptr = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dirptr == NULL)
+ return -1;
+ fHandle++;
+
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number in a loop.
+ }
+
+ // The name should be in the entry now
+ // Copy the actual directory location back
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = dirptr->DIR_Name[i];
+ }
+ fo->dirclus = dirclus;
+ fo->dirccls = dirclus;
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+ Function:
+ int FSmkdir (char * path)
+ Summary:
+ Create a directory
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create.
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdir function passes a RAM pointer to the path to the
+ mkdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSmkdir (char * path)
+{
+ return mkdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSmkdirpgm (const rom char * path)
+ Summary:
+ Create a directory with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create (ROM)
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdirpgm function passes a PIC18 ROM path pointer to the
+ mkdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arugments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSmkdirpgm (const rom char * path)
+{
+ return mkdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+ // PIC18
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+ Summary:
+ Helper function for FSmkdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was created
+ -1 - Directory could not be created
+ Side Effects:
+ Will create all non-existant directories in the path.
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first scan through the path
+ to ensure that any DIR names don't exceed 11 characters. It will then
+ backup the current working directory and begin changing directories
+ through the path until it reaches a directory than can't be changed to.
+ It will then create the specified directory and change directories to
+ the new directory. The function will continue creating and changing to
+ directories until the end of the path is reached. The function will
+ then restore the original current working directory.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ char tempArray[13];
+ FILEOBJ tempCWD = &tempCWDobj;
+
+#ifdef __18CXX
+ char dotdotPath[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath2 != 0) && (*temppath2 != '.')&& (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath2 == '.')
+ {
+ temppath2++;
+ i = 0;
+ while ((*temppath2 != 0) && (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath2 == '\\')
+ temppath2++;
+ if (*temppath2 == 0)
+ break;
+ }
+ }
+ else
+#endif
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath != 0) && (*temppath != '.')&& (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath == '.')
+ {
+ temppath++;
+ i = 0;
+ while ((*temppath != 0) && (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath == '\\')
+ temppath++;
+ if (*temppath == 0)
+ break;
+ }
+
+ temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ temppath2 = romptr;
+#endif
+
+ // We're going to be moving the CWD
+ // Back up the CWD
+ FileObjectCopy (tempCWD, cwdptr);
+
+ // get to the target directory
+ while (1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+
+ if (i == '.')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ if ((i != '.') && (i != 0) && (i != '\\'))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == '.')
+ {
+ if (cwdptr->dirclus == FatRootDirClusterValue)
+ {
+ // If we try to change to the .. from the
+ // root, operation fails
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if ((i != '\\') && (i != 0))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+// dotdot entry
+#ifndef __18CXX
+ FSchdir ("..");
+#else
+ FSchdir (dotdotPath);
+#endif
+ }
+ // Skip past any backslashes
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ // No point in creating a dot or dotdot entry directly
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ // Start at the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (i = 1; i < 11; i++)
+ {
+ cwdptr->name[i] = 0x20;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // If we just got two backslashes in a row at the
+ // beginning of the path, the function fails
+ if (i == '\\')
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (i == 0)
+ {
+ // We can't make the root dir
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ tempArray[12] = 0;
+ while (1)
+ {
+ while(1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Change directories as specified
+ i = *temppath2;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ // Change directories as specified
+ i = *temppath;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ tempArray[j] = 0;
+
+ if (tempArray[0] == '.')
+ {
+ if ((tempArray[1] != 0) && (tempArray[1] != '.'))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if ((tempArray[1] == '.') && (tempArray[2] != 0))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+
+ // Try to change to it
+ // If you can't we need to create it
+ if (FSchdir (tempArray))
+ {
+ break;
+ }
+ else
+ {
+ // We changed into the directory
+ while (i == '\\')
+ {
+ // Next char is a backslash
+ // Move past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // If it's the last one, return success
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+
+ // Create a dir here
+ if (!CreateDIR (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ // Try to change to that directory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Check for another backslash
+ while (*temppath2 == '\\')
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ while (*temppath == '\\')
+ {
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Check to see if we're at the end of the path string
+ if (i == 0)
+ {
+ // We already have one
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+}
+
+
+/**************************************************************************
+ Function:
+ int CreateDIR (char * path)
+ Summary:
+ FSmkdir helper function to create a directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the dir to create
+ Return Values:
+ TRUE - Directory was created successfully
+ FALSE - Directory could not be created.
+ Side Effects:
+ Any unwritten data in the data buffer or the FAT buffer will be written
+ to the device.
+ Description:
+ The CreateDIR function is a helper function for the mkdirhelper
+ function. The CreateDIR function will create a new file entry for
+ a directory and assign a cluster to it. It will erase the cluster
+ and write a dot and dotdot entry to it.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int CreateDIR (char * path)
+{
+ FSFILE * dirEntryPtr = &gFileTemp;
+ DIRENTRY dir;
+ WORD handle = 0;
+ DWORD dot, dotdot;
+ BYTE i;
+
+ for (i = 0; i < 12; i++)
+ {
+ defaultString[i] = *(path + i);
+ }
+
+ if (FormatDirName(defaultString, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return FALSE;
+ }
+
+ // Copy name into file object
+ for (i = 0; i < 11; i++)
+ {
+ dirEntryPtr->name[i] = defaultString[i];
+ }
+
+ dirEntryPtr->dirclus = cwdptr->dirclus;
+ dirEntryPtr->dirccls = cwdptr->dirccls;
+ dirEntryPtr->cluster = 0;
+ dirEntryPtr->ccls = 0;
+ dirEntryPtr->dsk = cwdptr->dsk;
+
+ // Create a directory entry
+ if(CreateFileEntry(dirEntryPtr, &handle, DIRECTORY) != CE_GOOD)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (gNeedFATWrite)
+ if(WriteFAT (dirEntryPtr->dsk, 0, 0, TRUE))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+ // Zero that cluster
+ if (dirEntryPtr->dirclus == FatRootDirClusterValue)
+ dotdot = 0;
+ else
+ dotdot = dirEntryPtr->dirclus;
+ dirEntryPtr->dirccls = dirEntryPtr->dirclus;
+ dir = Cache_File_Entry(dirEntryPtr, &handle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return FALSE;
+ }
+
+ // Get the cluster
+ dot = GetFullClusterNumber(dir); // Get complete cluster number.
+
+ if (writeDotEntries (dirEntryPtr->dsk, dot, dotdot))
+ return TRUE;
+ else
+ return FALSE;
+
+ }
+}
+
+
+/***********************************************************************************
+ Function:
+ BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+ Summary:
+ Create dot and dotdot entries in a non-root directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - The global disk structure
+ dotAddress - The cluster the current dir is in
+ dotdotAddress - The cluster the previous directory was in
+ Return Values:
+ TRUE - The dot and dotdot entries were created
+ FALSE - The dot and dotdot entries could not be created in the new directory
+ Side Effects:
+ None
+ Description:
+ The writeDotEntries function will create and write dot and dotdot entries
+ to a newly created directory.
+ Remarks:
+ None.
+ ***********************************************************************************/
+
+BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+{
+ WORD i;
+ WORD size;
+ _DIRENTRY entry;
+ DIRENTRY entryptr = &entry;
+ DWORD sector;
+
+ gBufferOwner = NULL;
+
+ size = sizeof (_DIRENTRY);
+
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ entry.DIR_Name[0] = '.';
+
+ for (i = 1; i < 11; i++)
+ {
+ entry.DIR_Name[i] = 0x20;
+ }
+ entry.DIR_Attr = ATTR_DIRECTORY;
+ entry.DIR_NTRes = 0x00;
+
+ entry.DIR_FstClusLO = (WORD)(dotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+ entry.DIR_FileSize = 0x00;
+
+// Times need to be the same as the times in the directory entry
+
+// Set dir date for uncontrolled clock source
+#ifdef INCREMENTTIMESTAMP
+ entry.DIR_CrtTimeTenth = 0xB2;
+ entry.DIR_CrtTime = 0x7278;
+ entry.DIR_CrtDate = 0x32B0;
+ entry.DIR_LstAccDate = 0x0000;
+ entry.DIR_WrtTime = 0x0000;
+ entry.DIR_WrtDate = 0x0000;
+#endif
+
+#ifdef USEREALTIMECLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i) = *((char *)entryptr + i);
+ }
+ entry.DIR_Name[1] = '.';
+
+ entry.DIR_FstClusLO = (WORD)(dotdotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotdotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i + size) = *((char *)entryptr + i);
+ }
+
+ sector = Cluster2Sector (disk, dotAddress);
+
+ if (MDD_SectorWrite(sector, disk->buffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// This array is used to prevent a stack frame error
+#ifdef __18CXX
+ char tempArray[13] = " ";
+#endif
+
+
+/**************************************************************************
+ Function:
+ int FSrmdir (char * path)
+ Summary:
+ Delete a directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to remove
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdir function passes a RAM pointer to the path to the
+ rmdirhelper function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int FSrmdir (char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (0, path, NULL, rmsubdirs);
+}
+
+/**************************************************************************
+ Function:
+ int FSrmdirpgm (const rom char * path)
+ Summary:
+ Delete a directory with a path in ROM on PIC18
+ Conditions:
+ None.
+ Input:
+ path - The path of the directory to remove (ROM)
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdirpgm function passes a PIC18 ROM path pointer to the
+ rmdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSrmdirpgm (const rom char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (1, NULL, path, rmsubdirs);
+}
+#endif
+
+/************************************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+ // PIC18
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+ Summary:
+ Helper function for FSrmdir
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The path of the dir to delete
+ rmsubdirs -
+ - TRUE - Remove all sub-directories and files in the directory
+ - FALSE - Non-empty directories can not be removed
+ Return Values:
+ 0 - The specified directory was successfully removed.
+ EOF - The specified directory could not be removed.
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSmkdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first change to the
+ specified directory. If the rmsubdirs argument is FALSE the function
+ will search through the directory to ensure that it is empty and then
+ remove it. If the rmsubdirs argument is TRUE the function will also
+ search through the directory for subdirectories or files. When the
+ function finds a file, the file will be erased. When the function
+ finds a subdirectory, it will switch to the subdirectory and begin
+ removing all of the files in that subdirectory. Once the subdirectory
+ is empty, the function will switch back to the original directory.
+ return to the original position in that directory, and continue removing
+ files. Once the specified directory is empty, the function will
+ change to the parent directory, search through it for the directory
+ to remove, and then erase that directory.
+ Remarks:
+ None.
+ ************************************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+#else
+int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+#endif
+{
+ FILEOBJ tempCWD = &tempCWDobj;
+ FILEOBJ fo = &gFileTemp;
+ DIRENTRY entry;
+ WORD handle = 0;
+ WORD handle2;
+ WORD subDirDepth;
+ BYTE Index, Index2;
+
+#ifndef __18CXX
+ char tempArray[13] = " ";
+#else
+ char dotdotname[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ // Back up the current working directory
+ FileObjectCopy (tempCWD, cwdptr);
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ if (chdirhelper (1, NULL, romptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ }
+ else
+ {
+#endif
+ if (FSchdir (ramptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Make sure we aren't trying to remove the root dir or the CWD
+ if ((cwdptr->dirclus == FatRootDirClusterValue) || (cwdptr->dirclus == tempCWD->dirclus))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Don't remove subdirectories and sub-files
+ if (!rmsubdirs)
+ {
+ while (entry->DIR_Name[0] != 0)
+ {
+ if ((unsigned char)entry->DIR_Name[0] != 0xE5)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_EMPTY;
+ return -1;
+ }
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if ((entry == NULL))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ // Do remove subdirectories and sub-files
+ dirCleared = FALSE;
+ subDirDepth = 0;
+
+ while (!dirCleared)
+ {
+ if (entry->DIR_Name[0] != 0)
+ {
+ if (((unsigned char)entry->DIR_Name[0] != 0xE5) && (entry->DIR_Attr != ATTR_VOLUME) && (entry->DIR_Attr != ATTR_LONG_NAME))
+ {
+ if ((entry->DIR_Attr & ATTR_DIRECTORY) == ATTR_DIRECTORY)
+ {
+ // We have a directory
+ subDirDepth++;
+ for (Index = 0; (Index < DIR_NAMESIZE) && (entry->DIR_Name[Index] != 0x20); Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (entry->DIR_Name[8] != 0x20)
+ {
+ tempArray[Index++] = '.';
+ for (Index2 = 0; (Index2 < DIR_EXTENSION) && (entry->DIR_Name[Index2 + DIR_NAMESIZE] != 0x20); Index2++)
+ {
+ tempArray[Index++] = entry->DIR_Name[Index2 + DIR_NAMESIZE];
+ }
+ }
+ tempArray[Index] = 0;
+ // Change to the subdirectory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Make sure we're not trying to delete the CWD
+ if (cwdptr->dirclus == tempCWD->dirclus)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ handle = 2;
+ recache = TRUE;
+ }
+ else
+ {
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ fo->name[Index] = entry->DIR_Name[Index];
+ }
+
+ fo->dsk = &gDiskData;
+
+ fo->entry = handle;
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+ fo->cluster = 0;
+ fo->ccls = 0;
+
+ if (FILEerase(fo, &handle, TRUE))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ }
+ } // Check to see if it's a DIR entry
+ }// Check non-dir entry to see if its a valid file
+ else
+ {
+ handle++;
+ }
+ if (recache)
+ {
+ recache = FALSE;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ }
+ else
+ {
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ }
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ else
+ {
+ // We have reached the end of the directory
+ if (subDirDepth != 0)
+ {
+ handle2 = 0;
+
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle2, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ handle2 = GetFullClusterNumber(entry); // Get complete cluster number.
+
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ // Return to our previous position in this directory
+ handle = 2;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != handle2) ||
+ ((TempClusterCalc == handle2) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME))))
+ {
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // Erase the directory that we just cleared the subdirectories out of
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+
+ // Decrease the subdirectory depth
+ subDirDepth--;
+ }
+ else
+ {
+ dirCleared = TRUE;
+ } // Check subdirectory depth
+ } // Check until we get an empty entry
+ } // Loop until the whole dir is cleared
+ }
+
+ // Cache the current directory name
+ // tempArray is used so we don't disturb the
+ // global getcwd buffer
+ if (FSgetcwd (tempArray, 12) == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ memset(tempArray, 0x00, 12);
+
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = cwdptr->name[Index];
+ }
+
+ // If we're here, this directory is empty
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+}
+
+
+/****************************************************************
+ Function:
+ int eraseDir (char * path)
+ Summary:
+ FSrmdir helper function to erase dirs
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the directory to delete
+ Return Values:
+ 0 - Dir was deleted successfully
+ -1 - Dir could not be deleted.
+ Side Effects:
+ None
+ Description:
+ The eraseDir function is a helper function for the rmdirhelper
+ function. The eraseDir function will search for the
+ directory that matches the specified path name and then erase
+ it with the FILEerase function.
+ Remarks:
+ None.
+ *****************************************************************/
+
+int eraseDir (char * path)
+{
+ CETYPE result;
+ BYTE Index;
+ FSFILE tempCWDobj2;
+
+ if (MDD_WriteProtectState())
+ {
+ return (-1);
+ }
+
+ // preserve CWD
+ FileObjectCopy(&tempCWDobj2, cwdptr);
+
+ for (Index = 0; Index <11; Index++)
+ {
+ cwdptr->name[Index] = *(path + Index);
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, cwdptr);
+
+ // See if the file is found
+ result = FILEfind (cwdptr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+ result = FILEerase(cwdptr, &cwdptr->entry, TRUE);
+ if( result == CE_GOOD )
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return 0;
+ }
+ else
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+}
+#endif
+
+
+
+#endif
+
+
+#ifdef ALLOW_FILESEARCH
+
+
+/***********************************************************************************
+ Function:
+ int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Initial search function
+ Conditions:
+ None
+ Input:
+ fileName - The name to search for
+ - Parital string search characters
+ - * - Indicates the rest of the filename or extension can vary (e.g. FILE.*)
+ - ? - Indicates that one character in a filename can vary (e.g. F?LE.T?T)
+ attr - The attributes that a found file may have
+ - ATTR_READ_ONLY - File may be read only
+ - ATTR_HIDDEN - File may be a hidden file
+ - ATTR_SYSTEM - File may be a system file
+ - ATTR_VOLUME - Entry may be a volume label
+ - ATTR_DIRECTORY - File may be a directory
+ - ATTR_ARCHIVE - File may have archive attribute
+ - ATTR_MASK - All attributes
+ rec - pointer to a structure to put the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the specified criteria was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object
+ will be lost. The FSerrno variable will be changed.
+ Description:
+ The FindFirst function will search for a file based on parameters passed in
+ by the user. This function will use the FILEfind function to parse through
+ the current working directory searching for entries that match the specified
+ parameters. If a file is found, its parameters are copied into the SearchRec
+ structure, as are the initial parameters passed in by the user and the position
+ of the file entry in the current working directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling FindNext
+ ***********************************************************************************/
+
+int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ WORD fHandle;
+ BYTE j;
+ BYTE Index;
+
+ FSerrno = CE_GOOD;
+
+ if( !FormatFileName(fileName, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ rec->initialized = FALSE;
+
+ for (Index = 0; (Index < 12) && (fileName[Index] != 0); Index++)
+ {
+ rec->searchname[Index] = fileName[Index];
+ }
+ rec->searchname[Index] = 0;
+ rec->searchattr = attr;
+#ifdef ALLOW_DIRS
+ rec->cwdclus = cwdptr->dirclus;
+#else
+ rec->cwdclus = FatRootDirClusterValue;
+#endif
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = attr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ fHandle = fo->entry;
+ result = FILEopen (fo, &fHandle, 'r');
+ }
+ if (result == CE_GOOD)
+ {
+ // Copy as much name as there is
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (Index = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[Index++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[Index] = 0;
+ }
+ else
+ {
+ for (Index = 0; Index < DIR_NAMECOMP; Index++)
+ {
+ rec->filename[Index] = fo->name[Index];
+ }
+ rec->filename[Index] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ rec->initialized = TRUE;
+ return 0;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+}
+
+
+/**********************************************************************
+ Function:
+ int FindNext (SearchRec * rec)
+ Summary:
+ Sequential search function
+ Conditions:
+ None
+ Input:
+ rec - The structure to store the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No additional files matching the specified criteria were found
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FindNext function performs the same function as the FindFirst
+ funciton, except it does not copy any search parameters into the
+ SearchRec structure (only info about found files) and it begins
+ searching at the last directory entry offset at which a file was
+ found, rather than at the beginning of the current working
+ directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling this function
+ **********************************************************************/
+
+int FindNext (SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ BYTE i, j;
+
+ FSerrno = CE_GOOD;
+
+ // Make sure we called FindFirst on this object
+ if (rec->initialized == FALSE)
+ {
+ FSerrno = CE_NOT_INIT;
+ return -1;
+ }
+
+ // Make sure we called FindFirst in the cwd
+#ifdef ALLOW_DIRS
+ if (rec->cwdclus != cwdptr->dirclus)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#endif
+
+ if( !FormatFileName(rec->searchname, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ /* Brn: Copy the formatted name to "fo" which is necesary before calling "FILEfind" function */
+ //strcpy(fo->name,rec->searchname);
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = rec->entry + 1;
+ fo->attributes = rec->searchattr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (i = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[i++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[i] = 0;
+ }
+ else
+ {
+ for (i = 0; i < DIR_NAMECOMP; i++)
+ {
+ rec->filename[i] = fo->name[i];
+ }
+ rec->filename[i] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ return 0;
+ }
+}
+
+
+#endif
+
+
+
+#ifdef ALLOW_FSFPRINTF
+
+
+
+/**********************************************************************
+ Function:
+ int FSputc (char c, FSFILE * file)
+ Summary:
+ FSfprintf helper function to write a char
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ c - The character to write to the file.
+ file - The file to write to.
+ Return Values:
+ 0 - The character was written successfully
+ EOF - The character was not written to the file.
+ Side Effects:
+ None
+ Description:
+ This is a helper function for FSfprintf. It will write one
+ character to a file.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSputc (char c, FSFILE * file)
+{
+ if (FSfwrite ((void *)&c, 1, 1, file) != 1)
+ return EOF;
+ else
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ int str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+ Summary:
+ FSfprintf helper function to write a char multiple times
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - The file to write to.
+ n - The number of times to write that character to a file.
+ c - The character to write to the file.
+ Return Values:
+ 0 - The characters were written successfully
+ EOF - The characters were not written to the file.
+ Side Effects:
+ None
+ Description:
+ This funciton is used by the FSfprintf function to write multiple
+ instances of a single character to a file (for example, when
+ padding a format specifier with leading spacez or zeros).
+ Remarks:
+ None.
+ **********************************************************************/
+
+
+unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+{
+ while (n--)
+ if (FSputc (c, handle) == EOF)
+ return 1;
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSfprintf (FSFILE * fptr, const char * fmt, ...)
+ // PIC18
+ int FSfpritnf (FSFILE * fptr, const rom char * fmt, ...)
+ Summary:
+ Function to write formatted strings to a file
+ Conditions:
+ For PIC18, integer promotion must be enabled in the project build
+ options menu. File opened in a write mode.
+ Input:
+ fptr - A pointer to the file to write to.
+ fmt - A string of characters and format specifiers to write to
+ the file
+ ... - Additional arguments inserted in the string by format
+ specifiers
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Writes a specially formatted string to a file.
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSfprintf (FSFILE *fptr, const rom char *fmt, ...)
+#else
+int FSfprintf (FSFILE *fptr, const char * fmt, ...)
+#endif
+{
+ va_list ap;
+ int n;
+
+ va_start (ap, fmt);
+ n = FSvfprintf (fptr, fmt, ap);
+ va_end (ap);
+ return n;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSvfprintf (FSFILE * handle, const char * formatString, va_list ap)
+ // PIC18
+ int FSvfpritnf (auto FSFILE * handle, auto const rom char * formatString, auto va_list ap)
+ Summary:
+ Helper function for FSfprintf
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - A pointer to the file to write to.
+ formatString - A string of characters and format specifiers to write to
+ the file
+ ap - A structure pointing to the arguments on the stack
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function will access the elements passed to FSfprintf
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSvfprintf (auto FSFILE *handle, auto const rom char * formatString, auto va_list ap)
+#else
+int FSvfprintf (FSFILE *handle, const char * formatString, va_list ap)
+#endif
+{
+ unsigned char c;
+ int count = 0;
+
+ for (c = *formatString; c; c = *++formatString)
+ {
+ if (c == '%')
+ {
+ unsigned char flags = 0;
+ unsigned char width = 0;
+ unsigned char precision = 0;
+ unsigned char have_precision = 0;
+ unsigned char size = 0;
+#ifndef __18CXX
+ unsigned char size2 = 0;
+#endif
+ unsigned char space_cnt;
+ unsigned char cval;
+#ifdef __18CXX
+ unsigned long larg;
+ far rom char * romstring;
+#else
+ unsigned long long larg;
+#endif
+ char * ramstring;
+ int n;
+
+ FSerrno = CE_GOOD;
+
+ c = *++formatString;
+
+ while (c == '-' || c == '+' || c == ' ' || c == '#'
+ || c == '0')
+ {
+ switch (c)
+ {
+ case '-':
+ flags |= _FLAG_MINUS;
+ break;
+ case '+':
+ flags |= _FLAG_PLUS;
+ break;
+ case ' ':
+ flags |= _FLAG_SPACE;
+ break;
+ case '#':
+ flags |= _FLAG_OCTO;
+ break;
+ case '0':
+ flags |= _FLAG_ZERO;
+ break;
+ }
+ c = *++formatString;
+ }
+ /* the optional width field is next */
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n < 0)
+ {
+ flags |= _FLAG_MINUS;
+ width = -n;
+ }
+ else
+ width = n;
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ width = cval;
+ }
+
+ /* if '-' is specified, '0' is ignored */
+ if (flags & _FLAG_MINUS)
+ flags &= ~_FLAG_ZERO;
+
+ /* the optional precision field is next */
+ if (c == '.')
+ {
+ c = *++formatString;
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n >= 0)
+ {
+ precision = n;
+ have_precision = 1;
+ }
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ precision = cval;
+ have_precision = 1;
+ }
+ }
+
+ /* the optional 'h' specifier. since int and short int are
+ the same size for MPLAB C18, this is a NOP for us. */
+ if (c == 'h')
+ {
+ c = *++formatString;
+ /* if 'c' is another 'h' character, this is an 'hh'
+ specifier and the size is 8 bits */
+ if (c == 'h')
+ {
+ size = _FMT_BYTE;
+ c = *++formatString;
+ }
+ }
+ else if (c == 't' || c == 'z')
+ c = *++formatString;
+#ifdef __18CXX
+ else if (c == 'H' || c == 'T' || c == 'Z')
+ {
+ size = _FMT_SHRTLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l' || c == 'j')
+#else
+ else if (c == 'q' || c == 'j')
+ {
+ size = _FMT_LONGLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l')
+#endif
+ {
+ size = _FMT_LONG;
+ c = *++formatString;
+ }
+
+ switch (c)
+ {
+ case '\0':
+ /* this is undefined behaviour. we have a trailing '%' character
+ in the string, perhaps with some flags, width, precision
+ stuff as well, but no format specifier. We'll, arbitrarily,
+ back up a character so that the loop will terminate
+ properly when it loops back and we'll output a '%'
+ character. */
+ --formatString;
+ /* fallthrough */
+ case '%':
+ if (FSputc ('%', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ break;
+ case 'c':
+ space_cnt = 0;
+ if (width > 1)
+ {
+ space_cnt = width - 1;
+ count += space_cnt;
+ }
+ if (space_cnt && !(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ c = va_arg (ap, int);
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'S':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ romstring = va_arg (ap, rom far char *);
+ else
+ romstring = (far rom char*)va_arg (ap, rom near char *);
+ n = strlenpgm (romstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the
+ string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *romstring; c && cval < width; c = *++romstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+#endif
+ case 's':
+ ramstring = va_arg (ap, char *);
+ n = strlen (ramstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *ramstring; c && cval < width; c = *++ramstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'd':
+ case 'i':
+ flags |= _FLAG_SIGNED;
+ /* fall through */
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'b':
+ case 'B':
+ /* This is a bit of a trick. The 'l' and 'hh' size
+ specifiers are valid only for the integer conversions,
+ not the 'p' or 'P' conversions, and are ignored for the
+ latter. By jumping over the additional size specifier
+ checks here we get the best code size since we can
+ limit the size checks in the remaining code. */
+ if (size == _FMT_LONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, long int);
+ else
+ larg = va_arg (ap, unsigned long int);
+ goto _do_integer_conversion;
+ }
+ else if (size == _FMT_BYTE)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed char) va_arg (ap, int);
+ else
+ larg = (unsigned char) va_arg (ap, unsigned int);
+ goto _do_integer_conversion;
+ }
+#ifndef __18CXX
+ else if (size == _FMT_LONGLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed long long)va_arg (ap, long long);
+ else
+ larg = (unsigned long long) va_arg (ap, unsigned long long);
+ goto _do_integer_conversion;
+ }
+#endif
+ /* fall trough */
+ case 'p':
+ case 'P':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, short long int);
+ else
+ larg = va_arg (ap, unsigned short long int);
+ }
+ else
+#endif
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, int);
+ else
+ larg = va_arg (ap, unsigned int);
+ _do_integer_conversion:
+ /* default precision is 1 */
+ if (!have_precision)
+ precision = 1;
+ {
+ unsigned char digit_cnt = 0;
+ unsigned char prefix_cnt = 0;
+ unsigned char sign_char;
+ /* A 32 bit number will require at most 32 digits in the
+ string representation (binary format). */
+#ifdef __18CXX
+ char buf[33];
+ /* Start storing digits least-significant first */
+ char *q = &buf[31];
+ /* null terminate the string */
+ buf[32] = '\0';
+#else
+ char buf[65];
+ char *q = &buf[63];
+ buf[64] = '\0';
+#endif
+ space_cnt = 0;
+ size = 10;
+
+ switch (c)
+ {
+ case 'b':
+ case 'B':
+ size = 2;
+#ifndef __18CXX
+ size2 = 1;
+#endif
+ break;
+ case 'o':
+ size = 8;
+#ifndef __18CXX
+ size2 = 3;
+#endif
+ break;
+ case 'p':
+ case 'P':
+ /* from here on out, treat 'p' conversions just
+ like 'x' conversions. */
+ c += 'x' - 'p';
+ /* fall through */
+ case 'x':
+ case 'X':
+ size = 16;
+#ifndef __18CXX
+ size2 = 4;
+#endif
+ break;
+ }// switch (c)
+
+ /* if it's an unsigned conversion, we should ignore the
+ ' ' and '+' flags */
+ if (!(flags & _FLAG_SIGNED))
+ flags &= ~(_FLAG_PLUS | _FLAG_SPACE);
+
+ /* if it's a negative value, we need to negate the
+ unsigned version before we convert to text. Using
+ unsigned for this allows us to (ab)use the 2's
+ complement system to avoid overflow and be able to
+ adequately handle LONG_MIN.
+
+ We'll figure out what sign character to print, if
+ any, here as well. */
+#ifdef __18CXX
+ if (flags & _FLAG_SIGNED && ((long) larg < 0))
+ {
+ larg = -(long) larg;
+#else
+ if (flags & _FLAG_SIGNED && ((long long) larg < 0))
+ {
+ larg = -(long long) larg;
+#endif
+ sign_char = '-';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_PLUS)
+ {
+ sign_char = '+';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_SPACE)
+ {
+ sign_char = ' ';
+ ++digit_cnt;
+ }
+ else
+ sign_char = '\0';
+ /* get the digits for the actual number. If the
+ precision is zero and the value is zero, the result
+ is no characters. */
+ if (precision || larg)
+ {
+ do
+ {
+#ifdef __18CXX
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ larg /= size;
+#else
+ // larg is congruent mod size2 to its lower 16 bits
+ // for size2 = 2^n, 0 <= n <= 4
+ if (size2 != 0)
+ cval = s_digits[(unsigned int) larg % size];
+ else
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ if (size2 != 0)
+ larg = larg >> size2;
+ else
+ larg /= size;
+#endif
+ *q-- = cval;
+ ++digit_cnt;
+ } while (larg);
+ /* if the '#' flag was specified and we're dealing
+ with an 'o', 'b', 'B', 'x', or 'X' conversion,
+ we need a bit more. */
+ if (flags & _FLAG_OCTO)
+ {
+ if (c == 'o')
+ {
+ /* per the standard, for octal, the '#' flag
+ makes the precision be at least one more
+ than the number of digits in the number */
+ if (precision <= digit_cnt)
+ precision = digit_cnt + 1;
+ }
+ else if (c == 'x' || c == 'X' || c == 'b' || c == 'B')
+ prefix_cnt = 2;
+ }
+ }
+ else
+ digit_cnt = 0;
+
+ /* The leading zero count depends on whether the '0'
+ flag was specified or not. If it was not, then the
+ count is the difference between the specified
+ precision and the number of digits (including the
+ sign character, if any) to be printed; otherwise,
+ it's as if the precision were equal to the max of
+ the specified precision and the field width. If a
+ precision was specified, the '0' flag is ignored,
+ however. */
+ if ((flags & _FLAG_ZERO) && (width > precision)
+ && !have_precision)
+ precision = width;
+ /* for the rest of the processing, precision contains
+ the leading zero count for the conversion. */
+ if (precision > digit_cnt)
+ precision -= digit_cnt;
+ else
+ precision = 0;
+ /* the space count is the difference between the field
+ width and the digit count plus the leading zero
+ count. If the width is less than the digit count
+ plus the leading zero count, the space count is
+ zero. */
+ if (width > precision + digit_cnt + prefix_cnt)
+ space_cnt = width - precision - digit_cnt - prefix_cnt;
+
+ /* for output, we check the justification, if it's
+ right justified and the space count is positive, we
+ emit the space characters first. */
+ if (!(flags & _FLAG_MINUS) && space_cnt)
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ count += space_cnt;
+ space_cnt = 0;
+ }
+ /* if we have a sign character to print, that comes
+ next */
+ if (sign_char)
+ if (FSputc (sign_char, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if we have a prefix (0b, 0B, 0x or 0X), that's next */
+ if (prefix_cnt)
+ {
+ if (FSputc ('0', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ }
+ /* if we have leading zeros, they follow. the prefix, if any
+ is included in the number of digits when determining how
+ many leading zeroes are needed. */
+// if (precision > prefix_cnt)
+ // precision -= prefix_cnt;
+ if (str_put_n_chars (handle, precision, '0'))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* print the actual number */
+ for (cval = *++q; cval; cval = *++q)
+ if (FSputc (cval, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if there are any spaces left, they go to right-pad
+ the field */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ count += precision + digit_cnt + space_cnt + prefix_cnt;
+ }
+ break;
+ case 'n':
+ switch (size)
+ {
+ case _FMT_LONG:
+ *(long *) va_arg (ap, long *) = count;
+ break;
+#ifdef __18CXX
+ case _FMT_SHRTLONG:
+ *(short long *) va_arg (ap, short long *) = count;
+ break;
+#else
+ case _FMT_LONGLONG:
+ *(long long *) va_arg (ap, long long *) = count;
+ break;
+#endif
+ case _FMT_BYTE:
+ *(signed char *) va_arg (ap, signed char *) = count;
+ break;
+ default:
+ *(int *) va_arg (ap, int *) = count;
+ break;
+ }
+ break;
+ default:
+ /* undefined behaviour. we do nothing */
+ break;
+ }
+ }
+ else
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ }
+ }
+ return count;
+}
+
+
+
+#endif
+
+
+
+
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.d b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.d new file mode 100644 index 00000000..11aa75db --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.d @@ -0,0 +1,60 @@ +FSIO.o: FSIO.c FSIO.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h FSconfig.h \
+ C:/Microchip\ Solutions/Microchip/Include/Compiler.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/string.h \
+ HardwareProfile.h FSDefs.h SD-SPI.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/ctype.h \
+ C:/Microchip\ Solutions/Microchip/Include/MDD\ File\ System\FSDefs.h
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.h new file mode 100644 index 00000000..5c2e4cea --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSIO.h @@ -0,0 +1,1364 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: FSIO.h
+ * Dependencies: GenericTypeDefs.h
+ * FSconfig.h
+ * FSDefs.h
+ * stddef.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#ifndef FS_DOT_H
+#define FS_DOT_H
+
+#include "GenericTypeDefs.h"
+#include "FSconfig.h"
+#include "FSDefs.h"
+#include "stddef.h"
+
+#ifdef USE_SD_INTERFACE_WITH_SPI
+ #include "SD-SPI.h"
+#endif
+#ifdef USE_CF_INTERFACE_WITH_PMP
+ #include "MDD File System\CF-PMP.h"
+#endif
+#ifdef USE_MANUAL_CF_INTERFACE
+ #include "MDD File System\CF- Bit transaction.h"
+#endif
+#ifdef USE_USB_INTERFACE
+ #include "USB\usb_host_msd_scsi.h"
+#endif
+
+
+/*******************************************************************/
+/* Strunctures and defines */
+/*******************************************************************/
+
+#ifndef FALSE
+ // Summary: False value
+ // Description: This macro will indicate that a condition is false.
+ #define FALSE 0
+#endif
+#ifndef TRUE
+ // Summary: True value
+ // Description: This macro will indicate that a condition is true.
+ #define TRUE !FALSE // True value
+#endif
+
+
+
+
+#ifndef SEEK_SET
+ // Summary: Macro for the FSfseek SEEK_SET base location.
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the beginning of the file.
+ #define SEEK_SET 0
+
+#endif
+#ifndef SEEK_CUR
+
+ // Summary: Macro for the FSfseek SEEK_CUR base location.
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the current location of the file
+ #define SEEK_CUR 1
+
+#endif
+#ifndef SEEK_END
+
+ // Summary: Macro for the FSfseek SEEK_END base location
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the end of the file. For this macro, the offset value will be subtracted from
+ // the end location of the file by default.
+ #define SEEK_END 2
+
+#endif
+
+
+
+
+// Summary: Macro for the FSfopen APPEND mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it's file information will be loaded and the
+// current location in the file will be set to the end. The user will then be able to write to the file.
+#define APPEND "a"
+
+// Summary: Macro for the FSfopen WRITE mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it will be erased and replaced by an empty file
+// of the same name. The user will then be able to write to the file.
+#define WRITE "w"
+
+// Summary: Macro for the FSfopen READ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file information for the
+// specified file will be loaded. If the file does not exist, the FSfopen function will fail. The user
+// will then be able to read from the file.
+#define READ "r"
+
+// Summary: Macro for the FSfopen APPEND+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it's file information will be loaded and the
+// current location in the file will be set to the end. The user will then be able to write to the file
+// or read from the file.
+#define APPENDPLUS "a+"
+
+// Summary: Macro for the FSfopen WRITE+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it will be erased and replaced by an empty file
+// of the same name. The user will then be able to write to the file or read from the file.
+#define WRITEPLUS "w+"
+
+// Summary: Macro for the FSfopen READ+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file information for the
+// specified file will be loaded. If the file does not exist, the FSfopen function will fail. The user
+// will then be able to read from the file or write to the file.
+#define READPLUS "r+"
+
+
+
+#ifndef intmax_t
+ #ifdef __PIC24F__
+ // Summary: A data type indicating the maximum integer size in an architecture
+ // Description: The intmax_t data type refers to the maximum-sized data type on any given architecture. This
+ // data type can be specified as a format specifier size specification for the FSfprintf function.
+ #define intmax_t long long
+ #elif defined __PIC24H__
+ #define intmax_t long long
+ #elif defined __dsPIC30F__
+ #define intmax_t long long
+ #elif defined __dsPIC33F__
+ #define intmax_t long long
+ #endif
+#endif
+
+
+
+// Summary: Indicates flag conditions for a file object
+// Description: The FILEFLAGS structure is used to indicate conditions in a file. It contains three flags: 'write' indicates
+// that the file was opened in a mode that allows writes, 'read' indicates that the file was opened in a mode
+// that allows reads, and 'FileWriteEOF' indicates that additional data that is written to the file will increase
+// the file size.
+typedef struct
+{
+ unsigned write :1; // Indicates a file was opened in a mode that allows writes
+ unsigned read :1; // Indicates a file was opened in a mode that allows reads
+ unsigned FileWriteEOF :1; // Indicates the current position in a file is at the end of the file
+}FILEFLAGS;
+
+
+
+// Summary: Indicates how to search for file entries in the FILEfind function
+// Description: The values in the SEARCH_TYPE enumeration are used internally by the library to indicate how the FILEfind function
+// how to perform a search. The 'LOOK_FOR_EMPTY_ENTRY' value indicates that FILEfind should search for an empty file entry.
+// The 'LOOK_FOR_MATCHING_ENTRY' value indicates that FILEfind should search for an entry that matches the FSFILE object
+// that was passed into the FILEfind function.
+typedef enum{
+ LOOK_FOR_EMPTY_ENTRY = 0,
+ LOOK_FOR_MATCHING_ENTRY
+} SEARCH_TYPE;
+
+
+
+// Summary: Macro indicating the length of a 8.3 file name
+// Description: The TOTAL_FILE_SIZE macro indicates the maximum number of characters in an 8.3 file name. This value includes
+// 8 characters for the name, three for the extentsion, and 1 for the radix ('.')
+#define TOTAL_FILE_SIZE 8+3+1
+
+// Summary: A mask that indicates the limit of directory entries in a sector
+// Description: The MASK_MAX_FILE_ENTRY_LIMIT_BITS is used to indicate to the Cache_File_Entry function that a new sector needs to
+// be loaded.
+#define MASK_MAX_FILE_ENTRY_LIMIT_BITS 0x0f
+
+// Summary: Value used for shift operations to calculate the sector offset in a directory
+// Description: The VALUE_BASED_ON_ENTRIES_PER_CLUSTER macro is used to calculate sector offsets for directories. The position of the
+// entry is shifted by 4 bits (divided by 16, since there are 16 entries in a sector) to calculate how many sectors a
+// specified entry is offset from the beginning of the directory.
+#define VALUE_BASED_ON_ENTRIES_PER_CLUSTER 4
+
+// Summary: A value that will indicate that a dotdot directory entry points to the root.
+// Description: The VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT macro is used as an absolute address when writing information to a dotdot entry
+// in a newly created directory. If a dotdot entry points to the root directory, it's cluster value must be set to 0,
+// regardless of the actual cluster number of the root directory.
+#define VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT 0
+
+// Summary: MAcro indicating the length of an 8.3 file name in a directory entry
+// Description: The FILE_NAME_SIZE macro indicates the number of characters that an 8.3 file name will take up when packed in
+// a directory entry. This value includes 8 characters for the name and 3 for the extension. Note that the radix is not
+// stored in the directory entry.
+#define FILE_NAME_SIZE 11
+
+
+
+// Summary: Contains file information and is used to indicate which file to access.
+// Description: The FSFILE structure is used to hold file information for an open file as it's being modified or accessed. A pointer to
+// an open file's FSFILE structure will be passeed to any library function that will modify that file.
+typedef struct
+{
+ DISK * dsk; // Pointer to a DISK structure
+ DWORD cluster; // The first cluster of the file
+ DWORD ccls; // The current cluster of the file
+ WORD sec; // The current sector in the current cluster of the file
+ WORD pos; // The position in the current sector
+ DWORD seek; // The absolute position in the file
+ DWORD size; // The size of the file
+ FILEFLAGS flags; // A structure containing file flags
+ WORD time; // The file's last update time
+ WORD date; // The file's last update date
+ char name[FILE_NAME_SIZE]; // The name of the file
+ WORD entry; // The position of the file's directory entry in it's directory
+ WORD chk; // File structure checksum
+ WORD attributes; // The file attributes
+ DWORD dirclus; // The base cluster of the file's directory
+ DWORD dirccls; // The current cluster of the file's directory
+} FSFILE;
+
+
+
+// Summary: A structure used for searching for files on a device.
+// Description: The SearchRec structure is used when searching for file on a device. It contains parameters that will be loaded with
+// file information when a file is found. It also contains the parameters that the user searched for, allowing further
+// searches to be perfomed in the same directory for additional files that meet the specified criteria.
+typedef struct
+{
+ char filename[FILE_NAME_SIZE + 2]; // The name of the file that has been found
+ unsigned char attributes; // The attributes of the file that has been found
+ unsigned long filesize; // The size of the file that has been found
+ unsigned long timestamp; // The last modified time of the file that has been found (create time for directories)
+
+ unsigned int entry; // The directory entry of the last file found that matches the specified attributes. (Internal use only)
+ char searchname[FILE_NAME_SIZE + 2]; // The name specified when the user began the search. (Internal use only)
+ unsigned char searchattr; // The attributes specified when the user began the search. (Internal use only)
+ unsigned long cwdclus; // The directory that this search was performed in. (Internal use only)
+ unsigned char initialized; // Check to determine if the structure was initialized by FindFirst (Internal use only)
+} SearchRec;
+
+
+/***************************************************************************
+* Prototypes *
+***************************************************************************/
+
+
+
+
+/*************************************************************************
+ Function:
+ int FSInit(void)
+ Summary:
+ Function to initialize the device.
+ Conditions:
+ The physical device should be connected to the microcontroller.
+ Input:
+ None
+ Return Values:
+ TRUE - Initialization successful
+ FALSE - Initialization unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Initializes the static or dynamic memory slots for holding file
+ structures. Initializes the device with the DISKmount function. Loads
+ MBR and boot sector information. Initializes the current working
+ directory to the root directory for the device if directory support
+ is enabled.
+ Remarks:
+ None
+ *************************************************************************/
+
+int FSInit(void);
+
+
+/*********************************************************************
+ Function:
+ FSFILE * FSfopen (const char * fileName, const char *mode)
+ Summary:
+ Open a file
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to open
+ mode -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ - WRITEPLUS - Create a new file or replace an existing file (reads also enabled)
+ - READPLUS - Read data from an existing file (writes also enabled)
+ - APPENDPLUS - Append data to an existing file (reads also enabled)
+ Return Values:
+ FSFILE * - The pointer to the file object
+ NULL - The file could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will open a file or directory. First, RAM in the
+ dynamic heap or static array will be allocated to a new FSFILE object.
+ Then, the specified file name will be formatted to ensure that it's
+ in 8.3 format. Next, the FILEfind function will be used to search
+ for the specified file name. If the name is found, one of three
+ things will happen: if the file was opened in read mode, its file
+ info will be loaded using the FILEopen function; if it was opened in
+ write mode, it will be erased, and a new file will be constructed in
+ its place; if it was opened in append mode, its file info will be
+ loaded with FILEopen and the current location will be moved to the
+ end of the file using the FSfseek function. If the file was not
+ found by FILEfind, it will be created if the mode was specified as
+ a write or append mode. In these cases, a pointer to the heap or
+ static FSFILE object array will be returned. If the file was not
+ found and the mode was specified as a read mode, the memory
+ allocated to the file will be freed and the NULL pointer value
+ will be returned.
+ Remarks:
+ None.
+ *********************************************************************/
+
+FSFILE * FSfopen(const char * fileName, const char *mode);
+
+
+
+#ifdef ALLOW_PGMFUNCTIONS
+
+/******************************************************************************
+ Function:
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+ Summary:
+ Open a file named with a ROM string on PIC18
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to be opened (ROM)
+ mode - The mode the file will be opened in (ROM)
+ Return Values:
+ FSFILE * - A pointer to the file object
+ NULL - File could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfopenpgm function will copy a PIC18 ROM fileName and mode argument
+ into RAM arrays, and then pass those arrays to the FSfopen function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ ******************************************************************************/
+
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode);
+
+
+/**************************************************************************************
+ Function:
+ int FindFirstpgm (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Find a file named with a ROM string on PIC18
+ Conditions:
+ None
+ Input:
+ fileName - The name of the file to be found (ROM)
+ attr - The attributes of the file to be found
+ rec - Pointer to a search record to store the file info in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the given parameters was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object will be lost.
+ The FSerrno variable will be changed.
+ Description:
+ The FindFirstpgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FindFirst function.
+ Remarks:
+ Call FindFirstpgm or FindFirst before calling FindNext.
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************************/
+
+ int FindFirstpgm (const rom char * fileName, unsigned int attr, SearchRec * rec);
+
+
+/**************************************************************************
+ Function:
+ int FSchdirpgm (const rom char * path)
+ Summary:
+ Changed the CWD with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to (ROM)
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdirpgm function passes a PIC18 ROM path pointer to the
+ chdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM
+ **************************************************************************/
+
+ int FSchdirpgm (const rom char * path);
+
+ #ifdef ALLOW_WRITES
+
+
+/*************************************************************
+ Function:
+ int FSremovepgm (const rom char * fileName)
+ Summary:
+ Delete a file named with a ROM string on PIC18
+ Conditions:
+ File not opened; file exists
+ Input:
+ fileName - The name of the file to be deleted (ROM)
+ Return Values:
+ 0 - File was removed successfully
+ -1 - File could not be removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremovepgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FSremove function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *************************************************************/
+
+ int FSremovepgm (const rom char * fileName);
+
+
+/**************************************************************************
+ Function:
+ int FSmkdirpgm (const rom char * path)
+ Summary:
+ Create a directory with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create (ROM)
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdirpgm function passes a PIC18 ROM path pointer to the
+ mkdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arugments in ROM
+ **************************************************************************/
+
+ int FSmkdirpgm (const rom char * path);
+
+
+/**************************************************************************
+ Function:
+ int FSrmdirpgm (const rom char * path)
+ Summary:
+ Delete a directory with a path in ROM on PIC18
+ Conditions:
+ None.
+ Input:
+ path - The path of the directory to remove (ROM)
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdirpgm function passes a PIC18 ROM path pointer to the
+ rmdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************/
+
+ int FSrmdirpgm (const rom char * path, unsigned char rmsubdirs);
+
+
+/*****************************************************************
+ Function:
+ int FSrenamepgm(const rom char * fileName, FSFILE * fo)
+ Summary:
+ Rename a file named with a ROM string on PIC18
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file (in ROM)
+ fo - The file to rename
+ Return Values:
+ 0 - File renamed successfully
+ -1 - File could not be renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The Fsrenamepgm function will copy the rom fileName specified
+ by the user into a RAM array and pass that array into the
+ FSrename function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *****************************************************************/
+
+ int FSrenamepgm (const rom char * fileName, FSFILE * fo);
+ #endif
+#endif
+
+
+/************************************************************
+ Function:
+ int FSfclose(FSFILE *fo)
+ Summary:
+ Update file information and free FSFILE objects
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to the file to close
+ Return Values:
+ 0 - File closed successfully
+ EOF - Error closing the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will update the directory entry for the
+ file pointed to by 'fo' with the information contained
+ in 'fo,' including the new file size and attributes.
+ Timestamp information will also be loaded based on the
+ method selected by the user and written to the entry
+ as the last modified time and date. The file entry will
+ then be written to the device. Finally, the memory
+ used for the specified file object will be freed from
+ the dynamic heap or the array of FSFILE objects.
+ Remarks:
+ A function to flush data to the device without closing the
+ file can be created by removing the portion of this
+ function that frees the memory and the line that clears
+ the write flag.
+ ************************************************************/
+
+int FSfclose(FSFILE *fo);
+
+
+/*********************************************************
+ Function:
+ void FSrewind (FSFILE * fo)
+ Summary:
+ Set the current position in a file to the beginning
+ Conditions:
+ File opened.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ None
+ Side Effects:
+ None.
+ Description:
+ The FSrewind funciton will reset the position of the
+ specified file to the beginning of the file. This
+ functionality is faster than using FSfseek to reset
+ the position in the file.
+ Remarks:
+ None.
+ *********************************************************/
+
+void FSrewind (FSFILE *fo);
+
+
+/**************************************************************************
+ Function:
+ size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Read data from a file
+ Conditions:
+ File is opened in a read mode
+ Input:
+ ptr - Destination buffer for read bytes
+ size - Size of units in bytes
+ n - Number of units to be read
+ stream - File to be read from
+ Return:
+ size_t - number of units read
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfread function will read data from the specified file. First,
+ the appropriate sector of the file is loaded. Then, data is read into
+ the specified buffer until the specified number of bytes have been read.
+ When a cluster boundary is reached, a new cluster will be loaded. The
+ parameters 'size' and 'n' indicate how much data to read. 'Size'
+ refers to the size of one object to read (in bytes), and 'n' will refer
+ to the number of these objects to read. The value returned will be equal
+ to 'n' unless an error occured or the user tried to read beyond the end
+ of the file.
+ Remarks:
+ None.
+ **************************************************************************/
+
+size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream);
+
+
+/**********************************************************************
+ Function:
+ int FSfseek(FSFILE *stream, long offset, int whence)
+ Summary:
+ Change the current position in a file
+ Conditions:
+ File opened
+ Input:
+ stream - Pointer to file structure
+ offset - Offset from base location
+ whence -
+ - SEEK_SET - Seek from start of file
+ - SEEK_CUR - Seek from current location
+ - SEEK_END - Seek from end of file (subtract offset)
+ Return Values:
+ 0 - Operation successful
+ -1 - Operation unsuccesful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfseek function will change the current position in the file to
+ one specified by the user. First, an absolute offset is calculated
+ using the offset and base location passed in by the user. Then, the
+ position variables are updated, and the sector number that corresponds
+ to the new location. That sector is then loaded. If the offset
+ falls exactly on a cluster boundary, a new cluster will be allocated
+ to the file and the position will be set to the first byte of that
+ cluster.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSfseek(FSFILE *stream, long offset, int whence);
+
+
+/*******************************************************************
+ Function:
+ long FSftell (FSFILE * fo)
+ Summary:
+ Determine the current location in a file
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to file structure
+ Return: Current location in the file
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSftell function will return the current position in the
+ file pointed to by 'fo' by returning the 'seek' variable in the
+ FSFILE object, which is used to keep track of the absolute
+ location of the current position in the file.
+ Remarks:
+ None
+ *******************************************************************/
+
+long FSftell(FSFILE *fo);
+
+
+/****************************************************
+ Function:
+ int FSfeof( FSFILE * stream )
+ Summary:
+ Indicate whether the current file position is at the end
+ Conditions:
+ File is open in a read mode
+ Input:
+ stream - Pointer to the target file
+ Return Values:
+ Non-Zero - EOF reached
+ 0 - Not at end of File
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfeof function will indicate that the end-of-
+ file has been reached for the specified file by
+ comparing the absolute location in the file to the
+ size of the file.
+ Remarks:
+ None.
+ ****************************************************/
+
+int FSfeof( FSFILE * stream );
+
+
+#ifdef ALLOW_FORMATS
+/*******************************************************************
+ Function:
+ int FSformat (char mode, long int serialNumber, char * volumeID)
+ Summary:
+ Formats a device
+ Conditions:
+ The device must possess a valid master boot record.
+ Input:
+ mode - - 0 - Just erase the FAT and root
+ - 1 - Create a new boot sector
+ serialNumber - Serial number to write to the card
+ volumeID - Name of the card
+ Return Values:
+ 0 - Format was successful
+ EOF - Format was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSformat function can be used to create a new boot sector
+ on a device, based on the information in the master boot record.
+ This function will first initialize the I/O pins and the device,
+ and then attempts to read the master boot record. If the MBR
+ cannot be loaded successfully, the function will fail. Next, if
+ the 'mode' argument is specified as '0' the existing boot sector
+ information will be loaded. If the 'mode' argument is '1' an
+ entirely new boot sector will be constructed using the disk
+ values from the master boot record. Once the boot sector has
+ been successfully loaded/created, the locations of the FAT and
+ root will be loaded from it, and they will be completely
+ erased. If the user has specified a volumeID parameter, a
+ VOLUME attribute entry will be created in the root directory
+ to name the device.
+ Remarks:
+ FAT12 and FAT16 formatting is supported.
+ *******************************************************************/
+
+int FSformat (char mode, long int serialNumber, char * volumeID);
+#endif
+
+
+#ifdef ALLOW_WRITES
+/***************************************************************************
+ Function:
+ int FSattrib (FSFILE * file, unsigned char attributes)
+ Summary:
+ Change the attributes of a file
+ Conditions:
+ File opened
+ Input:
+ file - Pointer to file structure
+ attributes - The attributes to set for the file
+ - Attribute - Value - Indications
+ - ATTR_READ_ONLY - 0x01 - The read-only attribute
+ - ATTR_HIDDEN - 0x02 - The hidden attribute
+ - ATTR_SYSTEM - 0x04 - The system attribute
+ - ATTR_ARCHIVE - 0x20 - The archive attribute
+ Return Values:
+ 0 - Attribute change was successful
+ -1 - Attribute change was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSattrib funciton will set the attributes of the specified file
+ to the attributes passed in by the user. This function will load the
+ file entry, replace the attributes with the ones specified, and write
+ the attributes back. If the specified file is a directory, the
+ directory attribute will be preserved.
+ Remarks:
+ None
+ ***************************************************************************/
+
+int FSattrib (FSFILE * file, unsigned char attributes);
+
+
+/***************************************************************
+ Function:
+ int FSrename (const rom char * fileName, FSFILE * fo)
+ Summary:
+ Change the name of a file or directory
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file
+ fo - The file to rename
+ Return Values:
+ 0 - File was renamed successfully
+ EOF - File was not renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrename function will rename a file. First, it will
+ search through the current working directory to ensure the
+ specified new filename is not already in use. If it isn't,
+ the new filename will be written to the file entry of the
+ file pointed to by 'fo.'
+ Remarks:
+ None
+ ***************************************************************/
+
+int FSrename (const char * fileName, FSFILE * fo);
+
+
+/*********************************************************************
+ Function:
+ int FSremove (const char * fileName)
+ Summary:
+ Delete a file
+ Conditions:
+ File not opened, file exists
+ Input:
+ fileName - Name of the file to erase
+ Return Values:
+ 0 - File removed
+ EOF - File was not removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremove function will attempt to find the specified file with
+ the FILEfind function. If the file is found, it will be erased
+ using the FILEerase function.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSremove (const char * fileName);
+
+
+/*********************************************************************************
+ Function:
+ size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Write data to a file
+ Conditions:
+ File opened in WRITE, APPEND, WRITE+, APPEND+, READ+ mode
+ Input:
+ ptr - Pointer to source buffer
+ size - Size of units in bytes
+ n - Number of units to transfer
+ stream - Pointer to file structure
+ Return:
+ size_t - number of units written
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfwrite function will write data to a file. First, the sector that
+ corresponds to the current position in the file will be loaded (if it hasn't
+ already been cached in the global data buffer). Data will then be written to
+ the device from the specified buffer until the specified amount has been written.
+ If the end of a cluster is reached, the next cluster will be loaded, unless
+ the end-of-file flag for the specified file has been set. If it has, a new
+ cluster will be allocated to the file. Finally, the new position and filezize
+ will be stored in the FSFILE object. The parameters 'size' and 'n' indicate how
+ much data to write. 'Size' refers to the size of one object to write (in bytes),
+ and 'n' will refer to the number of these objects to write. The value returned
+ will be equal to 'n' unless an error occured.
+ Remarks:
+ None.
+ *********************************************************************************/
+
+size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream);
+
+#endif
+
+#ifdef ALLOW_DIRS
+
+
+/**************************************************************************
+ Function:
+ int FSchdir (char * path)
+ Summary:
+ Change the current working directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to.
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdir function passes a RAM pointer to the path to the
+ chdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSchdir (char * path);
+
+
+/**************************************************************
+ Function:
+ char * FSgetcwd (char * path, int numchars)
+ Summary:
+ Get the current working directory name
+ Conditions:
+ None
+ Input:
+ path - Pointer to the array to return the cwd name in
+ numchars - Number of chars in the path
+ Return Values:
+ char * - The cwd name string pointer (path or defaultArray)
+ NULL - The current working directory name could not be loaded.
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSgetcwd function will get the name of the current
+ working directory and return it to the user. The name
+ will be copied into the buffer pointed to by 'path,'
+ starting at the root directory and copying as many chars
+ as possible before the end of the buffer. The buffer
+ size is indicated by the 'numchars' argument. The first
+ thing this function will do is load the name of the current
+ working directory, if it isn't already present. This could
+ occur if the user switched to the dotdot entry of a
+ subdirectory immediately before calling this function. The
+ function will then copy the current working directory name
+ into the buffer backwards, and insert a backslash character.
+ Next, the function will continuously switch to the previous
+ directories and copy their names backwards into the buffer
+ until it reaches the root. If the buffer overflows, it
+ will be treated as a circular buffer, and data will be
+ copied over existing characters, starting at the beginning.
+ Once the root directory is reached, the text in the buffer
+ will be swapped, so that the buffer contains as much of the
+ current working directory name as possible, starting at the
+ root.
+ Remarks:
+ None
+ **************************************************************/
+
+char * FSgetcwd (char * path, int numbchars);
+
+
+#ifdef ALLOW_WRITES
+
+/**************************************************************************
+ Function:
+ int FSmkdir (char * path)
+ Summary:
+ Create a directory
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create.
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdir function passes a RAM pointer to the path to the
+ mkdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSmkdir (char * path);
+
+
+/**************************************************************************
+ Function:
+ int FSrmdir (char * path)
+ Summary:
+ Delete a directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to remove
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdir function passes a RAM pointer to the path to the
+ rmdirhelper function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int FSrmdir (char * path, unsigned char rmsubdirs);
+#endif
+
+#endif
+
+#ifdef USERDEFINEDCLOCK
+
+
+/***********************************************************************************************************
+ Function:
+ int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+ Summary:
+ Manually set timestamp variables
+ Conditions:
+ USERDEFINEDCLOCK macro defined in FSconfig.h.
+ Input:
+ year - The year (1980\-2107)
+ month - The month (1\-12)
+ day - The day of the month (1\-31)
+ hour - The hour (0\-23)
+ minute - The minute (0\-59)
+ second - The second (0\-59)
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ Lets the user manually set the timing variables. The values passed in will be converted to the format
+ used by the FAT timestamps.
+ Remarks:
+ Call this before creating a file or directory (set create time) and
+ before closing a file (set last access time, last modified time)
+ ***********************************************************************************************************/
+
+int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second);
+#endif
+
+
+#ifdef ALLOW_FILESEARCH
+
+/***********************************************************************************
+ Function:
+ int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Initial search function
+ Conditions:
+ None
+ Input:
+ fileName - The name to search for
+ - Parital string search characters
+ - * - Indicates the rest of the filename or extension can vary (e.g. FILE.*)
+ - ? - Indicates that one character in a filename can vary (e.g. F?LE.T?T)
+ attr - The attributes that a found file may have
+ - ATTR_READ_ONLY - File may be read only
+ - ATTR_HIDDEN - File may be a hidden file
+ - ATTR_SYSTEM - File may be a system file
+ - ATTR_VOLUME - Entry may be a volume label
+ - ATTR_DIRECTORY - File may be a directory
+ - ATTR_ARCHIVE - File may have archive attribute
+ - ATTR_MASK - All attributes
+ rec - pointer to a structure to put the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the specified criteria was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object
+ will be lost. The FSerrno variable will be changed.
+ Description:
+ The FindFirst function will search for a file based on parameters passed in
+ by the user. This function will use the FILEfind function to parse through
+ the current working directory searching for entries that match the specified
+ parameters. If a file is found, its parameters are copied into the SearchRec
+ structure, as are the initial parameters passed in by the user and the position
+ of the file entry in the current working directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling FindNext
+ ***********************************************************************************/
+
+int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec);
+
+
+/**********************************************************************
+ Function:
+ int FindNext (SearchRec * rec)
+ Summary:
+ Sequential search function
+ Conditions:
+ None
+ Input:
+ rec - The structure to store the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No additional files matching the specified criteria were found
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FindNext function performs the same function as the FindFirst
+ funciton, except it does not copy any search parameters into the
+ SearchRec structure (only info about found files) and it begins
+ searching at the last directory entry offset at which a file was
+ found, rather than at the beginning of the current working
+ directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling this function
+ **********************************************************************/
+
+int FindNext (SearchRec * rec);
+#endif
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSfprintf (FSFILE * fptr, const char * fmt, ...)
+ // PIC18
+ int FSfpritnf (FSFILE * fptr, const rom char * fmt, ...)
+ Summary:
+ Function to write formatted strings to a file
+ Conditions:
+ For PIC18, integer promotion must be enabled in the project build
+ options menu. File opened in a write mode.
+ Input:
+ fptr - A pointer to the file to write to.
+ fmt - A string of characters and format specifiers to write to
+ the file
+ ... - Additional arguments inserted in the string by format
+ specifiers
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Writes a specially formatted string to a file.
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef ALLOW_FSFPRINTF
+ #ifdef __18CXX
+ int FSfprintf (FSFILE *fptr, const rom char *fmt, ...);
+ #else
+ int FSfprintf (FSFILE *fptr, const char * fmt, ...);
+ #endif
+#endif
+
+
+/**************************************************************************
+ Function:
+ int FSerror (void)
+ Summary:
+ Return an error code for the last function call
+ Conditions:
+ The return value depends on the last function called.
+ Input:
+ None
+ Side Effects:
+ None.
+ Return Values:
+ FSInit -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The physical media could not be initialized
+ - CE_BAD_SECTOR_READ � The MBR or the boot sector could not be
+ read correctly
+ - CE_BAD_PARITION � The MBR signature code was incorrect.
+ - CE_NOT_FORMATTED � The boot sector signature code was incorrect or
+ indicates an invalid number of bytes per sector.
+ - CE_CARDFAT32 � The physical media is FAT32 type (only an error
+ when FAT32 support is disabled).
+ - CE_UNSUPPORTED_FS � The device is formatted with an unsupported file
+ system (not FAT12 or 16).
+ FSfopen -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The device has not been initialized.
+ - CE_TOO_MANY_FILES_OPEN � The function could not allocate any
+ additional file information to the array
+ of FSFILE structures or the heap.
+ - CE_INVALID_FILENAME � The file name argument was invalid.
+ - CE_INVALID_ARGUMENT � The user attempted to open a directory in a
+ write mode or specified an invalid mode argument.
+ - CE_FILE_NOT_FOUND � The specified file (which was to be opened in read
+ mode) does not exist on the device.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_ERASE_FAIL � The existing file could not be erased (when opening
+ a file in WRITE mode).
+ - CE_DIR_FULL � The directory is full.
+ - CE_DISK_FULL� The data memory section is full.
+ - CE_WRITE_ERROR � A write to the device failed.
+ - CE_SEEK_ERROR � The current position in the file could not be set to
+ the end (when the file was opened in APPEND mode).
+ FSfclose -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer or the new file
+ entry information could not be written to the device.
+ - CE_BADCACHEREAD � The file entry information could not be cached
+ FSfread -
+ - CE_GOOD � No Error
+ - CE_WRITEONLY � The file was opened in a write-only mode.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_BAD_SECTOR_READ � The data sector could not be read.
+ - CE_EOF � The end of the file was reached.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be loaded.
+ FSfwrite -
+ - CE_GOOD � No Error
+ - CE_READONLY � The file was opened in a read-only mode.
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_WRITE_ERROR � There was an error writing data to the device.
+ - CE_BADCACHEREAD � The data sector to be modified could not be read from
+ the device.
+ - CE_DISK_FULL � All data clusters on the device are in use.
+ FSfseek -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_INVALID_ARGUMENT � The specified offset exceeds the size of the file.
+ - CE_BADCACHEREAD � The sector that contains the new current position
+ could not be loaded.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be
+ loaded/allocated.
+ FSftell -
+ - CE_GOOD � No Error
+ FSattrib -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The attribute argument was invalid.
+ - CE_BADCACHEREAD � The existing file entry information could not be
+ loaded.
+ - CE_WRITE_ERROR � The file entry information could not be written to
+ the device.
+ FSrename -
+ - CE_GOOD � No Error
+ - CE_FILENOTOPENED � A null file pointer was passed into the function.
+ - CE_INVALID_FILENAME � The file name passed into the function was invalid.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_FILENAME_EXISTS � A file with the specified name already exists.
+ - CE_WRITE_ERROR � The new file entry data could not be written to the
+ device.
+ FSfeof -
+ - CE_GOOD � No Error
+ FSformat -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The device could not be initialized.
+ - CE_BADCACHEREAD � The master boot record or boot sector could not be
+ loaded successfully.
+ - CE_INVALID_ARGUMENT � The user selected to create their own boot sector on
+ a device that has no master boot record, or the mode
+ argument was invalid.
+ - CE_WRITE_ERROR � The updated MBR/Boot sector could not be written to
+ the device.
+ - CE_BAD_PARTITION � The calculated number of sectors per clusters was
+ invalid.
+ - CE_NONSUPPORTED_SIZE � The card has too many sectors to be formatted as
+ FAT12 or FAT16.
+ FSremove -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � The specified file could not be found.
+ - CE_ERASE_FAIL � The file could not be erased.
+ FSchdir -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The path string was mis-formed or the user tried to
+ change to a non-directory file.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_FOUND � Could not find a directory in the path.
+ FSgetcwd -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The user passed a 0-length buffer into the function.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the current working directory.
+ FSmkdir -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_ARGUMENT � The path string was mis-formed.
+ - CE_BADCACHEREAD � Could not successfully change to a recently created
+ directory to store its dir entry information, or
+ could not cache directory entry information.
+ - CE_INVALID_FILENAME � One or more of the directory names has an invalid
+ format.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device or the dot/dotdot entries could
+ not be written to a newly created directory.
+ - CE_DIR_FULL � There are no available dir entries in the CWD.
+ - CE_DISK_FULL � There are no available clusters in the data region of
+ the device.
+ FSrmdir -
+ - CE_GOOD � No Error
+ - CE_DIR_NOT_FOUND � The directory specified could not be found or the
+ function could not change to a subdirectory within
+ the directory to be deleted (when recursive delete is
+ enabled).
+ - CE_INVALID_ARGUMENT � The user tried to remove the CWD or root directory.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_EMPTY � The directory to be deleted was not empty and
+ recursive subdirectory removal was disabled.
+ - CE_ERASE_FAIL � The directory or one of the directories or files
+ within it could not be deleted.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the CWD.
+ SetClockVars -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The time values passed into the function were
+ invalid.
+ FindFirst -
+ - CE_GOOD � No Error
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ - CE_BADCACHEREAD � The file information for the file that was found
+ could not be cached.
+ FindNext -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The SearchRec object was not initialized by a call to
+ FindFirst.
+ - CE_INVALID_ARGUMENT � The SearchRec object was initialized in a different
+ directory from the CWD.
+ - CE_INVALID_FILENAME � The filename is invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ FSfprintf -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � Characters could not be written to the file.
+ Description:
+ The FSerror function will return the FSerrno variable. This global
+ variable will have been set to an error value during the last call of a
+ library function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSerror (void);
+
+
+/*********************************************************************************
+ Function:
+ int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+ Summary:
+ Creates a master boot record
+ Conditions:
+ The I/O pins for the device have been initialized by the InitIO function.
+ Input:
+ firstSector - The first sector of the partition on the device (cannot
+ be 0; that's the MBR)
+ numSectors - The number of sectors available in memory (including the
+ MBR)
+ Return Values:
+ 0 - MBR was created successfully
+ EOF - MBR could not be created
+ Side Effects:
+ None
+ Description:
+ This function can be used to create a master boot record for a device. Note
+ that this function should not be used on a device that is already formatted
+ with a master boot record (i.e. most SD cards, CF cards, USB keys). This
+ function will fill the global data buffer with appropriate partition information
+ for a FAT partition with a type determined by the number of sectors available
+ to the partition. It will then write the MBR information to the first sector
+ on the device. This function should be followed by a call to FSformat, which
+ will create a boot sector, root dir, and FAT appropriate the the information
+ contained in the new master boot record. Note that FSformat only supports
+ FAT12 and FAT16 formatting at this time, and so cannot be used to format a
+ device with more than 0x3FFD5F sectors.
+ Remarks:
+ This function can damage the device being used, and should not be called
+ unless the user is sure about the size of the device and the first sector value.
+ *********************************************************************************/
+
+int FSCreateMBR (unsigned long firstSector, unsigned long numSectors);
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSconfig.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSconfig.h new file mode 100644 index 00000000..abf6a18f --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/FSconfig.h @@ -0,0 +1,291 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: FSconfig.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Dependencies: None
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+
+#ifndef _FS_DEF_
+
+#include "Compiler.h"
+#include "HardwareProfile.h"
+
+
+// Summary: A macro indicating the maximum number of concurrently open files
+// Description: The FS_MAX_FILES_OPEN #define is only applicable when dynamic memory allocation is not used (FS_DYNAMIC_MEM is not defined).
+// This macro defines the maximum number of open files at any given time. The amount of RAM used by FSFILE objects will
+// be equal to the size of an FSFILE object multipled by this macro value. This value should be kept as small as possible
+// as dictated by the application. This will reduce memory usage.
+#define FS_MAX_FILES_OPEN 3
+
+
+// Summary: A macro defining the size of a sector
+// Description: The MEDIA_SECTOR_SIZE macro will define the size of a sector on the FAT file system. This value must equal 512 bytes,
+// 1024 bytes, 2048 bytes, or 4096 bytes. The value of a sector will usually be 512 bytes.
+#define MEDIA_SECTOR_SIZE 512
+
+
+
+/* *******************************************************************************************************/
+/************** Compiler options to enable/Disable Features based on user's application ******************/
+/* *******************************************************************************************************/
+
+
+// Summary: A macro to enable/disable file search functions.
+// Description: The ALLOW_FILESEARCH definition can be commented out to disable file search functions in the library. This will
+// prevent the use of the FindFirst and FindNext functions and reduce code size.
+#define ALLOW_FILESEARCH
+
+// Summary: A macro to enable/disable write functionality
+// Description: The ALLOW_WRITES definition can be commented out to disable all operations that write to the device. This will
+// greatly reduce code size.
+#define ALLOW_WRITES
+
+
+// Summary: A macro to enable/disable format functionality
+// Description: The ALLOW_FORMATS definition can be commented out to disable formatting functionality. This will prevent the use of
+// the FSformat function. If formats are enabled, write operations must also be enabled by uncommenting ALLOW_WRITES.
+#define ALLOW_FORMATS
+
+// Summary: A macro to enable/disable directory operations.
+// Description: The ALLOW_DIRS definition can be commented out to disable all directory functionality. This will reduce code size.
+// If directories are enabled, write operations must also be enabled by uncommenting ALLOW_WRITES in order to use
+// the FSmkdir or FSrmdir functions.
+#define ALLOW_DIRS
+
+// Summary: A macro to enable/disable PIC18 ROM functions.
+// Description: The ALLOW_PGMFUNCTIONS definition can be commented out to disable all PIC18 functions that allow the user to pass string
+// arguments in ROM (denoted by the suffix -pgm). Note that this functionality must be disabled when not using PIC18.
+//#define ALLOW_PGMFUNCTIONS
+
+// Summary: A macro to enable/disable the FSfprintf function.
+// Description: The ALLOW_FSFPRINTF definition can be commented out to disable the FSfprintf function. This will save code space. Note that
+// if FSfprintf is enabled and the PIC18 architecture is used, integer promotions must be enabled in the Project->Build Options
+// menu. Write operations must be enabled to use FSfprintf.
+//#define ALLOW_FSFPRINTF
+
+// Summary: A macro to enable/disable FAT32 support.
+// Description: The SUPPORT_FAT32 definition can be commented out to disable support for FAT32 functionality. This will save a small amount
+// of code space.
+#define SUPPORT_FAT32
+
+
+
+/**************************************************************************************************/
+// Select a method for updating file timestamps
+/**************************************************************************************************/
+
+// Summary: A macro to enable RTCC based timestamp generation
+// Description: The USEREALTIMECLOCK macro will configure the code to automatically
+// generate timestamp information for files from the RTCC module. The user
+// must enable and configure the RTCC module before creating or modifying
+// files.
+#define USEREALTIMECLOCK
+
+// Summary: A macro to enable manual timestamp generation
+// Description: The USERDEFINEDCLOCK macro will allow the user to manually set
+// timestamp information using the SetClockVars function. The user will
+// need to set the time variables immediately before creating or closing a
+// file or directory.
+//#define USERDEFINEDCLOCK
+
+// Summary: A macro to enable don't-care timestamp generation
+// Description: The INCREMENTTIMESTAMP macro will set the create time of a file to a
+// static value and increment it when a file is updated. This timestamp
+// generation method should only be used in applications where file times
+// are not necessary.
+//#define INCREMENTTIMESTAMP
+
+
+#ifdef __18CXX
+ #ifdef USEREALTIMECLOCK
+ #error The PIC18 architecture does not have a Real-time clock and calander module
+ #endif
+#endif
+
+#ifdef ALLOW_PGMFUNCTIONS
+ #ifndef __18CXX
+ #error The pgm functions are unneccessary when not using PIC18
+ #endif
+#endif
+
+#ifndef USEREALTIMECLOCK
+ #ifndef USERDEFINEDCLOCK
+ #ifndef INCREMENTTIMESTAMP
+ #error Please enable USEREALTIMECLOCK, USERDEFINEDCLOCK, or INCREMENTTIMESTAMP
+ #endif
+ #endif
+#endif
+
+/************************************************************************/
+// Set this preprocessor option to '1' to use dynamic FSFILE object allocation. It will
+// be necessary to allocate a heap when dynamically allocating FSFILE objects.
+// Set this option to '0' to use static FSFILE object allocation.
+/************************************************************************/
+
+#if 0
+ // Summary: A macro indicating that FSFILE objects will be allocated dynamically
+ // Description: The FS_DYNAMIC_MEM macro will cause FSFILE objects to be allocated from a dynamic heap. If it is undefined,
+ // the file objects will be allocated using a static array.
+ #define FS_DYNAMIC_MEM
+ #ifdef __18CXX
+ // Description: Function pointer to a dynamic memory allocation function
+ #define FS_malloc SRAMalloc
+ // Description: Function pointer to a dynamic memory free function
+ #define FS_free SRAMfree
+ #else
+ #define FS_malloc malloc
+ #define FS_free free
+ #endif
+#endif
+
+
+// Function definitions
+// Associate the physical layer functions with the correct physical layer
+#ifdef USE_SD_INTERFACE_WITH_SPI // SD-SPI.c and .h
+
+ // Description: Function pointer to the Media Initialize Physical Layer function
+ #define MDD_MediaInitialize MDD_SDSPI_MediaInitialize
+
+ // Description: Function pointer to the Media Detect Physical Layer function
+ #define MDD_MediaDetect MDD_SDSPI_MediaDetect
+
+ // Description: Function pointer to the Sector Read Physical Layer function
+ #define MDD_SectorRead MDD_SDSPI_SectorRead
+
+ // Description: Function pointer to the Sector Write Physical Layer function
+ #define MDD_SectorWrite MDD_SDSPI_SectorWrite
+
+ // Description: Function pointer to the I/O Initialization Physical Layer function
+ #define MDD_InitIO MDD_SDSPI_InitIO
+
+ // Description: Function pointer to the Media Shutdown Physical Layer function
+ #define MDD_ShutdownMedia MDD_SDSPI_ShutdownMedia
+
+ // Description: Function pointer to the Write Protect Check Physical Layer function
+ #define MDD_WriteProtectState MDD_SDSPI_WriteProtectState
+
+ // Description: Function pointer to the Read Capacity Physical Layer function
+ #define MDD_ReadCapacity MDD_SDSPI_ReadCapacity
+
+ // Description: Function pointer to the Read Sector Size Physical Layer Function
+ #define MDD_ReadSectorSize MDD_SDSPI_ReadSectorSize
+
+#elif defined USE_CF_INTERFACE_WITH_PMP // CF-PMP.c and .h
+
+ // Description: Function pointer to the Media Initialize Physical Layer function
+ #define MDD_MediaInitialize MDD_CFPMP_MediaInitialize
+
+ // Description: Function pointer to the Media Detect Physical Layer function
+ #define MDD_MediaDetect MDD_CFPMP_MediaDetect
+
+ // Description: Function pointer to the Sector Read Physical Layer function
+ #define MDD_SectorRead MDD_CFPMP_SectorRead
+
+ // Description: Function pointer to the Sector Write Physical Layer function
+ #define MDD_SectorWrite MDD_CFPMP_SectorWrite
+
+ // Description: Function pointer to the I/O Initialization Physical Layer function
+ #define MDD_InitIO MDD_CFPMP_InitIO
+
+ // Description: Function pointer to the Media Shutdown Physical Layer function
+ #define MDD_ShutdownMedia MDD_CFPMP_ShutdownMedia
+
+ // Description: Function pointer to the Write Protect Check Physical Layer function
+ #define MDD_WriteProtectState MDD_CFPMP_WriteProtectState
+
+ // Description: Function pointer to the CompactFlash Wait Physical Layer function
+ #define MDD_CFwait MDD_CFPMP_CFwait
+
+ // Description: Function pointer to the CompactFlash Write Physical Layer function
+ #define MDD_CFwrite MDD_CFPMP_CFwrite
+
+ // Description: Function pointer to the CompactFlash Read Physical Layer function
+ #define MDD_CFread MDD_CFPMP_CFread
+
+#elif defined USE_MANUAL_CF_INTERFACE // CF-Bit transaction.c and .h
+
+ // Description: Function pointer to the Media Initialize Physical Layer function
+ #define MDD_MediaInitialize MDD_CFBT_MediaInitialize
+
+ // Description: Function pointer to the Media Detect Physical Layer function
+ #define MDD_MediaDetect MDD_CFBT_MediaDetect
+
+ // Description: Function pointer to the Sector Read Physical Layer function
+ #define MDD_SectorRead MDD_CFBT_SectorRead
+
+ // Description: Function pointer to the Sector Write Physical Layer function
+ #define MDD_SectorWrite MDD_CFBT_SectorWrite
+
+ // Description: Function pointer to the I/O Initialization Physical Layer function
+ #define MDD_InitIO MDD_CFBT_InitIO
+
+ // Description: Function pointer to the Media Shutdown Physical Layer function
+ #define MDD_ShutdownMedia MDD_CFBT_ShutdownMedia
+
+ // Description: Function pointer to the Write Protect Check Physical Layer function
+ #define MDD_WriteProtectState MDD_CFBT_WriteProtectState
+
+ // Description: Function pointer to the CompactFlash Wait Physical Layer function
+ #define MDD_CFwait MDD_CFBT_CFwait
+
+ // Description: Function pointer to the CompactFlash Write Physical Layer function
+ #define MDD_CFwrite MDD_CFBT_CFwrite
+
+ // Description: Function pointer to the CompactFlash Read Physical Layer function
+ #define MDD_CFread MDD_CFBT_CFread
+
+#elif defined USE_USB_INTERFACE // USB host MSD library
+
+ // Description: Function pointer to the Media Initialize Physical Layer function
+ #define MDD_MediaInitialize USBHostMSDSCSIMediaInitialize
+
+ // Description: Function pointer to the Media Detect Physical Layer function
+ #define MDD_MediaDetect USBHostMSDSCSIMediaDetect
+
+ // Description: Function pointer to the Sector Read Physical Layer function
+ #define MDD_SectorRead USBHostMSDSCSISectorRead
+
+ // Description: Function pointer to the Sector Write Physical Layer function
+ #define MDD_SectorWrite USBHostMSDSCSISectorWrite
+
+ // Description: Function pointer to the I/O Initialization Physical Layer function
+ #define MDD_InitIO();
+
+ // Description: Function pointer to the Media Shutdown Physical Layer function
+ #define MDD_ShutdownMedia USBHostMSDSCSIMediaReset
+
+ // Description: Function pointer to the Write Protect Check Physical Layer function
+ #define MDD_WriteProtectState USBHostMSDSCSIWriteProtectState
+
+#endif
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/G_Code.c b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/G_Code.c new file mode 100644 index 00000000..94f74b6e --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/G_Code.c @@ -0,0 +1,530 @@ +/**********************************************************************
+ *************************** G_Code.c *******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+#include "G_Code.h"
+#include "Stepper.h"
+#include "Extruder.h"
+
+#define FastFeed 960
+#define SlowFeed 240
+
+//Internal
+void G_Code_G0(void);
+void G_Code_G1(void);
+void G_Code_G2(void);
+void G_Code_G3(void);
+void G_Code_G4(void);
+//void G_Code_G10(void);
+void G_Code_G20(void);
+void G_Code_G21(void);
+void G_Code_G28(void); //Go Home.
+void G_Code_G90(void); //Absolute Positioning
+void G_Code_G91(void); //Incremental Positioning
+void G_Code_G92(void); //Set current as home
+
+void M_Code_M101(void); //M101 Turn extruder on.
+void M_Code_M103(void); //M103 Turn extruder off.
+//see header for M104 external
+//void M_Code_M104(void); //M104 S145.0 Set temperature to 145.0 C.
+void M_Code_M106(void); //M106 Turn fan on.
+void M_Code_M107(void); //Turn fan off.
+void M_Code_M108(void); //M108 S210 Set extruder speed to 21.0RPM
+//*********************
+//BFB codes
+void M_Code_M220(void); //Turn off AUX
+void M_Code_M221(void); //Turn on AUX
+void M_Code_M222(void); //M122 S500 Set speed of fast XY moves
+void M_Code_M223(void); //M123 S500 Set speed of fast Z moves
+ //500fast - 2000slow
+void M_Code_M224(void); //Enable extruder motor during fast move
+void M_Code_M225(void); //Disable extruder motor during fast move
+void M_Code_M226(void); //Issue a Pause command from G-Code
+void M_Code_M227(void); //Enable Extruder Reverse S=Reverse time in ms P=Prime time in ms
+void M_Code_M228(void); //Disable Extruder Reverse
+//*********************
+
+//Glaobal variables
+int F_Code = 0; //copy of code numbers that are being worked on
+int G_Code;
+int M_Code;
+int Inch_mm = 0;
+
+
+
+float GX; //copy of Axis data being worked on
+float GY;
+float GZ;
+float GI_Val;
+float GJ_Val;
+float GP_Val;
+float GS_Val;
+
+int GX_On = 0;
+int GY_On = 0;
+int GZ_On = 0;
+int GI_On = 0;
+int GJ_On = 0;
+
+//TODO here:
+//Code in some data validation checks
+//const char LetterCode[18]={"DFGHIJKLMNPQRSTXYZ"};
+//const int GNumberCode[39]={
+//0,1,2,3,4,10,17,18,19,20,
+//21,40,41,42,43,49,53,45,55,56,
+//57,58,59,80,81,82,83,84,85,86,
+//87,88,89,90,91,92,93,94,98
+//};
+//const int MNumberCode[]={
+//0,1,2,3,4,5,6,7,8,9,26,27,30,48,49,60};
+/********************************************************/
+void G_CodeRun(char GC_L, int iGC_N, char GC_1L, float fGC_1, char GC_2L,
+ float fGC_2, char GC_3L, float fGC_3, char GC_4L,float fGC_4)
+{
+extern char EOF_Flag;
+//Going into this function we do not know where the axis data
+//appears in the line. The following sorts axis Data and stores
+//in local globals. It then issues function calls to run the code
+
+ while (SBR!= SBW)
+ {
+ if ((EOF_Flag == 1)&&(SBW+1 == SBR))
+ {//at end of file and one entry in buffer, let it go
+ SBW = SBR;
+ }
+ };
+
+ GX = 0;
+ if (GC_1L==0x58) GX=fGC_1; //checks for char "X"
+ if (GC_2L==0x58) GX=fGC_2;
+ if (GC_3L==0x58) GX=fGC_3;
+ if (GC_4L==0x58) GX=fGC_4;
+ if ((GC_1L==0x58)|(GC_2L==0x58)|(GC_3L==0x58)|(GC_4L==0x58))
+ {
+ GX_On=1;
+ }
+ else
+ GX_On=0;
+
+ GY = 0;
+ if (GC_1L==0x59) GY=fGC_1; //checks for char "Y"
+ if (GC_2L==0x59) GY=fGC_2;
+ if (GC_3L==0x59) GY=fGC_3;
+ if (GC_4L==0x59) GY=fGC_4;
+ if ((GC_1L==0x59)|(GC_2L==0x59)|(GC_3L==0x59)|(GC_4L==0x59))
+ {
+ GY_On=1;
+ }
+ else
+ GY_On=0;
+
+ GZ = 0;
+ if (GC_1L==0x5A) GZ=fGC_1; //checks for char "Z"
+ if (GC_2L==0x5A) GZ=fGC_2;
+ if (GC_3L==0x5A) GZ=fGC_3;
+ if (GC_4L==0x5A) GZ=fGC_4;
+ if ((GC_1L==0x5A)|(GC_2L==0x5A)|(GC_3L==0x5A)|(GC_4L==0x5A))
+ {
+ GZ_On = 1;
+ }
+ else
+ GZ_On = 0;
+
+ GI_Val = 0;
+ if (GC_1L==0x49) GI_Val=fGC_1; //checks for char "I"
+ if (GC_2L==0x49) GI_Val=fGC_2;
+ if (GC_3L==0x49) GI_Val=fGC_3;
+ if (GC_4L==0x49) GI_Val=fGC_4;
+ if ((GC_1L==0x49)|(GC_2L==0x49)|(GC_3L==0x49)|(GC_4L==0x49))
+ {
+ GI_On = 1;
+ }
+ else
+ GI_On = 0;
+ GJ_Val = 0;
+ if (GC_1L==0x4A) GJ_Val=fGC_1; //checks for char "J"
+ if (GC_2L==0x4A) GJ_Val=fGC_2;
+ if (GC_3L==0x4A) GJ_Val=fGC_3;
+ if (GC_4L==0x4A) GJ_Val=fGC_4;
+ if ((GC_1L==0x4A)|(GC_2L==0x4A)|(GC_3L==0x4A)|(GC_4L==0x4A))
+ {
+ GJ_On = 1;
+ }
+ else
+ GJ_On = 0;
+
+ //F_Code = 0;//F_Code persistes until its reset by Gcode
+ if (GC_1L==0x46) F_Code=fGC_1; //checks for char "F"
+ if (GC_2L==0x46) F_Code=fGC_2;
+ if (GC_3L==0x46) F_Code=fGC_3;
+ if (GC_4L==0x46) F_Code=fGC_4;
+
+ GP_Val = 0;
+ if (GC_1L==0x50) GP_Val=fGC_1; //checks for char "P"
+ if (GC_2L==0x50) GP_Val=fGC_2;
+ if (GC_3L==0x50) GP_Val=fGC_3;
+ if (GC_4L==0x50) GP_Val=fGC_4;
+
+ GS_Val = 0;
+ if (GC_1L==0x53) GS_Val=fGC_1; //checks for char "S"
+ if (GC_2L==0x53) GS_Val=fGC_2;
+ if (GC_3L==0x53) GS_Val=fGC_3;
+ if (GC_4L==0x53) GS_Val=fGC_4;
+/*
+ while (SBR!= SBW)
+ {
+ if ((EOF_Flag == 1)&&(SBW+1 == SBR))
+ {//at end of file and one entry in buffer, let it go
+ SBW = SBR;
+ }
+ };
+*/
+ switch(GC_L)
+ {
+ case 0x47: //G Code
+ G_Code=iGC_N;
+ if (G_Code==0) G_Code_G0();
+ if (G_Code==1) G_Code_G1();
+ if (G_Code==2) G_Code_G2();
+ if (G_Code==3) G_Code_G3();
+ if (G_Code==4) G_Code_G4();
+ //if (G_Code==10) G_Code_G10();//?
+ if (G_Code==20) G_Code_G20(); //Set Units Inches
+ if (G_Code==21) G_Code_G21(); //Set Units Metric
+ if (G_Code==28) G_Code_G28(); //Go Home.
+ if (G_Code==90) G_Code_G90(); //Absolute Positioning
+ if (G_Code==91) G_Code_G91(); //Incremental Positioning
+ if (G_Code==92) G_Code_G92(); //Set current as home
+ break;
+ case 0x4D: //M Code
+ M_Code = iGC_N; //Sets M code
+ G_Code=0, F_Code=0;
+
+ if (M_Code == 101) M_Code_M101(); //M101 Turn extruder on.
+ if (M_Code == 103) M_Code_M103(); //M103 Turn extruder off.
+ if (M_Code == 104) M_Code_M104(); //M104 Set temperature to S???
+ if (M_Code == 106) M_Code_M106(); //M106 Turn fan on
+ if (M_Code == 107) M_Code_M107(); //M107 Turn fan off.
+ if (M_Code == 108) M_Code_M108(); //M108 S210 Set extruder speed to 21.0RPM
+ if (M_Code == 220) M_Code_M220(); //Turn AUX off
+ if (M_Code == 221) M_Code_M221(); //Turn AUX On
+ if (M_Code == 222) M_Code_M222(); //Set speed of fast XY moves
+ if (M_Code == 223) M_Code_M223(); //Set speed of fast Z moves
+ if (M_Code == 224) M_Code_M224(); //Enable extruder motor during fast move
+ if (M_Code == 225) M_Code_M225(); //Disable extruder motor during fast move
+ if (M_Code == 226) M_Code_M226(); //Issue a Pause command from G-Code
+ if (M_Code == 227) M_Code_M227(); //Enable reverse extruder during extruder off
+ if (M_Code == 228) M_Code_M228(); //Disable reverse extruder during extruder off
+ break;
+ }//Switch
+}
+/********************************************************/
+// G Code Functions to be added here.
+// Please use same format and annotate.
+/********************************************************/
+void G_Code_G0(void)
+{ //G00 rapid positioning
+//Tool coordinates are set as Globals.
+// Sets variables and calls functions to execute the code
+
+ //if (M_Code == 0) M_Code = StopSpindle; //if not set, make default
+ if (F_Code == 0) F_Code = FastFeed; //if not set, make default
+ //Load values into Stepper control
+ Stepper_LoadNewValues(F_Code, M_Code);
+ if (ToolType == 1) ExtruderStatus = 1; //Switch to set normal feed rate
+ Stepper_CalcSteps(Inch_mm,0x00);
+ Stepper_Run3DLine();
+}
+/********************************************************/
+void G_Code_G1(void)
+{ //G01 linear interpolation
+//Tool coordinates are set as Globals.
+//Sets variables and calls functions to execute the code
+extern int ManualChange;
+
+ //if (M_Code == 0) M_Code = StopSpindle; //if not set, make default
+ if (F_Code == 0) F_Code = SlowFeed; //if not set, make slowest feed rate
+ if (FeedRate_ManualChange)
+ {
+ F_Code += ManualChange;
+ }
+
+ //Load values into Stepper control
+ Stepper_LoadNewValues(F_Code, M_Code);
+ if (ToolType == 1) ExtruderStatus = 1; //Switch to set normal feed rate
+ Stepper_CalcSteps(Inch_mm,0x00);
+ Stepper_Run3DLine(); //Linear machining
+}
+/********************************************************/
+void G_Code_G2(void)
+{ //G02 circular interpolation (clockwise)
+//The tool is already at the start position for this instruction
+// X,Y coordinates following G2 are the end position of the tool.
+// I X-axis offset to centre
+// J Y-axis offset to centre
+
+ //if (M_Code == 0) M_Code = StopSpindle; //if not set, make default
+ if (F_Code == 0) F_Code = SlowFeed; //if not set, make slowest feed rate
+ Stepper_LoadNewValues(F_Code, M_Code);
+ Stepper_CalcSteps(Inch_mm, 0x01);
+// Stepper_RunArcLine(2); //run as G2
+}
+/********************************************************/
+void G_Code_G3(void)
+{ //G03 circular interpolation (c-clockwise)
+//The tool is already at the start position for this instruction
+// X,Y coordinates following G3 are the end position of the tool.
+// I X-axis offset to centre
+// J Y-axis offset to centre
+
+ //if (M_Code == 0) M_Code = StopSpindle; //if not set, make default
+ if (F_Code == 0) F_Code = SlowFeed; //if not set, make slowest feed rate
+ Stepper_LoadNewValues(F_Code, M_Code);
+ Stepper_CalcSteps(Inch_mm,0x01);
+// Stepper_RunArcLine(3); //run as G3
+}
+/********************************************************/
+void G_Code_G4(void)
+{ //G4 Dwell time
+//P Dwell time in seconds
+int delay = 0;
+//TODO HERE: Time needs sorting out, values here are incorrect
+//ms function not scaled correctly and is running at 1/5th speed
+ if (GP_Val != 0)
+ {
+ delay = (int)GP_Val*200;
+ delay_ms(delay);
+ }
+}
+/********************************************************/
+//void G_Code_G10(void)
+//{ //G10 Coordinate system origin
+
+//}
+/********************************************************/
+void G_Code_G20(void)
+{ //G20 Set Units Inches
+ Inch_mm = 20;
+}
+/********************************************************/
+void G_Code_G21(void)
+{ //G21 Set Units Metric mm (This is the machine default setting)
+ Inch_mm = 21;
+}
+/********************************************************/
+void G_Code_G28(void)
+{//Go Home.TODO HERE
+// if(!RapMan_Home())
+// {
+ //home error
+// }
+}
+/********************************************************/
+void G_Code_G90(void)
+{//Absolute Positioning relative to machine home
+ ResetOrigin();
+}
+/********************************************************/
+void G_Code_G91(void)
+{//Incremental Positioning, X5 moves +5 units regardless of where the tool is
+ //TODO HERE
+}
+/********************************************************/
+void G_Code_G92(void)
+{//Set new origin point
+ //G92 X10 Y20 Z0 sets the new origin to these coordinates
+ G_Code_G0(); //Go to new origin
+ OriginOffset(); //Set new origin
+}
+
+/********************************************************/
+// M Code Functions to be added here.
+// Please use same format and annotate.
+/********************************************************/
+void M_Code_M101(void)
+{ //"101" Extruder on
+ //Switch to flag any special functions required when Extruder is ON
+ if (ToolType == 2) //2 is EXTRUDER
+ {
+ ExtruderStatus = 1;
+ }
+}
+/********************************************************/
+void M_Code_M103(void)
+{ //"103" Extruder off
+ //Switch to flag any special functions required when Extruder is OFF
+ if (ToolType == 2) //2 is EXTRUDER
+ {
+ ExtruderStatus = 0;
+ }
+}
+/********************************************************/
+void M_Code_M104(void)
+{ //M104 S145.0 Set temperature to 145.0 C
+extern X_Rest_mm;
+extern Y_Rest_mm;
+extern Z_Rest_mm;
+
+ if (ToolType == 2) //2 is EXTRUDER
+ {
+ OLED_ClearLine(4);
+ OLED_ClearLine(5);
+ OLED_ClearLine(6);
+ OLED_FastText57(5, 0, "TEMPERATURE CHANGE",0);
+
+ temperature_OK = FALSE; //assume temperature is false to start with
+ Change_M104 = 1; //Flag to indicate the temperature change is generated
+ //by this G-Code instruction
+
+ if (GS_Val != 0)SetTemperature = GS_Val;
+ GoToRest();
+ Extruder_Status(On); //enables the temperature interrupt
+ do
+ {
+ OLED_UpdateThermistorReading();
+ OLED_UpdateSetTemperature();
+ OLED_UpdateSetRPM();
+ }
+ while(temperature_OK == FALSE && SetTemperature != 0);
+ Change_M104 = 0; //Reset flag for normal temperature control
+ //Delayms(1000);
+ OLED_ClearLine(5); //Clear msg
+ }
+}
+/********************************************************/
+void M_Code_M106(void)
+{ // M106 Turn fan on.
+extern char EnableFanControl; //Set if Fan is to be active
+ EnableFanControl=TRUE;
+ FAN = On;
+}
+/********************************************************/
+void M_Code_M107(void)
+{ // M107 Turn fan off.
+extern char EnableFanControl; //Set if Fan is to be active
+ EnableFanControl=FALSE;
+ FAN = OFF;
+}
+/********************************************************/
+void M_Code_M108(void)
+{ //M108 S210 Set extruder speed to 21.0 RPM
+ if (ToolType == 2)
+ {
+ if (GS_Val > 0) RPM_Setting = GS_Val;
+ Control_Stepper_Motor();
+ RPM_Change = 1;//flag to indicate change in value
+ }
+}
+/********************************************************/
+void M_Code_M220(void)
+{ //M220 Aux OFF
+ AUX = OFF;
+}
+/********************************************************/
+void M_Code_M221(void)
+{ //M220 Aux ON
+ AUX = On;
+}
+/********************************************************/
+void M_Code_M222(void)
+{ //M222 S500 Set fast XY move to 500 Fast
+ if (ToolType == 2)
+ {
+ if (GS_Val > 0) G_CodeRapidXYMove = GS_Val;
+ }
+}
+/********************************************************/
+void M_Code_M223(void)
+{ //M223 S500 Set fast Z move to 500 Fast
+ if (ToolType == 2)
+ {
+ if (GS_Val > 0) G_CodeRapidZMove = GS_Val;
+ }
+}
+/********************************************************/
+void M_Code_M224(void) //Enable extruder motor during fast move
+{
+ FastMoveMotorEnable = TRUE;
+}
+/********************************************************/
+void M_Code_M225(void) //Disable extruder motor during fast move
+{//Defailt setting
+ FastMoveMotorEnable = FALSE;
+}
+/********************************************************/
+void M_Code_M226(void) //Issue a Pause command from G-Code
+{
+extern float Save3_X, Save3_Y; //defined in Stepper.c
+extern char EOF_Flag; //defined in RapMan.h
+
+ while (SBR!= SBW) //let buffer empty then continue
+ {
+ if ((EOF_Flag == 1)&&(SBW+1 == SBR))
+ {//at end of file and one entry in buffer, let it go
+ SBW = SBR;
+ }
+ };
+ Pause_Print();
+ while(!Manual_Select); //wait for key up
+ RapMan_MoveTo(Save3_X,Save3_Y,0,0); //move back to print.
+}
+/********************************************************/
+void M_Code_M227(void)
+{ //M228 Enable Extruder reverse during extruder off
+ //P=reverse time in ms S=prime time in ms P would
+ //normally be longer than S
+
+ if (ToolType == 2)
+ {
+ Ex_Reverse = TRUE;
+ if (GS_Val > 0) Reverse_Steps = ceil(GS_Val);
+ if (GP_Val > 0) Prime_Steps = ceil(GP_Val);
+ }
+}
+/********************************************************/
+void M_Code_M228(void)
+{ //M228 Disable Extruder reverse during extruder off
+ if (ToolType == 2)
+ {
+ Ex_Reverse = FALSE;
+ }
+}
+/********************************************************/
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/G_Code.d b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/G_Code.d new file mode 100644 index 00000000..845132cd --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/G_Code.d @@ -0,0 +1,7 @@ +G_Code.o: G_Code.c G_Code.h Stepper.h Extruder.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h \
+ Enviroment.h
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/G_Code.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/G_Code.h new file mode 100644 index 00000000..ce99f44e --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/G_Code.h @@ -0,0 +1,194 @@ +/**********************************************************************
+ *************************** G_Code.h *******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+//List of G-Codes.
+//See G_Code.c for list of the ones implemented
+/*
+RS274NGC G-CODE PROGRAMMING
+
+G and M Code Modal Groups
+group 1 = {G0, G1, G2, G3, G80, G81, G82, G83, G84, G85, G86, G87, G88, G89} - motion
+group 2 = {G17, G18, G19} - plane selection
+group 3 = {G90, G91} - distance mode
+group 5 = {G93, G94} - spindle speed mode
+group 6 = {G20, G21} - units
+group 7 = {G40, G41, G42} - cutter diameter compensation
+group 8 = {G43, G49} - tool length offset
+group 10 = {G98, G99} - return mode in canned cycles
+group12 = {G54, G55, G56, G57, G58, G59, G59.1, G59.2, G59.3} coordinate system selection
+
+group 2 = {M26, M27} - axis clamping
+group 4 = {M0, M1, M2, M30, M60} - stopping
+group 6 = {M6} - tool change
+group 7 = {M3, M4, M5} - spindle turning
+group 8 = {M7, M8, M9} - coolant
+group 9 = {M48, M49} - feed and speed override bypass
+
+
+Words acceptable to the interpreter
+No D Tool radius compensation number
+Yes F Feedrate
+Yes G General function see list below
+No H Tool length offset
+No I X-axis offset for arcs
+No J Y-axis offset for arcs
+No K Z-axis offset for arcs
+No L Number of repetitions in canned cycles
+Yes M Miscellanious function
+No N Line Number
+Yes P Dwell time in G4 and canned cycles
+No Q Feed increment in G83 canned cycle
+ Key used with G10
+No R arc radius
+Yes S canned cycle plane
+No T Tool selection
+Yes X X-axis of machine
+Yes Y Y-axis of machine
+Yes Z Z-axis of machine
+*/
+
+/*
+Yes G00 rapid positioning
+Yes G01 linear interpolation
+No G02 circular/helical interpolation (clockwise)
+No G03 circular/helical interpolation (c-clockwise)
+Yes G04 dwell
+Yes G10 coordinate system origin setting
+No G17 xy plane selection
+No G18 xz plane selection
+No G19 yz plane selection
+Yes G20 inch system selection
+Yes G21 millimeter system selection
+No G40 cancel cutter diameter compensation
+No G41 start cutter diameter compensation left
+No G42 start cutter diameter compensation right
+No G43 tool length offset (plus)
+No G49 cancel tool length offset
+No G53 motion in machine coordinate system
+G54 use preset work coordinate system 1
+G55 use preset work coordinate system 2
+G56 use preset work coordinate system 3
+G57 use preset work coordinate system 4
+G58 use preset work coordinate system 5
+G59 use preset work coordinate system 6
+G59.1 use preset work coordinate system 7
+G59.2 use preset work coordinate system 8
+G59.3 use preset work coordinate system 9
+G80 cancel motion mode (includes canned)
+G81 drilling canned cycle
+G82 drilling with dwell canned cycle
+G83 chip-breaking drilling canned cycle
+G84 right hand tapping canned cycle
+G85 boring, no dwell, feed out canned cycle
+G86 boring, spindle stop, rapid out canned
+G87 back boring canned cycle
+G88 boring, spindle stop, manual out canned
+G89 boring, dwell, feed out canned cycle
+Yes G90 absolute distance mode
+Yes G91 incremental distance mode
+Yes G92 offset coordinate systems
+G92.2 cancel offset coordinate systems
+G93 inverse time feed mode
+G94 feed per minute mode
+G98 initial level return in canned cycles
+
+M0 program stop
+M1 optional program stop
+M2 program end
+M3 turn spindle clockwise
+M4 turn spindle counterclockwise
+M5 stop spindle turning
+M6 tool change
+M7 mist coolant on
+M8 flood coolant on
+M9 mist and flood coolant off
+M26 enable automatic b-axis clamping
+M27 disable automatic b-axis clamping
+M30 program end, pallet shuttle, and reset
+M48 enable speed and feed overrides
+M49 disable speed and feed overrides
+M60 pallet shuttle and program stop
+
+RepRap special codes
+GCode generated by March 29,2007 Skeinforge
+M100 P210 Set extruder speed to 210.0
+M103 Turn extruder off.
+M101 Turn extruder on.
+M104 P145.0 Set temperature to 145.0 C.
+M105 Custom code for temperature reading.
+M106 Turn fan on.
+M107 Turn fan off.
+M108 P0.8 Set extrusion diameter to 0.8 mm.
+**********************
+BFB codes
+**********************
+M220 Turn off AUX
+M221 Turn on AUX
+M222 Set speed of fast XY moves
+M223 Set speed of fast Z moves
+M224
+M225
+**********************
+*/
+
+extern char ToolType; //1 Pen, 2 Extruder1 , 3 Extruder2, 4 Not Defined, 5 Router, 0 No Tool fitted
+extern long SetTemperature; //value for extruder
+extern int temperature_OK;
+extern int RPM_Setting; //value for extruder
+extern int SBR, SBW; //Buffer pointers
+
+extern int Ex_Reverse;
+extern int Reverse_Steps;
+extern int Prime_Steps;
+
+char Change_M104;
+char FeedRate_ManualChange;
+char FastMoveMotorEnable;//Flag to switch motor on/off during fast move
+
+
+/*****************************************************************************/
+/* External Functions */
+/*****************************************************************************/
+extern void G_CodeRun(char GC_L, int iGC_N, char GC_1L, float fGC_1, char GC_2L,
+ float fGC_2, char GC_3L, float fGC_3, char GC_4L,float fGC_4);
+
+extern void M_Code_M104(void); //enable external tremperature control
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/HIDBootLoader.exe b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/HIDBootLoader.exe Binary files differnew file mode 100644 index 00000000..0a6c7178 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/HIDBootLoader.exe diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/HardwareProfile.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/HardwareProfile.h new file mode 100644 index 00000000..1170c6fd --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/HardwareProfile.h @@ -0,0 +1,60 @@ +
+#ifndef _HARDWAREPROFILE_H_
+#define _HARDWAREPROFILE_H_
+
+
+#define RUN_AT_80MHZ
+#define GetSystemClock() (80000000ul)
+#define GetPeripheralClock() (GetSystemClock()/2)
+#define GetInstructionClock() (GetSystemClock())
+#define MILLISECONDS_PER_TICK 10
+#define TIMER_PRESCALER TIMER_PRESCALER_8
+#define TIMER_PERIOD 37500
+
+
+#define USE_SD_INTERFACE_WITH_SPI
+
+//I guess here we need SPI2 as PIC32MX440H only has SPI2
+#define MDD_USE_SPI_2
+
+#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON)
+#define SPI_START_CFG_2 (SPI_ENABLE)
+#define SPI_FREQUENCY (20000000)
+
+// SD-SPI
+#define SD_CS PORTBbits.RB1 // Chip Select Output bit
+#define SD_CD PORTEbits.RE4 // Card Detect Input bit
+#define SD_WE PORTEbits.RE3 // Write Protect Check Input bit
+
+#define SD_CS_TRIS TRISBbits.TRISB1 // Chip Select TRIS bit
+#define SD_CD_TRIS TRISEbits.TRISE4 // Card Detect TRIS bit
+#define SD_WE_TRIS TRISEbits.TRISE3 // Write Protect Check TRIS bit
+
+
+#define SPICON1 SPI2CON
+#define SPISTAT SPI2STAT
+#define SPIBUF SPI2BUF
+#define SPISTAT_RBF SPI2STATbits.SPIRBF
+#define SPICON1bits SPI2CONbits
+#define SPISTATbits SPI2STATbits
+#define SPIENABLE SPI2CONbits.ON
+#define SPIBRG SPI2BRG
+
+// Tris pins for SCK/SDI/SDO lines
+#define SPICLOCK TRISGbits.TRISG6 // The TRIS bit for the SCK pin
+#define SPIIN TRISGbits.TRISG7 // The TRIS bit for the SDI pin
+#define SPIOUT TRISGbits.TRISG8 // The TRIS bit for the SDO pin
+#define putcSPI putcSPI2
+#define getcSPI getcSPI2
+#define OpenSPI(config1, config2) OpenSPI2(config1, config2)
+
+/* added from newer BfB code: */
+
+// Description: The main SPI 2 control register
+#define SPICON2 SPI2CON
+#define SPICON2bits SPI2CONbits
+
+
+/* end of added code */
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/OLED.c b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/OLED.c new file mode 100644 index 00000000..71c88b35 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/OLED.c @@ -0,0 +1,654 @@ +/**********************************************************************
+ *************************** OLED.c *********************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+#include <p32xxxx.h>
+#include "OLED.h"
+#include "Screens.h"
+#include "stepper.h"
+#include "extruder.h"
+
+//SPI2 pins for OLED
+#define OLED_CS PORTBbits.RB5 //Analog pin
+#define DC PORTEbits.RE6 //Digital
+#define RES PORTEbits.RE7 //Digital
+
+
+extern int RPM_Setting;
+extern long SetTemperature;
+extern float temperature1;
+extern int HeaterON;
+extern int LineNumber;
+extern char SaveFileName[12];
+
+float ExtrusionRate;
+/**************************************************/
+/* Forward Declarations */
+/**************************************************/
+int WriteSPI(int i);
+void write_command(unsigned char command);
+void write_data(unsigned char data);
+void Fill_RAM(unsigned char Data);
+
+/***********************************************************/
+void OLED_Printing_Screen(void) //Static Lables only
+{
+extern int ToolType;
+
+ OLED_FastText57(0, 0, OLED_Header_VerNo,0);
+ OLED_FastText57(1, 28, SaveFileName,0);
+ OLED_FastText57(2, 0, "G-Code Line:",0); //Display G Code line number
+ OLED_FastText57(3, 0, "Head Speed:",0); //Display Feed Rate
+ if (ToolType==2)OLED_FastText57(4, 0, "Ext. Rate:",0); //Display Extrusion Rate
+
+}//OLED_Printing_Screen
+
+/***********************************************************/
+void OLED_UpdatePrintScreen(void) //Info updated every G_Code line
+{
+char AsciiString[10];
+float data1;
+extern int S_F_Code;
+extern int ToolType;
+
+ sprintf(AsciiString, "%1u", LineNumber); //Converts number to text
+ OLED_FastText57(2, 90, AsciiString,0); //Write the new number
+
+ if (S_F_Code > 0 )
+ {
+ data1 = (float)S_F_Code/60;
+ sprintf(AsciiString, "%5.1fmm/s", data1); //Converts number to text
+ OLED_FastText57(3, 75, AsciiString,0); //Write the new number
+ ExtrusionRate = (float)RPM_Setting*0.056; //factor is 0.0563814
+ sprintf(AsciiString, "%5.1fmm/s", ExtrusionRate); //Converts number to text
+ OLED_FastText57(4, 75, AsciiString,0); //Write the new number
+ }
+ else
+ OLED_FastText57(3, 75, "Not Set",0);
+
+
+ ShowBufferFillState(); //ln6 Show how full the look ahead buffer is
+ ShowPrintProgress(); //ln5 Progress through the file
+
+ if (ToolType==2)//Extruder
+ {
+ OLED_UpdateThermistorReading();
+ if (Temp_Change)OLED_UpdateSetTemperature(); //Update only if changed
+ if (RPM_Change)OLED_UpdateSetRPM(); //Update only if changed
+ }
+
+}//OLED_UpdatePrintScreen
+
+/***********************************************************/
+void OLED_Extruder_Screen(void)
+{
+ OLED_FastText57(0, 0, OLED_Header_VerNo,0);
+ OLED_FastText57(1, 0, "Extruder Control",0);
+
+ if(HEATER)OLED_FastText57(5, 0, "Heater On ",0);
+ else OLED_FastText57(5, 0, "Heater Off",0);
+
+ if (temperature1 < 100)
+ {
+ OLED_FastText57(3, 0, " <100C Motor OFF",0);
+ }
+ else
+ OLED_ClearLine(3);
+
+ OLED_UpdateSetTemperature();
+ OLED_UpdateThermistorReading();
+ OLED_UpdateSetRPM();
+
+}//OLED_Extruder_Screen
+
+/***********************************************************/
+void OLED_UpdateThermistorReading(void)
+{
+char AsciiString[10];
+int data1;
+
+ if (temperature1 == 999||temperature1 == -1){
+ OLED_ClearLine(7);
+ if (temperature1 == 999)OLED_FastText57(7, 10,"TEMPERATURE ERROR",0);
+ if (temperature1 == -1)OLED_FastText57(7, 10, "THERMISTOR ERROR",0);
+ return;
+ }
+
+ data1=(int)temperature1; //Display actual temperature
+ sprintf(AsciiString, "%3uC", (int)data1); //Converts number to text
+ OLED_FastText57(7, 45, AsciiString,0); //Write the new number
+ if(HEATER)OLED_FastText57(7, 35, "*",0); //Heater indication
+ else OLED_FastText57(7, 35, " ",0);
+
+}// OLED_UpdateThermistorReading
+
+/***********************************************************/
+void OLED_UpdateSetRPM(void)
+{
+char AsciiString[10];
+int data1;
+extern char RPM_Change; //set if RPM has changed
+
+ data1=RPM_Setting/10; //Display RPM Setting
+ sprintf(AsciiString, "%3uRPM", (int)data1); //Converts number to text
+ OLED_FastText57(7, 85, AsciiString,0); //Write the new number
+
+ OLED_FastText57(4, 0, "Ext. Rate:",0); //Display Extrusion Rate
+ ExtrusionRate= (float)RPM_Setting*0.04643;
+ sprintf(AsciiString, "%5.1fmm/s", ExtrusionRate); //Converts number to text
+ OLED_FastText57(4, 75, AsciiString,0); //Write the new number
+
+ RPM_Change = 0;
+
+}//OLED_UpdateSetRPM
+
+/***********************************************************/
+void OLED_UpdateSetTemperature(void)
+{
+char AsciiString[10];
+extern char Temp_Change; //set if Temperature has changed
+
+ if (SetTemperature <0)SetTemperature = 0;
+ sprintf(AsciiString, "%3uC", (int)SetTemperature); //Converts number to text
+ OLED_FastText57(7, 0, AsciiString,0); //Write the new number
+ Temp_Change = 0;
+
+}//OLED_UpdateSetTemperature
+
+/***********************************************************/
+void OLED_Fill_RAM(unsigned char Data)
+{
+unsigned char i,j;
+
+ for(i=0;i<8;i++){
+ write_command(0xB0+i);
+ write_command(0x00);
+ write_command(0x10);
+ for(j=0;j<128;j++)write_data(Data);
+ }
+}//OLED_Fill_RAM
+
+/***********************************************************/
+void OLED_ProgressBar(unsigned char Line, int Value)
+{
+unsigned char j;
+
+ write_command(0xB0+Line);
+ write_command(0x00);
+ write_command(0x10);
+
+ for(j=0;j<Value;j++)
+ {
+ write_data(0x18);
+ }
+ for(j=Value;j<128;j++)
+ {
+ write_data(0x00);
+ }
+}//OLEDProgressBar
+
+/***********************************************************/
+void OLED_ClearLine(unsigned char Line) {
+
+unsigned char j;
+
+ write_command(0xB0+Line);
+ write_command(0x00);
+ write_command(0x10);
+
+ for(j=0;j<128;j++)
+ {
+ write_data(0x00);
+ }
+}//OLEDClearLine
+
+/***********************************************************/
+void OLED_BitMapFill_RAM(unsigned char screen)
+{
+unsigned char i,j;
+const unsigned char *screen_ptr;
+int offset;
+
+switch(screen)
+ {
+ case DSP_RAPMAN_LOGO:
+ {
+ screen_ptr = RAPMAN_LOGO;
+ break;
+ }
+ case DSP_BfB_LOGO:
+ {
+ screen_ptr = BfB_LOGO;
+ break;
+ }
+ case DSP_EXTRUDER_SCREEN:
+ {
+ screen_ptr = EXTRUDER_SCREEN;
+ break;
+ }
+ }
+
+ for(i=0;i<8;i++) //loop through 8 pages
+ {
+ offset = i*128;
+ write_command(0xB0+i); //set start of page
+ write_command(0x00);
+ write_command(0x10);
+
+ for(j=0;j<128;j++) //loop through each col on page
+ {
+ write_data(screen_ptr[offset+j]);
+ }
+ }
+}//BitMapFill_RAM
+
+/***********************************************************/
+void OLED_FastText57(int txtpage, int txtcol, unsigned char* textptr, unsigned char colour)
+{
+
+unsigned char add, lAddr, hAddr;
+int i, j, k; // Loop counters
+unsigned char pixelData[5]; // Stores character data
+
+ k = 0;
+ add = txtcol;
+ lAddr = 0x0F & add; // Low address
+ hAddr = 0x10 | (add >> 4); // High address
+
+ write_command(0xB0 + txtpage); //set start page
+ write_command(lAddr);
+ write_command(hAddr);
+
+ for(i=0; textptr[i] != '\0'; ++i) // Loop through the passed string
+ {
+ if(textptr[i] < 'S') // Checks if the letter is in the first text array
+ memcpy(pixelData, TEXT[textptr[i]-' '], 5);
+ else
+ if(textptr[i] <= '~') // Check if the letter is in the second array
+ {
+ if (textptr[i]>91)//if ascii char is > [ then realign
+ {
+ memcpy(pixelData, TEXT2[textptr[i]- 84], 5); //1 more than S to realign the lower case letters
+ }
+ else
+ memcpy(pixelData, TEXT2[textptr[i]-'S'], 5);
+ }
+ else
+ memcpy(pixelData, TEXT[0], 5); // Default to space
+
+ for(j=0; j<5; ++j) // Loop through character byte data
+ {
+ if (k <128){
+ if (colour == 0)
+ {
+ write_data(pixelData[j]);
+ }
+ else
+ {
+ write_data(~pixelData[j]);
+ }
+ ++k;
+ }
+ else{ //text wrap if required
+ write_command(0xB0 + txtpage+1);
+ write_data(pixelData[j]);
+ }
+ }
+ write_data(0x00);
+ ++k;
+ }
+}//OLED_FastText
+
+/***********************************************************/
+void OLED_Start_Menu(void)
+{
+ OLED_Fill_RAM(BLANK_SCREEN); //clear screen
+ OLED_FastText57(0, 10, OLED_Header_VerNo,0);
+ OLED_FastText57(1, 20, OLED_Menu_Title0,0);
+ OLED_FastText57(2, 20, OLED_Menu_0,0);
+ OLED_FastText57(3, 20, OLED_Menu_1,0);
+ OLED_FastText57(4, 20, OLED_Menu_2,0);
+ OLED_FastText57(5, 20, OLED_Menu_3,0);
+
+}//OLED_Start_Menu
+
+/***********************************************************/
+void OLED_Manual_Screen(void)
+{
+ OLED_Fill_RAM(BLANK_SCREEN); //clear screen
+ OLED_FastText57(0, 10, OLED_Header_VerNo,0);
+ OLED_FastText57(1, 0, "MANUAL", 0);
+ OLED_FastText57(4, 0, "X_Step:",0);
+ OLED_FastText57(5, 0, "Y_Step:",0);
+ OLED_FastText57(6, 0, "Z_Step:",0);
+
+}//OLED_Manual_Screen
+
+/***********************************************************/
+void OLED_Auto_Screen(void)
+{
+ OLED_Fill_RAM(BLANK_SCREEN); //clear screen
+ OLED_FastText57(0, 10, OLED_Header_VerNo,0);
+ OLED_FastText57(1, 20,OLED_Auto_Load,0);
+
+}//OLED_Auto_Screen
+
+/***********************************************************/
+ void OLED_ToolSetup_Screen(void)
+{
+ OLED_ClearLine(1);
+ OLED_FastText57(1, 20,OLED_ToolSet,0);
+
+}//OLED_ToolSetup_Screen
+
+/***********************************************************/
+void OLED_Home_Screen(void)
+{
+ OLED_Fill_RAM(BLANK_SCREEN); //clear screen
+ OLED_FastText57(1, 0,OLED_Home,0);
+
+}//OLED_Home_Screen
+
+/***********************************************************/
+void OLED_RapManMove_Screen(float X_pos, float Y_pos, float Z_pos, char DoZmove)
+{
+char AsciiString[10];
+
+ OLED_Fill_RAM(BLANK_SCREEN); //clear screen
+ OLED_FastText57(1, 0, "MOVE TO:",0);
+ sprintf(AsciiString, "X=%6.2f",X_pos); // Converts number to text
+ OLED_FastText57(3, 0, AsciiString,0); // Write the new number
+ sprintf(AsciiString, "Y=%6.2f",Y_pos); // Converts number to text
+ OLED_FastText57(4, 0, AsciiString,0); // Write the new number
+ if (DoZmove)
+ {
+ sprintf(AsciiString, "Z=%6.2f",Z_pos); // Converts number to text
+ OLED_FastText57(5, 0, AsciiString,0); // Write the new number
+ }
+ else OLED_FastText57(5, 0, "NO Z MOVE",0);
+
+}//OLED_Home_Screen
+
+/***********************************************************/
+void OLED_FileEnd_Screen(void)
+{
+ OLED_Fill_RAM(BLANK_SCREEN);
+ OLED_FastText57(0, 0, "Prog.End",0);
+ OLED_FastText57(2, 0, "Return to Menu",0);
+ OLED_FastText57(4, 0, "<<< Press Esc.",0);
+
+}//OLED_FileEnd_Screen
+
+/***********************************************************/
+void OLED_SetCursor(int txtpage, int txtcol, unsigned char colour)
+{
+ //Cursor
+ switch (txtpage)
+ {
+ case 0: //txtpage 0 reserved for headings
+ {
+ // OLED_FastText57(0, txtcol, OLED_Cursor, colour);
+ // OLED_FastText57(1, txtcol, " ",0);
+ // OLED_FastText57(2, txtcol, " ",0);
+ // OLED_FastText57(3, txtcol, " ",0);
+ // OLED_FastText57(4, txtcol, " ",0);
+ // OLED_FastText57(5, txtcol, " ",0);
+ // OLED_FastText57(6, txtcol, " ",0);
+ // OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 1:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 2:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 3:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 4:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 5:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 6:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, OLED_Cursor, colour);
+ OLED_FastText57(7, txtcol, " ",0);
+ break;
+ }
+ case 7:
+ {
+ // OLED_FastText57(0, txtcol, " ",0);
+ OLED_FastText57(1, txtcol, " ",0);
+ OLED_FastText57(2, txtcol, " ",0);
+ OLED_FastText57(3, txtcol, " ",0);
+ OLED_FastText57(4, txtcol, " ",0);
+ OLED_FastText57(5, txtcol, " ",0);
+ OLED_FastText57(6, txtcol, " ",0);
+ OLED_FastText57(7, txtcol, OLED_Cursor, colour);
+ break;
+ }
+ }
+
+}//OLED_SetCursor
+
+/***********************************************************/
+//SCREEN DRIVER
+//Col address 0 to 127 is made up of a high and low nibble screen address
+//col 1 is lower nibble 1, higher nibble 0
+//col 127 is lower nibble = f, higher nibble 7
+/***********************************************************/
+int WriteSPI(int i) {
+
+ SPI2BUF = i;
+ while( !SPI2STATbits.SPIRBF);
+ return SPI2BUF;
+
+}//WriteSPI
+
+/***********************************************************/
+void write_command(unsigned char command){
+
+ DC = 0; //When Low send Display command
+ OLED_CS = 0; //OLED chip select
+ WriteSPI(command);
+ OLED_CS = 1;
+ DC =1;
+
+}//write_command
+
+/***********************************************************/
+void write_data(unsigned char data) {
+
+ DC =1;
+ OLED_CS = 0;
+ WriteSPI(data);
+ OLED_CS = 1;
+ DC =1;
+
+}//write_data
+
+/***********************************************************/
+void Fill_RAM(unsigned char Data)
+{
+unsigned char i,j;
+
+ for(i=0;i<8;i++)
+ {
+ write_command(0xB0+i);
+ write_command(0x00);
+ write_command(0x10);
+
+ for(j=0;j<128;j++)
+ {
+ write_data(Data);
+ }
+ }
+}//Fill_RAM
+
+/***********************************************************/
+int OLED_Init(void)
+{
+unsigned int i = 0;
+
+ SPI2CON = 0x8120; //Enable & configure SPI port
+
+ DC = 0; //When Low D7-D0 is Display command
+ OLED_CS = 0; //Communication with chip only when Low
+ RES = 0; //Reset when pin is low
+ for(i=0;i<2000;i++); //10ms delay
+ RES = 1; //Reset complete
+ for(i=0;i<2000;i++); //10ms delay
+ OLED_CS = 1;
+
+//LCD commands
+//panel_128x64
+ write_command(0xd5); //SetDisplayClock(0x10)
+ write_command(0x10);
+
+ write_command(0xd3); //SetDisplayOffset(0)
+ write_command(0);
+
+ write_command(0xa8); //SetMultiplex(63)
+ write_command(63);
+
+ write_command(0xd8); //SetAreaColor(0)
+ write_command(0);
+
+ write_command(0x40); //SetStartLine(0)
+
+ write_command(0xa0); //SetSegmentReMap(0)
+
+ write_command(0xc8); //SetCOMScan(8)
+
+ write_command(0xda); //SetCOMHWConfig(0x12)
+ write_command(0x12);
+
+ write_command(0x81); //SetContrast(0xff)
+ write_command(0xf0);
+
+ write_command(0xa4); //SetEntireDisplay(0)
+
+ write_command(0xd9); //Setprecharge(0xf2)
+ write_command(0xf2);
+
+ write_command(0xa6); //SetNormal_Inverse_Display(0xa6 or 0xa7)
+
+ write_command(0x26); //horizontal scroll setup
+ write_command(0x01);
+ write_command(0x00);
+ write_command(0x00);
+ write_command(0x01);
+
+ Fill_RAM(0x00); //Clear screen
+ for(i=0;i<2000;i++);
+ write_command(0xAF); //display on
+
+}//InitOLED
+
+/***********************************************************/
+void OLED_Start_Msg(void)
+{
+ // Start Message
+ OLED_Fill_RAM(BLANK_SCREEN); //Clear screen
+ OLED_BitMapFill_RAM(DSP_BfB_LOGO);
+ Delayms(200);
+ OLED_Fill_RAM(BLANK_SCREEN); //Clear screen
+ OLED_BitMapFill_RAM(DSP_RAPMAN_LOGO);
+ Delayms(200);
+
+}//OLED_Start_Msg
+
+/***********************************************************/
+
+
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/OLED.d b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/OLED.d new file mode 100644 index 00000000..4038c91a --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/OLED.d @@ -0,0 +1,8 @@ +OLED.o: OLED.c \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h OLED.h \
+ Screens.h stepper.h extruder.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h \
+ Enviroment.h
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/OLED.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/OLED.h new file mode 100644 index 00000000..f45056e0 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/OLED.h @@ -0,0 +1,79 @@ +/**********************************************************************
+ *************************** OLED.h *********************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+#define OLED_Header_VerNo "RapMan v1.0.8-Erik" //UPDATE VERSION NUMBER HERE (1.0.8)
+#define OLED_Auto_Load "AUTO: Loading.."
+#define OLED_ToolSet "TOOL SETUP"
+#define OLED_Home "HOMING PLEASE WAIT"
+#define OLED_Menu_Title0 "MENU"
+#define OLED_Menu_0 "RUN FILE"
+#define OLED_Menu_1 "MANUAL MOVE"
+#define OLED_Menu_2 "TOOL SETUP"
+#define OLED_Menu_3 "HOME TOOL HEAD"
+#define OLED_Cursor ">"
+
+#define BLANK_SCREEN 0x00
+#define DSP_RAPMAN_LOGO 0
+#define DSP_BfB_LOGO 1
+#define DSP_EXTRUDER_SCREEN 2
+
+extern void OLED_Fill_RAM(unsigned char Data);
+extern void OLED_BitMapFill_RAM(unsigned char screen);
+extern void OLED_ProgressBar(unsigned char Line, int Value);
+extern void OLED_ClearLine(unsigned char Line);
+extern void OLED_FastText57(int txtpage, int txtcol, unsigned char* textptr, unsigned char colour);
+extern void OLED_Start_Menu(void);
+extern void OLED_Auto_Screen(void);
+extern void OLED_Manual_Screen(void);
+extern void OLED_ToolSetup_Screen(void);
+extern void OLED_Home_Screen(void);
+extern void OLED_RapManMove_Screen(float X_pos, float Y_pos, float Z_pos, char DoZmove);
+extern void OLED_FileEnd_Screen(void);
+extern void OLED_SetCursor(int txtpage, int txtcol, unsigned char colour);
+extern void OLED_Printing_Screen(void);
+extern int OLED_Init(void);
+extern void OLED_Start_Msg(void);
+
+extern void OLED_Extruder_Screen(void);
+extern void OLED_UpdatePrintScreen(void);
+extern void OLED_UpdateThermistorReading(void);
+extern void OLED_UpdateSetTemperature(void);
+extern void OLED_UpdateSetRPM(void);
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan.c b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan.c new file mode 100644 index 00000000..362047a4 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan.c @@ -0,0 +1,1015 @@ +/**********************************************************************
+ *************************** RapMan.c *******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+
+/***********************************************************
+************************Rap_Man*****************************
+************************************************************
+*
+*Notes for G_Code syntax for input file.
+*The Progamme has been developed using:
+*ACE DXF Converter
+*Eagle PCB
+*Enrique's Skienforge STL to G_Code
+*
+*Performance with other converters or G_Code from other
+*sources should be checked before running.
+*
+*Basic File requirement.
+* 1) Max line length is 50 characters long.
+* 2) Alows Blank lines
+* 3) One instruction per line
+* 4) G0 feed fast feed
+* G1 - If no F code is found the default slowest feed
+* rate will be used
+* 5) M Codes should be added to the file as required.
+* This should be the only instruction on the line.
+* If more than one Mcode is required, each should be
+* placed on a new line
+* 6) The default filenames on the SD-Card are *.bfb or *.gco
+* 7) Any line started with a open bracket is ignored
+* as comment
+* 8) GCode format is with a space between axis data.
+
+************************************************************
+************************Rap_Man*****************************
+************************************************************/
+
+#pragma config POSCMOD=XT, FNOSC=PRIPLL, FSOSCEN = OFF
+#pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_20, FPLLODIV=DIV_1 //(8MHz/2)=4 *20=80 /1=80MHz
+#pragma config FWDTEN=OFF, CP=OFF, BWP=OFF
+
+#include <p32xxxx.h>
+#include "RapMan.h"
+#include "OLED.h"
+#include <int.h>
+
+#define NUNBER_OF_MENU_ITEMS 3 //equals number of menu items -1
+#define PRINT_OBJECT 0
+#define MANUAL_MOVE_HEAD 1
+#define TOOL_CONTROL 2
+#define SEND_TO_HOME 3
+//Tool Head Defines
+#define NO_TOOL 0
+#define PEN 1
+#define EXTRUDER 2
+#define EXTRUDER2 3
+#define NOT_DEFINED 4
+#define ROUTER 5
+
+int Start_Menu(void);
+int GetMenuSelection(void);
+void Print_Gcode_File(void);
+void Pause_Print(void);
+void ErrorCondition(int ErrNo);
+
+char CharBuffer[1];
+unsigned char LineBuffer[50];
+
+int ADC_readingToolID = 0;
+int SampleCountToolID = 0;
+long AveSamplesToolID = 0;
+int Operation_Mode = 0;
+
+char ToolType = 0; //1 Pen, 2 Extruder1 , 3 Extruder2
+ //4 Not Defined, 5 Router, 0 No Tool fitted
+
+int SetTemp = 0; //value for extruder
+int SetRPM = 0; //value for extruder
+
+int GoToRestSpeed = 0;
+
+//File type switch
+int FileType = INVALID_FILE; //init to invalid file type
+
+/***********************************************************
+ * Function: int main(void)
+ *
+ * PreCondition: None
+ *
+ * Input: None
+ *
+ * Output: None
+ *
+ * Overview:
+ *
+ * Note: Modules:Stepper, Manual, G_Code External
+ * functions are prefixed with the module name, internal functions
+ * have no prefix. This does not apply to third party modules like
+ * SPI, FSIO and LCD.
+ *
+ ************************************************************/
+//*************************************************************
+/*
+int main( void )
+{
+// Setup(); //Configure the IO etc
+TRISDbits.TRISD11 = OUTPUT_PIN; //FET
+// OLED_Start_Msg();
+ while(TRUE) //restart prog
+ {
+PORTDbits.RD11 = On;
+Delayms(200);
+PORTDbits.RD11 = OFF;
+
+ }
+} // main
+*/
+int main( void )
+{
+int Operation_Mode;
+
+ Setup(); //Configure the IO etc
+ OLED_Start_Msg();
+ while(TRUE) //restart prog
+ {
+ while(!XPlusRight_Btn); //wait for key up
+ Operation_Mode = Start_Menu();
+ switch(Operation_Mode)
+ {
+ case PRINT_OBJECT: Print_Gcode_File(); break;
+ case MANUAL_MOVE_HEAD: Manual_Mode(SHOW_POSITIONS); break; //Maunal control of the tool head
+ case TOOL_CONTROL: if (ToolType==2)Manual_Extruder(); break; //Manual control of the extruder
+ case SEND_TO_HOME: RapMan_Home(); break; //Move to home and reset position
+ }
+ }
+} // main
+
+//*************************************************************
+void Print_Gcode_File(void)
+{
+extern float Save3_X, Save3_Y;
+
+ PauseFlag == 0; //Initialise flag
+ FeedRate_ManualChange = 0;
+
+ if(GetTool_ID() != NO_TOOL){
+ OLED_Fill_RAM(BLANK_SCREEN); //Clear screen
+ OLED_FastText57(0, 10, OLED_Header_VerNo,0);
+ while(!XPlusRight_Btn); //wait for key up
+
+ while (!MDD_SDSPI_MediaDetect())
+ {//Handle no card error
+ OLED_FastText57(2, 0, "Insert SD-Card or",0);
+ OLED_FastText57(4, 0, "<<ESC TO RESUME",0);
+ Delayms(250);
+ if(!Manual_Select) return;
+ }
+ OLED_ClearLine(2); //ensure error msg lines are clear
+ OLED_ClearLine(4);
+
+ OpenReadSDFile(); //sets the file name to open
+ while(!XPlusRight_Btn); //wait for key up
+ if(!Manual_Select) return;
+ if ((FileType == BFB_FILE) || (FileType == GCO_FILE))
+ {
+ if(!RapMan_Home()) return; //Test home completed normally.
+ Operation_Mode = AUTO_MODE;
+ OLED_Fill_RAM(BLANK_SCREEN); //Clear screen
+ OLED_Printing_Screen(); //Static lables
+
+ Stepper_InitIO ();
+ Axis_Stepper_Motors(On);
+
+ do { //MAIN LOOP
+
+ if(!Manual_Select){
+ Pause_Print();
+ while(!Manual_Select);
+ while (SBR!= SBW)
+ {
+ if ((EOF_Flag == 1)&&(SBW+1 == SBR))
+ {//at end of file and one entry in buffer, let it go
+ SBW = SBR;
+ }
+ };
+ RapMan_MoveTo(Save3_X,Save3_Y,0,0);
+ }
+ OLED_UpdatePrintScreen();
+
+ do{ReadData();}while (LineBuffer[1] == 40); //skip comment lines
+ GetCodes(); //Words from the line put into globals
+ //Control now passed to the G_Code module
+ G_CodeRun(Inst_Code_Letter, iInst_Code, Dim_1_Letter, fDim_1, Dim_2_Letter, fDim_2, Dim_3_Letter, fDim_3, Dim_4_Letter,fDim_4);
+
+ FlushBuffer(); //Flush buffer ready for new data
+ if (ToolType==2)
+ {
+ Control_Stepper_Motor();//if the current action is not a fast move
+ }
+
+ if (!ZPlus_up_Btn){FeedRate_ManualChange = 1; ManualChange += 10;}
+ if (!ZMinus_down_Btn){FeedRate_ManualChange = 1; ManualChange -= 10;}
+
+ }//MAIN LOOP
+ while ((EOF_Flag !=1)|(ItemsRead != 0)); //loop to end of file
+ }
+ else{
+ OLED_Fill_RAM(BLANK_SCREEN);
+ OLED_FastText57(2, 0, "Invalid File Type",0);
+ OLED_FastText57(3, 0, "Please only use",0);
+ OLED_FastText57(4, 0, "*.BFB or *.GCO Files",0);
+ while(Manual_Select);
+ }
+ Extruder_Status(OFF); //Disable Stepper
+ Axis_Stepper_Motors(OFF);
+ pointer = FilePointer; //set the file pointer
+ FSfclose (pointer); //close the file
+
+ Setup();
+ OLED_FileEnd_Screen();
+
+ while(Manual_Select);
+ }
+}//Print_Gcode_File
+
+/************************************************************/
+void Pause_Print(void)
+{
+ while(!Manual_Select); //wait for key up
+ OLED_ClearLine(4);
+ OLED_ClearLine(5);
+ OLED_ClearLine(6);
+ OLED_FastText57(5, 0, "PAUSE",0);
+
+ PauseFlag = 1; //to stop heater going on
+ RapMan_MoveTo(X_Rest_mm,Y_Rest_mm,Z_Rest_mm,0); //Move to rest, No Z move
+
+ OLED_FastText57(5, 0, "<<ESC TO RESUME",0);
+
+ do
+ {
+ OLED_UpdateSetTemperature();
+ OLED_UpdateThermistorReading(); //monitor temperature during pause
+ Delayms(500);
+ }
+ while(Manual_Select); //Release from pause
+ PauseFlag = 0;
+ OLED_ClearLine(5); //Clear pause msg
+ Extruder_Status(On); //Heater and motor back on
+ M_Code_M104(); //Hold for temp change
+
+}// Pause_Print
+
+/************************************************************/
+void ErrorCondition(int ErrNo)
+{
+ //Puts the machine in a safe condition if an error is detected
+ OLED_ClearLine(2);
+ OLED_ClearLine(3);
+ OLED_ClearLine(4);
+ OLED_ClearLine(5);
+ OLED_ClearLine(6);
+ OLED_ClearLine(7);
+
+ switch(ErrNo)
+ { //Definitions in RapMan.h
+ case TEST:
+ OLED_FastText57(3, 0, "Error TEST",0);
+ if (ToolType == 2 )//Extruder
+ {
+ Extruder_Status(OFF);
+ OLED_FastText57(4, 0, "Extruder OFF",0);
+ }
+ RapMan_MoveTo(X_Rest_mm,Y_Rest_mm,Z_Rest_mm,0); //Move to rest, No Z move
+ EOF_Flag = 1;
+ break;
+
+ case SEEK_POINT_ERR: //File error
+ OLED_FastText57(3, 0, "File Error :seek pt",0);
+ if (ToolType == 2 )//Extruder
+ {
+ Extruder_Status(OFF);
+ OLED_FastText57(4, 0, "Extruder OFF",0);
+ }
+ RapMan_MoveTo(X_Rest_mm,Y_Rest_mm,Z_Rest_mm,0); //Move to rest, No Z move
+ EOF_Flag = 1;
+ break;
+
+ default: //unknown error
+ OLED_FastText57(3, 0, "Unknown Error",0);
+ break;
+ }//switch
+
+ do
+ {
+ OLED_FastText57(5, 0, " <ESC TO RESUME",0);
+ Delayms(150);
+ OLED_FastText57(5, 0, "<",0);
+ Delayms(150);
+ }
+ while(Manual_Select);
+ while(!Manual_Select);//wait for keyup
+
+}//ErrorCondition
+
+/************************************************************/
+void Setup(void)
+{
+
+ //OLED setup I/O
+ AD1PCFGbits.PCFG5 = 1; //AtoD port cfg AN5/B5 digital for OLED chip select
+ TRISBbits.TRISB5 = OUTPUT_PIN; //OLED chip Select
+
+ TRISEbits.TRISE6 = OUTPUT_PIN; //Display DC
+ TRISEbits.TRISE7 = OUTPUT_PIN; //Display RES
+ //SPI IN OUT and CLK are in Hardware Profile
+
+ //THERMISTOR
+ AD1PCFGbits.PCFG11 = 0; //AtoD port cfg AN11/B11 Analog
+ TRISBbits.TRISB11 = INPUT_PIN; //Thermistor Input
+
+ //Tool ID
+ AD1PCFGbits.PCFG12 = 0; //AtoD port cfg AN12/B12 Analog
+ TRISBbits.TRISB12 = INPUT_PIN; //Tool ID input
+
+ //Fillament switch
+ AD1PCFGbits.PCFG0 = 1; //AtoD port cfg AN0 make digital for switch
+ TRISBbits.TRISB0 = INPUT_PIN; //Fillament switch Input
+
+ //Push Buttons on Analog pins
+ AD1PCFGbits.PCFG2 = 1; //AtoD port cfg AN2 make digital for btn
+ AD1PCFGbits.PCFG3 = 1; //AtoD port cfg AN3 make digital for btn
+ AD1PCFGbits.PCFG4 = 1; //AtoD port cfg AN4 make digital for btn
+ AD1PCFGbits.PCFG15 = 1; //AtoD port cfg AN15 make digital for btn
+
+ //TRIS for buttons
+ TRISBbits.TRISB2 = INPUT_PIN; //Button
+ TRISBbits.TRISB3 = INPUT_PIN; //Button
+ TRISBbits.TRISB4 = INPUT_PIN; //Button
+ TRISBbits.TRISB15 = INPUT_PIN; //Button
+
+ TRISFbits.TRISF4 = INPUT_PIN; //Button
+ TRISFbits.TRISF5 = INPUT_PIN; //Button
+ TRISGbits.TRISG9 = INPUT_PIN; //Button
+
+ //Weak Pullups - Buttons
+ CNPUEbits.CNPUE4=1; //B2
+ CNPUEbits.CNPUE5=1; //B3
+ CNPUEbits.CNPUE6=1; //B4
+ CNPUEbits.CNPUE12=1; //B15
+ CNPUEbits.CNPUE17=1; //F4
+ CNPUEbits.CNPUE18=1; //F5
+ CNPUEbits.CNPUE11=1; //G9
+
+ //Limit switches
+ TRISDbits.TRISD4 = INPUT_PIN; //switch
+ TRISCbits.TRISC13 = INPUT_PIN; //switch
+ TRISCbits.TRISC14 = INPUT_PIN; //switch
+
+ //Weak Pullups - Switch
+ CNPUEbits.CNPUE13 = 1; //X limit D4
+ CNPUEbits.CNPUE1 = 1; //Y limit C13
+ CNPUEbits.CNPUE0 = 1; //Z Limit C14
+
+ //Setup AtoD
+ AD1CON1 = 0x0000; //Auto conversion sequence start after sampling
+ AD1CON2 = 0; //use MUXA, AVss and AVdd are used for VRef+/-
+ AD1CON3 = 0x1F02; //Tad =
+ AD1CSSL = 0; //no scanning required
+ //Once set up, turn on A to D
+ AD1CON1bits.ADON = 1; //turn on ADC
+
+ //Drive all FET's to off state on Start up
+ TRISFbits.TRISF0 = OUTPUT_PIN; //FET
+ HEATER = OFF;
+ TRISEbits.TRISE5 = OUTPUT_PIN; //FET
+ FAN = OFF;
+ TRISDbits.TRISD11 = OUTPUT_PIN; //FET
+ AUX = OFF;
+
+ PMCON = 0x00; //disable PMP
+ Stepper_InitIO();
+ InitExtruder();
+ OLED_Init();
+ INTEnableSystemMultiVectoredInt();
+
+ FeedRate_ManualChange = 0;
+ ManualChange = 0 ;//No manual change applied to gcode feed rates
+
+ X_Rest_mm = X_REST_ABS_MM;
+ Y_Rest_mm = Y_REST_ABS_MM;
+ Z_Rest_mm = Z_REST_ABS_MM;
+
+}//Setup
+
+/************************************************************/
+ char GetTool_ID(void) {
+//Any tool attached has an Identification resistor. The voltage drop accross it
+//is the tool ID.
+//Descriotion Resistor A/D
+//976 Ohm resistor for PEN 1K (90)
+//4.7K Ohm resistor for Extruder 4K7 (320)
+//9.9K Ohm resistor for Extruder2 10K (500)
+//22K Ohm resistor for Not Defined 22K (700)
+//47K to 100K Ohm resistor for Router 47K to 100K (840 to 920)
+//1M Ohm resistor for No Tool 1M to open circuit(1010 to 1024)
+
+int Reading = 0;
+char type = 0;
+
+ while(Reading == 0){
+ ADC_readingToolID = Read_Analog(TOOL_ID);
+ AveSamplesToolID += ADC_readingToolID;
+ ++SampleCountToolID;
+ if (SampleCountToolID > 3){
+ Reading = AveSamplesToolID / 4;
+ SampleCountToolID = 0;
+ AveSamplesToolID = 0;
+ }
+ }
+
+ if((Reading >= 0)&&(Reading <= 200)) {type = 1; OLED_FastText57(1, 20, "Tool: Pen",0);} //Pen
+ if((Reading >= 200)&&(Reading <= 400)) {type = 2; OLED_FastText57(1, 20, "Tool: Extruder",0);} //Extruder - Primary material
+ if((Reading >= 400)&&(Reading <= 600)) {type = 3; OLED_FastText57(1, 20, "Tool: Extruder2",0);} //Extruder2 - Fill
+ if((Reading >= 600)&&(Reading <= 800)) {type = 4; OLED_FastText57(1, 20, "Tool: Not Defined",0);} //Not Defined
+ if((Reading >= 800)&&(Reading <= 1000)) {type = 5; OLED_FastText57(1, 20, "Tool: Router",0);} //Router
+ if(Reading >= 1020) {type = 0; OLED_FastText57(1, 20, "Tool: None",0);} //No tool fitted
+ return type;
+
+}//GetTool_ID
+
+/************************************************************/
+int Start_Menu(void)
+{
+int mode = 0;
+
+ ToolType = GetTool_ID();
+ OLED_Start_Menu(); //Draw the menu screen
+ mode = GetMenuSelection();
+ return mode;
+
+}//Start_Menu
+
+/************************************************************/
+int GetMenuSelection(void)
+{
+int mode = 0;
+ while(XPlusRight_Btn == NOT_PRESSED){ //Run this until a menu item is selected
+ delay_ms(5);
+
+ if (YMinusBot_Btn == PRESSED){ //Move cursor up & down the menu choices
+ delay_ms(5);
+ while(YMinusBot_Btn == PRESSED); //wait for key up
+ mode += 1;
+ if (mode >NUNBER_OF_MENU_ITEMS) mode = 0;
+ }
+ if (YPlusTop_Btn == PRESSED){ //key down
+ delay_ms(5);
+ while(YPlusTop_Btn == PRESSED); //wait for key up
+ mode -= 1;
+ if (mode <0) mode = NUNBER_OF_MENU_ITEMS;
+ }
+ switch(mode){ //Move the Cursor on the screen
+ case 0: {OLED_SetCursor(2, 0, 1); break;} //Print Object
+ case 1: {OLED_SetCursor(3, 0, 1); break;} //Manual
+ case 2: {OLED_SetCursor(4, 0, 1); break;} //Tool Setup
+ case 3: {OLED_SetCursor(5, 0, 1); break;} //Home
+ }
+ }//while
+
+ return mode;
+
+}//GetMenuSelection
+
+/************************************************************/
+void RapMan_MoveTo(float X_pos, float Y_pos, float Z_pos, char DoZmove) {
+
+ //Move to coordinate
+ //With Z move (1)
+ //Without Z move (0)
+
+ mT4IntEnable(TRUE);
+ GoToRestSpeed = 1; //flag to switch in the speed
+
+ Inst_Code_Letter = 0x47; //"G" //G0 to coordeinate
+ iInst_Code = 0;
+ Dim_1_Letter = 0x58; //"X"
+ fDim_1 = X_pos;
+ Dim_2_Letter = 0x59; //"Y"
+ fDim_2 = Y_pos;
+
+ if (DoZmove)
+ {
+ Dim_3_Letter = 0x5A; //"Z" Z move
+ fDim_3 = Z_pos;
+ }
+ else
+ {
+ Dim_3_Letter = 0; //"Z" No Z move
+ fDim_3 = 0;
+ }
+
+ Dim_4_Letter = 0x46; //"F"
+ fDim_4 = 0; //note, this value is set to the defaut fast.
+
+ G_CodeRun(Inst_Code_Letter, iInst_Code, Dim_1_Letter, fDim_1, Dim_2_Letter,
+ fDim_2, Dim_3_Letter, fDim_3, Dim_4_Letter,fDim_4);
+
+ Inst_Code_Letter = 0; //"G"
+ iInst_Code = 0;
+ Dim_1_Letter = 0; //"X"
+ fDim_1 = 0;
+ Dim_2_Letter = 0; //"Y"
+ fDim_2 = 0;
+ Dim_3_Letter = 0; //"Z"
+ fDim_3 = 0;
+ Dim_4_Letter = 0; //"F"
+ fDim_4 = 0;
+
+ GoToRestSpeed = 0;
+ Delayms(250);
+
+}//RapMan_MoveTo
+
+/************************************************************/
+void OpenReadSDFile(void)
+{
+ if (EOF_Flag == 1)
+ { //It may be after restart
+ EOF_Flag = 0;
+ FilePointer = 0;
+ ItemsRead = 0;
+ PosInFile = 0;
+ LineNumber = 0;
+ }
+ //Initialize the SD/MMC library
+ while (!FSInit());
+ GetFileToOpen(); //select file to open and save as global
+ if(!Manual_Select) return;
+ //File type returned is *.*
+ FileType = Get_file_Type(); //file types defined as
+ // 1 = .TXT
+ // 2 = .BIN
+ // 0 = Invalid type
+
+ pointer = FSfopen ( SaveFileName, "r");
+
+ FilePointer = pointer; //save file pointer as global
+
+ if ((pointer == NULL)|(pointer == 0x0000))
+ {
+ do
+ {//Handle file error
+ OLED_FastText57(2, 0, "File Error ",0);
+ OLED_FastText57(3, 40,"File Not Found",0);
+ OLED_FastText57(4, 0, "<<ESC TO RESUME",0);
+ Delayms(250);
+ if(!Manual_Select) return;
+ }
+ while(1);
+
+ } //file open error
+
+ OLED_FastText57(2, 90, "Open",0);
+
+}//OpenReadSDFile
+
+/************************************************************/
+void GetFileToOpen(void)
+{
+//Searches the SD card root directory for :
+//Flies with File attribute set to archive
+SearchRec rec;
+unsigned char attributes = ATTR_ARCHIVE;
+char name[] = "*.*";
+int result = 1;
+static int FileNumber = 0;
+static int FilesOnCard = 0;
+int i =0;
+int SkipFindLast = 0;
+char AsciiString[10];
+
+do
+{
+ //Test SD card for valid file type
+ result = FindFirst(name,attributes,&rec); //Test for first file
+ if (result == 0)
+ {//if success
+ //FILE COUNT
+ FilesOnCard = 1;
+ do
+ {//Loop to end of file table
+ result = FindNext(&rec);//check to see if there is another file
+ if (result == 0)FilesOnCard++;
+ }
+ while(result==0);
+ if (!SkipFindLast)//find last file only first time through
+ {
+ //FIND LAST FILE
+ result = FindFirst(name,attributes,&rec); //reset to first
+ FileNumber = 1;
+ for (i=1;i<FilesOnCard;i++) //loop to last file
+ {
+ result = FindNext(&rec);
+ }
+ FileNumber = FilesOnCard; //set file number to last
+ OLED_FastText57(2, 0,rec.filename,0); //show last file
+ }
+ }
+ if (result!=0)
+ {//failure
+ FilesOnCard=0;
+ FileNumber = 0;
+
+ do
+ { //Crash with "File Error"
+ OLED_FastText57(2, 0,"Find First Error",0);
+ OLED_FastText57(3, 0,"No files on card",0);
+ OLED_FastText57(5, 0, "Switch OFF/ON",0);
+ OLED_FastText57(6, 0, "to Reset",0);
+ Delayms(250);
+ if(!Manual_Select) return;
+ }
+ while(1);
+ }
+
+ do
+ {
+ if (result == 0)
+ {
+ if (YMinusBot_Btn == 0)
+ { //FIND NEXT FILE
+ while (YMinusBot_Btn==0); //wait for key up
+ Delayms(30);
+
+ result = FindNext(&rec);//check to see if there is another file
+ if (result==0)
+ {//success
+ if (FileNumber > FilesOnCard)FileNumber = FilesOnCard;
+ else
+ FileNumber++;
+ }
+ else
+ {
+ result = FindFirst(name,attributes,&rec);
+ FileNumber = 1;
+ }
+ OLED_ClearLine(2);
+ OLED_FastText57(2, 0,rec.filename,0);
+ }
+
+ if (YPlusTop_Btn == 0)
+ { //FIND PREVIOUS FILE
+ while (YPlusTop_Btn==0); //wait for key up
+ Delayms(30);
+ do
+ { //Loop to end of file table
+ result = FindNext(&rec);//check to see if there is another file
+ }
+ while(result==0);
+ result = FindFirst(name,attributes,&rec);
+ --FileNumber;
+ if (FileNumber == 0)//If less than first file show last file
+ {
+ FileNumber = FilesOnCard;
+ SkipFindLast = 1;
+ }
+ for (i=1;i<FileNumber;i++)
+ {
+ result = FindNext(&rec);
+ }
+ OLED_ClearLine(2);
+ OLED_FastText57(2, 0,rec.filename,0);
+ }
+
+ OLED_FastText57(6, 0,"File",0);
+ sprintf(AsciiString, "%3u", FileNumber); //Converts number to text
+ OLED_FastText57(6, 25,AsciiString,0); //Write the new number
+ OLED_FastText57(6, 65,"of",0);
+ sprintf(AsciiString, "%3u", FilesOnCard); //Converts number to text
+ OLED_FastText57(6, 90,AsciiString,0); //Write the new number
+ }
+ if(!Manual_Select) return;
+ }
+ while ((XPlusRight_Btn == 1)&(result==0));
+}
+while (XPlusRight_Btn == 1);
+
+//save the selected filename & filesize to global
+strcpy(SaveFileName, rec.filename);
+SaveFileSize = rec.filesize;
+
+}//GetFileToOpen
+
+/************************************************************/
+int Get_file_Type(void)
+{
+BYTE type;
+BYTE f;
+//file name is 12 chars long 0-11 4 back from end is index 8
+//this is the first possible site of the "."
+//then work back in the filename array to find the "."
+ for(f=8; f; --f)
+ { //Flush line Buffer
+ if (SaveFileName[f] == 46)
+ { //look for full stop before file extension
+ if ((SaveFileName[f+1] == 'G') &
+ (SaveFileName[f+2] == 'C') &
+ (SaveFileName[f+3] == 'O'))
+ {
+ return type = GCO_FILE; //Set for TXT file type
+ }
+
+ if ((SaveFileName[f+1] == 'B') &
+ (SaveFileName[f+2] == 'F') &
+ (SaveFileName[f+3] == 'B'))
+ {
+ return type = BFB_FILE; //Set for BIN file type
+ }
+ return type = 0; //Invalid file type
+ }
+ }
+}//Get_file_Type
+
+/************************************************************/
+void ReadData(void)
+{
+unsigned char AsciiString[9];
+int CharNum=1;
+int n=0;
+
+ //Read into buffer, Num.of bytes, Num.of Items, File handle
+ //FSfread returns the number of items read from the file
+ EOF_Flag=0;
+ pointer = FilePointer; //set the file pointer
+ LineNumber += 1; //move on line counter
+ LineBuffer[0] = 0x3E; //fill with >
+
+ //pointer is the file, pos in file, zero offset from file beginning
+ if(FSfseek(pointer,PosInFile,0) !=0)
+ { //set file pos to last char & test
+ ErrorCondition(SEEK_POINT_ERR);
+ EOF_Flag = 1;
+ }
+
+ if (EOF_Flag == 0)
+ {
+ do
+ {
+ ItemsRead = FSfread (CharBuffer, 1, 1, pointer);
+ LineBuffer[CharNum]=CharBuffer[0];
+ CharNum++;
+
+ if (CharBuffer[0]== 40)
+ { //Open bracket - GCode comment line
+ //loop through and discard the data.
+ do
+ {
+ ItemsRead = FSfread (CharBuffer, 1, 1, pointer);
+ if (FSfeof (pointer))break;
+ }
+ while (CharBuffer[0] !=10); //read line checking for line feed
+ }
+
+ if (FSfeof (pointer)){// Check if this is the end of the file
+ FSfclose (pointer);
+ EOF_Flag = 1;
+ break;
+ }
+ }
+ while (CharBuffer[0] !=10); //while charbuffer is not line feed char.
+ PosInFile=FSftell(pointer); //where we are after reading line
+ }//end if
+
+}//ReadData
+
+/********************************************************/
+void GetCodes(void)
+{
+//Runs through the contents of the LineBuffer and splits out the G-code words.
+//Note code looks for a space between words, edit if Gcode
+//runs words together
+//Code words saved as globals for use in other functions
+
+int CharPosLine = 1; //Caracter position in line
+int CharPosWord = 0;
+
+ Word_Count = 1; //to get first word
+ do
+ { //Search for first character
+ if (LineBuffer[1] == 13)
+ {//13Carriage return so exit loop
+ break;
+ }
+
+ if (Word_Count == 1)
+ {
+ if (CharPosWord == 0)
+ { //its the letter code
+ Inst_Code_Letter = LineBuffer[CharPosLine];
+ CharPosLine++;
+ }
+ Inst_Code[CharPosWord] = LineBuffer[CharPosLine];
+ CharPosWord++;
+ if (LineBuffer[CharPosLine] == 32)
+ {
+ CharPosLine++; //skip space
+ CharPosWord=0; //reset
+ Word_Count=2; //spot space at end of word
+ }
+ }
+ if (Word_Count == 2)
+ {
+ if (CharPosWord == 0)
+ { //its the letter code
+ Dim_1_Letter = LineBuffer[CharPosLine];
+ CharPosLine++;
+ }
+ Dim_1[CharPosWord] = LineBuffer[CharPosLine];
+ CharPosWord++;
+ if (LineBuffer[CharPosLine] == 32)
+ {
+ CharPosLine++; //skip space
+ CharPosWord=0; //reset
+ Word_Count=3; //spot space at end of word
+ }
+ }
+ if (Word_Count == 3)
+ {
+ if (CharPosWord == 0)
+ { //its the letter code
+ Dim_2_Letter=LineBuffer[CharPosLine];
+ CharPosLine++;
+ }
+ Dim_2[CharPosWord]=LineBuffer[CharPosLine];
+ CharPosWord++;
+ if (LineBuffer[CharPosLine] == 32)
+ {
+ CharPosLine++; //skip space
+ CharPosWord = 0; //reset
+ Word_Count = 4; //spot space at end of word
+ }
+ }
+ if (Word_Count == 4)
+ {
+ if (CharPosWord == 0)
+ { //its the letter code
+ Dim_3_Letter = LineBuffer[CharPosLine];
+ CharPosLine++;
+ }
+ Dim_3[CharPosWord] = LineBuffer[CharPosLine];
+ CharPosWord++;
+ if (LineBuffer[CharPosLine] == 32)
+ {
+ CharPosLine++; //skip space
+ CharPosWord=0; //reset
+ Word_Count=5; //spot space at end of word
+ }
+ }
+ if (Word_Count == 5)
+ {
+ if (CharPosWord == 0)
+ { //its the letter code
+ Dim_4_Letter = LineBuffer[CharPosLine];
+ CharPosLine++;
+ }
+ Dim_4[CharPosWord] = LineBuffer[CharPosLine];
+ CharPosWord++;
+ }
+
+ if (LineBuffer[CharPosLine]== 10) break; //to deal with space at end of line
+ CharPosLine++;
+ }
+ while (LineBuffer[CharPosLine]!= 13); //spot end of line
+
+ //recast the data from ascii to integer or float
+ iInst_Code = atoi(Inst_Code);
+ fDim_1=atof(Dim_1);
+ fDim_2=atof(Dim_2);
+ fDim_3=atof(Dim_3);
+ fDim_4=atof(Dim_4);
+
+}//GetCodes
+
+/********************************************************/
+void FlushBuffer(void)
+{
+//Clears out all old data ready for a new line
+int f;
+
+ //LineBuffer
+ for(f=49; f; --f)
+ { //Flush line Buffer
+ LineBuffer[f]=0;
+ }
+ if (f==0) LineBuffer[0]=0; //to clear remaining character
+
+ //Inst_Code
+ Inst_Code_Letter=0;
+ for(f=7; f; --f)
+ {
+ Inst_Code[f]=0;
+ }
+ if (f==0) Inst_Code[0]=0; //to clear remaining character
+
+ //Dim_1
+ Dim_1_Letter=0;
+ for(f=7; f; --f)
+ {
+ Dim_1[f]=0;
+ }
+ if (f==0) Dim_1[0]=0; //to clear remaining character
+
+ //Dim_2
+ Dim_2_Letter=0;
+ for(f=7; f; --f)
+ {
+ Dim_2[f]=0;
+ }
+ if (f==0) Dim_2[0]=0; //to clear remaining character
+
+ //Dim_3
+ Dim_3_Letter=0;
+ for(f=7; f; --f)
+ {
+ Dim_3[f]=0;
+ }
+ if (f==0) Dim_3[0]=0; //to clear remaining character
+
+ //Dim_4
+ Dim_4_Letter=0;
+ for(f=7; f; --f)
+ {
+ Dim_4[f]=0;
+ }
+ if (f==0) Dim_4[0]=0; //to clear remaining character
+
+}//FlushBuffer
+
+/********************************************************/
+void ShowBufferFillState(void) { //Step buffer fill status
+
+float FillStat = 0;
+extern int SBR,SBW;
+
+ if (SBW>SBR)
+ {
+ FillStat = SBW-SBR;
+ }
+ else
+ FillStat = (SB_SIZE - SBR)+SBW;
+
+ FillStat /= SB_SIZE;
+ FillStat *= (int) 127;
+
+ OLED_ProgressBar(6,FillStat); //Bar on line number , Value to show relative to 127
+
+}//ShowBufferFillState
+
+/********************************************************/
+void ShowPrintProgress(void)
+{
+float FillStat = 0;
+
+ FillStat = (float)PosInFile / SaveFileSize;
+ FillStat *= (int) 127;
+ if (FillStat >127) FillStat = 127;
+
+ OLED_ProgressBar(5,FillStat); //Bar on line number , Value to show relative to 127
+
+}//ShowPrintProgress
+
+/********************************************************/
+
+
+
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan.d b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan.d new file mode 100644 index 00000000..0a74dbdf --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan.d @@ -0,0 +1,61 @@ +RapMan.o: RapMan.c \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ RapMan.h Enviroment.h FSIO.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h FSconfig.h \
+ C:/Microchip\ Solutions/Microchip/Include/Compiler.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/string.h \
+ HardwareProfile.h FSDefs.h SD-SPI.h Stepper.h G_Code.h Extruder.h \
+ OLED.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan.h new file mode 100644 index 00000000..f7fade33 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan.h @@ -0,0 +1,138 @@ +/**********************************************************************
+ *************************** RapMan.h *******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+//add in below as required
+#include "Enviroment.h"
+#include "FSIO.h"
+#include "Stepper.h" //Stepper motor functions and defines
+#include "G_Code.h" //G code table
+#include "Extruder.h"
+#include "stdlib.h"
+#include "stdio.h" //for printf **See note
+//To use printf the build options need to show a heap.
+//for output printf ONLY the heap can be set to 0
+//add to end of compile line --heap=0
+
+#include "OLED.h"
+
+//General Defines
+#define PRESSED 0
+#define NOT_PRESSED 1
+
+//File types
+#define INVALID_FILE 0
+#define GCO_FILE 1
+#define BIN_FILE 2
+#define BFB_FILE 3
+
+//Error Conditions
+#define TEST 0
+#define SEEK_POINT_ERR 1
+
+int PosInFile = 0; //character count in file
+int LineNumber = 0; //Line count in file
+
+int Word_Count=0;
+char Inst_Code_Letter;
+char Inst_Code[8];
+int iInst_Code;
+char Dim_1_Letter;
+char Dim_1[8];
+float fDim_1;
+char Dim_2_Letter;
+char Dim_2[8];
+float fDim_2;
+char Dim_3_Letter;
+char Dim_3[8];
+float fDim_3;
+char Dim_4_Letter;
+char Dim_4[8];
+float fDim_4;
+
+float X_Rest_mm;
+float Y_Rest_mm;
+float Z_Rest_mm;
+
+char EOF_Flag = 0; //end of file
+
+char ExtruderStatus;
+
+FSFILE * pointer;
+
+char SaveFileName[12];
+int SaveFileSize;
+
+FSFILE *FilePointer;
+
+int ItemsRead = 0;
+
+extern int GX_On;
+extern int GY_On;
+extern int GZ_On;
+extern int GI_On;
+extern int GJ_On;
+extern signed long lX_Steps,lY_Steps,lZ_Steps;
+extern int Feed_Rate;
+
+int ManualChange;
+
+char PauseFlag; //Used to prevent heater going on during pause
+
+signed int Ops_mode;
+
+void Setup(void);
+char GetTool_ID(void);
+
+//**********************************************************************
+// Functions
+//**********************************************************************
+void RapMan_MoveTo(float X_pos, float Y_pos, float Z_pos, char DoZmove);
+void OpenReadSDFile(void);
+void GetFileToOpen(void);
+int Get_file_Type(void);
+void ReadBinData(void);
+void ReadData(void);
+void GetCodes(void);
+void FlushBuffer(void);
+extern void ShowBufferFillState(void);
+extern void ShowPrintProgress(void);
+char RapMan_Mode();
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan1_0_8-factory.hex b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan1_0_8-factory.hex new file mode 100644 index 00000000..59683f95 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan1_0_8-factory.hex @@ -0,0 +1,6979 @@ +:020000040000fa +:020000041fc01b +:042ff400d9fff8ff0a +:020000040000fa +:020000041fc01b +:042ff800dbfd7fff7f +:020000040000fa +:020000041fc01b +:042ffc00ffffff7f55 +:020000040000fa +:020000041d00dd +:10600000009d1a3c90645a270800400300000000dd +:020000040000fa +:020000041d00dd +:10638000029d1a3c50b55a27080040030000000047 +:020000040000fa +:020000041d00dd +:10518000029d1a3cf4aa5a270800400300000000c0 +:020000040000fa +:020000041d00dd +:08530000af5d400b000000004e +:020000040000fa +:020000041d00dd +:08538000725e400b000000000a +:020000040000fa +:020000041d00dd +:085400008726400b00000000ac +:020000040000fa +:020000041d00dd +:1064900000601a40c0045a7f05004013000000004d +:1064a000029d1a3c68b55a2708004003000000000e +:1064b00001a01d3c0080bd2701a01c3cf0809c2752 +:1064c0000260094020582001801e2a7d8449497db0 +:1064d0000260894000e0dc4102608b40029d083c84 +:1064e00058b5082509f800010000000000a0083c8c +:1064f0002001082500a0093c84122925060000106f +:1065000000000000000000ad040000ad080000ad78 +:106510000c0000ad100008252b080901f9ff20141c +:1065200000000000029d083c8018082500a0093cde +:106530000000292500a00a3c20014a250500001082 +:106540000000000000000b8d00002bad04000825aa +:10655000040029252b082a01faff2014000000005e +:106560000000093c000029251d002011000000004a +:10657000029d083ca019082500a0093c00202925ff +:1065800000a00a3c00204a2500000b8d00002bad26 +:1065900004000825040029252b082a01faff2014ed +:1065a000000000000000093c0020292588bf0a3cab +:1065b00010204a25000049ad0100093c0080292532 +:1065c00088bf0a3c20204a25000049ad0100093c53 +:1065d0000080292588bf0a3c30204a25000049adab +:1065e00000488040ffff0a2400588a40009d093c73 +:1065f00000502925017889400000093c0100292527 +:1066000000000a2444492a7d01608a408000093c38 +:1066100000688940008008408005097d404c0900e1 +:10662000006008405800013c244001012540280139 +:1066300000608840029d083c60b5082509f800010b +:106640000000000000600840bfff013cffff213454 +:106650002440010100608840000084300000a53023 +:10666000009d083c006a08250800000100000000a9 +:020000040000fa +:020000041d00dd +:106a0000861a400f00000000496b400f0000000094 +:106a1000ffff001000000000e0ffbd271c00bfaf1b +:106a20001800beaf21f0a003ab1c400f0000000017 +:106a30005b69400f0000000088bf023c5060428c40 +:106a4000c000427c0300401400000000faff001068 +:106a500000000000111e400f000000001000c2af37 +:106a60001000c28f1400c2af010002241400c38fb3 +:106a700018006210000000001400c38f020062289a +:106a800006004010000000001400c28f0d004010ee +:106a900000000000e8ff00100000000002000224d7 +:106aa0001400c38f100062100000000003000224d5 +:106ab0001400c38f1400621000000000deff0010fd +:106ac00000000000c61a400f00000000daff0010ae +:106ad00000000000010004244923400f00000000d2 +:106ae000d5ff0010000000005480838302000224c0 +:106af000d1ff6214000000006161400f000000003f +:106b0000cdff0010000000008f24400f00000000a7 +:106b1000c9ff001000000000d0ffbd272c00bfaf50 +:106b20002800beaf21f0a003448180a3831d400f45 +:106b300000000000010140100000000021200000c2 +:106b4000f463400f00000000212000000a0005242b +:106b5000029d023c6000462421380000d864400faa +:106b60000000000088bf023c5060428cc000427ca4 +:106b70000300401400000000faff001000000000b5 +:106b8000165a400f000000001900401400000000d9 +:106b90000200042421280000029d023c74004624c7 +:106ba00021380000d864400f0000000004000424d5 +:106bb00021280000029d023c880046242138000064 +:106bc000d864400f00000000fa000424365c400f37 +:106bd0000000000088bf023c9061428c4002427c71 +:106be000e7ff401400000000d40000100000000087 +:106bf000020004245964400f000000000400042433 +:106c00005964400f00000000f41e400f0000000017 +:106c100088bf023c5060428cc000427c030040149c +:106c200000000000faff00100000000088bf023cd6 +:106c30009061428c4002427c03004014000000003e +:106c4000be000010000000006480838f0300022457 +:106c500007006210000000006480838f010002249e +:106c600003006210000000007f0000100000000020 +:106c70008f24400f000000000300401400000000bb +:106c8000ae0000100000000003000224508082af1c +:106c900021200000f463400f000000004262400f1a +:106ca000000000008628400f0000000001000424be +:106cb0005a24400f0000000088bf023c9061428cc3 +:106cc0004002427c2100401400000000d51b400f10 +:106cd0000000000088bf023c9061428c4002427c70 +:106ce0000300401400000000faff00100000000044 +:106cf000cc81838ff081828f0e0062100000000033 +:106d00003c80838301000224f9ff6214000000002c +:106d1000f081828f01004324cc81828ff4ff6214c2 +:106d200000000000cc81828ff08182aff0ff001064 +:106d3000000000009080848f9480858f21300000b7 +:106d4000213800009d1e400f000000007362400fbc +:106d500000000000ed20400f0000000000a0023cf9 +:106d60008804422401004390280002240300621496 +:106d700000000000f7ff0010000000005021400f4d +:106d8000000000005481838399818683648182831b +:106d90001000a2af4081828f1400a2af7c81828359 +:106da0001800a2af9c81828f1c00a2af5581828304 +:106db0002000a2af3c81828f2400a2af212060007e +:106dc0002c81858f1881878f4c2d400f000000008b +:106dd0006622400f000000005480838302000224da +:106de0000300621400000000d05e400f00000000ad +:106df00088bf023c5061428c4001427c0600401436 +:106e00000000000001000224448182a36881828f77 +:106e10000a004224688182af88bf023c5061428ce4 +:106e20000001427c06004014000000000100022422 +:106e3000448182a36881828ff6ff4224688182aff9 +:106e40003c808283010042382b1802004080828ff0 +:106e50002b100200251062002200401000000000ec +:106e600095ff00100000000021200000f463400f97 +:106e7000000000000200042421280000029d023cc2 +:106e80009800462421380000d864400f000000001c +:106e90000300042421280000029d023cac0046248b +:106ea00021380000d864400f0000000004000424d2 +:106eb00021280000029d023cbc004624213800002d +:106ec000d864400f0000000088bf023c9061428cf3 +:106ed0004002427c0300401000000000faff001056 +:106ee00000000000212000006f60400f0000000043 +:106ef000212000005a24400f000000003081828fc2 +:106f00005c8182af5c81848f0e3f400f00000000e7 +:106f1000ab1c400f000000009c66400f000000000a +:106f200088bf023c9061428c4002427c03004010ca +:106f300000000000faff00100000000021e8c0037c +:106f40002c00bf8f2800be8f3000bd270800e00353 +:106f500000000000e8ffbd271400bfaf1000beaf67 +:106f600021f0a00388bf023c9061428c4002427c29 +:106f70000300401400000000faff001000000000b1 +:106f8000040004245964400f00000000050004249c +:106f90005964400f00000000060004245964400fab +:106fa000000000000500042421280000029d023c8e +:106fb000d400462421380000d864400f00000000af +:106fc00001000224a08182a32881848f6081858fa3 +:106fd0008081868f213800009d1e400f0000000038 +:106fe0000500042421280000029d023c880046245c +:106ff00021380000d864400f00000000d963400f22 +:10700000000000002c63400f00000000f401042485 +:10701000365c400f0000000088bf023c9061428c4b +:107020004002427c0300401000000000f3ff00100b +:1070300000000000a08180a3050004245964400fd3 +:1070400000000000010004246f60400f00000000f9 +:107050004e30400f0000000021e8c0031400bf8f35 +:107060001000be8f1800bd270800e00300000000dc +:10707000e0ffbd271c00bfaf1800beaf21f0a0038a +:107080002000c4af020004245964400f0000000037 +:10709000030004245964400f00000000040004248d +:1070a0005964400f00000000050004245964400f9b +:1070b00000000000060004245964400f0000000096 +:1070c000070004245964400f000000002000c28f14 +:1070d0001000c2af1000c38f070060100000000056 +:1070e000010002241000c38f220062100000000083 +:1070f0003f000010000000000300042421280000cd +:10710000029d023cdc00462421380000d864400f78 +:107110000000000054808383020002240b006214ec +:1071200000000000212000006f60400f0000000000 +:107130000400042421280000029d023ce8004624ab +:1071400021380000d864400f000000002881848f9f +:107150006081858f8081868f213800009d1e400fc1 +:1071600000000000010002243c8082a327000010e0 +:10717000000000000300042421280000029d023cbe +:10718000f800462421380000d864400f00000000b9 +:1071900054808383020002240b006214000000006c +:1071a000212000006f60400f000000000400042454 +:1071b00021280000029d023ce800462421380000fe +:1071c000d864400f000000002881848f6081858f83 +:1071d0008081868f213800009d1e400f0000000036 +:1071e000010002243c8082a308000010000000007f +:1071f0000300042421280000029d023c0c014624c7 +:1072000021380000d864400f00000000050004246d +:1072100021280000029d023c1c0146242138000068 +:10722000d864400f0000000096000424365c400f34 +:10723000000000000500042421280000029d023cfb +:107240002c01462421380000d864400f00000000c3 +:1072500096000424365c400f0000000088bf023c0a +:107260009061428c4002427c03004010000000000c +:10727000e6ff00100000000088bf023c9061428cd5 +:107280004002427c0300401400000000faff00109e +:107290000000000021e8c0031c00bf8f1800be8f53 +:1072a0002000bd270800e00300000000e8ffbd2724 +:1072b0001400bfaf1000beaf21f0a00381bf033c9c +:1072c0006090629020004234609062a088bf043ccd +:1072d00040608390dfff022424106200406082a09f +:1072e00088bf043c00618390bfff02242410620029 +:1072f000006182a088bf033c006162907f00423041 +:10730000006162a081bf043c61908390f7ff02247a +:1073100024106200619082a088bf033c41606290ab +:1073200008004234416062a081bf043c61908390b8 +:10733000efff022424106200619082a088bf033c0a +:107340004160629010004234416062a081bf033c02 +:107350006090629001004234609062a088bf033c5c +:107360004060629001004234406062a081bf033cf3 +:107370006090629004004234609062a081bf033c40 +:107380006090629008004234609062a081bf033c2c +:107390006090629010004234609062a081bf043c13 +:1073a0006190839080ff022425106200619082a08a +:1073b00088bf033c4060629004004234406062a099 +:1073c00088bf033c4060629008004234406062a085 +:1073d00088bf033c4060629010004234406062a06d +:1073e00088bf043c4160839080ff02242510620026 +:1073f000416082a088bf033c40616290100042342b +:10740000406162a088bf033c40616290200042342a +:10741000406162a088bf033c8161629002004234f7 +:10742000816162a088bf033ce06162901000423439 +:10743000e06162a088bf033ce061629020004234ba +:10744000e06162a088bf033ce0616290400042348a +:10745000e06162a088bf033ce161629010004234a9 +:10746000e16162a088bf033ce261629002004234a5 +:10747000e26162a088bf033ce26162900400423492 +:10748000e26162a088bf033ce1616290080042347f +:10749000e16162a088bf033cc0606290100042348a +:1074a000c06062a088bf033c8160629020004234cb +:1074b000816062a088bf033c8160629040004234da +:1074c000816062a088bf033ce16162902000423489 +:1074d000e16162a088bf033ce06162900200423437 +:1074e000e06162a088bf033ce06162900100423429 +:1074f000e06162a081bf023c009040ac81bf023cd1 +:10750000109040ac81bf033c021f0224209062ac6b +:1075100081bf023c509040ac81bf043c01908390fd +:1075200080ff022425106200019082a088bf043ce5 +:1075300040618390feff022424106200406182a01b +:1075400088bf043c50618390feff02242410620037 +:10755000506182a088bf043c00618390dfff022459 +:1075600024106200006182a088bf043c10618390f7 +:10757000dfff022424106200106182a088bf043c57 +:10758000c1608390f7ff022424106200c16082a0d2 +:1075900088bf043cd1608390f7ff0224241062006e +:1075a000d16082a080bf023c007040ac8628400fb2 +:1075b00000000000c160400f00000000ca68400fda +:1075c00000000000bf7d400f00000000448180a348 +:1075d000688180af029d023c3001428c288182afdd +:1075e000029d023c3401428c608182af2110000078 +:1075f000808182af21e8c0031400bf8f1000be8fce +:107600001800bd270800e00300000000d8ffbd27d8 +:107610002400bfaf2000beaf21f0a0031000c0af18 +:107620001400c0a31000c28f1f004014000000000f +:107630000c0004244560400f00000000448082af2d +:107640004c80838f4480828f211062004c8082aff7 +:107650004880828f01004224488082af4880828f18 +:1076600004004228efff4014000000004c80828f8d +:107670001800c2af1800c28f0400410400000000cf +:107680001800c38f030063241800c3af1800c38f12 +:10769000831003001000c2af488080af4c8080afe1 +:1076a000e0ff0010000000001000c28f0e00400438 +:1076b000000000001000c28fc90042280a004010dc +:1076c00000000000010002241400c2a301000424f1 +:1076d00014000524029d023c380146242138000094 +:1076e000d864400f000000001000c28fc80042287c +:1076f0000e004014000000001000c28f91014228cb +:107700000a00401000000000020002241400c2a37e +:107710000100042414000524029d023c4401462477 +:1077200021380000d864400f000000001000c28f14 +:10773000900142280e004014000000001000c28f8b +:10774000590242280a0040100000000003000224f1 +:107750001400c2a30100042414000524029d023c6d +:107760005401462421380000d864400f0000000076 +:107770001000c28f580242280e0040140000000082 +:107780001000c28f210342280a00401000000000b0 +:10779000040002241400c2a30100042414000524e0 +:1077a000029d023c6401462421380000d864400f49 +:1077b000000000001000c28f200342280e00401479 +:1077c000000000001000c28fe90342280a004010a8 +:1077d00000000000050002241400c2a301000424dc +:1077e00014000524029d023c780146242138000043 +:1077f000d864400f000000001000c28ffc03422834 +:1078000009004014000000001400c0a3010004247b +:1078100014000524029d023c880146242138000002 +:10782000d864400f000000001400c28321e8c003a8 +:107830002400bf8f2000be8f2800bd270800e00372 +:1078400000000000e0ffbd271c00bfaf1800beaf66 +:1078500021f0a0031000c0af831d400f0000000006 +:10786000548082a39d65400f00000000251e400f3c +:10787000000000001000c2af1000c28f21e8c0035a +:107880001c00bf8f1800be8f2000bd270800e0033a +:1078900000000000e0ffbd271c00bfaf1800beaf16 +:1078a00021f0a0031000c0af88bf023c5060428ca2 +:1078b000c000437c01000224670062140000000045 +:1078c00005000424ce61400f0000000088bf023c88 +:1078d0005060428c0001427c130040140000000004 +:1078e00005000424ce61400f0000000088bf023c68 +:1078f0005060428c0001427c0300401400000000f4 +:10790000faff0010000000001000c28f01004224a6 +:107910001000c2af1000c28f0400422802004014c1 +:10792000000000001000c0af88bf023c5060428cd5 +:10793000c003427c13004014000000000500042432 +:10794000ce61400f0000000088bf023c5060428cb6 +:10795000c003427c0300401400000000faff001046 +:10796000000000001000c28fffff42241000c2afd1 +:107970001000c28f03004104000000000300022435 +:107980001000c2af1000c28f1400c2af0100022469 +:107990001400c38f1b006210000000001400c38f8e +:1079a0000200622806004010000000001400c28f90 +:1079b0000d00401000000000bbff001000000000a0 +:1079c000020002241400c38f1500621000000000a2 +:1079d000030002241400c38f18006210000000008e +:1079e000b1ff001000000000020004242128000064 +:1079f00001000624be66400f00000000aaff001030 +:107a000000000000030004242128000001000624d7 +:107a1000be66400f00000000a3ff00100000000041 +:107a2000040004242128000001000624be66400f43 +:107a3000000000009cff001000000000050004246e +:107a40002128000001000624be66400f000000004f +:107a500095ff0010000000001000c28f21e8c00355 +:107a60001c00bf8f1800be8f2000bd270800e00358 +:107a700000000000d0ffbd272c00bfaf2800beaf24 +:107a800021f0a0033000c4af3400c5af3800c6af4a +:107a90002110e0003c00c2a388bf033c0100023c6f +:107aa000641062ac88bf033c0100023c681062ac09 +:107ab00001000224608082af47000224548182a327 +:107ac0002c8180af58000224998182a33000c28f9c +:107ad000188182af59000224648182a33400c28fce +:107ae000408182af3c00c2830700401000000000cc +:107af0005a0002247c8182a33800c28f9c8182af0d +:107b000004000010000000007c8180a32110000010 +:107b10009c8182af46000224558182a3211000007f +:107b20003c8182af5481838399818683648182837f +:107b30001000a2af4081828f1400a2af7c818283ab +:107b40001800a2af9c81828f1c00a2af5581828356 +:107b50002000a2af3c81828f2400a2af21206000d0 +:107b60002c81858f1881878f4c2d400f00000000dd +:107b7000548180a32c8180af998180a321100000c3 +:107b8000188182af648180a321100000408182af00 +:107b90007c8180a3211000009c8182af558180a34d +:107ba000211000003c8182af608080affa00042485 +:107bb000365c400f0000000021e8c0032c00bf8f9e +:107bc0002800be8f3000bd270800e0030000000041 +:107bd000e8ffbd271400bfaf1000beaf21f0a00327 +:107be0003c80838301000224060062140000000030 +:107bf0003c8080a3308180af408080af308080aff8 +:107c0000348080afa931400f000000000300401411 +:107c100000000000fbff0010000000004e1f400f9e +:107c20000000000088bf023c9061428c4002427c10 +:107c300003004014000000003900001000000000a4 +:107c40009020400f00000000648082af00a0023c42 +:107c5000bc044424029d023c94014524df41400fb2 +:107c6000000000005c8182af5c81828f308182af36 +:107c70005c81828f000042380100422c25104200b6 +:107c80002000401000000000020004242128000011 +:107c9000029d023c9801462421380000d864400f20 +:107ca000000000000300042428000524029d023c7b +:107cb000a801462421380000d864400f00000000cd +:107cc0000400042421280000029d023c8800462470 +:107cd00021380000d864400f00000000fa0004249e +:107ce000365c400f0000000088bf023c9061428c6f +:107cf0004002427ce4ff4014000000000800001035 +:107d000000000000020004245a000524029d023ce9 +:107d1000b801462421380000d864400f000000005c +:107d200021e8c0031400bf8f1000be8f1800bd27cc +:107d30000800e0030000000080ffbd277c00bfaf0b +:107d40007800beaf21f0a003200002244800c2a3a7 +:107d5000029d023cc001428c5000c2af01000224cf +:107d60005800c2af5c00c0af6000c0af5000c22777 +:107d70004800c39321204000212860001000c6273e +:107d80001958400f000000005800c2af5800c28fc1 +:107d90003700401400000000010002246c8082af14 +:107da0001000c4272859400f000000005800c2af3f +:107db0005800c28f04004014000000006c80828fc5 +:107dc000010042246c8082af5800c28f030040142f +:107dd00000000000f2ff0010000000006000c28ff1 +:107de00023004014000000005000c2274800c39345 +:107df00021204000212860001000c6271958400f9c +:107e0000000000005800c2af01000224688082af69 +:107e1000010002245c00c2af5c00c28f6c80838fc3 +:107e20002a1043000a004010000000001000c42780 +:107e30002859400f000000005800c2af5c00c28ffc +:107e4000010042245c00c2aff3ff001000000000fc +:107e50006c80828f688082af020004242128000099 +:107e60001000c62721380000d864400f0000000031 +:107e70005800c28f22004010000000006c8080afcc +:107e8000688080af0200042421280000029d023c8b +:107e9000c401462421380000d864400f00000000cf +:107ea0000300042421280000029d023cd80146243e +:107eb00021380000d864400f0000000005000424b1 +:107ec00021280000029d023c880046242138000041 +:107ed000d864400f00000000fa000424365c400f14 +:107ee0000000000088bf023c9061428c4002427c4e +:107ef000e4ff401400000000cb0000100000000070 +:107f00005800c28fa50040140000000088bf023c4a +:107f10005060428c0001427c33004014000000009d +:107f200088bf023c5060428c0001427c0300401438 +:107f300000000000faff0010000000001e000424f2 +:107f4000365c400f000000001000c4272859400f85 +:107f5000000000005800c2af5800c28f0f0040144c +:107f6000000000006880828f6c80838f2a1062007e +:107f700005004010000000006c80828f688082af96 +:107f800010000010000000006880828f0100422471 +:107f9000688082af0b000010000000005000c22774 +:107fa0004800c39321204000212860001000c6270c +:107fb0001958400f000000005800c2af0100022411 +:107fc000688082af020004245964400f0000000062 +:107fd00002000424212800001000c62721380000d8 +:107fe000d864400f0000000088bf023c5060428c03 +:107ff000c003427c3f0040140000000088bf023ce8 +:108000005060428cc003427c03004014000000001a +:10801000faff0010000000001e000424365c400f30 +:10802000000000001000c4272859400f0000000085 +:108030005800c2af5800c28f030040140000000077 +:10804000f8ff0010000000005000c2274800c39352 +:1080500021204000212860001000c6271958400f39 +:10806000000000005800c2af6880828fffff4224ea +:10807000688082af6880828f050040140000000095 +:108080006c80828f688082af010002246000c2afe2 +:10809000010002245c00c2af5c00c28f6880838f45 +:1080a0002a1043000a004010000000001000c427fe +:1080b0002859400f000000005800c2af5c00c28f7a +:1080c000010042245c00c2aff3ff0010000000007a +:1080d000020004245964400f000000000200042440 +:1080e000212800001000c62721380000d864400f66 +:1080f000000000000600042421280000029d023c2c +:10810000ec01462421380000d864400f0000000034 +:108110006800c22721204000029d023cf401452452 +:108120006880868f106d400f000000006800c22735 +:1081300006000424190005242130400021380000e5 +:10814000d864400f0000000006000424410005240c +:10815000029d023cf801462421380000d864400ffb +:10816000000000006800c22721204000029d023c60 +:10817000f40145246c80868f106d400f00000000d4 +:108180006800c227060004245a000524213040005c +:1081900021380000d864400f0000000088bf023c76 +:1081a0009061428c4002427c0300401400000000b9 +:1081b0001d0000100000000088bf023c5060428c8f +:1081c000c000427c010042380100432c5800c28f9d +:1081d000000042380100422c2410620003004010cd +:1081e0000000000046ff00100000000088bf023cb5 +:1081f0005060428cc000437c0100022403006214e2 +:1082000000000000d9fe00100000000000a0023ca9 +:10821000bc0444241000c527fb69400f0000000087 +:108220002000c28f488182af21e8c0037c00bf8f4d +:108230007800be8f8000bd270800e003000000002a +:10824000f0ffbd270800beaf21f0a0030800022404 +:108250000100c2a30100c2935000401000000000c2 +:1082600000a0023c0100c393bc0442242110620020 +:10827000000043802e00022443006214000000002e +:1082800000a0023c0100c393bc0442242110620000 +:1082900001004280470042380100442c00a0023c0b +:1082a0000100c393bc0442242110620002004280fa +:1082b000430042380100422c2420820000a0023cee +:1082c0000100c393bc0442242110620003004280d9 +:1082d0004f0042380100422c241082000700401059 +:1082e00000000000010002240000c2a301000224db +:1082f0000400c2af290000100000000000a0023cf2 +:108300000100c393bc04422421106200010042809a +:10831000420042380100442c00a0023c0100c393fb +:10832000bc04422421106200020042804600423810 +:108330000100422c2420820000a0023c0100c393d3 +:10834000bc044224211062000300428042004238f3 +:108350000100422c241082000700401000000000a1 +:10836000030002240000c2a3030002240400c2afe1 +:108370000a000010000000000000c0a30400c0af0d +:1083800006000010000000000100c293ffff42241d +:108390000100c2a3afff0010000000000400c28f64 +:1083a00021e8c0030800be8f1000bd270800e003cd +:1083b00000000000d0ffbd272c00bfaf2800beafdb +:1083c00021f0a003010002242000c2af2400c0afae +:1083d0003c8080a33081828f5c8182af3480828f29 +:1083e00001004224348082af00a0033c3e000224fe +:1083f000880462a05c81848f3080858f21300000ea +:10840000054a400f00000000060040100000000078 +:10841000010004241c1c400f000000000100022485 +:108420003c8082a33c8082833f0040140000000017 +:108430009881842701000524010006245c81878f30 +:108440003d47400f00000000408082af00a0023c8a +:108450002000c38f880442242118620098818293ef +:10846000000062a02000c28f010042242000c2afa1 +:108470009881838328000224150062140000000004 +:108480009881842701000524010006245c81878fe0 +:108490003d47400f00000000408082af5c81848f28 +:1084a0002d47400f000000000300401000000000b6 +:1084b0000700001000000000988183830a00022456 +:1084c0000300621000000000edff0010000000003b +:1084d0005c81848f2d47400f000000000800401091 +:1084e000000000005c81848f0e3f400f0000000000 +:1084f000010002243c8082a307000010000000005d +:10850000988183830a0002240300621000000000a7 +:10851000c7ff0010000000005c81848f8b43400f78 +:1085200000000000308082af21e8c0032c00bf8f24 +:108530002800be8f3000bd270800e00300000000c7 +:10854000e0ffbd271c00bfaf1800beaf21f0a003a5 +:10855000010002241000c2af1400c0af01000224c9 +:10856000388082af00a0023c88044224010043907e +:108570000d0002240300621400000000dc00001063 +:10858000000000003880838f01000224270062145d +:10859000000000001400c28f0a0040140000000018 +:1085a00000a0023c1000c38f880442242110620006 +:1085b00000004290548182a31000c28f0100422427 +:1085c0001000c2af1400c38f3481822721206200c3 +:1085d00000a0023c1000c38f8804422421106200d6 +:1085e00000004290000082a01400c28f01004224cb +:1085f0001400c2af00a0023c1000c38f88044224c4 +:108600002110620000004390200002240700621441 +:10861000000000001000c28f010042241000c2af11 +:108620001400c0af02000224388082af3880838fec +:108630000200022427006214000000001400c28f10 +:108640000a0040140000000000a0023c1000c38f8c +:10865000880442242110620000004290998182a384 +:108660001000c28f010042241000c2af1400c38f5b +:10867000a48182272120620000a0023c1000c38f49 +:10868000880442242110620000004290000082a071 +:108690001400c28f010042241400c2af00a0023cab +:1086a0001000c38f88044224211062000000439010 +:1086b0002000022407006214000000001000c28f96 +:1086c000010042241000c2af1400c0af0300022416 +:1086d000388082af3880838f030002242700621421 +:1086e000000000001400c28f0a00401400000000c7 +:1086f00000a0023c1000c38f8804422421106200b5 +:1087000000004290648182a31000c28f01004224c5 +:108710001000c2af1400c38f748182272120620031 +:1087200000a0023c1000c38f880442242110620084 +:1087300000004290000082a01400c28f0100422479 +:108740001400c2af00a0023c1000c38f8804422472 +:1087500021106200000043902000022407006214f0 +:10876000000000001000c28f010042241000c2afc0 +:108770001400c0af04000224388082af3880838f99 +:108780000400022427006214000000001400c28fbd +:108790000a0040140000000000a0023c1000c38f3b +:1087a0008804422421106200000042907c8182a350 +:1087b0001000c28f010042241000c2af1400c38f0a +:1087c000908182272120620000a0023c1000c38f0c +:1087d000880442242110620000004290000082a020 +:1087e0001400c28f010042241400c2af00a0023c5a +:1087f0001000c38f880442242110620000004390bf +:108800002000022407006214000000001000c28f44 +:10881000010042241000c2af1400c0af05000224c2 +:10882000388082af3880838f0500022419006214db +:10883000000000001400c28f0a0040140000000075 +:1088400000a0023c1000c38f880442242110620063 +:1088500000004290558182a31000c28f0100422483 +:108860001000c2af1400c38f208182272120620034 +:1088700000a0023c1000c38f880442242110620033 +:1088800000004290000082a01400c28f0100422428 +:108890001400c2af00a0023c1000c38f8804422421 +:1088a00021106200000043900a00022403006214b9 +:1088b000000000000e000010000000001000c28f39 +:1088c000010042241000c2af00a0023c1000c38f80 +:1088d0008804422421106200000043900d0002240d +:1088e00003006210000000001eff001000000000e6 +:1088f00034818427d16b400f000000002c8182afaf +:10890000a4818427ca6b400f000000002120400092 +:1089100021286000f278400f00000000188182af2b +:1089200074818427ca6b400f0000000021204000a2 +:1089300021286000f278400f00000000408182afe3 +:1089400090818427ca6b400f000000002120400066 +:1089500021286000f278400f000000009c8182af67 +:1089600020818427ca6b400f0000000021204000b6 +:1089700021286000f278400f000000003c8182afa7 +:1089800021e8c0031c00bf8f1800be8f2000bd2748 +:108990000800e00300000000f0ffbd270800beafa4 +:1089a00021f0a003310002240000c2af0000c28ffa +:1089b0000b0040100000000000a0023c0000c38f2c +:1089c0008804422421106200000040a00000c28ff1 +:1089d000ffff42240000c2aff4ff001000000000bf +:1089e0000000c28f030040140000000000a0023c01 +:1089f000880440a0548180a3070002240000c2af75 +:108a00000000c28f0a004010000000000000c38f69 +:108a10003481822721106200000040a00000c28f34 +:108a2000ffff42240000c2aff5ff0010000000006d +:108a30000000c28f0200401400000000348180a3b7 +:108a4000998180a3070002240000c2af0000c28ffa +:108a50000a004010000000000000c38fa48182279c +:108a600021106200000040a00000c28fffff4224de +:108a70000000c2aff5ff0010000000000000c28f30 +:108a80000200401400000000a48180a3648180a340 +:108a9000070002240000c2af0000c28f0a0040108d +:108aa000000000000000c38f748182272110620043 +:108ab000000040a00000c28fffff42240000c2afb0 +:108ac000f5ff0010000000000000c28f02004014fb +:108ad00000000000748180a37c8180a30700022431 +:108ae0000000c2af0000c28f0a004010000000006a +:108af0000000c38f9081822721106200000040a0f7 +:108b00000000c28fffff42240000c2aff5ff00103b +:108b1000000000000000c28f0200401400000000ae +:108b2000908180a3558180a3070002240000c2af7a +:108b30000000c28f0a004010000000000000c38f38 +:108b40002081822721106200000040a00000c28f17 +:108b5000ffff42240000c2aff5ff0010000000003c +:108b60000000c28f0200401400000000208180a39a +:108b700021e8c0030800be8f1000bd270800e003f5 +:108b800000000000e0ffbd271c00bfaf1800beaf13 +:108b900021f0a003211000001000c2aff081828fed +:108ba000cc81838f2a1062000a0040100000000070 +:108bb000f081838fcc81828f2310620021204000be +:108bc000767b400f000000001000c2af09000010cb +:108bd00000000000f081838fcc81828f231062001f +:108be0000002422421204000767b400f000000005c +:108bf0001000c2af029d023c1000c48ffc01458ce6 +:108c0000eb7a400f000000001000c2af029d023c52 +:108c10001000c48f0002458c7d7a400f00000000d8 +:108c20001000c2af1000c48fa07b400f00000000f6 +:108c300006000424212840002464400f00000000a6 +:108c400021e8c0031c00bf8f1800be8f2000bd2785 +:108c50000800e00300000000d8ffbd272000bfafe0 +:108c60001c00beaf1800b0af21f0a003211000001f +:108c70001000c2af3080848f767b400f0000000070 +:108c8000218040004881848f767b400f00000000e7 +:108c90002120000221284000eb7a400f0000000054 +:108ca0001000c2af029d023c1000c48f0402458c2c +:108cb0007d7a400f000000001000c2af029d023c10 +:108cc0000402448c1000c58fdb7b400f00000000c5 +:108cd0000300400400000000040000100000000039 +:108ce000029d023c0402428c1000c2af1000c48fef +:108cf000a07b400f00000000050004242128400054 +:108d00002464400f0000000021e8c0032000bf8f52 +:108d10001c00be8f1800b08f2800bd270800e0039c +:108d200000000000c8ffbd273400bfaf3000beaf59 +:108d300021f0a003211080003800c2a32110000000 +:108d40002000c2af211000002400c2af211000009b +:108d50002800c2afcc81838ff081828f0300621024 +:108d600000000000fbff00100000000088bf033c73 +:108d70000100023c641062ac88bf023c681040ac49 +:108d800060ea02348c8182afa48080a3a58080a396 +:108d9000a68080a3010004245a24400f0000000094 +:108da000d465400f0000000088bf023c5060428c38 +:108db000c000427c0300401400000000faff0010d5 +:108dc0000000000088bf023c9061428c4002437c5e +:108dd00001000224d80062140000000001000224f7 +:108de000a88082af8c81828fe9034228040040145e +:108df000000000008c81828fb5ff42248c8182affd +:108e00008c81828f6500422804004014000000001d +:108e10008c81828ffbff42248c8182af8c81828f78 +:108e2000900142280300401000000000900102243d +:108e30008c8182af88bf023c5060428cc000427c73 +:108e40000400401400000000088280af01000224ea +:108e5000a48082a388bf023c5060428c8000427c88 +:108e6000050040140000000001000224088282afc7 +:108e700001000224a48082a388bf023c5060428c7f +:108e8000c000427c070040100000000088bf023c88 +:108e90005060428c8000427c0200401000000000c4 +:108ea000a48080a388bf023c5060428cc003427cf7 +:108eb0000400401400000000e88180af010002249b +:108ec000a58082a388bf023c5060428c0001427c96 +:108ed000050040140000000001000224e88182af78 +:108ee00001000224a58082a388bf023c5060428c0e +:108ef000c003427c070040100000000088bf023c15 +:108f00005060428c0001427c0200401000000000d2 +:108f1000a58080a388bf023c5061428c4001427c06 +:108f20000400401400000000f48180af010002241e +:108f3000a68082a388bf023c5061428c0001427c23 +:108f4000050040140000000001000224f48182affb +:108f500001000224a68082a388bf023c5061428c9b +:108f60004001427c070040100000000088bf023c26 +:108f70005061428c0001427c020040100000000061 +:108f8000a68080a3a4808283090040140000000012 +:108f9000a58082830600401400000000a680828322 +:108fa000030040140000000060ea02348c8182afac +:108fb0003800c28383ff401000000000b881848f16 +:108fc000767b400f0000000021204000c978400f50 +:108fd00000000000029d063c212040002128600086 +:108fe0001402c78c1002c68c6b77400f0000000083 +:108ff0002120400021286000f278400f000000008e +:109000002000c2af2000c48fc978400f00000000cc +:1090100021304000213860001000c427029d023c2e +:1090200008024524106d400f0000000004000424d5 +:10903000400005241000c62721380000d864400fe6 +:1090400000000000ec81848f767b400f0000000060 +:1090500021204000c978400f00000000029d063c1e +:1090600021204000212860001402c78c1002c68c09 +:109070006b77400f00000000212040002128600095 +:10908000f278400f000000002400c2af2400c48f1b +:10909000c978400f000000002130400021386000f6 +:1090a0001000c427029d023c08024524106d400fa9 +:1090b0000000000005000424400005241000c6271d +:1090c00021380000d864400f00000000c081848f68 +:1090d000767b400f00000000029d033c21204000f1 +:1090e0001802658ceb7a400f000000002800c2af28 +:1090f0002800c48fc978400f0000000021304000d4 +:10910000213860001000c427029d023c080245245b +:10911000106d400f000000000600042440000524ec +:109120001000c62721380000d864400f000000005e +:1091300024ff001000000000a88080af88bf023c20 +:109140000100033c641043ac88bf023c681040ac93 +:1091500021e8c0033400bf8f3000be8f3800bd2728 +:109160000800e00300000000f8ffbd270000beafcc +:1091700021f0a0030800c4af0800c38f010002243f +:10918000180062140000000088bf043cd060839087 +:10919000f7ff022424106200d06082a088bf043c44 +:1091a000d1608390fbff022424106200d16082a072 +:1091b00088bf043c51608390dfff022424106200ca +:1091c000516082a088bf033c0100023c641062ac85 +:1091d00088bf033c0100023c681062ac1200001022 +:1091e0000000000088bf033cd06062900800423459 +:1091f000d06062a088bf033cd1606290040042341a +:10920000d16062a088bf033c51606290200042346c +:10921000516062a088bf033c0100023c641062ac54 +:1092200088bf023c681040ac21e8c0030000be8f3c +:109230000800bd270800e00300000000e0ffbd2794 +:109240001c00bfaf1800beaf21f0a0033366400f73 +:1092500000000000a48080a3a58080a3a68080a336 +:109260008628400f00000000010004245a24400f0b +:109270000000000001000224a88082aff401022453 +:109280008c8182af0300042421280000029d023c4f +:109290001c02462421380000d864400f0000000062 +:1092a00001000224f48182af01000224a68082a37f +:1092b0001000c0af1000c38f0300023c3f0d4234ca +:1092c0002a10430006004014000000001000c28f66 +:1092d000010042241000c2aff6ff001000000000a1 +:1092e000a68080a30300042421280000029d023ce4 +:1092f0002802462421380000d864400f00000000f6 +:10930000e80302248c8182af01000224e88182af4d +:1093100001000224a58082a31000c0af1000c28ffc +:109320005fea03342a1062000600401400000000c7 +:109330001000c28f010042241000c2aff7ff0010de +:1093400000000000a58080a3030004242128000061 +:10935000029d023c3402462421380000d864400fac +:1093600000000000e80302248c8182af88bf023c29 +:10937000d060428c0001427c2100401400000000bb +:1093800088bf023c9061428c4002427c1c0040102d +:109390000000000001000224088282af88bf023c66 +:1093a000d060428c0001427c0a00401400000000a2 +:1093b00088bf023c9061428c4002427c0500401014 +:1093c0000000000001000224a48082a3f3ff00102b +:1093d00000000000a48080a31000c0af1000c28f66 +:1093e000204e4228e1ff4010000000001000c28f14 +:1093f000010042241000c2aff8ff0010000000007e +:1094000001000224a48082a31000c0af1000c28f0c +:109410001027422806004010000000001000c28ff4 +:10942000010042241000c2aff8ff0010000000004d +:10943000a48080a360ea02348c8182af88bf023ca2 +:10944000d060428c0001427c2600401000000000e9 +:1094500088bf023c9061428c4002427c2100401057 +:1094600000000000088280af88bf023cd060428cc0 +:109470000001427c0a0040100000000088bf023c4e +:109480009061428c4002427c0500401000000000c8 +:1094900001000224a48082a3f3ff0010000000005a +:1094a000a48080a31000c0af1000c28fd007422854 +:1094b00006004010000000001000c28f010042248e +:1094c0001000c2aff8ff001000000000d2d102244b +:1094d000b88182afb881828fbc8182afd7ff001084 +:1094e000000000000300042421280000029d023c2b +:1094f0004002462421380000d864400f00000000dc +:10950000e80302248c8182af88bf023c9060428cc9 +:109510004003427c200040140000000088bf023c51 +:109520009061428c4002427c1b0040100000000011 +:10953000e88180af88bf023c9060428c4003427c4f +:109540000a0040140000000088bf023c9061428c79 +:109550004002427c0500401000000000010002248f +:10956000a58082a3f3ff001000000000a58080a367 +:109570001000c0af1000c28f204e4228e2ff401002 +:10958000000000001000c28f010042241000c2af92 +:10959000f8ff00100000000001000224a58082a353 +:1095a0001000c0af1000c28f1027422806004010e4 +:1095b000000000001000c28f010042241000c2af62 +:1095c000f8ff001000000000a58080a360ea0234cc +:1095d0008c8182af88bf023c9060428c4003427c09 +:1095e000270040100000000088bf023c9061428cc0 +:1095f0004002427c220040100000000001000224d2 +:10960000e88182af88bf023c9060428c4003427c7c +:109610000a0040100000000088bf023c9061428cac +:109620004002427c050040100000000001000224be +:10963000a58082a3f3ff001000000000a58080a396 +:109640001000c0af1000c28fd007422806004010a3 +:10965000000000001000c28f010042241000c2afc1 +:10966000f8ff00100000000035220224ec8182afd8 +:10967000ec81828fd48182afd6ff00100000000001 +:109680000300042421280000029d023c4c024624d1 +:1096900021380000d864400f00000000f4010224cb +:1096a0008c8182af88bf023c9060428c8003427cf8 +:1096b000200040140000000088bf023c9061428cf2 +:1096c0004002427c1b00401000000000f48180af8b +:1096d00088bf023c9060428c8003427c0a004014a8 +:1096e0000000000088bf023c9061428c4002427c36 +:1096f000050040100000000001000224a68082a3a3 +:10970000f3ff001000000000a68080a31000c0af8f +:109710001000c28fd0074228e2ff40100000000076 +:109720001000c28f010042241000c2aff8ff0010e9 +:109730000000000001000224a68082a31000c0af38 +:109740001000c28f102742280600401000000000c1 +:109750001000c28f010042241000c2aff8ff0010b9 +:1097600000000000a68080a3881302248c8182afb1 +:1097700088bf023c9060428c8003427c26004010ef +:109780000000000088bf023c9061428c4002427c95 +:10979000210040100000000001000224f48182af8b +:1097a00088bf023c9060428c8003427c0a004010db +:1097b0000000000088bf023c9061428c4002427c65 +:1097c000050040100000000001000224a68082a3d2 +:1097d000f3ff001000000000a68080a31000c0afbf +:1097e0001000c28fd0074228060040100000000081 +:1097f0001000c28f010042241000c2aff8ff001019 +:1098000000000000c08180afc081828fe08182af04 +:10981000d7ff001000000000a88080af88bf033c85 +:109820000100023c641062ac88bf023c681040ac8e +:1098300088bf023c9061428c4002427c1700401479 +:10984000000000000300042421280000029d023cc7 +:109850005802462421380000d864400f0000000060 +:109860001000c0af1000c38f1e00023c7f84423442 +:109870002a10430006004014000000001000c28fb0 +:10988000010042241000c2aff6ff001000000000eb +:109890001400c0af160000100000000003000424f4 +:1098a00021280000029d023c680246242138000065 +:1098b000d864400f000000001000c0af1000c38f3c +:1098c0001e00023c7f8442342a10430006004014ec +:1098d000000000001000c28f010042241000c2af3f +:1098e000f6ff001000000000010002241400c2afc7 +:1098f0001400c28f21e8c0031c00bf8f1800be8f68 +:109900002000bd270800e00300000000e8ffbd279d +:109910001400bfaf1000beaf21f0a003010002246d +:10992000c08082af01000224c48082afc88080afb3 +:10993000f40102248c8182af2881848fc978400f82 +:1099400000000000029d063c21204000212860000c +:109950007c02c78c7802c68ca176400f0000000004 +:109960002120400021286000f278400f0000000014 +:10997000e48182af6081848fc978400f00000000cd +:10998000029d063c21204000212860007c02c78cfb +:109990007802c68ca176400f000000002120400014 +:1099a00021286000f278400f00000000d88182afcb +:1099b000e481848fc22c400f00000000b48182af8c +:1099c000d881848fc22c400f00000000048282af37 +:1099d00088bf033c0100023c641062ac88bf033cba +:1099e0000100023c681062ac642a400f00000000d5 +:1099f000c08080afc48080affa000424365c400f82 +:109a00000000000021e8c0031400bf8f1000be8fcb +:109a10001800bd270800e0030000000000e85d41d9 +:109a200000681a4000701b40c0ffbd273c00bbaf60 +:109a300000601b4082d21a003800bbaf847a5b7f83 +:109a400044201b7c00609b403400beaf3000a4afbc +:109a50002c00a3af2800a2af21f0a0030400c0a3f4 +:109a6000a880828f9800401000000000a080828fa4 +:109a70000800c2af010002240800c38f2600621054 +:109a8000000000000800c38f02006228060040109a +:109a9000000000000800c28f090040100000000014 +:109aa0008200001000000000020002240800c38fa2 +:109ab0006b006210000000007c000010000000003d +:109ac00088bf043cd060828c0882838fc439627c5a +:109ad000d06082ac88bf043cd060828ce881838fe8 +:109ae000444a627cd06082ac88bf043c5060828c67 +:109af000f481838f444a627c506082ac80bf033c17 +:109b000005000224200c62ac01000224a08082af78 +:109b10006600001000000000a48082831200401044 +:109b20000000000088bf033cd06062900400423413 +:109b3000d06062a00882828f0600401400000000fe +:109b4000b881828f01004224b88182af0b000010df +:109b500000000000b881828fffff4224b88182afed +:109b6000060000100000000088bf043cd060839015 +:109b7000fbff022424106200d06082a0a5808283b3 +:109b8000120040100000000088bf033cd1606290ca +:109b900001004234d16062a0e881828f0600401447 +:109ba00000000000ec81828f01004224ec8182af32 +:109bb0000b00001000000000ec81828fffff4224a8 +:109bc000ec8182af060000100000000088bf043c5a +:109bd000d1608390feff022424106200d16082a035 +:109be000a6808283120040100000000088bf033c62 +:109bf0005160629001004234516062a0f481828f12 +:109c00000600401400000000c081828f0100422441 +:109c1000c08182af0b00001000000000c081828f65 +:109c2000ffff4224c08182af060000100000000048 +:109c300088bf043c51608390feff02242410620020 +:109c4000516082a080bf023c0a000324200c43ac78 +:109c500002000224a08082af140000100000000067 +:109c600080bf033c8c81828f200c62ac88bf043c97 +:109c7000d0608390fbff022424106200d06082a099 +:109c800088bf043cd1608390feff02242410620050 +:109c9000d16082a088bf043c51608390feff022403 +:109ca00024106200516082a0a08080af80bf023c7f +:109cb000100c40ac88bf033c0100023c341062ac85 +:109cc00048010010000000009c80828f2400c2af79 +:109cd000010002242400c38fa500621000000000d0 +:109ce0002400c38f0200622806004010000000001c +:109cf0002400c28f09004010000000003401001051 +:109d000000000000020002242400c38f0d01621035 +:109d1000000000002e01001000000000b081828fc2 +:109d20008c00401400000000cc81838ff081828f72 +:109d3000880062100000000000a0043ccc81828feb +:109d400080180200c8048224211062000000428ca6 +:109d5000d08182af00a0043ccc81828f80180200a9 +:109d6000c804822421106200000040accc81828fa4 +:109d700001004224cc8182afcc81828f0c00c2af23 +:109d80000c00c38f1000c3af1000c28f0400410449 +:109d9000000000001000c38fff0163241000c3af58 +:109da0001000c38f43120300401202000c00c38f47 +:109db00023106200cc8182af01000224b08182af07 +:109dc0000008023c0000c2af030002240400c2a34a +:109dd000d081828f0000c38f241043002a004010de +:109de000000000000400c2931400c2af050002246a +:109df0001400c38f17006210000000001400c38f0e +:109e00000600622807004010000000000300022442 +:109e10001400c38f0900621000000000420000100f +:109e200000000000070002241400c38f0f0062101e +:109e3000000000003c0000100000000088bf023c51 +:109e40005160439002006334516043a0360000101b +:109e50000000000088bf023cd160439002006334e0 +:109e6000d16043a0300000100000000088bf043c17 +:109e7000d060839080ff022425106200d06082a011 +:109e800029000010000000000400c2931800c2afb7 +:109e9000050002241800c38f1800621000000000a3 +:109ea0001800c38f06006228070040100000000061 +:109eb000030002241800c38f090062100000000094 +:109ec0001900001000000000070002241800c38fd2 +:109ed00011006210000000001300001000000000dc +:109ee00088bf043c51608390fdff0224241062006f +:109ef000516082a00c0000100000000088bf043cec +:109f0000d1608390fdff022424106200d16082a002 +:109f1000050000100000000088bf023cd0604390a4 +:109f20007f006330d06043a00400c293020042244b +:109f30000400c2a30000c28f801002000000c2af64 +:109f40000000c28f0300401000000000a0ff0010be +:109f50000000000080bf023c05000324200c43ac3d +:109f6000010002249c8082af9900001000000000d4 +:109f7000b081828f6c004010000000000004023ca1 +:109f80000000c2af020002240400c2a3d081828f6d +:109f90000000c38f241043002d004010000000007b +:109fa0000400c2931c00c2af040002241c00c38f33 +:109fb00017006210000000001c00c38f050062281b +:109fc0000700401000000000020002241c00c38fa4 +:109fd00009006210000000004800001000000000ae +:109fe000060002241c00c38f110062100000000054 +:109ff000420000100000000088bf023c5160439006 +:10a0000001006334516043a03c00001000000000d8 +:10a0100088bf033cd160629001004234d16062a0ed +:10a02000010002240600c2a334000010000000005a +:10a0300088bf033cd060629004004234d06062a0cc +:10a04000010002240500c2a32c0000100000000043 +:10a050000400c2932000c2af040002242000c38f7a +:10a0600018006210000000002000c38f0500622865 +:10a070000700401000000000020002242000c38fef +:10a0800009006210000000001c0000100000000029 +:10a09000060002242000c38f12006210000000009e +:10a0a000160000100000000088bf043c516083903f +:10a0b000feff022424106200516082a00f000010f5 +:10a0c0000000000088bf043cd1608390feff0224a2 +:10a0d00024106200d16082a00600c0a30700001017 +:10a0e0000000000088bf043cd0608390fbff022486 +:10a0f00024106200d06082a00500c0a30400c293b7 +:10a10000020042240400c2a30000c28f801002009b +:10a110000000c2af0000c28f03004010000000002a +:10a120009aff00100000000080bf023c0a000324d8 +:10a13000200c43ac020002249c8082af240000105b +:10a1400000000000b081828f0c0040100000000071 +:10a15000ffff02340000c2afd081838f0000c28fa6 +:10a16000241062000c8082af80bf033c0c80828f81 +:10a17000200c62ac040000100000000080bf033c13 +:10a1800088130224200c62ac88bf043cd06083900a +:10a19000fbff022424106200d06082a088bf043c30 +:10a1a000d1608390feff022424106200d16082a05f +:10a1b00088bf043c51608390feff0224241062009b +:10a1c000516082a09c8080afb08180afd08180af91 +:10a1d00080bf023c100c40ac88bf033c0100023c35 +:10a1e000341062ac21e8c0033400be8f3000a48f6d +:10a1f0002c00a38f2800a28f00606041c0000000e7 +:10a200003c00ba8f00709a403800ba8f4000bd27da +:10a2100000609a4018000042e8ffbd271400bfaf5d +:10a220001000beaf21f0a00380bf033c3080023499 +:10a23000000662ac81bf043c00f28390f7ff022469 +:10a240002410620000f282a081bf033c6190629002 +:10a2500001004234619062a088bf043c4160839059 +:10a26000feff022424106200416082a081bf033cf3 +:10a270006190629002004234619062a088bf043c09 +:10a2800041608390fdff022424106200416082a09f +:10a2900081bf033c6190629020004234619062a0d3 +:10a2a00088bf043c41608390dfff022424106200d9 +:10a2b000416082a088bf033cc060629010004234bd +:10a2c000c06062a088bf043cc1608390feff02248e +:10a2d00024106200c16082a088bf043cc1608390ea +:10a2e000fdff022424106200c16082a088bf043cec +:10a2f000c1608390fbff022424106200c16082a031 +:10a3000088bf033c8160629020004234816062a07b +:10a3100088bf043cc0608390fbff022424106200cd +:10a32000c06082a088bf033cc06062907f00423062 +:10a33000c06062a088bf043cc0608390f7ff022425 +:10a3400024106200c06082a088bf033c81606290dc +:10a3500040004234816062a088bf033cd0606290bc +:10a3600008004234d06062a088bf033cd160629094 +:10a3700004004234d16062a088bf033c5160629007 +:10a3800020004234516062a080bf023c000c40ac0f +:10a3900080bf033c10000224080c62ac80bf023c6a +:10a3a000100c40ac80bf033cf4010224200c62acd2 +:10a3b00088bf033c1c000224d41062ac88bf033c5d +:10a3c0001c000224d81062acbf7d400f00000000ca +:10a3d00088bf033c0100023c341062ac80bf033ce8 +:10a3e00000800234080c62ac88bf033c0100023cd0 +:10a3f000641062ac88bf023c681040accc8180af76 +:10a40000f08180af708180af508180af21e8c003c0 +:10a410001400bf8f1000be8f1800bd270800e00396 +:10a4200000000000e0ffbd271c00bfaf1800beaf5a +:10a4300021f0a0032000c4af2400c5af2000c28fcc +:10a440001c8182af2400c28ff88182af2000c38fad +:10a450008888023c8988423418006200101000008d +:10a460002110430043210200c31703002310820080 +:10a470002000c2af2000c28f090040100000000081 +:10a4800006df03342000c28f1a006200f40140008e +:10a49000121000008c8182af030000100000000049 +:10a4a000d00702248c8182af5081828f0500401832 +:10a4b000000000005081828f748082af0300001082 +:10a4c00000000000ee020224748082af8c81848f31 +:10a4d0009878400f00000000029d063c21204000bb +:10a4e000212860008402c78c8002c68ca176400fb0 +:10a4f0000000000021204000212860003079400f3a +:10a5000000000000708082af7d8182831a004014b9 +:10a51000000000007081828f0500401800000000dc +:10a520007081828f8c8182af0300001000000000d8 +:10a53000ee0202248c8182af4c818283150040148c +:10a54000000000001080838f0100022403006214c9 +:10a5500000000000df61400f0000000088bf023ce7 +:10a560001061439001006334106143a0108080affc +:10a5700008000010000000001080828f03004014cb +:10a58000000000000562400f0000000001000224ee +:10a59000108082af6080828f1200401000000000a7 +:10a5a0007081828f07004018000000007081828f48 +:10a5b0008c8182af7081828f708082af0500001025 +:10a5c00000000000ee0202248c8182afee02022421 +:10a5d000708082af88bf023c1061439001006334f9 +:10a5e000106143a021e8c0031c00bf8f1800be8f7c +:10a5f0002000bd270800e00300000000e8ffbd27a1 +:10a600001400bfaf1000beaf21f0a0031800c4af0c +:10a610002110a0001c00c2a31800c38f1400022444 +:10a620000300621000000000210000100000000084 +:10a63000029d023c3082848f8802458c7d7a400fd7 +:10a6400000000000e48182af029d023c1882848fea +:10a650008802458c7d7a400f00000000d88182afcf +:10a66000029d023c2482848f8802458c7d7a400fb3 +:10a67000000000000c8282afe481848fc22c400f66 +:10a6800000000000b48182afd881848fc22c400fbb +:10a6900000000000048282af0c82848fc22c400f25 +:10a6a00000000000dc8182af3100001000000000db +:10a6b0003082848fc978400f00000000029d063c64 +:10a6c00021204000212860009402c78c9002c68c93 +:10a6d000a176400f000000002120400021286000ea +:10a6e000f278400f00000000e48182af1882848f6e +:10a6f000c978400f00000000029d063c2120400068 +:10a70000212860009402c78c9002c68ca176400f6d +:10a71000000000002120400021286000f278400f56 +:10a7200000000000d88182af029d023c2482848f09 +:10a730009802458c7d7a400f000000000c8282afa9 +:10a74000e481848fc22c400f00000000b48182afee +:10a75000d881848fc22c400f00000000048282af99 +:10a760000c82848fc22c400f00000000dc8182af7d +:10a7700021e8c0031400bf8f1000be8f1800bd2752 +:10a780000800e00300000000d8ffbd272400bfaf91 +:10a790002000beaf21f0a003bc81838fb881828fdf +:10a7a00023106200ac8082afd481838fec81828fd2 +:10a7b00023106200b08082afe081838fc081828fde +:10a7c00023106200b48082afb88180afec8180af8b +:10a7d000c08180afac80848f9878400f000000006b +:10a7e000029d063c2120400021286000a402c78c65 +:10a7f000a002c68c6b77400f0000000021204000b3 +:10a8000021286000f278400f000000001000c2af65 +:10a81000b080848f9878400f00000000029d063cb5 +:10a820002120400021286000a402c78ca002c68c11 +:10a830006b77400f000000002120400021286000bd +:10a84000f278400f000000001400c2afb480848f83 +:10a850006666023c676642341800820010100000f1 +:10a86000831a0200c3170400231062002120400055 +:10a87000767b400f000000001800c2af029d023c32 +:10a880001000c48fa802458ce279400f0000000040 +:10a89000288182af029d023c1400c48fac02458c1b +:10a8a000e279400f00000000608182af1800c48f81 +:10a8b00021280000e279400f00000000808182af73 +:10a8c00021e8c0032400bf8f2000be8f2800bd27d1 +:10a8d0000800e00300000000f8ffbd270000beaf45 +:10a8e00021f0a003b881838fbc81828f07006210a2 +:10a8f00000000000bc81838fac80828f231862002f +:10a90000b881828f21104300b88182afec81838fa0 +:10a91000d481828f0700621000000000d481838ff1 +:10a92000b080828f23186200ec81828f2110430057 +:10a93000ec8182afc081838fe081828f070062103b +:10a9400000000000e081838fb480828f23186200b2 +:10a95000c081828f21104300c08182af029d023ce2 +:10a96000b002428c288182af029d023cb402428c2c +:10a97000608182af21100000808182af21e8c00396 +:10a980000000be8f0800bd270800e00300000000a3 +:10a99000e0ffbd271c00bfaf1800beaf21f0a00331 +:10a9a000ec81828f1000a2afc081828f1400a2af11 +:10a9b000b481848f0482858fdc81868fb881878ff4 +:10a9c0007a2a400f00000000642c400f00000000b5 +:10a9d00021e8c0031c00bf8f1800be8f2000bd27d8 +:10a9e0000800e0030000000098ffbd276400bfaf2f +:10a9f0006000beaf21f0a0036800c4af6c00c5af1b +:10aa00007000c6af7400c7af1000c0af01000224d1 +:10aa10001400c2af010002241800c2af01000224da +:10aa20001c00c2af7400c38f6800c28f2310620085 +:10aa30002000c2af7800c38f6c00c28f2310620069 +:10aa40002400c2af7c00c38f7000c28f231062004d +:10aa50002800c2af2000c38f2000c28f21106200e7 +:10aa60002c00c2af2400c38f2400c28f21106200cb +:10aa70003000c2af2800c38f2800c28f21106200af +:10aa80003400c2af6800c28f3800c2af6c00c28f02 +:10aa90003c00c2af7000c28f4000c2af4400c0afe4 +:10aaa0004800c0af4c00c0af5000c0af5400c0afb2 +:10aab0005800c0af5c00c0a3c080828f0300401468 +:10aac000000000002000c0af2c00c0afc480828f07 +:10aad00003004014000000002400c0af3000c0afed +:10aae000c880828f03004014000000002800c0af1f +:10aaf0003400c0af2000c28f0700401400000000e7 +:10ab00007400c28f6800c2afb881828fb48182aff7 +:10ab10007880828f308282af2400c28f0700401479 +:10ab2000000000007800c28f6c00c2afec81828f01 +:10ab3000048282af7c80828f188282af2800c28f0d +:10ab400007004014000000007c00c28f7000c2affc +:10ab5000c081828fdc8182af8080828f248282af2d +:10ab60002000c28f130041040000000088bf033c96 +:10ab7000d06062907f004230d06062a07f000324ea +:10ab80005c00c293241043005c00c2a3ffff0224b8 +:10ab90001400c2af2000c28f231002002000c2aff9 +:10aba0002c00c28f231002002c00c2af0a0000103c +:10abb0000000000088bf043cd060839080ff022426 +:10abc00025106200d06082a05c00c39380ff022445 +:10abd000251062005c00c2a32400c28f140041044f +:10abe0000000000088bf043cd1608390fdff022478 +:10abf00024106200d16082a05c00c393dfff0224b6 +:10ac0000241062005c00c2a3ffff02241800c2af40 +:10ac10002400c28f231002002400c2af3000c28f74 +:10ac2000231002003000c2af080000100000000036 +:10ac300088bf033cd160629002004234d16062a0c0 +:10ac40005c00c293200042345c00c2a32800c28f83 +:10ac5000120041040000000088bf033c5160629074 +:10ac600002004234516062a05c00c293080042348a +:10ac70005c00c2a3ffff02241c00c2af2800c28fe9 +:10ac8000231002002800c2af3400c28f231002003c +:10ac90003400c2af0a0000100000000088bf043c6e +:10aca00051608390fdff022424106200516082a055 +:10acb0005c00c393f7ff0224241062005c00c2a36f +:10acc0002000c28f000042380100432c2400c28fb4 +:10acd000000042380100422c24106200060040109f +:10ace000000000002800c28f030040100000000098 +:10acf0007480828f8c8182af2800c38f2000c28f26 +:10ad00002a106200010044382800c38f2400c28f3b +:10ad10002a10620001004238241082000300401013 +:10ad200000000000010002241000c2af2000c38f09 +:10ad30002800c28f2a106200010044382000c38f0f +:10ad40002400c28f2a1062000100423824108200c1 +:10ad50000300401000000000020002241000c2aff7 +:10ad60002400c38f2000c28f2a10620001004438e3 +:10ad70002400c38f2800c28f2a10620001004238cd +:10ad80002410820003004010000000000300022491 +:10ad90001000c2af2000c28f000042380100432cd7 +:10ada0002400c28f000042380100422c24186200a7 +:10adb0002800c28f000042380100422c241062009b +:10adc00002004010000000001000c0af1000c38f50 +:10add000010002244a006214000000004000c38ffa +:10ade0001c00c28f211062004000c2af4400c38f1c +:10adf0002c00c28f211062004400c2af4800c38ff4 +:10ae00003000c28f211062004800c2af4400c38fdf +:10ae10002800c28f2a1043000e00401000000000de +:10ae20003800c38f1400c28f211062003800c2aff7 +:10ae30004400c38f3400c28f231062004400c2afad +:10ae4000010002245000c2af5c00c29340004234b3 +:10ae50005c00c2a34800c28f2800c38f2a10620082 +:10ae60000e004010000000003c00c38f1800c28f8d +:10ae7000211062003c00c2af4800c38f3400c28f73 +:10ae8000231062004800c2af010002245400c2af88 +:10ae90005c00c293100042345c00c2a35c00c29309 +:10aea000040042345c00c2a35c00c3935000c28f14 +:10aeb000202c027c5400c28f2014027c21206000d0 +:10aec00021304000f92c400f000000005000c0afbe +:10aed0005400c0af5800c0af5c00c393abff022466 +:10aee000241062005c00c2a34000c38f7c00c28fac +:10aef0000300621000000000b8ff00100000000016 +:10af00001000c38f020002244a00621400000000f7 +:10af10003800c38f1400c28f211062003800c2af06 +:10af20004c00c38f3400c28f211062004c00c2afae +:10af30004800c38f3000c28f211062004800c2afaa +:10af40004c00c38f2000c28f2a1043000e00401017 +:10af5000000000004000c38f1c00c28f211062005f +:10af60004000c2af4c00c38f2c00c28f2310620080 +:10af70004c00c2af010002245800c2af5c00c29373 +:10af8000040042345c00c2a34800c28f2000c38f7b +:10af90002a1062000e004010000000003c00c38f29 +:10afa0001800c28f211062003c00c2af4800c38f5e +:10afb0002c00c28f231062004800c2af010002249f +:10afc0005400c2af5c00c293100042345c00c2a3c4 +:10afd0005c00c293400042345c00c2a35c00c39397 +:10afe0005000c28f202c027c5400c28f2014027c9f +:10aff0002120600021304000f92c400f00000000ab +:10b000005000c0af5400c0af5800c0af5c00c39345 +:10b01000abff0224241062005c00c2a33800c38f7f +:10b020007400c28f0300621000000000b8ff00101f +:10b03000000000001000c38f030002244e006214c1 +:10b04000000000003c00c38f7800c28f4a006210ed +:10b05000000000003c00c38f1800c28f2110620066 +:10b060003c00c2af4400c38f2c00c28f211062008d +:10b070004400c2af4c00c38f3400c28f2110620065 +:10b080004c00c2af4400c38f2400c28f2a1043007b +:10b090000e004010000000003800c38f1400c28f63 +:10b0a000211062003800c2af4400c38f3000c28f4d +:10b0b000231062004400c2af010002245000c2af5e +:10b0c0005c00c293400042345c00c2a34c00c28fbb +:10b0d0002400c38f2a1062000e0040100000000000 +:10b0e0004000c38f1c00c28f211062004000c2af1d +:10b0f0004c00c38f3000c28f231062004c00c2afdf +:10b10000010002245800c2af5c00c2930400423424 +:10b110005c00c2a35c00c293100042345c00c2a376 +:10b120005c00c3935000c28f202c027c5400c28f5d +:10b130002014027c2120600021304000f92c400fb7 +:10b14000000000005000c0af5400c0af5800c0afb6 +:10b150005c00c393abff0224241062005c00c2a316 +:10b160003c00c38f7800c28f030062100000000013 +:10b17000b8ff00100000000021e8c0036400bf8f8a +:10b180006000be8f6800bd270800e00300000000db +:10b19000f8ffbd270000beaf21f0a003b481828f6d +:10b1a000b88182af0482828fec8182afdc81828f92 +:10b1b000c08182af8480828f908082af8880828fae +:10b1c000948082af8c80828f988082af7880828fcb +:10b1d000848082af7c80828f888082af8080828fe3 +:10b1e0008c8082af3082828f788082af1882828f8b +:10b1f0007c8082af2482828f808082af2110000009 +:10b20000008282af21100000c88182af21100000af +:10b21000c48182af21100000e48182af21100000c0 +:10b22000d88182af211000000c8282afb48180af40 +:10b23000048280afdc8180af21e8c0030000be8fb4 +:10b240000800bd270800e00300000000d0ffbd2774 +:10b250002c00bfaf2800beaf21f0a0033000c4af68 +:10b260003000c48fc978400f00000000212040004a +:10b27000212860001000c6271075400f0000000054 +:10b280001800c2af1c00c3af1000c48f1400c58fdc +:10b290003079400f000000002000c2af029d023c48 +:10b2a000b802448cbc02458c1800c68f1c00c78fa6 +:10b2b0007379400f000000000300401800000000f8 +:10b2c00008000010000000002000c28f010042248e +:10b2d0002000c2af2000c28f2400c2af03000010c4 +:10b2e000000000002000c28f2400c2af2400c28fe3 +:10b2f00021e8c0032c00bf8f2800be8f3000bd277f +:10b300000800e00300000000d0ffbd272c00bfaf05 +:10b310002800beaf21f0a0033000c4af3000c48fbe +:10b32000c978400f00000000212040002128600063 +:10b330001000c6271075400f000000001800c2afb3 +:10b340001c00c3af1000c48f1400c58f3079400fac +:10b35000000000002000c2af029d023cc002448ced +:10b36000c402458c1800c68f1c00c78f7379400f2c +:10b37000000000000300401800000000040000105e +:10b38000000000002000c28f010042242000c2af54 +:10b39000029d023c1800c48f1c00c58fc802468c59 +:10b3a000cc02478c7379400f000000000300401866 +:10b3b0000000000004000010000000002000c28f08 +:10b3c000ffff42242000c2af2000c28f21e8c0034b +:10b3d0002c00bf8f2800be8f3000bd270800e0037f +:10b3e00000000000e0ffbd271800beaf21f0a00361 +:10b3f000211080002118a0002120c0002000c2a33d +:10b400002400c3a32800c4a30000c0af2000c2933f +:10b410000000c2af0000c28f001602000000c2afe1 +:10b420002400c28308004010000000002800c283ee +:10b4300005004010000000007080828f0400c2af41 +:10b4400003000010000000008c81828f0400c2af56 +:10b450000000c28f0400c38f251043000000c2af5c +:10b46000f081828f010042240800c2af0800c28f21 +:10b470000c00c2af0c00c38f040061040000000088 +:10b480000c00c48fff0184240c00c4af0c00c38fd8 +:10b4900043120300401202000800c48f23188200e8 +:10b4a000cc81828f0300621400000000ecff0010ca +:10b4b0000000000000a0043cf081828f8018020090 +:10b4c000c8048224211862000000c28f000062ac10 +:10b4d000f081828f01004224f08182aff081828f5f +:10b4e0001000c2af1000c38f1400c3af1400c48f8c +:10b4f00004008104000000001400c28fff014224f8 +:10b500001400c2af1400c38f4312030040120200a4 +:10b510001000c48f23108200f08182af21e8c003a5 +:10b520001800be8f2000bd270800e00300000000c7 +:10b53000e0ffbd271c00bfaf1800beaf21f0a00385 +:10b54000214080002400c5af2128c0002c00c7afd7 +:10b550003000c28f3800c38f4000c48f2000c8a3c2 +:10b560002800c5a31000c2a31100c3a31200c4a3e6 +:10b57000cc81838ff081828f0e006210000000006a +:10b580003c80838301000224f9ff62140000000064 +:10b59000f081828f01004324cc81828ff4ff6214fa +:10b5a00000000000cc81828ff08182aff0ff00109c +:10b5b0000000000021100000308282af2800c38309 +:10b5c0005800022403006214000000002c00c28f07 +:10b5d000308282af1000c38358000224030062143b +:10b5e000000000003400c28f308282af1100c3839c +:10b5f0005800022403006214000000003c00c28fc7 +:10b60000308282af1200c383580002240300621408 +:10b61000000000004400c28f308282af2800c28345 +:10b62000580042380100432c1000c28358004238b1 +:10b630000100422c251862001100c28358004238d4 +:10b640000100422c251862001200c28358004238c3 +:10b650000100422c2510620005004010000000008f +:10b6600001000224c08082af020000100000000030 +:10b67000c08080af21180000188283af2800c383e8 +:10b680005900022403006214000000002c00c28f45 +:10b69000188282af1000c383590002240300621491 +:10b6a000000000003400c28f188282af1100c383f3 +:10b6b0005900022403006214000000003c00c28f05 +:10b6c000188282af1200c38359000224030062145f +:10b6d000000000004400c28f188282af2800c2839d +:10b6e000590042380100432c1000c28359004238ef +:10b6f0000100422c251862001100c2835900423813 +:10b700000100422c251862001200c2835900423801 +:10b710000100422c251062000500401000000000ce +:10b7200001000224c48082af02000010000000006b +:10b73000c48080af21100000248282af2800c38320 +:10b740005a00022403006214000000002c00c28f83 +:10b75000248282af1000c3835a00022403006214c3 +:10b76000000000003400c28f248282af1100c38326 +:10b770005a00022403006214000000003c00c28f43 +:10b78000248282af1200c3835a0002240300621491 +:10b79000000000004400c28f248282af2800c283d0 +:10b7a0005a0042380100432c1000c2835a0042382c +:10b7b0000100422c251862001100c2835a00423851 +:10b7c0000100422c251862001200c2835a00423840 +:10b7d0000100422c2510620005004010000000000e +:10b7e00001000224c88082af0200001000000000a7 +:10b7f000c88080af211800001c8283af2800c3835b +:10b800004900022403006214000000002c00c28fd3 +:10b810001c8282af1000c38349000224030062141b +:10b82000000000003400c28f1c8282af1100c3836d +:10b830004900022403006214000000003c00c28f93 +:10b840001c8282af1200c3834900022403006214e9 +:10b85000000000004400c28f1c8282af2800c28317 +:10b86000490042380100432c1000c283490042388d +:10b870000100422c251862001100c28349004238a1 +:10b880000100422c251862001200c2834900423890 +:10b890000100422c2510620005004010000000004d +:10b8a00001000224cc8082af0200001000000000e2 +:10b8b000cc8080af21100000208282af2800c3839b +:10b8c0004a00022403006214000000002c00c28f12 +:10b8d000208282af1000c3834a0002240300621456 +:10b8e000000000003400c28f208282af1100c383a9 +:10b8f0004a00022403006214000000003c00c28fd2 +:10b90000208282af1200c3834a0002240300621423 +:10b91000000000004400c28f208282af2800c28352 +:10b920004a0042380100432c1000c2834a004238ca +:10b930000100422c251862001100c2834a004238df +:10b940000100422c251862001200c2834a004238ce +:10b950000100422c2510620005004010000000008c +:10b9600001000224d08082af02000010000000001d +:10b97000d08080af2800c3834600022405006214f3 +:10b98000000000002c00c48fa07b400f00000000ce +:10b99000b88082af1000c383460002240500621401 +:10b9a000000000003400c48fa07b400f00000000a6 +:10b9b000b88082af1100c3834600022405006214e0 +:10b9c000000000003c00c48fa07b400f000000007e +:10b9d000b88082af1200c3834600022405006214bf +:10b9e000000000004400c48fa07b400f0000000056 +:10b9f000b88082af21180000288283af2800c3835b +:10ba00005000022403006214000000002c00c28fca +:10ba1000288282af1000c383500002240300621406 +:10ba2000000000003400c28f288282af1100c3835f +:10ba30005000022403006214000000003c00c28f8a +:10ba4000288282af1200c3835000022403006214d4 +:10ba5000000000004400c28f288282af2110000045 +:10ba60002c8282af2800c383530002240300621497 +:10ba7000000000002c00c28f2c8282af1000c38314 +:10ba80005300022403006214000000003400c28f3f +:10ba90002c8282af1100c38353000224030062147e +:10baa000000000003c00c28f2c8282af1200c383d2 +:10bab0005300022403006214000000004400c28fff +:10bac0002c8282af2000c3831400c3af470002243e +:10bad0001400c38f07006210000000004d00022414 +:10bae0001400c38f4800621000000000a400001082 +:10baf000000000002400c28f148282af1482828f63 +:10bb00000300401400000000662f400f00000000fa +:10bb10001482838f010002240300621400000000dd +:10bb2000852f400f000000001482838f0200022442 +:10bb30000300621400000000ab2f400f0000000063 +:10bb40001482838f030002240300621400000000ab +:10bb5000c22f400f000000001482838f04000224d3 +:10bb60000300621400000000d92f400f0000000005 +:10bb70001482838f1400022403006214000000006a +:10bb8000f52f400f000000001482838f150002245f +:10bb90000300621400000000ff2f400f00000000af +:10bba0001482838f1c000224030062140000000032 +:10bbb0000930400f000000001482838f5a000224d5 +:10bbc00003006214000000001130400f000000006c +:10bbd0001482838f5b0002240300621400000000c3 +:10bbe0001d30400f000000001482838f5c0002248f +:10bbf00063006214000000002530400f00000000c8 +:10bc00005f000010000000002400c28f108282af8d +:10bc1000148280afb88080af1082838f65000224c9 +:10bc200003006214000000003330400f00000000e9 +:10bc30001082838f6700022403006214000000005a +:10bc40004130400f000000001082838f6800022402 +:10bc500003006214000000004e30400f000000009e +:10bc60001082838f6a000224030062140000000027 +:10bc70009230400f000000001082838f6b0002247e +:10bc80000300621400000000a030400f000000001c +:10bc90001082838f6c0002240300621400000000f5 +:10bca000ae30400f000000001082838fdc000224c1 +:10bcb0000300621400000000cc30400f00000000c0 +:10bcc0001082838fdd000224030062140000000054 +:10bcd000d930400f000000001082838fde00022464 +:10bce0000300621400000000e530400f0000000077 +:10bcf0001082838fdf000224030062140000000022 +:10bd0000ff30400f000000001082838fe00002240b +:10bd100003006214000000001931400f0000000011 +:10bd20001082838fe10002240300621400000000ef +:10bd30002331400f000000001082838fe2000224b4 +:10bd400003006214000000002c31400f00000000ce +:10bd50001082838fe30002240300621400000000bd +:10bd60006431400f000000001082838fe400022441 +:10bd700003006214000000009c31400f000000002e +:10bd800021e8c0031c00bf8f1800be8f2000bd2714 +:10bd90000800e00300000000e8ffbd271400bfaf6b +:10bda0001000beaf21f0a003b880828f03004014c2 +:10bdb00000000000c0030224b88082afb880848fe6 +:10bdc0001082858f0929400f000000005480838372 +:10bdd000010002240300621400000000010002249c +:10bde0007d8182a3bc80848f212800007f29400fa1 +:10bdf00000000000642a400f0000000021e8c0039a +:10be00001400bf8f1000be8f1800bd270800e0038c +:10be100000000000e8ffbd271400bfaf1000beaf58 +:10be200021f0a003b880828f0300401400000000be +:10be3000f0000224b88082af448182830500401064 +:10be400000000000b880828f6881838f211043003a +:10be5000b88082afb880848f1082858f0929400f07 +:10be60000000000054808383010002240300621458 +:10be700000000000010002247d8182a3bc80848f29 +:10be8000212800007f29400f00000000642a400f95 +:10be90000000000021e8c0031400bf8f1000be8f17 +:10bea0001800bd270800e00300000000e8ffbd27e0 +:10beb0001400bfaf1000beaf21f0a003b880828f86 +:10bec0000300401400000000f0000224b88082af9c +:10bed000b880848f1082858f0929400f00000000f0 +:10bee000bc80848f010005247f29400f00000000e2 +:10bef00021e8c0031400bf8f1000be8f1800bd27bb +:10bf00000800e00300000000e8ffbd271400bfaff9 +:10bf10001000beaf21f0a003b880828f0300401450 +:10bf200000000000f0000224b88082afb880848f47 +:10bf30001082858f0929400f00000000bc80848f8b +:10bf4000010005247f29400f0000000021e8c00304 +:10bf50001400bf8f1000be8f1800bd270800e0033b +:10bf600000000000e0ffbd271c00bfaf1800beafff +:10bf700021f0a0031000c0af2882848f2128000088 +:10bf8000db7b400f000000000300401400000000b5 +:10bf90000a000010000000002882848fa07b400f60 +:10bfa00000000000c8000324021043701000c2af5c +:10bfb0001000c48fce61400f0000000021e8c003d4 +:10bfc0001c00bf8f1800be8f2000bd270800e003b3 +:10bfd00000000000f8ffbd270000beaf21f0a00365 +:10bfe00014000224bc8082af21e8c0030000be8f91 +:10bff0000800bd270800e00300000000f8ffbd278f +:10c000000000beaf21f0a00315000224bc8082af67 +:10c0100021e8c0030000be8f0800bd270800e00330 +:10c0200000000000f8ffbd270000beaf21f0a00314 +:10c0300021e8c0030000be8f0800bd270800e00310 +:10c0400000000000e8ffbd271400bfaf1000beaf26 +:10c0500021f0a003362a400f0000000021e8c003b1 +:10c060001400bf8f1000be8f1800bd270800e0032a +:10c0700000000000f8ffbd270000beaf21f0a003c4 +:10c0800021e8c0030000be8f0800bd270800e003c0 +:10c0900000000000e8ffbd271400bfaf1000beafd6 +:10c0a00021f0a003662f400f00000000e229400f9e +:10c0b0000000000021e8c0031400bf8f1000be8ff5 +:10c0c0001800bd270800e00300000000f8ffbd27ae +:10c0d0000000beaf21f0a00354808383020002243d +:10c0e0000300621400000000010002247d8182a38d +:10c0f00021e8c0030000be8f0800bd270800e00350 +:10c1000000000000f8ffbd270000beaf21f0a00333 +:10c1100054808383020002240200621400000000a5 +:10c120007d8180a321e8c0030000be8f0800bd27e9 +:10c130000800e00300000000e8ffbd271400bfafc7 +:10c140001000beaf21f0a0035480838302000224bc +:10c150003700621400000000040004245964400ffa +:10c1600000000000050004245964400f0000000096 +:10c17000060004245964400f000000000500042458 +:10c1800021280000029d023cd002462421380000f4 +:10c19000d864400f00000000f48080af010002244a +:10c1a000888182a32c82848f21280000db7b400fb2 +:10c1b0000000000003004014000000000500001013 +:10c1c000000000002c82848fa07b400f0000000044 +:10c1d000fc8082af4326400f0000000001000424d1 +:10c1e0006f60400f000000002c63400f0000000053 +:10c1f000d963400f000000009063400f0000000072 +:10c20000f480828f0600401400000000fc80828fc2 +:10c210000300401000000000f3ff001000000000c9 +:10c22000888180a3050004245964400f00000000a9 +:10c2300021e8c0031400bf8f1000be8f1800bd2777 +:10c240000800e00300000000f8ffbd270000beafbb +:10c2500021f0a003010002246c8182a388bf033c6b +:10c260001061629020004234106162a021e8c00396 +:10c270000000be8f0800bd270800e003000000009a +:10c28000f8ffbd270000beaf21f0a0036c8180a3a2 +:10c2900088bf043c10618390dfff022424106200f9 +:10c2a000106182a021e8c0030000be8f0800bd27f6 +:10c2b0000800e00300000000e8ffbd271400bfaf46 +:10c2c0001000beaf21f0a00354808383020002243b +:10c2d0001100621400000000212000002c82858fd4 +:10c2e000db7b400f00000000030040040000000062 +:10c2f00005000010000000002c82848fa07b400ffe +:10c3000000000000208082afd05e400f00000000df +:10c3100001000224898182a321e8c0031400bf8f99 +:10c320001000be8f1800bd270800e00300000000c9 +:10c33000f8ffbd270000beaf21f0a00388bf043c7a +:10c34000d1608390f7ff022424106200d16082a0a4 +:10c3500021e8c0030000be8f0800bd270800e003ed +:10c3600000000000f8ffbd270000beaf21f0a003d1 +:10c3700088bf023cd160439008006334d16043a081 +:10c3800021e8c0030000be8f0800bd270800e003bd +:10c3900000000000e8ffbd271400bfaf1000beafd3 +:10c3a00021f0a00354808383020002240d00621454 +:10c3b00000000000212000002c82858fdb7b400fd5 +:10c3c0000000000003004004000000000500001011 +:10c3d000000000002c82848fa07b400f0000000032 +:10c3e000708182af21e8c0031400bf8f1000be8fa0 +:10c3f0001800bd270800e00300000000e8ffbd278b +:10c400001400bfaf1000beaf21f0a003548083839f +:10c41000020002240d006214000000002120000030 +:10c420002c82858fdb7b400f00000000030040045e +:10c430000000000005000010000000002c82848f26 +:10c44000a07b400f00000000508182af21e8c003b4 +:10c450001400bf8f1000be8f1800bd270800e00336 +:10c4600000000000f8ffbd270000beaf21f0a003d0 +:10c47000010002244c8182a321e8c0030000be8f8a +:10c480000800bd270800e00300000000f8ffbd27fa +:10c490000000beaf21f0a0034c8180a321e8c003bf +:10c4a0000000be8f0800bd270800e0030000000068 +:10c4b000d8ffbd272400bfaf2000beaf1c00b1af26 +:10c4c0001800b0af21f0a003cc81838ff081828f60 +:10c4d0000e006210000000003c80838301000224f3 +:10c4e000f9ff621400000000f081828f01004324f4 +:10c4f000cc81828ff4ff621400000000cc81828f17 +:10c50000f08182aff0ff001000000000d51b400f4b +:10c510000000000088bf023c9061428c4002427cd7 +:10c520000300401400000000faff001000000000ab +:10c530009080848fc978400f000000002180400067 +:10c54000218860009480848fc978400f000000002b +:10c550001000a0af1400a0af21200002212820026b +:10c5600021304000213860009d1e400f0000000077 +:10c5700021e8c0032400bf8f2000be8f1c00b18fb4 +:10c580001800b08f2800bd270800e003000000005d +:10c59000e8ffbd271400bfaf1000beaf21f0a0031d +:10c5a00054808383020002242b00621400000000e8 +:10c5b00001000224848182af212000002c82858f1b +:10c5c000db7b400f0000000003004004000000007f +:10c5d0000d000010000000002c82848fc978400fed +:10c5e0000000000021204000212860005775400f06 +:10c5f0000000000021204000212860003079400f19 +:10c6000000000000608282af212000002882858f18 +:10c61000db7b400f0000000003004004000000002e +:10c620000d000010000000002882848fc978400fa0 +:10c630000000000021204000212860005775400fb5 +:10c640000000000021204000212860003079400fc8 +:10c65000000000006c8282af21e8c0031400bf8f8d +:10c660001000be8f1800bd270800e0030000000086 +:10c67000f8ffbd270000beaf21f0a00354808383e4 +:10c68000020002240200621400000000848180afd6 +:10c6900021e8c0030000be8f0800bd270800e003aa +:10c6a00000000000e0ffbd271c00bfaf1800beafb8 +:10c6b00021f0a0031000c0af1000c28f0300422879 +:10c6c0000b004010000000001000c38f348282274e +:10c6d0002118620001000224000062a01000c28f35 +:10c6e000010042241000c2aff3ff00100000000060 +:10c6f000de8080a3395a400f0000000000a0023cf9 +:10c70000041244240634400f00000000300040149e +:10c71000000000001c80838f00a0023c0412422411 +:10c72000000062ac1c80828f0c0040a41c80828fb1 +:10c730000e0040a41c80828f100040ac1c80828fb1 +:10c74000140040ac1c80838f5c000224200062a097 +:10c75000010002241000c2af1000c28f0b0042285b +:10c760000b004010000000001c80838f1000c28f5f +:10c770002118620020000224200062a01000c28f55 +:10c78000010042241000c2aff3ff001000000000bf +:10c790001c80828f2c0040a41c80838f10000224f8 +:10c7a000300062a41c80838f3c82828f340062ac94 +:10c7b0001c80838f3c82828f380062ac4c8280a3c5 +:10c7c000010002241400c2af0200001000000000ab +:10c7d0001400c0af1400c28f21e8c0031c00bf8f3b +:10c7e0001800be8f2000bd270800e00300000000f5 +:10c7f000c8ffbd273000bfaf2c00beaf2800b0afd0 +:10c8000021f0a0033800c4af3c00c5af2110c00028 +:10c810002118e0004000c2a34400c3a33800c28f27 +:10c820002c0042941400c2a70b0002241800c2afcf +:10c830003800c38f3800c28f3400428c380062ac9d +:10c840003c00c28f30004294271002001200c2a7a1 +:10c850001400c2970d004014000000001400c2270d +:10c860003800c48f2128400001000624a63b400f59 +:10c870000000000013004014000000001b00022410 +:10c880001800c2af0f000010000000001400c29793 +:10c890000f0042300b004010000000001400c227bf +:10c8a0003800c48f2128400001000624a63b400f19 +:10c8b0000000000003004014000000001b000224e0 +:10c8c0001800c2af1800c38f1b000224cc006210f6 +:10c8d000000000001800c28fc900401000000000d6 +:10c8e0001400c2273800c48f21284000863f400f23 +:10c8f000000000001600c2a31600c3930200022429 +:10c900000300621400000000bd00001000000000e1 +:10c910001600c293b1004014000000003800c28f1e +:10c92000300042941000c2a71000c2973f0042306e +:10c930001000c2a74400c2932000c2af2000c38fe2 +:10c940000700601000000000010002242000c38fd7 +:10c950002d00621000000000a40000100000000084 +:10c960001000c39708000224a0006210000000001d +:10c970001800c0af6d0002241c00c2a31700c0a3a2 +:10c980001700c2930b00422c9800401000000000da +:10c990003800c38f1700c29321106200200042901c +:10c9a0001c00c2a33c00c38f1700c2932110620079 +:10c9b000200042901d00c2a31c00c2932120400011 +:10c9c000706b400f00000000218040001d00c293ea +:10c9d00021204000706b400f000000000500021293 +:10c9e000000000000b0002241800c2af7f000010fe +:10c9f000000000001700c293010042241700c2a3e8 +:10ca0000dfff0010000000001000c3971200c29763 +:10ca100024106200ffff4230740040140000000048 +:10ca20001000c3970f000224700062100000000085 +:10ca30001800c0af6d0002241c00c2a33c00c28fce +:10ca4000200043802a0002242e0062100000000013 +:10ca50001700c0a31700c2930800422c2900401001 +:10ca6000000000003800c38f1700c293211062003d +:10ca7000200042901c00c2a33c00c38f1700c29349 +:10ca800021106200200042901d00c2a31d00c3932c +:10ca90002a000224030062140000000019000010a4 +:10caa000000000001d00c3933f000224100062102c +:10cab000000000001c00c29321204000706b400f5a +:10cac00000000000218040001d00c2932120400092 +:10cad000706b400f00000000050002120000000013 +:10cae0000b0002241800c2af060000100000000076 +:10caf0001700c293010042241700c2a3d5ff001003 +:10cb0000000000003c00c28f280043802a0002245d +:10cb100036006210000000001800c28f330040147d +:10cb200000000000080002241700c2a31700c293ef +:10cb30000b00422c2d004010000000003800c38f75 +:10cb40001700c29321106200200042901c00c2a373 +:10cb50003c00c38f1700c293211062002000429056 +:10cb60001d00c2a31d00c3932a0002240300621407 +:10cb7000000000001d000010000000001d00c39315 +:10cb80003f00022410006210000000001c00c2934d +:10cb900021204000706b400f000000002180400009 +:10cba0001d00c29321204000706b400f0000000068 +:10cbb00005000212000000000b0002241800c2afa2 +:10cbc0000a000010000000001700c2930100422478 +:10cbd0001700c2a3d5ff0010000000004000c29360 +:10cbe00002004014000000001800c0af1400c297fb +:10cbf000010042241400c2a736ff0010000000000c +:10cc00001800c28f21e8c0033000bf8f2c00be8ff8 +:10cc10002800b08f3800bd270800e00300000000a6 +:10cc2000d0ffbd272c00bfaf2800beaf21f0a0036e +:10cc30003000c4af3400c5af2110c0003800c2a31b +:10cc40001c00c0af3000c28f0000428c1000c2af89 +:10cc50001000c28f21004290050040140000000027 +:10cc6000070002241c00c2af860000100000000074 +:10cc70003000c38f3000c28f3400428c380062ac69 +:10cc80003400c28f000042940c00401400000000e9 +:10cc90003000c48f3400c58f01000624a63b400f2e +:10cca0000000000013004014000000001b000224dc +:10ccb0001c00c2af0f000010000000003400c28f43 +:10ccc000000042940f0042300a00401000000000b3 +:10ccd0003000c48f3400c58f01000624a63b400fee +:10cce0000000000003004014000000001b000224ac +:10ccf0001c00c2af3000c48f3400c58f863f400f88 +:10cd0000000000001400c2a31400c29305004010ec +:10cd1000000000000b0002241c00c2af59000010ec +:10cd2000000000003000c28f100040ac3000c38f04 +:10cd30003000c28f0400428c080062ac3000c28f09 +:10cd40000c0040a43000c28f0e0040a41400c39316 +:10cd50000100022405006214000000000b00022400 +:10cd60001c00c2af24000010000000003000c28f81 +:10cd70001000c48f0800458c4c45400f0000000097 +:10cd80001800c2afdc808293090040100000000050 +:10cd90000447400f000000000500401000000000a4 +:10cda000090002242000c2af38000010000000007b +:10cdb0003000c28fd88082af1880838f1800c28f56 +:10cdc0000d00621000000000de8080a31000c28f02 +:10cdd0001800c48f0000458c285b400f0000000045 +:10cde0000300401400000000080002241c00c2af31 +:10cdf0001800c28f188082af3000c48f1800838c57 +:10ce0000fbff022424106200180082ac3800c383a8 +:10ce10007700022407006210000000003800c3837e +:10ce20006100022403006210000000000c000010ea +:10ce3000000000003000c38f1800628c01004234f3 +:10ce4000180062ac3000c48f1800838cfdff0224f0 +:10ce500024106200180082ac0a00001000000000dc +:10ce60003000c48f1800838cfeff0224241062005f +:10ce7000180082ac3000c38f1800628c020042346c +:10ce8000180062ac1c00c28f2000c2af2000c28f0d +:10ce900021e8c0032c00bf8f2800be8f3000bd27c3 +:10cea0000800e00300000000c8ffbd273400bfaf4a +:10ceb0003000beaf21f0a0033800c4af3c00c5afc6 +:10cec0002000c0a33800c28f0000428c2400c2aff3 +:10ced0002400c28f200042902800c2af010002242b +:10cee0002800c38f0f00621000000000030002241e +:10cef0002800c38f03006210000000000f00001024 +:10cf000000000000ff0f023cf8ff42341c00c2afdb +:10cf1000ff0f023cffff42341800c2af0b000010ad +:10cf200000000000f80f02241c00c2afffff023413 +:10cf30001800c2af0500001000000000f8ff023426 +:10cf40001c00c2afffff02341800c2af3800c28f0e +:10cf50000800428c1400c2af2400c48f1400c58f97 +:10cf6000f04a400f000000001000c2af1000c38f55 +:10cf70001800c28f0500621400000000080002249f +:10cf80002000c2a310000010000000002400c28f87 +:10cf90001800438c1000c28f2b1043000300401474 +:10cfa000000000000a0002242000c2a31000c28f6b +:10cfb0001c00c38f2b10430003004014000000002e +:10cfc0003c0002242000c2a33800c38f1000c28f8f +:10cfd000080062ac3c00c28fffff42243c00c2af9d +:10cfe00006004010000000002000c293030040141f +:10cff00000000000d5ff0010000000002000c293d8 +:10d0000021e8c0033400bf8f3000be8f3800bd2739 +:10d010000800e00300000000e0ffbd271c00bfafd8 +:10d020001800beaf21f0a0032000c4af1000c0a3c1 +:10d030002000c28f210040a02000c38f00a0023c2e +:10d04000c80c4224000062acba5c400f0000000033 +:10d0500021184000010002240700621000000000b7 +:10d06000060002241000c2a3060002244c8282a300 +:10d0700012000010000000002000c48f3634400f62 +:10d08000000000001000c2a31000c2930b00401467 +:10d09000000000002000c48f1435400f0000000085 +:10d0a0001000c2a31000c29304004014000000004e +:10d0b0002000c38f01000224210062a01000c2934f +:10d0c00021e8c0031c00bf8f1800be8f2000bd27c1 +:10d0d0000800e00300000000d0ffbd272c00bfaf18 +:10d0e0002800beaf21f0a0033000c4af1400c0a3dd +:10d0f0003000c28f212000000000458c285b400fcb +:10d100000000000021184000010002240700621006 +:10d1100000000000080002241400c2a3080002243a +:10d120004c8282a3c1000010000000003000c28fba +:10d130000000428c1800c2af1800c28ffe0143905d +:10d140005500022470006214000000001800c28f15 +:10d15000ff014390aa0002246b006214000000004b +:10d160003000c28f0000448c36000524f944400f83 +:10d170000000000021184000460002242d00621427 +:10d18000000000003000c28f0000448c37000524ee +:10d19000f944400f00000000211840004100022423 +:10d1a00024006214000000003000c28f0000448c94 +:10d1b00038000524f944400f000000002118400009 +:10d1c000540002241b006214000000003000c28fd3 +:10d1d0000000448c39000524f944400f0000000091 +:10d1e00021184000310002241200621400000000e7 +:10d1f0003000c28f0000448c26000524f944400f03 +:10d2000000000000211840002900022409006214d7 +:10d21000000000003000c28f040040ac3000c38f1b +:10d2200002000224200062a01c00c0af8100001098 +:10d23000000000003000c28f0000448c5200052422 +:10d24000f944400f0000000021184000460002246d +:10d250002d006214000000003000c28f0000448cda +:10d2600053000524f944400f00000000211840003d +:10d270004100022424006214000000003000c28f2c +:10d280000000448c54000524f944400f00000000c5 +:10d2900021184000540002241b006214000000000a +:10d2a0003000c28f0000448c55000524f944400f23 +:10d2b0000000000021184000330002241200621414 +:10d2c000000000003000c28f0000448c42000524a2 +:10d2d000f944400f000000002118400029000224fa +:10d2e00009006214000000003000c28f040040ac4e +:10d2f0003000c38f03000224200062a01c00c0afd6 +:10d300004c000010000000003000c28f0000428c72 +:10d310001000c2af1000c28ffe01439055000224de +:10d3200008006214000000001000c28fff0143904b +:10d33000aa0002240300621400000000070000108d +:10d3400000000000040002244c8282a30400022496 +:10d350001400c2a335000010000000003000c48f8c +:10d360001000c28fc9014388c60143982110600094 +:10d37000040082ac1000c28fc20142901500c2a30b +:10d380001500c2932000c2af2000c38f0f00622c93 +:10d390002200401000000000010002242000c38f82 +:10d3a000041062002400c2af2400c38f50406230da +:10d3b00010004014000000002400c38f00186230e9 +:10d3c00011004014000000002400c38f02006230ee +:10d3d00003004014000000001000001000000000d6 +:10d3e0003000c38f01000224200062a00f00001053 +:10d3f000000000003000c38f02000224200062a061 +:10d400000a000010000000003000c38f0300022457 +:10d41000200062a0050000100000000005000224aa +:10d420004c8282a3050002241400c2a31400c293fc +:10d430001c00c2af1c00c28f21e8c0032c00bf8fac +:10d440002800be8f3000bd270800e0030000000068 +:10d45000c0ffbd273800bfaf3400beaf3000b0af53 +:10d4600021f0a0034000c4af1c00c0a34000c28f45 +:10d470004000c38f0400448c0000658c285b400f83 +:10d480000000000021184000010002240700621083 +:10d4900000000000080002244c8282a3080002243d +:10d4a0001c00c2a3d3000010000000004000c28f87 +:10d4b0000000428c2000c2af2000c28ffe014390ca +:10d4c0005500022408006214000000002000c28ff2 +:10d4d000ff014390aa000224030062140000000030 +:10d4e0000700001000000000030002244c8282a309 +:10d4f000030002241c00c2a3be00001000000000b4 +:10d500004000c28f0000448c0e0005240845400fe7 +:10d51000000000002600c2a74000d08f4000c28f4c +:10d520000000448c0d000524f944400f0000000069 +:10d530001f0002a24000c48f4000c28f2600c39784 +:10d540000400428c21104300080082ac4000d08fc0 +:10d550004000c28f0000448c10000524f944400fa5 +:10d56000000000001e0002a24000d08f4000c28fc9 +:10d570000000448c160005240845400f0000000000 +:10d580001c0002a64000c28f1c00429408004014f8 +:10d59000000000004000d08f4000c28f0000448c8b +:10d5a000240005242745400f000000001c0002a6af +:10d5b0004000c48f4000c58f4000c28f1e004390c2 +:10d5c0004000c28f1c004294021862700800a28cb6 +:10d5d000211043000c0082ac4000d08f4000c28f6d +:10d5e0000000448c110005240845400f0000000095 +:10d5f000140002a64000c28f0000448c13000524d2 +:10d600000845400f000000001400c2af1400c28f94 +:10d6100007004014000000004000c28f0000448c4e +:10d62000200005242745400f000000001400c2af71 +:10d630004000c28f0000448c0b0005240845400fb9 +:10d64000000000002400c2a72400c2970700401079 +:10d65000000000002400c297010042300300401483 +:10d66000000000000700001000000000030002247a +:10d670004c8282a3030002242800c2af5f00001086 +:10d68000000000004000c28f1400429440190200c4 +:10d690002400c29721106200ffff43242400c29798 +:10d6a0001a006200f4014000121000001000c2af26 +:10d6b0002600c4974000c28f1e0043904000c28fd6 +:10d6c0001c00429402106270211882001000c28f68 +:10d6d000211862001400c28f231043001800c2af4b +:10d6e0004000c48f4000c28f1f0043901800c28fbb +:10d6f0001b004300f401600012100000180082ac0f +:10d700004000c28f1800428cf50f422c06004010da +:10d71000000000004000c38f01000224200062a02e +:10d720000f000010000000004000c28f1800438c62 +:10d73000f4ff02342b1043000600401400000000e8 +:10d740004000c38f02000224200062a004000010e9 +:10d75000000000004000c38f03000224200062a0ec +:10d760004000c28f20004390030002240f00621487 +:10d77000000000004000c28f0000448c2c000524f3 +:10d780002745400f000000003c8282af4000c48f5c +:10d790004000c28f0c00438c1000c28f2110620029 +:10d7a000100082ac0b000010000000003c8280af33 +:10d7b0004000c58f4000c48f4000c28f14004294c7 +:10d7c00002110200ffff43300c00828c2110430045 +:10d7d0001000a2ac2400c3970002022405006210ce +:10d7e00000000000030002241c00c2a30300022466 +:10d7f0004c8282a31c00c2932800c2af2800c28fb3 +:10d8000021e8c0033800bf8f3400be8f3000b08fd6 +:10d810004000bd270800e00300000000f0ffbd2726 +:10d820000800beaf21f0a0031000c4af0000c0afdd +:10d830001000c28f140042940000c2af0000c28fdb +:10d84000001402000000c2af1000c28f1a004394ff +:10d850000000c28f251043000000c2af0000c28f3d +:10d8600021e8c0030800be8f1000bd270800e003b8 +:10d8700000000000d8ffbd272400bfaf2000beafce +:10d8800021f0a0032800c4af2c00c5af1400c0af26 +:10d890002800c28f07004010000000002c00c28f3b +:10d8a0000200422c0300401400000000050000109c +:10d8b00000000000ffff02241c00c2aff6000010b1 +:10d8c000000000002c00c28fffff43242800c28ffd +:10d8d0002b1062000500401000000000ffff022432 +:10d8e0001c00c2afec00001000000000dc8082933e +:10d8f00009004010000000000447400f0000000035 +:10d900000500401000000000ffff02241c00c2af11 +:10d91000e10000100000000000a0023cc80c4424fc +:10d920002128000000020624d169400f00000000f9 +:10d9300000a0023cc80c42241000c2af2800c28fd5 +:10d940001800c2af1800c48f1505023c5b56423464 +:10d9500019008200101800002310830042100200fa +:10d960002110620042130200801302001400c2afb3 +:10d970001800c58f1505023c5b5642341900a20001 +:10d98000101800002310a3004210020021106200b2 +:10d990004223020021108000801902002318640035 +:10d9a00000120300231043002310a2001800c2af8e +:10d9b0001800c48f1004023c054142341900820053 +:10d9c0001018000023108300421002002110620092 +:10d9d00042110200801902001400c28f251043007a +:10d9e0001400c2af1800c48f1004023c0541423439 +:10d9f000190082001018000023108300421002005a +:10da00002110620042190200211060008011020002 +:10da100023104300231082001800c2af1800c28fe9 +:10da2000010043241400c28f251043001400c2af2c +:10da300000a0023cc80c43241400c28f0214020050 +:10da4000bf0162a000a0023cc80c43241400c28f96 +:10da500002120200c00162a000a0023cc80c4324d4 +:10da60001400c28fc10162a01000c28f2c00c48fad +:10da70002800c38f23188300cd0143a8ca0143b8ef +:10da80001000c28fcd014388ca0143982110600065 +:10da90003910422c06004010000000001000c38f17 +:10daa00001000224c20162a0120000100000000068 +:10dab0001000c28fcd014388ca0143983f00023c49 +:10dac0005ffd42342b1043000600401400000000ac +:10dad0001000c38f06000224c20162a005000010de +:10dae00000000000ffff02241c00c2af6a0000100b +:10daf000000000001000c28f2800c38fc90143a896 +:10db0000c60143b82800c38f2c00c28f21106200c9 +:10db1000ffff42241800c2af1800c48f1505023c55 +:10db20005b56423419008200101800002310830055 +:10db30004210020021106200421302008013020012 +:10db40001400c2af1800c58f1505023c5b56423465 +:10db50001900a200101800002310a30042100200b8 +:10db6000211062004223020021108000801902006f +:10db70002318640000120300231043002310a200a6 +:10db80001800c2af1800c48f1004023c0541423493 +:10db900019008200101800002310830042100200b8 +:10dba0002110620042110200801902001400c28f8d +:10dbb000251043001400c2af1800c48f1004023cab +:10dbc0000541423419008200101800002310830020 +:10dbd0004210020021106200421902002110600070 +:10dbe0008011020023104300231082001800c2afee +:10dbf0001800c28f010043241400c28f2510430077 +:10dc00001400c2af00a0023cc80c43241400c28f11 +:10dc100002140200c30162a000a0023cc80c43240d +:10dc20001400c28f02120200c40162a000a0023cd4 +:10dc3000c80c43241400c28fc50162a01000c28f1b +:10dc4000be0140a01000c38f55000224fe0162a057 +:10dc50001000c38faaff0224ff0162a02120000050 +:10dc600000a0023cc80c452401000624b05b400f14 +:10dc7000000000002118400001000224050062108d +:10dc800000000000ffff02241c00c2af02000010d1 +:10dc9000000000001c00c0af1c00c28f21e8c003c0 +:10dca0002400bf8f2000be8f2800bd270800e0039e +:10dcb0000000000068ffbd279400bfaf9000beaf1a +:10dcc00021f0a003211080009c00c5afa000c6afca +:10dcd0009800c2a32800c2275000c2af4c8280a384 +:10dce0005000c38f00a0023cc80c4224000062ac6c +:10dcf000395a400f00000000ba5c400f00000000dd +:10dd000021184000010002240700621000000000fa +:10dd1000060002244c8282a3ffff02246400c2afeb +:10dd20007e030010000000002120000000a0023c43 +:10dd3000c80c4524285b400f000000000700401479 +:10dd4000000000001b0002244c8282a3ffff03247a +:10dd50006400c3af71030010000000005000c28fc8 +:10dd60000000428c2000c2af2000c28ffe01439011 +:10dd7000550002245a006214000000002000c28fe7 +:10dd8000ff014390aa000224550062140000000025 +:10dd90005000c28f0000448c36000524f944400f27 +:10dda00000000000211840004600022443006214d5 +:10ddb000000000005000c28f0000448c3700052492 +:10ddc000f944400f000000002118400041000224e7 +:10ddd0003a006214000000005000c28f0000448c22 +:10dde00038000524f944400f0000000021184000cd +:10ddf0005400022431006214000000005000c28f61 +:10de00000000448c39000524f944400f0000000054 +:10de10002118400031000224280062140000000094 +:10de20005000c28f0000448c26000524f944400fa6 +:10de30000000000021184000290002241f00621485 +:10de4000000000009800c2836800c2af6800c38f62 +:10de50000d00601000000000010002246800c38f64 +:10de600003006210000000001d0000100000000010 +:10de70001f0002244c8282a3ffff02246400c2af71 +:10de800026030010000000005000c28f040040acc8 +:10de90005000c48f1435400f0000000010004010e7 +:10dea000000000001b0002244c8282a3ffff032419 +:10deb0006400c3af190300100000000000a0023c82 +:10dec000c80c42241000c2af5000c48f1000c28f93 +:10ded000c9014388c601439821106000040082ac48 +:10dee0009800c2838400c2af8400c38f090260100f +:10def00000000000010002248400c38f03006210b0 +:10df0000000000000e020010000000001000c28f90 +:10df1000cd014388ca014398211060001400c2afac +:10df20001400c28f3910422c2d0040100000000058 +:10df30005000c38f01000224200062a01000c38f94 +:10df400001000224c20162a02120000000a0023cc6 +:10df5000c80c452401000624b05b400f00000000ff +:10df60000700401400000000090002244c8282a334 +:10df7000ffff02246400c2afe802001000000000ae +:10df80001400c28f2810422c06004014000000002c +:10df90005000c38f020002241f0062a00400001082 +:10dfa000000000005000c38f010002241f0062a087 +:10dfb00000a0023cc80c44242128000000020624d2 +:10dfc000d169400f0000000000a0023cc80c4324af +:10dfd000320002243a0062a04d0000100000000050 +:10dfe0001400c38f3f00023c5ffd42342b104300fe +:10dff00041004014000000005000c38f02000224c2 +:10e00000200062a01000c38f06000224c20162a09b +:10e010002120000000a0023cc80c45240100062479 +:10e02000b05b400f0000000007004014000000003b +:10e03000090002244c8282a3ffff03246400c3afc3 +:10e04000b6020010000000001400c28fe8fd422458 +:10e050001800c2af5000c38f010002241f0062a04d +:10e060001800c28fedff03342b1062000b0040102c +:10e07000000000005000c38f5000c28f1f0042906c +:10e08000401002001f0062a01800c28f4210020060 +:10e090001800c2aff2ff0010000000005000c28f55 +:10e0a0001f0042908100422c070040140000000035 +:10e0b000040002244c8282a3ffff02246400c2af4a +:10e0c000960200100000000000a0023cc80c44248e +:10e0d0002128000000020624d169400f0000000042 +:10e0e00000a0023cc80c4324360002243a0062a07f +:10e0f0000700001000000000170002244c8282a3d9 +:10e10000ffff03246400c3af84020010000000007e +:10e110005000c28f1f004290401802001400c28fae +:10e1200021106200dfff42245800c2af5000c28fae +:10e130002000439001000224090062140000000046 +:10e140005000c28f1f0043905501022402106270dc +:10e15000020042245c00c2af060000100000000074 +:10e160005000c28f1f0042900012020002004224a1 +:10e170005c00c2af5c00c38f5800c28f21106200e8 +:10e18000ffff43245c00c28f1b006200f4014000cb +:10e19000121000005800c2af00a0033cebff0224a5 +:10e1a000c80c62a000a0023cc80c43243c0002241e +:10e1b000010062a000a0023cc80c432490ff02248e +:10e1c000020062a000a0023cc80c43244d000224bf +:10e1d000030062a000a0023cc80c432443000224b8 +:10e1e000040062a000a0023cc80c432448000224a2 +:10e1f000050062a000a0023cc80c43245000022489 +:10e20000060062a000a0023cc80c432420000224a7 +:10e21000070062a000a0023cc80c43244600022470 +:10e22000080062a000a0023cc80c43244100022464 +:10e23000090062a000a0023cc80c43245400022440 +:10e240000a0062a000a0023cc80c42240b0040a0bf +:10e2500000a0023cc80c4324020002240c0062a06f +:10e2600000a0023cc80c43245000c28f1f00429003 +:10e270000d0062a000a0023cc80c43240800022448 +:10e280000e0062a000a0023cc80c42240f0040a077 +:10e290005000c38f5000c28f0400428c08004224fb +:10e2a000080062ac00a0023cc80c43240200022417 +:10e2b000100062a05000c38f020002241e0062a062 +:10e2c00000a0023cc80c4224110040a000a0023c67 +:10e2d000c80c432402000224120062a05000c38f25 +:10e2e00000020224140062a400a0023cc80c4224d4 +:10e2f000130040a000a0023cc80c4224140040a01f +:10e3000000a0023cc80c4324f8ff0224150062a0c0 +:10e3100000a0023cc80c43245800c28f160062a023 +:10e3200000a0023cc80c43245800c28f0212020015 +:10e33000170062a05000c38f5800c28f1c0062a457 +:10e3400000a0023cc80c43243f000224180062a035 +:10e3500000a0023cc80c4224190040a000a0023cce +:10e36000c80c4324ffff02241a0062a000a0023c54 +:10e37000c80c42241b0040a000a0023cc80c43244f +:10e380005000c28f0400428c1c0062a000a0023c1e +:10e39000c80c43245000c28f0400428c02120200b9 +:10e3a0001d0062a000a0023cc80c43245000c28f94 +:10e3b0000400428c021402001e0062a000a0023c75 +:10e3c000c80c43245000c28f0400428c0216020085 +:10e3d0001f0062a000a0023cc80c43241400c28f9e +:10e3e000200062a000a0023cc80c43241400c28f8d +:10e3f00002120200210062a000a0023cc80c4324cb +:10e400001400c28f02140200220062a000a0023c8d +:10e41000c80c43241400c28f02160200230062a01d +:10e4200000a0023cc80c4224240040a000a0023cf2 +:10e43000c80c4224250040a000a0023cc80c432484 +:10e4400029000224260062a000a0023cc80c44243b +:10e450009c00c28fffff032424104300270082a0ea +:10e4600000a0023cc80c42246c00c2af9c00c28fca +:10e470007000c2af7000c28f0400410400000000b1 +:10e480007000c38fff0063247000c3af7000c38fa0 +:10e4900003120300ffff0324241043006c00c38f0a +:10e4a000280062a000a0023cc80c42247400c2af45 +:10e4b0009c00c28f7800c2af7800c28f0500410473 +:10e4c00000000000ffff02347800c38f21186200b3 +:10e4d0007800c3af7800c38f03140300ffff032449 +:10e4e000241043007400c38f290062a000a0023ce6 +:10e4f000c80c42247c00c2af9c00c28f8000c2af17 +:10e500008000c28f0600410400000000ff00023cb2 +:10e51000ffff42348000c38f211862008000c3af28 +:10e520008000c38f03160300ffff03242410430061 +:10e530007c00c38f2a0062a0a000c28f2900401077 +:10e54000000000006000c0a36000c393a000c28f61 +:10e550002110620000004280130040100000000003 +:10e560006000c2930b00422c0f004010000000001e +:10e5700000a0023c6000c393c80c4224212062002a +:10e580006000c393a000c28f21106200000042907f +:10e590002b0082a06000c293010042246000c2a34d +:10e5a000e9ff0010000000006000c2930b00422c45 +:10e5b0001b0040100000000000a0043c6000c3935a +:10e5c000010062246000c2a3ff006330c80c8224f3 +:10e5d00021186200200002242b0062a0f2ff00102c +:10e5e000000000006000c0a36000c2930b00422c3a +:10e5f0000b0040100000000000a0023c6000c3932c +:10e60000c80c4224211062002b0040a06000c2937d +:10e61000010042246000c2a3f3ff001000000000cc +:10e6200000a0023cc80c432446000224360062a02d +:10e6300000a0023cc80c432441000224370062a021 +:10e6400000a0023cc80c432454000224380062a0fd +:10e6500000a0023cc80c432431000224390062a00f +:10e6600000a0023cc80c4324200002243b0062a00e +:10e6700000a0023cc80c4324200002243c0062a0fd +:10e6800000a0023cc80c4324200002243d0062a0ec +:10e6900000a0023cc80c432455000224fe0162a0e5 +:10e6a00000a0023cc80c4324aaff0224ff0162a080 +:10e6b0005000c48f5000c58f5000c28f1e00439081 +:10e6c0005000c28f1c004294021862700800a28c95 +:10e6d000211043000c0082ac5000c28f0400448c17 +:10e6e00000a0023cc80c452421300000b05b400f64 +:10e6f000000000001800401400000000090002247f +:10e700004c8282a3ffff02246400c2af0301001009 +:10e71000000000005000c48f1435400f00000000be +:10e720000d004010000000001b0002244c8282a358 +:10e73000ffff03246400c3aff800001000000000d6 +:10e740001f0002244c8282a3ffff02246400c2af98 +:10e75000f20000100000000000a0023cc80c44249d +:10e760002128000000020624d169400f00000000ab +:10e7700000a0033cf8ff0224c80c62a000a0023ce9 +:10e78000c80c4324ffff0224010062a000a0023c49 +:10e79000c80c4324ffff0224020062a05000c28f75 +:10e7a00020004390020002240500621400000000d3 +:10e7b00000a0023cc80c4324ffff0224030062a017 +:10e7c0005000c28f1e004290ffff42245400c2a797 +:10e7d0005400c397ffff02341900621000000000cc +:10e7e0005000c48f5400c3975000c28f1c00429445 +:10e7f000021862700800828c211062002120400003 +:10e8000000a0023cc80c452421300000b05b400f42 +:10e81000000000000500401400000000ffff02247b +:10e820006400c2afbd000010000000005400c29799 +:10e83000ffff42245400c2a7e5ff001000000000c3 +:10e8400000a0023cc80c4424212800000400062437 +:10e85000d169400f000000005000c28f0800428cb8 +:10e86000010042246000c2a36000c5935000c48f21 +:10e870005000c28f1c0043940800828c211062005b +:10e880002b10a20025004010000000005000c28f95 +:10e890001e004290ffff42245400c2a75400c397b9 +:10e8a000ffff023418006210000000006000c493f3 +:10e8b0005400c3975000c28f1c0042940210627033 +:10e8c000211082002120400000a0023cc80c4524f9 +:10e8d00021300000b05b400f000000000500401434 +:10e8e00000000000ffff02246400c2af8b00001094 +:10e8f000000000005400c297ffff42245400c2a74a +:10e90000e6ff0010000000006000c29301004224f6 +:10e910006000c2a3d4ff0010000000005000c28fae +:10e920001400429440110200ff0142248800c2af4b +:10e930008800c38f04006104000000008800c28fbb +:10e94000ff0142248800c2af8800c38f4312030036 +:10e950001c00c2af010002246000c2a36000c29389 +:10e960001c00c38f2b104300160040100000000055 +:10e970005000c28f6000c3930c00428c21106200d3 +:10e980002120400000a0023cc80c4524213000009a +:10e99000b05b400f000000000500401400000000c4 +:10e9a000ffff02246400c2af5c0000100000000002 +:10e9b0006000c293010042246000c2a3e7ff001080 +:10e9c00000000000a000c28f4600401000000000c0 +:10e9d0006000c0a36000c393a000c28f211062003a +:10e9e0000000428013004010000000006000c2934d +:10e9f0000b00422c0f0040100000000000a0023c61 +:10ea00006000c393c80c4224212062006000c393bd +:10ea1000a000c28f2110620000004290000082a07e +:10ea20006000c293010042246000c2a3e9ff00100d +:10ea3000000000006000c2930b00422c0c0040104c +:10ea40000000000000a0043c6000c39301006224a9 +:10ea50006000c2a3ff006330c80c8224211862004a +:10ea600020000224000062a0f2ff0010000000005d +:10ea700000a0023cc80c4324080002240b0062a042 +:10ea800000a0023cc80c432411000224110062a023 +:10ea900000a0023cc80c432411000224130062a011 +:10eaa00000a0023cc80c432411000224170062a0fd +:10eab0005000c28f0c00448c00a0023cc80c4524be +:10eac00021300000b05b400f000000001200401435 +:10ead00000000000ffff03246400c3af0f0000101c +:10eae000000000005000c28f0c00448c00a0023ccb +:10eaf000c80c452421300000b05b400f000000002e +:10eb00000500401400000000ffff02246400c2afb3 +:10eb100002000010000000006400c0af6400c28f5b +:10eb200021e8c0039400bf8f9000be8f9800bd27de +:10eb30000800e00300000000d0ffbd272c00bfaf9d +:10eb40002800beaf21f0a0033000c4af3400c5af31 +:10eb50003000c28f0000428c1000c2af3000c28f64 +:10eb60003800428c1c00c2af3400c28f00004294b7 +:10eb7000021102001500c2a31000c28f20004290b3 +:10eb80002000c2af2000c38f010062281f00401484 +:10eb9000000000002000c38f030062281000401412 +:10eba00000000000030002242000c38f0300621055 +:10ebb0000000000015000010000000001000c28fcf +:10ebc0001500c3931f0042901b006200f401400037 +:10ebd000101000001500c2a30c000010000000007f +:10ebe0001c00c38f3c82828f08006210000000006e +:10ebf0001000c28f1500c3931f0042901b006200db +:10ec0000f4014000101000001500c2a31000c48fd2 +:10ec10001c00c58f4c45400f000000001800c2af1b +:10ec20001500c3931800c28f211062001000c38f1b +:10ec3000212040000000658c21300000b05b400fb7 +:10ec40000000000004004014000000001400c0a3f5 +:10ec50000300001000000000010002241400c2a301 +:10ec60001400c29321e8c0032c00bf8f2800be8f80 +:10ec70003000bd270800e00300000000d0ffbd27e2 +:10ec80002c00bfaf2800beaf21f0a0033000c4affe +:10ec90003400c5af1c00c0af3400c28f20004290ca +:10eca0002400c2af020002242400c38f19006210a6 +:10ecb000000000002400c38f0300622807004010fa +:10ecc00000000000010002242400c38f170062101e +:10ecd00000000000190000100000000003000224e2 +:10ece0002400c38f03006210000000001300001016 +:10ecf00000000000ff0f023cffff42341800c2afcb +:10ed0000ff0f023cf8ff42341400c2af0b000010aa +:10ed100000000000ffff02341800c2aff8ff023409 +:10ed20001400c2af0500001000000000ffff023415 +:10ed30001800c2aff80f02241400c2af3000c28f17 +:10ed400007004010000000003000c38f01000224c3 +:10ed50000300621000000000050000100000000029 +:10ed6000020002241c00c2af3500001000000000a9 +:10ed70001c00c28f32004014000000003400c48f19 +:10ed80003000c58ff04a400f000000001000c2aff5 +:10ed90001000c38f1800c28f05006214000000002d +:10eda000010002241c00c2aff1ff001000000000af +:10edb0001000c28f07004010000000001000c38f39 +:10edc0000100022403006210000000000500001092 +:10edd00000000000020002241c00c2afe4ff00108b +:10ede000000000001000c28f1400c38f2b104300de +:10edf0000300401400000000020002241c00c2af07 +:10ee00003400c48f3000c58f21300000213800004d +:10ee1000124c400f00000000211840001800c28f63 +:10ee20000300621400000000010002241c00c2afb5 +:10ee30001000c28f3000c2afcdff001000000000f4 +:10ee40003400c48f21280000213000000100072475 +:10ee5000124c400f000000001c00c38f020002246f +:10ee60000500621400000000010002242000c2af6f +:10ee700002000010000000002000c0af2000c28f80 +:10ee800021e8c0032c00bf8f2800be8f3000bd27b3 +:10ee90000800e00300000000c0ffbd273c00bfaf3a +:10eea0003800beaf21f0a0034000c4af4400c5af9e +:10eeb0002110c0004800c2a34000c28f0000428c55 +:10eec0001400c2af4000c28f3400428c1c00c2af9d +:10eed0004000c28f3800428c2400c2af4400c28f71 +:10eee00000004294021102002800c2a31400c28f45 +:10eef000200042903000c2af3000c38f0100622872 +:10ef000023004014000000003000c38f030062287b +:10ef10001300401400000000030002243000c38fdf +:10ef20000300621000000000190000100000000043 +:10ef30001400c28f2800c3931f0042901b00620080 +:10ef4000f4014000101000002800c2a3ff0f023c93 +:10ef5000f8ff42342000c2af0d0000100000000096 +:10ef60001c00c28f08004010000000001400c28f77 +:10ef70002800c3931f0042901b006200f401400070 +:10ef8000101000002800c2a3f8ff02342000c2af16 +:10ef90004800c29306004014000000004400c28fe5 +:10efa000000042940f0042308f0040140000000027 +:10efb0002800c29306004014000000004400c28fe5 +:10efc000000042941000422c060040100000000097 +:10efd0004800c29303004014000000002c00001001 +:10efe000000000001c00c28f04004014000000005c +:10eff0002400c0af26000010000000004800c293ab +:10f000000d004010000000004400c38f1400c28fa8 +:10f010001f0042900011020000006394ffff423085 +:10f020001b006200f4014000121000002900c2a37e +:10f030000300001000000000010002242900c2a308 +:10f040002900c29312004010000000001400c48f79 +:10f050002400c58ff04a400f000000002400c2af1a +:10f060002400c38f2000c28f2b10620003004014c5 +:10f070000000000006000010000000002900c293fc +:10f08000ffff42242900c2a3edff00100000000092 +:10f090002400c28f2000c38f2b1043004d0040106e +:10f0a000000000004000c38f2400c28f380062ac13 +:10f0b0001400c48f2400c58f4c45400f0000000091 +:10f0c0001800c2af2400c38f3c82828f11006214eb +:10f0d000000000002800c3931800c28f21186200ae +:10f0e0001400c28f1000428c2b10620009004014e3 +:10f0f000000000001400c28f20004390030002248f +:10f1000004006210000000001000c0af3f000010bb +:10f1100000000000dc808293080040100000000026 +:10f120000447400f000000000400401000000000f1 +:10f130002c00c0af3700001000000000d88080af66 +:10f14000de8080a32800c3931800c28f21106200c4 +:10f150001400c38f212040000000658c285b400f05 +:10f160000000000021184000010002240400621089 +:10f17000000000001000c0af1200001000000000ee +:10f180004800c2930c004010000000001400c48f1f +:10f190004400c28f000042940f004230ffff423013 +:10f1a000401902000000828c211043001000c2af01 +:10f1b00004000010000000001400c28f0000428c08 +:10f1c0001000c2afffff0224188082af0f000010b2 +:10f1d0000000000001000224dd8082a31000c0af07 +:10f1e0000a000010000000001400c48f4400c28f09 +:10f1f000000042940f004230ffff423040190200ed +:10f200000000828c211043001000c2af1000c28f9a +:10f210002c00c2af2c00c28f21e8c0033c00bf8f7e +:10f220003800be8f4000bd270800e003000000004a +:10f23000d0ffbd272c00bfaf2800beaf21f0a00338 +:10f240003000c4af3400c5af2110c0003800c2a3e5 +:10f250001400c0af4c8280a31000c0a31000c29362 +:10f260000b00422c0e004010000000001000c39361 +:10f270001000c227212062003000c38f1000c2930b +:10f280002110620020004290080082a01000c2936a +:10f29000010042241000c2a3f0ff00100000000093 +:10f2a0003400c28f000040a43000c48f3400c58fea +:10f2b000033d400f0000000013004010000000005c +:10f2c0001800c2273800c3933000c48f21284000a3 +:10f2d0003400c68f213860009e3d400f00000000c2 +:10f2e0001400c2af1400c28f0900401400000000d7 +:10f2f0003000c48fcd3c400f000000001400c2afae +:10f300000300001000000000140002241400c2af2b +:10f310001400c28f4c8282a31400c28f21e8c00364 +:10f320002c00bf8f2800be8f3000bd270800e003ef +:10f3300000000000d0ffbd272c00bfaf2800beafeb +:10f3400021f0a0033000c4af3000c28f2c004294e3 +:10f350001c00c2a71400c2273000c48f212840001f +:10f360004f44400f000000001000c2af1000c28fd9 +:10f370001f004014000000001c00c2273000c48f92 +:10f38000212840003c40400f000000002000c2af98 +:10f390002000c38f1400c28f1a0062a41400c38f10 +:10f3a000ff0f023c241062001800c2af1800c28f89 +:10f3b000021402001800c2af2000c38f1800c28fd1 +:10f3c000140062a41c00c2273000c48f2128400012 +:10f3d000ce3a400f00000000211840000100022436 +:10f3e0000300621000000000090002241000c2aff8 +:10f3f0001000c28f21e8c0032c00bf8f2800be8ff1 +:10f400003000bd270800e00300000000d0ffbd274a +:10f410002c00bfaf2800beaf21f0a0033000c4af66 +:10f420003400c5af010002241000c2a33000c38f16 +:10f430003000c28f3400428c380062ac3000c48f80 +:10f440003400c58f01000624a63b400f00000000d9 +:10f450001c00c2af1c00c28f050040140000000059 +:10f460001b0002241000c2a3740000100000000062 +:10f470001000c393010002246d006214000000001c +:10f480001100c0a33400c28f000042941400c2a730 +:10f490003000c48f3400c58f21300000a63b400fe0 +:10f4a000000000001c00c2af1c00c28f0000429090 +:10f4b0001200c2a33400c38f3400c28f00004294f4 +:10f4c00001004224000062a41200c393e50002245c +:10f4d00004006210000000001200c2930c004014ef +:10f4e000000000001c00c28f090040100000000056 +:10f4f0001100c293010042241100c2a3ff00423058 +:10f500000300401400000000e1ff001000000000b4 +:10f510001c00c28f3c004014000000003000c28f6d +:10f520003800428c1800c2af1800c38f3c82828f13 +:10f5300020006214000000003000c28f0000428ce6 +:10f540002000439003000224050062100000000028 +:10f55000020002241000c2a3c5ff0010000000003a +:10f560003000c38f1800c28f080062ac3000c48f17 +:10f5700001000524443e400f000000002118400017 +:10f58000150002240500621400000000020002249d +:10f590001000c2a3b6ff0010000000003400c38fab +:10f5a0001400c297000062a41000c0a3b0ff0010b6 +:10f5b000000000003000c38f1800c28f080062ac4a +:10f5c0003000c48f01000524443e400f00000000bd +:10f5d00021184000150002240500621400000000fc +:10f5e000020002241000c2a3a1ff001000000000ce +:10f5f0003400c38f1400c297000062a41000c0a39f +:10f600009bff0010000000001100c39301000224c2 +:10f6100097ff6214000000001000c0a33400c38fe5 +:10f620001400c297000062a491ff001000000000c7 +:10f630003400c38f1400c297000062a41000c2936c +:10f640000500401400000000010002242000c2afa9 +:10f6500002000010000000002000c0af2000c28f98 +:10f6600021e8c0032c00bf8f2800be8f3000bd27cb +:10f670000800e00300000000d8ffbd272400bfaf52 +:10f680002000beaf21f0a0032800c4af2c00c5affe +:10f690003000c6af2110e0003400c2a31000c0a3a8 +:10f6a0002800c38f2800c28f3400428c380062ac1f +:10f6b0002800c48f3000c58f01000624a63b400ff0 +:10f6c000000000001400c2af1400c28f05004014f7 +:10f6d000000000001b0002241800c2af5a000010f6 +:10f6e000000000001400c48f2c00c58f0b000624fe +:10f6f000f16a400f000000003400c393120002249e +:10f7000006006214000000001400c38f10000224e1 +:10f710000b0062a004000010000000001400c38f62 +:10f72000200002240b0062a01400c28f0c0040a035 +:10f730001400c28f140040a41400c28f1a0040a409 +:10f740001400c28f1c0040ac193e400f00000000a6 +:10f750001400c38f378282930d0062a01400c38f00 +:10f76000388282970e0062a41400c38f428282976f +:10f77000100062a43400c393120002240c00621033 +:10f78000000000001400c38f4a828297120062a416 +:10f790001400c38f4e828297160062a41400c38f98 +:10f7a00040828297180062a4070000100000000049 +:10f7b0001400c28f120040a41400c28f160040a48f +:10f7c0001400c28f180040a42800c38f1400c28ff9 +:10f7d0001c00428c140062ac2800c38f1400c28f3e +:10f7e0000e0042941c0062a42800c38f1400c28f34 +:10f7f000100042941e0062a42800c38f1400c28f20 +:10f800000b004290300062a42800c38f3000c28fea +:10f81000000042942c0062a42800c48f3000c58fe1 +:10f82000ce3a400f000000002118400001000224e1 +:10f830000300621000000000090002241000c2a3af +:10f840001000c2931800c2af1800c28f21e8c00395 +:10f850002400bf8f2000be8f2800bd270800e003d2 +:10f8600000000000e0ffbd271800beaf21f0a0039c +:10f870000800deaf0400c2270c00c2af80bf023c0c +:10f880003002428c1400c2af80bf023c2002428c86 +:10f890001000c2af0800c38f80bf023c2002428c20 +:10f8a000000062ac0c00c38f80bf023c3002428c6f +:10f8b000000062ac0c00c28f1400c38f0000428ca9 +:10f8c000eeff6214000000000800c28f1000c38f1a +:10f8d0000000428ce9ff6214000000000200c397a0 +:10f8e0000000c29725106200388282a70600c397e5 +:10f8f0000000c29725106200408282a721e8c00361 +:10f900001800be8f2000bd270800e00300000000a3 +:10f91000d8ffbd272400bfaf2000beaf21f0a00359 +:10f920002800c4af2110a0002c00c2a32800c28f61 +:10f930000000428c1000c2af2800c28f0800428c29 +:10f940001400c2af2800c48f9c3e400f000000008e +:10f950001400c2af1400c28f050040140000000064 +:10f96000150002241c00c2af3a0000100000000085 +:10f970001000c28f2000439001000224090062148d +:10f98000000000001000c48f1400c58ff80f06247b +:10f9900021380000124c400f00000000150000103c +:10f9a000000000001000c28f2000439002000224db +:10f9b00009006214000000001000c48f1400c58ffd +:10f9c000f8ff063421380000124c400f0000000000 +:10f9d00008000010000000001000c48f1400c58f44 +:10f9e000ff0f023cf8ff463421380000124c400f54 +:10f9f000000000002800c28f0800428c1800c2af2f +:10fa00001000c48f1800c58f1400c68f2138000065 +:10fa1000124c400f000000002800c38f1400c28f5a +:10fa2000080062ac2c00c393010002240800621499 +:10fa3000000000001000c48f1400c58fae44400fba +:10fa4000000000001c00c2af020000100000000017 +:10fa50001c00c0af1c00c28f21e8c0032400bf8f70 +:10fa60002000be8f2800bd270800e0030000000032 +:10fa7000c8ffbd273400bfaf3000beaf21f0a003e8 +:10fa80003800c4af1400c0af3800c28f0000428cf1 +:10fa90001000c2af3800c28f0800428c1800c2affd +:10faa0001000c28f200042902800c2af0200022442 +:10fab0002800c38f19006210000000002800c38fc7 +:10fac000030062280700401000000000010002242b +:10fad0002800c38f170062100000000019000010fa +:10fae00000000000030002242800c38f03006210fe +:10faf000000000001300001000000000ff0f023c97 +:10fb0000f7ff42342000c2afff0f023cffff423438 +:10fb10002400c2af0b00001000000000f7ff023409 +:10fb20002000c2afffff02342400c2af0500001066 +:10fb300000000000f70f02242000c2afffff0234d4 +:10fb40002400c2af1800c28f0200422c03004010f4 +:10fb500000000000020002241800c2af1800c28f8b +:10fb60001c00c2af1000c48f1800c58ff04a400fb0 +:10fb7000000000001800c28f2800401000000000a4 +:10fb80001000c48f1800c58ff04a400f000000001d +:10fb90001400c2af1400c38f2400c28f040062148b +:10fba000000000001800c0af1c00001000000000a2 +:10fbb0001400c28f03004014000000001700001062 +:10fbc000000000001800c28f010042241800c2afdc +:10fbd0001400c38f2000c28f0900621000000000d3 +:10fbe0001000c28f1800438c1800c28f2b104300e6 +:10fbf000030040100000000003000010000000009f +:10fc0000020002241800c2af1800c38f1c00c28f6c +:10fc1000d8ff6214000000001800c0af1800c28fa7 +:10fc200021e8c0033400bf8f3000be8f3800bd27ed +:10fc30000800e00300000000d8ffbd272400bfaf8c +:10fc40002000beaf21f0a0032800c4af480002246a +:10fc50001400c2af4c8280a32800c28f2c004294b3 +:10fc60001000c2a72800c28f1800428c0000427cfe +:10fc70004200401000000000dc8082930a00401027 +:10fc8000000000000447400f000000000600401084 +:10fc900000000000090002244c8282a3ffff02241e +:10fca000570000101c00c2af2800c28f0000448c17 +:10fcb0002128000021300000124c400f01000724d1 +:10fcc0002800c48f3c40400f1000c5271800c2af69 +:10fcd0001800c28f08004014000000001b0002241e +:10fce0004c8282a3ffff02241400c2af1400c28f13 +:10fcf000430000101c00c2af193e400f000000007e +:10fd00001800c38f4e828297160062a41800c38f1a +:10fd100040828297180062a4000000001800c38f80 +:10fd20002800c28f1400428c1c0062ac1800c38fe4 +:10fd30002800c28f300042940b0062a02800c48fbc +:10fd4000ce3a400f1000c52703004010000000000d +:10fd5000050000101400c0af090002244c8282a3e9 +:10fd6000ffff02241400c2af2800c48f1800838c48 +:10fd7000feff022424106200180082ac1200c0a70b +:10fd80001200c2970300422c160040100000000031 +:10fd90001200c397211060000011020023104300dd +:10fda0008018020000a0023c501142242118620079 +:10fdb0002800c28f07006214000000001200c397e1 +:10fdc00034828227211862000100022405000010fd +:10fdd000000062a01200c29701004224e8ff001058 +:10fde0001200c2a71400c38f48000224020062144c +:10fdf000000000001400c0af1400c28f1c00c2af8e +:10fe00001c00c28f21e8c0032400bf8f2000be8fda +:10fe10000800e0032800bd27d0ffbd272800bfafa2 +:10fe20002400beaf2000b0af21f0a0033000c4af6b +:10fe30003400c5af1800c0a33400c28f0000429444 +:10fe40000f00423011004014000000003400c28f47 +:10fe5000000042940d004010000000003000c38fed +:10fe60003000c28f3400428c380062ac3000c48f46 +:10fe70003400c58f01000624a63b400f000000009f +:10fe80001000c2af07000010000000003000c48f57 +:10fe90003400c58f21300000a63b400f0000000059 +:10fea0001000c2af1000c28f000042901500c2a324 +:10feb0001000c28f04004010000000001500c29323 +:10fec0000500401400000000020002241700c2a335 +:10fed0007f000010000000001500c393e50002241d +:10fee0000500621400000000010002241700c2a3f4 +:10fef00077000010000000001000c28f0b0042903d +:10ff00001500c2a31400c0a31400c2930800422c21 +:10ff100018004010000000001000c38f1400c293ae +:10ff200021104300000042901600c2a31600c293a5 +:10ff300021204000786b400f000000001600c2a393 +:10ff40003000c48f1800c393010062241800c2a3bc +:10ff5000ff006230211882001600c293200062a0c8 +:10ff60001400c293010042241400c2a3e6ff001053 +:10ff7000000000001000c28f0b0042901500c2a3c9 +:10ff80001000c28f080042901600c2a31400c0a344 +:10ff90001400c2930300422c18004010000000001f +:10ffa0001000c38f1400c293211062000800429019 +:10ffb0001600c2a31600c29321204000786b400fa8 +:10ffc000000000001600c2a33000c48f1800c393c5 +:10ffd000010062241800c2a3ff00623021188200d1 +:10ffe0001600c293200062a01400c29301004224b4 +:10fff0001400c2a3e6ff0010000000003000c38f11 +:020000041d01dc +:100000003400c28f000042942c0062a41000c28f02 +:10001000000042901500c2a31500c393e50002241e +:100020000500621400000000010002241700c2a3b2 +:1000300002000010000000001700c0a33000c38fb2 +:100040001000c28f1c00428c140062ac3000d08fb4 +:100050001000c48f0736400f00000000040002aefd +:100060001000c28f0b0042901500c2a33000c38f56 +:100070001500c293300062a41500c29310004230f4 +:100080000b004010000000003000c38f1000c28f32 +:100090000e0042941c0062a43000c38f1000c28f77 +:1000a000100042941e0062a409000010000000002d +:1000b0003000c38f1000c28f160042941c0062a44f +:1000c0003000c38f1000c28f180042941e0062a43b +:1000d0001700c29321e8c0032800bf8f2400be8f01 +:1000e0002000b08f3000bd270800e00300000000b2 +:1000f000d8ffbd272400bfaf2000beaf21f0a00372 +:100100002800c4af2c00c5af2800c38f2800c28fc1 +:100110003400428c380062ac2800c48f2c00c58f9c +:1001200001000624a63b400f000000001000c2aff3 +:100130001000c28f04004014000000001800c0af7f +:1001400031000010000000001000c28f000042903b +:100150001400c2a31400c293020040140000000067 +:100160001000c0af1000c28f25004010000000003a +:100170001400c393e5000224040062140000000090 +:100180001000c0af1e000010000000001000c28f61 +:100190000b0042901400c2a31400c3930f0002246a +:1001a00017006214000000002c00c38f2c00c28fc7 +:1001b0000000429401004224000062a42800c48f81 +:1001c0002c00c58f21300000a63b400f000000002e +:1001d0001000c2af1000c28f0400401400000000e5 +:1001e0001800c0af08000010000000001000c28f0f +:1001f0000b0042901400c2a3e7ff001000000000b3 +:100200001000c28f1800c2af1800c28f21e8c003cf +:100210002400bf8f2000be8f2800bd270800e00308 +:1002200000000000d0ffbd272c00bfaf2800beafec +:1002300021f0a0033000c4af3400c5af2110c000ce +:100240003800c2a31800c0af3000c28f0000428c3b +:100250002000c2af3000c28f3400428c1c00c2affd +:100260003000c38f1c00c28f380062ac3000c48fd6 +:100270003400c58f01000624a63b400f000000009b +:100280001000c2af1000c28f070040140000000031 +:10029000010002244c8282a31b0002242400c2af6e +:1002a00045000010000000001000c28f00004290c6 +:1002b0001400c2a31000c28f040040100000000010 +:1002c0001400c29305004014000000000b0002243b +:1002d0001800c2af2e000010000000001400c393ed +:1002e000e500022405006214000000000b00022457 +:1002f0001800c2af26000010000000001000c28fde +:100300000b0042901400c2a31000c38fe5ff02242b +:10031000000062a01000c48f0736400f00000000ec +:100320001c00c2af1800c28f07004014000000007c +:100330003000c48f3400c58fce3a400f000000005b +:100340000500401400000000010002241800c2afa4 +:100350000f000010000000001c00c38f3c82828f41 +:100360000b006210000000003800c293080040102b +:10037000000000001c00c48f2000c58f1f3b400ff1 +:1003800000000000000042380100422c1800c2affb +:100390001800c28f04004014000000004c8280a3ab +:1003a0000300001000000000010002244c8282a320 +:1003b0001800c28f2400c2af2400c28f21e8c003fe +:1003c0002c00bf8f2800be8f3000bd270800e0033f +:1003d00000000000c0ffbd273c00bfaf3800beaf2b +:1003e00021f0a0034000c4af4400c5af1100c0a37a +:1003f000010002242800c2a74c8280a34400c28fbf +:100400000700401400000000190002244c8282a35f +:10041000ffff02243000c2afd10000100000000036 +:100420004400c28f200042244000c48f2128400095 +:10043000213000000848400f000000000700401471 +:1004400000000000120002244c8282a3ffff02245d +:100450003000c2afc2000010000000001000c0a3b6 +:100460001000c2930b00422c0e0040100000000050 +:100470001000c3931000c227212062004400c38fe4 +:100480001000c2932110620020004290080082a058 +:100490001000c293010042241000c2a3f0ff00101c +:1004a000000000004400c28f2c0042942a00c2a722 +:1004b0002800c0a74400c38f4400c28f3400428c80 +:1004c000380062ac2800c2274400c48f21284000b5 +:1004d00001000624a63b400f000000002c00c2af24 +:1004e0002c00c28f07004014000000001b000224f3 +:1004f0004c8282a3ffff02243000c2af980000109c +:10050000000000001000c0a31000c2930b00422c9a +:1005100012004010000000002c00c38f1000c29396 +:10052000212043001000c3931000c2272110620055 +:100530000000838008004280030062100000000079 +:10054000010002241100c2a31000c2930100422442 +:100550001000c2a3ecff0010000000001100c293c5 +:100560000700401400000000110002244c8282a306 +:10057000ffff02243000c2af79000010000000002d +:100580001100c0a3dd8080a32800c2274400c48fcf +:100590002128400021300000a63b400f0000000051 +:1005a0002c00c2af2c00c28f0d00401400000000d0 +:1005b000dd80839301000224030062140000000028 +:1005c00032000010000000001b0002244c8282a3b5 +:1005d000ffff02243000c2af6100001000000000e5 +:1005e0002c00c28f00004280030040140000000075 +:1005f00026000010000000001000c0a31000c293ed +:100600000b00422c12004010000000002c00c38f91 +:100610001000c293212043001000c3931000c22792 +:1006200021106200000083800800428003006210f5 +:1006300000000000010002241100c2a31000c293b8 +:10064000010042241000c2a3ecff001000000000d3 +:100650001100c293070040140000000011000224a2 +:100660004c8282a3ffff02243000c2af3c00001086 +:10067000000000001100c0a32800c297010042241e +:100680002800c2a7c0ff0010000000002a00c29787 +:100690002800c2a74400c38f4400c28f3400428c9c +:1006a000380062ac2800c2274400c48f21284000d3 +:1006b0003c40400f000000002c00c2af2c00c28f55 +:1006c00007004014000000001b0002244c8282a39b +:1006d000ffff02243000c2af210000100000000024 +:1006e0001000c0a31000c2930b00422c0e0040105b +:1006f000000000002c00c38f1000c2932120430093 +:100700004400c38f1000c293211062002000429069 +:10071000000082a01000c293010042241000c2a376 +:10072000f0ff0010000000002800c2274400c48f22 +:1007300021284000ce3a400f00000000070040147e +:1007400000000000090002244c8282a3ffff022463 +:100750003000c2af02000010000000003000c0af47 +:100760003000c28f21e8c0033c00bf8f3800be8f2d +:100770004000bd270800e00300000000d0ffbd27b7 +:100780002c00bfaf2800beaf21f0a0033000c4afe3 +:100790003400c5af1000c0af1400c0af1400c28f4a +:1007a000030042281b004010000000001400c38f0b +:1007b0003482822721106200000042901000401015 +:1007c000000000001400c38f3482822721106200d1 +:1007d000000040a01400c38f21106000001102002f +:1007e000231043008018020000a0023c5011422454 +:1007f000211062001000c2af0600001000000000cf +:100800001400c28f010042241400c2afe3ff0010a5 +:10081000000000001000c28f06004014000000001d +:10082000200002244c8282a32000c0af7801001077 +:10083000000000001000c28f200042243000c48f4e +:1008400021284000213000000848400f000000002f +:100850000b004014000000001400c38f3482822774 +:100860002118620001000224000062a0120002248c +:100870004c8282a32000c0af650100100000000080 +:100880003400c28f000042901800c2a31000c38f32 +:1008900000a0023c04124224000062ac1000c28f8f +:1008a000040040ac1000c28f080040ac1000c28fa2 +:1008b0002c0040a41000c38f20000224300062a44a +:1008c0001000c38f1c80828f3400428c340062acd5 +:1008d0001000c38f1c80828f3800428c380062acbd +:1008e00000a0023c281244241000c58f2c44400f65 +:1008f000000000001000c48f00a0023c2812452414 +:100900000100062421380000fc31400f00000000e7 +:10091000db004014000000001800c293bfff422417 +:100920002400c2af2400c38f3700622cce004010d9 +:10093000000000002400c28f80180200029d023ccb +:10094000e4024224211062000000428c08004000b2 +:10095000000000001000c28f2c0042941a00c2a7b1 +:100960001a00c2271000c48f21284000010006246d +:100970008940400f000000001c00c2af1c00c28f65 +:100980000c014014000000001a00c2271000c48fa0 +:1009900021284000213000008c3c400f0000000066 +:1009a0001c00c2af1c00c28f0201401400000000f6 +:1009b0001a00c2271000c48f2128400077000624a7 +:1009c0000833400f000000001c00c2af1000c28faf +:1009d000300042941000423005004010000000003a +:1009e0001f0002244c8282a3ff0002241c00c2af1d +:1009f0001c00c28fef004014000000001000c48fe4 +:100a00002128000002000624054a400f00000000d3 +:100a10001c00c2af3400c28f010043802b000224af +:100a2000e4006214000000001000c28f1800438c24 +:100a300002006334180043acde0000100000000028 +:100a40001000c28f1400428c2d00401000000000e6 +:100a50001000c28f2c0042941a00c2a71a00c227ad +:100a60001000c48f21284000770006240833400f6f +:100a7000000000001c00c2af1000c28f3000429482 +:100a80001000423005004010000000001f0002244a +:100a90004c8282a3ff0002241c00c2af1c00c28f44 +:100aa000c4004014000000001000c48f2128000082 +:100ab00002000624054a400f000000001c00c2afdf +:100ac0001c00c28f03004010000000001a00022426 +:100ad0004c8282a33400c28f010043802b00022489 +:100ae000b4006214000000001000c28f1800438c94 +:100af00002006334180043acae0000100000000098 +:100b00001000c28f2c0042941a00c2a71a00c227fc +:100b10001000c48f21284000010006248940400fa6 +:100b2000000000001c00c2af1c00c28fa1004014d6 +:100b3000000000001a00c2271000c48f21284000c6 +:100b4000213000008c3c400f000000001c00c2afb0 +:100b50001c00c28f97004014000000001a00c2273a +:100b60001000c48f21284000770006240833400f6e +:100b7000000000001c00c2af1000c28f3000429481 +:100b80001000423005004010000000001f00022449 +:100b90004c8282a3ff0002241c00c2af1c00c28f43 +:100ba00084004014000000001000c48f21280000c1 +:100bb00002000624054a400f000000001c00c2afde +:100bc0001c00c28f03004010000000001a00022425 +:100bd0004c8282a33400c28f010043802b00022488 +:100be00074006214000000001000c28f1800438cd3 +:100bf00002006334180043ac6e00001000000000d7 +:100c00001000c28f2c0042941a00c2a71a00c227fb +:100c10001000c48f21284000720006240833400fc2 +:100c2000000000001c00c2af3400c28f01004380ee +:100c30002b0002245f006214000000001000c28f2d +:100c400030004294100042305a004014000000006e +:100c50001000c28f1800438c01006334180043acad +:100c600054000010000000001f0002244c8282a3e8 +:100c7000ff0002241c00c2af4e0000100000000064 +:100c80001000c48f00a0023c281245242c44400fc1 +:100c9000000000001800c393770002240f006210c8 +:100ca000000000001800c393570002240b006210dc +:100cb000000000001800c3936100022407006210c6 +:100cc000000000001800c3934100022403006210da +:100cd0000000000035000010000000001a00c0a74e +:100ce0001a00c2271000c48f2128400021300000c4 +:100cf0008c3c400f000000001c00c2af1c00c28fe3 +:100d00002c004014000000001a00c2271000c48ffd +:100d100021284000770006240833400f000000001f +:100d20001c00c2af1000c28f30004294100042304d +:100d300005004010000000001f0002244c8282a326 +:100d4000ff0002241c00c2af1c00c28f1900401417 +:100d5000000000001000c48f2128000002000624bb +:100d6000054a400f000000001c00c2af1c00c28feb +:100d700003004010000000001a0002244c8282a3ed +:100d80003400c28f010043802b000224090062144a +:100d9000000000001000c28f1800438c0200633472 +:100da000180043ac03000010000000000b000224f8 +:100db0001c00c2af2a5c400f00000000060040107b +:100dc000000000001000c48f1800838cfeff022476 +:100dd00024106200180082ac1c00c28f0900401071 +:100de000000000001400c38f3482822721186200a3 +:100df00001000224000062a01000c0af0200001039 +:100e0000000000004c8280a31000c28f2000c2afff +:100e10002000c28f21e8c0032c00bf8f2800be8fa6 +:100e20003000bd270800e00300000000f8ffbd27e8 +:100e30000000beaf21f0a0030800c4af4c8280a325 +:100e40000800c28f1000428c21e8c0030000be8f52 +:100e50000800bd270800e00300000000d8ffbd2700 +:100e60002400bfaf2000beaf21f0a0032800c4af14 +:100e700000a0023c140f42241000c2af4c8280a399 +:100e80002a5c400f00000000070040100000000036 +:100e9000180002244c8282a3ffff02241800c2af74 +:100ea00058000010000000001000c28f20004224f3 +:100eb0002800c48f21284000213000000848400f3e +:100ec000000000000700401400000000120002248f +:100ed0004c8282a3ffff02241800c2af4900001019 +:100ee000000000001000c38f00a0023c0412422446 +:100ef000000062ac1000c28f040040ac1000c28f32 +:100f0000080040ac1000c28f2c0040a41000c38f1a +:100f100020000224300062a41000c38f1c80828f46 +:100f20003400428c340062ac1000c38f1c80828f6e +:100f30003800428c380062ac00a0023c28124424e5 +:100f40001000c58f2c44400f000000001000c48f1b +:100f500000a0023c2812452401000624213800008c +:100f6000fc31400f000000001400c2af1400c28f1b +:100f700007004010000000000b0002244c8282a3f6 +:100f8000ffff02241800c2af1e0000100000000086 +:100f90001000c28f30004294100042300700401011 +:100fa00000000000130002244c8282a3ffff0224f1 +:100fb0001800c2af13000010000000001000c28f24 +:100fc0002c0042241000c48f212840000100062478 +:100fd0008940400f000000001400c2af1400c28f0f +:100fe00004004014000000001800c0af050000100d +:100ff00000000000010002244c8282a3ffff0224b3 +:101000001800c2af1800c28f21e8c0032400bf8fb0 +:101010002000be8f2800bd270800e003000000006c +:10102000e8ffbd271400bfaf1000beaf21f0a00342 +:101030001800c4afdc808293030040100000000061 +:101040000447400f000000001800c28f100040aca1 +:101050001800c28f0e0040a41800c28f0c0040a4dc +:101060001800c38f1800c28f0400428c080062acc5 +:10107000d88080af21e8c0031400bf8f1000be8f5e +:101080001800bd270800e00300000000f8ffbd279e +:101090000000beaf21f0a0034c82829321e8c00380 +:1010a0000000be8f0800bd270800e003000000001c +:1010b000e8ffbd271000beaf21f0a0031800c4afa9 +:1010c0001c00c5af1800c28f0400c2af1c00c28f45 +:1010d0000800c2af3c0002240000c2a30c00c0a361 +:1010e0000c00c2930000c3932b1043000e0040106d +:1010f000000000000c00c3930400c28f2120620096 +:101100000c00c3930800c28f2110620000004290bf +:10111000000082a00c00c293010042240c00c2a374 +:10112000efff00100000000021e8c0031000be8f98 +:101130001800bd270800e00300000000e0ffbd2705 +:101140001c00bfaf1800beaf21f0a0032000c4af49 +:101150002400c5af1400c0af2000c28f0000428c35 +:101160001000c2af2000c48f9c3e400f0000000062 +:10117000211840002400c28f000043ac2400c28f1d +:101180000000428c050040140000000015000224fd +:101190001400c2af41000010000000001000c28f18 +:1011a000200043900100022410006214000000009f +:1011b0002400c28f1000c48f0000458cf80f062455 +:1011c00021380000124c400f0000000021184000a0 +:1011d000ffff02342800621400000000090002240e +:1011e0001400c2af24000010000000001000c28fe5 +:1011f000200043900200022410006214000000004e +:101200002400c28f1000c48f0000458cf8ff063404 +:1012100021380000124c400f00000000211840004f +:10122000ffff0234140062140000000009000224d1 +:101230001400c2af10000010000000002400c28f94 +:101240001000c48f0000458cff0f023cf8ff4634ad +:1012500021380000124c400f00000000211840000f +:10126000ff0f023cffff4234030062140000000045 +:10127000090002241400c2af1400c28f07004014fa +:10128000000000002400c28f1000c48f0000458cb5 +:10129000ae44400f000000001400c2af1400c28f23 +:1012a00021e8c0031c00bf8f1800be8f2000bd279f +:1012b0000800e00300000000d8ffbd272400bfaff6 +:1012c0002000beaf21f0a0032800c4af2c00c5afa2 +:1012d0001800c0a32800c48f2c00c58f4c45400fb8 +:1012e000000000001400c2afdc80829309004010af +:1012f000000000000447400f0000000005004010ff +:1013000000000000090002241c00c2af2e000010e3 +:1013100000000000d88080afde8082930900401476 +:10132000000000002800c28f0000448c212800002b +:1013300000020624d169400f0000000001000224d1 +:10134000de8082a31000c0a32800c28f1f0043903c +:101350001000c2932b104300190040100000000041 +:101360001800c29316004014000000001400c327a8 +:101370000000628c2120400001004224000062ac89 +:101380002800c28f0000458c21300000b05b400f68 +:101390000000000021184000010002240300621038 +:1013a00000000000090002241800c2a31000c2932c +:1013b000010042241000c2a3e3ff0010000000005f +:1013c0001800c2931c00c2af1c00c28f21e8c003ea +:1013d0002400bf8f2000be8f2800bd270800e00337 +:1013e00000000000f8ffbd270000beaf21f0a00301 +:1013f0000800c4af2110a0000c00c2a70c00c397c6 +:101400000800c28f211062000000429021e8c00352 +:101410000000be8f0800bd270800e00300000000a8 +:10142000f0ffbd270800beaf21f0a0031000c4af3d +:101430002110a0001400c2a71400c3971000c28f8f +:1014400021106200000042900000c2a31400c39764 +:101450001000c28f21106200010042900100c2a35f +:101460000100c2930200c2a70200c297001202004c +:101470000200c2a70000c3930200c29725104300d8 +:101480000200c2a70200c29721e8c0030800be8f75 +:101490001000bd270800e00300000000e0ffbd27aa +:1014a0001c00bfaf1800beaf21f0a0032000c4afe6 +:1014b0002110a0002400c2a72400c2972000c48fde +:1014c000212840000845400f000000001000c2a77e +:1014d0002400c29702004224ffff42302000c48f44 +:1014e000212840000845400f000000001200c2a75c +:1014f0001200c2971400c2af1400c28f0014020081 +:101500001400c2af1000c3971400c28f251043000f +:101510001400c2af1400c28f21e8c0031c00bf8fab +:101520001800be8f2000bd270800e0030000000067 +:10153000f0ffbd270800beaf21f0a0031000c4af2c +:101540001400c5af1000c28f200042900400c2af4b +:101550000400c38f010062282f0040140000000027 +:101560000400c38f03006228120040140000000032 +:10157000030002240400c38f030062100000000077 +:1015800025000010000000001400c28ffeff43245d +:101590001000c28f1f004290021862701000c28fac +:1015a0001000428c211062000000c2af1a0000102f +:1015b000000000001400c28f07004010000000006f +:1015c0001400c38f01000224030062100000000019 +:1015d00008000010000000001000c28f0c00438cb7 +:1015e0001400c28f211062000000c2af0a00001078 +:1015f000000000001400c28ffeff43241000c28fc1 +:101600001f004290021862701000c28f1000428cbe +:10161000211062000000c2af0000c28f21e8c003a9 +:101620000800be8f1000bd270800e0030000000086 +:10163000d8ffbd272400bfaf2000beaf21f0a0031c +:101640002800c4af2110a0002c00c2a34c8280a3ac +:101650002c00c393d8ff022424106200070040101e +:10166000000000001f0002244c8282a3ffff02241e +:101670001800c2af3c000010000000002800c28f1c +:101680002c0042941000c2a72800c38f2800c28fec +:101690003400428c380062ac2800c48f1000c5278b +:1016a0003c40400f000000001400c2af1400c28f85 +:1016b00007004014000000001b0002244c8282a39b +:1016c000ffff02241800c2af270000100000000036 +:1016d0001400c28f0b0042900800423007004010f7 +:1016e000000000001f0002244c8282a3ffff02249e +:1016f0001800c2af1c000010000000002800c28fbc +:1017000030004294100042300700401000000000fa +:101710001400c28f2c00c393100063340b0043a04d +:1017200004000010000000001400c38f2c00c293be +:101730000b0062a02800c48f1000c527ce3a400fce +:10174000000000000700401400000000090002240f +:101750004c8282a3ffff02241800c2af02000010d7 +:10176000000000001800c0af1800c28f21e8c003bd +:101770002400bf8f2000be8f2800bd270800e00393 +:1017800000000000c0ffbd273c00bfaf3800beaf67 +:1017900021f0a0034000c4af4400c5af4800c6af6d +:1017a0004c00c7af4400c38f4800c28f0210627064 +:1017b0001000c2af4000c28f1400c2af1c00c0af07 +:1017c0003000c0a74c00c28f1800428c0000427c41 +:1017d00008004014000000001d0002244c8282a377 +:1017e000090002241c00c2af3400c0af0101001088 +:1017f000000000001000c28f040040140000000030 +:101800003400c0affb000010000000002a5c400f55 +:101810000000000008004010000000001800022432 +:101820004c8282a3180002241c00c2af3400c0af57 +:10183000f000001000000000de8080a34c00c28f8a +:101840000000428c1800c2af4c00c28f0e004294c0 +:101850002000c2a74c00c28f1000428c2800c2afeb +:101860004c00c28f1800c48f0800458c4c45400fb7 +:10187000000000002400c2af4c00c28f0c00439453 +:101880002400c28f211043002400c2afd880838f70 +:101890004c00c28f0f00621000000000dc808293b9 +:1018a0000a004010000000000447400f0000000044 +:1018b0000600401000000000090002244c8282a3b0 +:1018c0003400c0afcb000010000000004c00c28ffd +:1018d000d88082af1880838f2400c28f1b006210d3 +:1018e00000000000dc8082930a004010000000002d +:1018f0000447400f000000000600401000000000f8 +:10190000090002244c8282a33400c0afb900001049 +:1019100000000000de8080a31800c28f2400c48f66 +:101920000000458c285b400f0000000005004014bb +:10193000000000001b0002244c8282a30800022445 +:101940001c00c2af2400c28f188082af4c00c28f2f +:101950001400428c2c00c2af1c00c28f96004014b1 +:10196000000000001000c28f930040100000000033 +:101970002800c38f2c00c28f0500621400000000f5 +:101980004c00c28f1800438c04006334180043ac31 +:101990002000c397000202246200621400000000cd +:1019a000010002243200c2a3dc8082930a004010ae +:1019b000000000000447400f000000000600401037 +:1019c00000000000090002244c8282a33400c0af52 +:1019d00088000010000000002000c0a74c00c38f4a +:1019e0004c00c28f0c004294010042240c0062a4ff +:1019f0004c00c38f1800c28f1f0042900c006394ec +:101a0000ffff423015006214000000004c00c28f3e +:101a10000c0040a44c00c28f1800428c8000427c15 +:101a200009004010000000004c00c48f2128000075 +:101a3000443e400f000000001c00c2af3200c0a3b3 +:101a400006000010000000004c00c48f01000524b7 +:101a5000aa33400f000000001c00c2af1c00c38f5f +:101a60001500022406006214000000001500022484 +:101a70004c8282a33400c0af5e0000100000000062 +:101a80001c00c28f27004014000000004c00c28fd1 +:101a90001800c48f0800458c4c45400f0000000022 +:101aa0002400c2af4c00c28f0c0043942400c28fac +:101ab000211043002400c2af4c00c28fd88082aff7 +:101ac0003200c29315004010000000001800c28fc1 +:101ad0002400c48f0000458c285b400f00000000ec +:101ae0000a004014000000001b0002244c8282a364 +:101af000080002241c00c2afffff0224188082af3e +:101b00003400c0af3b000010000000002400c28f72 +:101b1000188082af03000010000000002400c28f74 +:101b2000188082af1c00c28f8bff401400000000a1 +:101b30001800c48f2000c397010062242000c2a7b0 +:101b4000ffff63300000828c211862001400c28ff6 +:101b500000004290000062a01400c28f01004224e5 +:101b60001400c2af2800c28f010042242800c2af77 +:101b70001000c28fffff42241000c2af3000c29796 +:101b8000010042243000c2a74c00c28f1800428cd2 +:101b90008000427c04004010000000002c00c28f36 +:101ba000010042242c00c2af01000224dc8082a389 +:101bb00069ff0010000000004c00c38f2000c29796 +:101bc0000e0062a44c00c38f2800c28f100062accc +:101bd0004c00c38f2c00c28f140062ac3000c3973e +:101be0004400c28f1b006200f4014000121000008c +:101bf0003400c2af3400c28f21e8c0033c00bf8f65 +:101c00003800be8f4000bd270800e0030000000040 +:101c1000d8ffbd272400bfaf2000beaf21f0a00336 +:101c2000d880828f1800c2af1800c28f0000428c8b +:101c30001400c2af1800c28f1400c48f0800458c76 +:101c40004c45400f000000001000c2af1800c28fca +:101c50000c0043941000c28f211043001000c2af4b +:101c60001400c28f1000c48f0000458c213000008a +:101c7000b05b400f000000000500401400000000b1 +:101c8000090002241c00c2af030000100000000085 +:101c9000dc8080a31c00c0af1c00c28f21e8c00301 +:101ca0002400bf8f2000be8f2800bd270800e0035e +:101cb00000000000f8ffbd270000beaf21f0a00328 +:101cc0000800c4af4c8280a30800c28f0800c38ff5 +:101cd0001000448c1400628c261082000100422cfb +:101ce00021e8c0030000be8f0800bd270800e00304 +:101cf00000000000c0ffbd273c00bfaf3800beaff2 +:101d000021f0a0034000c4af4400c5af4800c6aff7 +:101d10004c00c7af4400c38f4800c28f02106270ee +:101d20001000c2af4000c28f1400c2af2800c0af85 +:101d30002c00c0a74c8280a34c00c28f0000428cb4 +:101d40001800c2af4c00c28f0e0042942400c2a7fc +:101d50004c00c28f1000428c1c00c2af4c00c28fde +:101d60001800428c4000427c060040140000000035 +:101d70001e0002244c8282a33000c0afa1000010dc +:101d800000000000dc8082930a0040100000000088 +:101d90000447400f00000000060040100000000053 +:101da000090002244c8282a33000c0af95000010cd +:101db00000000000d880838f4c00c28f2300621087 +:101dc000000000002400c397000202241f006210dc +:101dd000000000004c00c28fd88082af4c00c28f40 +:101de0001800c48f0800458c4c45400f00000000cf +:101df0002000c2af4c00c28f0c0043942000c28f61 +:101e0000211043002000c2afde8080a31800c28fe3 +:101e10002000c48f0000458c285b400f00000000ac +:101e20000800401400000000080002244c8282a335 +:101e3000080002242800c2af3000c0af71000010bb +:101e4000000000002000c28f188082af1000c28ff7 +:101e500060004010000000004c00c28f1400438c52 +:101e60001c00c28f07006214000000003d00022425 +:101e70004c8282a33d0002242800c2af550000100e +:101e8000000000002400c3970002022439006214fd +:101e9000000000002400c0a74c00c38f4c00c28f7c +:101ea0000c004294010042240c0062a44c00c38f39 +:101eb0001800c28f1f0042900c006394ffff423055 +:101ec0000f006214000000004c00c28f0c0040a400 +:101ed0004c00c48f01000524aa33400f000000000d +:101ee0002800c2af2800c28f05004010000000008b +:101ef0000f0002244c8282a3360000100000000074 +:101f00004c00c28f1800c48f0800458c4c45400f10 +:101f1000000000002000c2af4c00c28f0c004394b0 +:101f20002000c28f211043002000c2af4c00c28f9e +:101f3000d88082afde8080a31800c28f2000c48fbb +:101f40000000458c285b400f000000000700401493 +:101f500000000000080002244c8282a30800022432 +:101f60002800c2af1b000010000000002000c28f3c +:101f7000188082af1400c58f1800c48f2400c39747 +:101f8000010062242400c2a7ffff63300000828c9e +:101f900021106200000042900000a2a01400c28f35 +:101fa000010042241400c2af1c00c28f0100422471 +:101fb0001c00c2af2c00c297010042242c00c2a713 +:101fc0001000c28fffff42241000c2af9fff00101d +:101fd000000000004c00c38f2400c2970e0062a4d2 +:101fe0004c00c38f1c00c28f100062ac2c00c39742 +:101ff0004400c28f1b006200f40140001210000078 +:102000003000c2af3000c28f21e8c0033c00bf8f58 +:102010003800be8f4000bd270800e003000000002c +:10202000c0ffbd273800bfaf3400beaf3000b0af37 +:1020300021f0a0034000c4af4400c5af2110c00090 +:102040004800c2a32800c0a32800c2930b00422c62 +:102050000b004010000000002800c3934400c28f12 +:102060002118620020000224000062a02800c29310 +:10207000010042242800c2a3f3ff0010000000006a +:102080004000c28f000043802e0002240500621031 +:10209000000000004000c28f000042800400401495 +:1020a000000000002c00c0af730000100000000012 +:1020b0004000c48f636a400f000000001400c2a7f4 +:1020c0001400c2970d00422c0800401000000000d0 +:1020d0001800c227212040004000c58ffb69400f37 +:1020e0000000000004000010000000002c00c0af41 +:1020f00061000010000000001800c2274800c393d0 +:1021000021204000212860003649400f00000000d7 +:1021100004004014000000002c00c0af5600001066 +:10212000000000001800c227212040002e000524d6 +:10213000256b400f000000001000c2af1000c28fde +:102140000f004010000000001000c28f000040a0ef +:102150001000c28f010042241000c2af1000c48fd3 +:10216000636a400f000000000400422c0400401489 +:10217000000000002c00c0af3f0000100000000075 +:102180001800c22721204000636a400f00000000b1 +:102190000900422c04004014000000002c00c0afd5 +:1021a00035000010000000002800c0a32800d093d4 +:1021b0001800c22721204000636a400f0000000081 +:1021c0002b1002020e004010000000002800c393f4 +:1021d0004400c28f212062002800c3931000c22750 +:1021e0002110620008004290000082a02800c293e3 +:1021f000010042242800c2a3ecff001000000000f0 +:102200001000c28f1a004010000000001000c28fa2 +:102210000000428016004010000000002800c0a30b +:102220002800d0931000c48f636a400f00000000a4 +:102230002b1002020e004010000000002800c39383 +:102240004400c28f212062002800c3931000c28f77 +:102250002110620000004290080082a02800c29372 +:10226000010042242800c2a3edff0010000000007e +:10227000010002242c00c2af2c00c28f21e8c00351 +:102280003800bf8f3400be8f3000b08f4000bd27b4 +:102290000800e00300000000c8ffbd273400bfaf06 +:1022a0003000beaf21f0a0033800c4af2110a00061 +:1022b0003c00c2a33c00c2933800c48f21284000d8 +:1022c0003649400f000000000400401400000000e8 +:1022d0002800c0af79000010000000001000c0a36b +:1022e0001000c2930800422c1b00401000000000a8 +:1022f0001000c3933800c28f211062000000438099 +:102300002e00022414006210000000001000c3938d +:102310003800c28f21106200000042800e00401081 +:10232000000000001000c3931000c22721206200ab +:102330001000c3933800c28f211062000000429049 +:10234000080082a01000c293010042241000c2a322 +:10235000e3ff0010000000001000c2931100c2a3b0 +:102360001000c2930800422c0b0040100000000037 +:102370001000c393010062241000c2a3ff00633069 +:102380001000c2272118620020000224080062a069 +:10239000f3ff0010000000001100c3933800c28f4b +:1023a00021106200000043802e0002241a006214f3 +:1023b000000000001100c293010042241100c2a3da +:1023c0001100c3933800c28f2110620000004280c8 +:1023d00011004010000000001000c39301006224af +:1023e0001000c2a3ff0063301000c227212062004a +:1023f0001100c393010062241100c2a3ff006330e7 +:102400003800c28f2110620000004290080082a0b4 +:10241000ebff0010000000001000c2930b00422ce4 +:102420000b004010000000001000c3930100622464 +:102430001000c2a3ff0063301000c2272118620001 +:1024400020000224080062a0f3ff0010000000003a +:102450002300c0a31800c3832000022403006214d9 +:10246000000000005f0002241800c2a31000c0a3f7 +:102470001000c2930c00422c0e004010000000001f +:102480001000c3933800c28f212062001000c39354 +:102490001000c2272110620008004290000082a0b4 +:1024a0001000c293010042241000c2a3f0ff0010ec +:1024b00000000000010002242800c2af2800c28fe3 +:1024c00021e8c0033400bf8f3000be8f3800bd2725 +:1024d0000800e00300000000d8ffbd272400bfafc4 +:1024e0002000beaf21f0a0032800c4af2110a0003f +:1024f0002c00c2a31800c0a32800c48f636a400f39 +:10250000000000001000c2af1400c0af1400c28f62 +:102510001000c38f2a104300b500401000000000d7 +:102520001400c38f2800c28f211062000000428077 +:102530002100422808004010000000001400c38f52 +:102540002800c28f21106200000043800500022491 +:1025500069006214000000001400c38f2800c28fbd +:1025600021106200000043802200022462006210f9 +:10257000000000001400c38f2800c28f21106200e9 +:10258000000043802b0002245b006210000000006a +:102590001400c38f2800c28f211062000000438006 +:1025a0002c00022454006210000000001400c38fad +:1025b0002800c28f21106200000043802f000224f7 +:1025c0004d006210000000001400c38f2800c28f6d +:1025d00021106200000043803a000224460062108d +:1025e000000000001400c38f2800c28f2110620079 +:1025f000000043803b0002243f0062100000000006 +:102600001400c38f2800c28f211062000000438095 +:102610003c00022438006210000000001400c38f48 +:102620002800c28f21106200000043803d00022478 +:1026300031006210000000001400c38f2800c28f18 +:1026400021106200000043803e0002242a00621034 +:10265000000000001400c38f2800c28f2110620008 +:10266000000043805b000224230062100000000091 +:102670001400c38f2800c28f211062000000438025 +:102680005c0002241c006210000000001400c38fd4 +:102690002800c28f21106200000043805d000224e8 +:1026a00015006210000000001400c38f2800c28fc4 +:1026b00021106200000043807c0002240e006210a2 +:1026c000000000001400c38f2800c28f2110620098 +:1026d000000043802e0002240a0062140000000063 +:1026e0001800c393010002240300621000000000e0 +:1026f00004000010000000001c00c0af3e000010ed +:10270000000000002c00c2931400401400000000e0 +:102710001400c38f2800c28f211062000000438084 +:102720002a0002240a006210000000001400c38f77 +:102730002800c28f21106200000043803f00022465 +:102740000300621000000000040000100000000000 +:102750001c00c0af28000010000000001400c38f50 +:102760002800c28f21106200000043802e00022446 +:102770000300621400000000010002241800c2a33c +:102780001400c38f2800c28f211062000000428015 +:102790006100422811004014000000001400c38fa3 +:1027a0002800c28f21106200000042807b00422876 +:1027b0000a004010000000001400c38f2800c28fe0 +:1027c000212062001400c38f2800c28f21106200f4 +:1027d00000004290e0ff4224000082a01400c28f5b +:1027e000010042241400c2af48ff001000000000a6 +:1027f000010002241c00c2af1c00c28f21e8c003ec +:102800002400bf8f2000be8f2800bd270800e003f2 +:1028100000000000c8ffbd273400bfaf3000beafce +:1028200021f0a0033800c4af3c00c5af4000c6afe4 +:102830003c00c28f2000c2af3800c28f0000428c23 +:102840001800c2af4000c28f2800c2af01000224ae +:102850002800c38f0700621000000000020002245d +:102860002800c38f0a006210000000000d00001055 +:10287000000000003800c28f2000c38f1000428c7f +:10288000211062002000c2af06000010000000000e +:102890003800c28f1400438c2000c28f23106200c6 +:1028a0002000c2afdc8082930b00401000000000cb +:1028b0000447400f00000000070040100000000027 +:1028c000090002244c8282a3ffff02242400c2af2d +:1028d000b4000010000000003800c28f0400428cd9 +:1028e0001400c2af3800c38f1400c28f080062ac5e +:1028f0003800c28f1400428c1400c2af2000c38f76 +:102900001400c28f2b10430007004010000000008d +:102910001f0002244c8282a3ffff03242400c3afc4 +:10292000a0000010000000003800c48f1800838c45 +:10293000fbff022424106200180082ac3800c38f11 +:102940002000c28f100062ac2000c28f2c00c2afea +:102950002c00c28f04004104000000002c00c38f33 +:10296000ff0163242c00c3af2c00c38f431203006c +:102970001000c2af1000c28f401a02002000c28fa8 +:10298000231043002000c2af3800c38f2000c28f45 +:102990000e0062a41800c28f1f0043901000c28f67 +:1029a0001b004300f4016000121000001400c2afcd +:1029b0001800c28f1f0043901400c28f021862706b +:1029c0001000c28f231043001000c2af3800c38f25 +:1029d0001000c28f0c0062a41400c28f510040107e +:1029e000000000003800c48f1400c58faa33400fc8 +:1029f000000000001c00c2a31c00c293490040104c +:102a0000000000001c00c3933c0002243f0062143d +:102a1000000000003800c28f1800428c0000427c89 +:102a20001c004010000000003800c38f3800c28f27 +:102a30000400428c080062ac1400c38f0100022421 +:102a400008006210000000001400c28fffff422443 +:102a50003800c48f21284000aa33400f0000000036 +:102a60001c00c2a33800c48f21280000443e400f40 +:102a7000000000002b004010000000000f000224a6 +:102a80004c8282a3ffff02242400c2af4500001045 +:102a9000000000003800c38f3800c28f0400428c51 +:102aa000080062ac1400c28fffff42243800c48fbc +:102ab00021284000aa33400f000000001c00c2a3e0 +:102ac0001c00c29307004010000000000f00022409 +:102ad0004c8282a3ffff03242400c3af3100001007 +:102ae000000000003800c38f000202240e0062a420 +:102af0003800c38f1800c28f1f004290ffff42248e +:102b00000c0062a407000010000000000f00022467 +:102b10004c8282a3ffff02242400c2af21000010d8 +:102b2000000000003800c28f1800c48f0800458cd8 +:102b30004c45400f000000001400c2af3800c28fa7 +:102b40000c0042941000c2af1400c38f1000c28f5b +:102b5000211062001400c2afd88080afde8080a355 +:102b60001800c28f1400c48f0000458c285b400ff2 +:102b70000000000007004014000000001b000224b9 +:102b80004c8282a3ffff03242400c3af0500001082 +:102b9000000000001400c28f188082af4c8280a316 +:102ba0002400c0af2400c28f21e8c0033400bf8fcf +:102bb0003000be8f3800bd270800e0030000000091 +:102bc000c0ffbd273c00bfaf3800beaf21f0a0035f +:102bd0004000c4af4400c5afde8080a34000c28f78 +:102be000200042903000c2af010002243000c38fa9 +:102bf0001200621000000000030002243000c38fa6 +:102c000003006210000000001d0000100000000022 +:102c10004400c28f801002001400c2afff0f023cbc +:102c2000ffff42342400c2afff0f023cf8ff4234e2 +:102c30002800c2af19000010000000004400c38f3c +:102c40002110600040100200211043001400c2afa8 +:102c50001400c28f010042301000c2a31400c28fc2 +:102c6000421002001400c2afffff02342400c2afc2 +:102c7000f80f02242800c2af080000100000000076 +:102c80004400c28f401002001400c2afffff0234a4 +:102c90002400c2aff8ff02342800c2af4000c48f46 +:102ca0001400c28f421a02000800828c21104300d7 +:102cb0001800c2af1400c28fff0142301400c2af2f +:102cc0001480838f1800c28f6c0062140000000013 +:102cd0004000c28f200043900300022409006214c8 +:102ce000000000001400c38f00a0023c500f4224db +:102cf000211062000000428c1c00c2afc200001014 +:102d0000000000004000c28f200043900200022417 +:102d100009006214000000001400c38f00a0023cf0 +:102d2000500f422421106200000042941c00c2afe8 +:102d3000b5000010000000004000c28f200043904a +:102d400001000224b0006214000000001400c38fd0 +:102d500000a0023c500f422421106200000042906b +:102d60001c00c2af1000c29304004010000000001d +:102d70001c00c28f021102001c00c2af1400c28fdf +:102d800001004224ff0142301400c2af1400c28f80 +:102d90002200401400000000d48082930d004010f7 +:102da000000000004000c48f2128000021300000f6 +:102db00001000724124c400f0000000005004010e5 +:102dc000000000002400c28f2c00c2af970000104a +:102dd000000000001800c28f0100422421204000a2 +:102de00000a0023c500f4524285b400f000000006b +:102df0000700401400000000ffff0234148082af7f +:102e00002400c28f2c00c2af880000100000000018 +:102e10001800c28f01004224148082af1400c38fb7 +:102e200000a0023c500f422421106200000042909a +:102e30002000c2af1000c293080040100000000044 +:102e40002000c28f001902001c00c28f2110430015 +:102e50001c00c2af6c000010000000002000c28ff8 +:102e60000f004230001a02001c00c28f21104300e4 +:102e70001c00c2af6400001000000000d4808293e8 +:102e80000d004010000000004000c48f2128000009 +:102e90002130000001000724124c400f0000000008 +:102ea00005004010000000002400c28f2c00c2afbb +:102eb0005e000010000000001800c48f00a0023c5b +:102ec000500f4524285b400f00000000070040140d +:102ed00000000000ffff0234148082af2400c28f84 +:102ee0002c00c2af51000010000000001800c28f7b +:102ef000148082af4000c28f200043900300022460 +:102f000009006214000000001400c38f00a0023cfe +:102f1000500f4224211062000000428c1c00c2affe +:102f200039000010000000004000c28f20004390d4 +:102f30000200022409006214000000001400c38f84 +:102f400000a0023c500f4224211062000000429475 +:102f50001c00c2af2c000010000000004000c28f17 +:102f600020004390010002242700621400000000aa +:102f70001400c38f00a0023c500f422421106200b5 +:102f8000000042901c00c2af1000c2930400401029 +:102f9000000000001c00c28f021102001c00c2af22 +:102fa0001400c28f01004224ff0142301400c2af5e +:102fb0001400c38f00a0023c500f42242110620075 +:102fc000000042902000c2af1000c29308004010e1 +:102fd000000000002000c28f001902001c00c28ff8 +:102fe000211043001c00c2af0700001000000000c9 +:102ff0002000c28f0f004230001a02001c00c28f56 +:10300000211043001c00c2af1c00c28f2800c38fd8 +:103010002b10430003004014000000002800c28f62 +:103020001c00c2af1c00c28f2c00c2af2c00c28f8c +:1030300021e8c0033c00bf8f3800be8f4000bd2791 +:103040000800e00300000000c8ffbd273400bfaf48 +:103050003000beaf21f0a0033800c4af3c00c5afc4 +:103060004000c6af2110e0004400c2a33800c28f68 +:1030700020004390030002241000621000000000b2 +:103080003800c28f20004390020002240b0062101f +:10309000000000003800c28f20004390010002248d +:1030a0000600621000000000ff0f023cffff4234e8 +:1030b0002400c2af41010010000000003800c28fa0 +:1030c000200042902800c2af2800c38f0100622870 +:1030d00012004014000000002800c38f0300622883 +:1030e0000c00401400000000030002242800c38fdd +:1030f0000300621000000000080000100000000043 +:10310000ff0f023cffff42342000c2af030000105b +:1031100000000000ffff02342000c2afde8080a369 +:103120004400c29324004010000000001000c0a31f +:103130001480828f1800c2af3800c28f1e004390e7 +:103140001000c2932b104300170040100000000035 +:103150001480848f00a0023c500f452421300000d1 +:10316000b05b400f000000000500401400000000ac +:103170002000c28f2400c2af100100100000000028 +:103180001000c293010042241000c2a33800c28f75 +:103190001c0043941800c28f211043001800c2afd6 +:1031a000e5ff001000000000d48080a32400c0af21 +:1031b00002010010000000003800c28f2000429081 +:1031c0002c00c2af010002242c00c38f0c0062103f +:1031d00000000000030002242c00c38f03006210d3 +:1031e0000000000013000010000000003c00c28f2f +:1031f000801002001400c2af110000100000000097 +:103200003c00c38f211060004010020021104300d9 +:103210001400c2af1400c28f010042301100c2a3db +:103220001400c28f421002001400c2af040000104c +:10323000000000003c00c28f401002001400c2af2a +:103240003800c48f1400c28f421a02000800828c1a +:10325000211043001c00c2af1400c28fff01423096 +:103260001400c2af1480838f1c00c28f3300621021 +:1032700000000000d4808293210040100000000074 +:103280001000c0a31480828f1800c2af3800c28f14 +:103290001e0043901000c2932b10430017004010f3 +:1032a000000000001480848f00a0023c500f4524d1 +:1032b00021300000b05b400f00000000050040140a +:1032c000000000002000c28f2400c2afbb0000102d +:1032d000000000001000c293010042241000c2a3ad +:1032e0003800c28f1c0043941800c28f2110430085 +:1032f0001800c2afe5ff001000000000d48080a3da +:103300001c00c48f00a0023c500f4524285b400fd6 +:10331000000000000700401400000000ffff02341e +:10332000148082af2000c28f2400c2afa30000101f +:10333000000000001c00c28f148082af3800c28fd2 +:1033400020004390030002242300621400000000c8 +:103350001400c38f00a0023c500f422421186200c9 +:103360004000c28f000062a01400c38f00a0023c86 +:10337000510f4224211862004000c28f00ff4230ea +:1033800002120200000062a01400c38f00a0023ce1 +:10339000520f4224212062004000c38fff00023cf4 +:1033a0002410620002140200000082a01400c38fe7 +:1033b00000a0023c530f4224212062004000c38f32 +:1033c000000f023c2410620002160200000082a0de +:1033d00077000010000000003800c28f20004390ea +:1033e0000200022411006214000000001400c38fc8 +:1033f00000a0023c500f4224211862004000c28ffe +:10340000000062a01400c38f00a0023c510f4224b0 +:10341000211862004000c28f00ff423002120200f9 +:10342000000062a062000010000000003800c28f9f +:1034300020004390010002245d006214000000009f +:103440001400c38f00a0023c500f422421106200e0 +:10345000000042901200c2a31100c2930a00401063 +:10346000000000004000c28f0f004230001902002f +:103470001200c2930f004230251062001200c2a356 +:1034800003000010000000004000c28f1200c2a321 +:103490001400c38f00a0023c500f42242118620088 +:1034a0001200c293000062a01400c28f01004224e7 +:1034b000ff0142301400c2af1400c28f1f0040143d +:1034c000000000003800c48f2128000021300000d7 +:1034d00001000724124c400f0000000005004010be +:1034e000000000002000c28f2400c2af3300001093 +:1034f000000000001c00c28f010042242120400077 +:1035000000a0023c500f4524285b400f0000000043 +:103510000700401400000000ffff0234148082af57 +:103520002000c28f2400c2af240000100000000061 +:103530001c00c28f01004224148082af1400c38f8c +:1035400000a0023c500f4224211062000000429073 +:103550001200c2a31100c293060040100000000038 +:103560004000c28f021102001200c2a30a00001024 +:10357000000000004000c28f021202000f00443021 +:103580001200c393f0ff022424106200211880006f +:10359000251062001200c2a31400c38f00a0023cd9 +:1035a000500f4224211862001200c293000062a052 +:1035b00001000224d48082a32400c0af2400c28f63 +:1035c00021e8c0033400bf8f3000be8f3800bd2714 +:1035d0000800e00300000000e8ffbd271400bfafb3 +:1035e0001000beaf21f0a0031800c4af21200000de +:1035f0001800c58f21300000864d400f00000000ec +:1036000021e8c0031400bf8f1000be8f1800bd2733 +:103610000800e0030000000070ffbd278800bfaf76 +:103620008400beaf8000b0af21f0a0032110800065 +:103630009400c5af9800c6af9000c2a30100022459 +:103640001200c2a79400c28f1800c2af2000c22788 +:103650007000c2af7000c48f1c80858f2c44400f57 +:10366000000000004c8280a31800c28f000042902e +:103670001000c2a31000c293070040140000000015 +:103680001f0002244c8282a3ffff02247400c2aff9 +:10369000c4010010000000001000c3937800c3af05 +:1036a0002e0002247800c38f070062100000000083 +:1036b0005c0002247800c38fc1006210000000008b +:1036c00007010010000000001800c28f0100422412 +:1036d0001800c2af1800c28f000042901000c2a3b1 +:1036e0001000c3932e0002248b006214000000001f +:1036f0001800c28f010042241800c2af1800c28f08 +:10370000000042901000c2a37000c28f3400438cae +:103710003c82828f07006214000000001f00022418 +:103720004c8282a3ffff02247400c2af9d010010ef +:10373000000000007000c38f7000c28f3400428c04 +:10374000380062ac010002241200c2a71200c22796 +:103750007000c48f2128400001000624a63b400fc2 +:10376000000000001400c2af1400c28f0700401414 +:10377000000000001b0002244c8282a3ffff0324f0 +:103780007400c3af87010010000000007000d08fec +:103790001400c48f0736400f00000000340002ae52 +:1037a0007000c38f7000c28f3400428c380062ac4e +:1037b0007000c28f3400428c1c00401400000000d6 +:1037c0007000c28f5c000324200043a0010002248b +:1037d0001100c2a31100c2930b00422c0b00401039 +:1037e000000000007000c38f1100c2932118620016 +:1037f00020000224200062a01100c2930100422494 +:103800001100c2a3f3ff0010000000007000c38f7e +:103810003c82828f380062ac7000c38f3c82828f02 +:10382000340062ac17000010000000007000c38f6d +:103830002e000224200062a07000c38f2e000224fc +:10384000210062a0020002241100c2a31100c29351 +:103850000b00422c0b004010000000007000c38fd2 +:103860001100c2932118620020000224200062a0ef +:103870001100c293010042241100c2a3f3ff001003 +:10388000000000001200c0a71200c2277000c48f01 +:103890002128400001000624a63b400f0000000044 +:1038a00007004014000000001b0002244c8282a389 +:1038b000ffff02247400c2af3a01001000000000b4 +:1038c0001000c3935c000224090062140000000091 +:1038d0001800c28f010042241800c2af1800c28f26 +:1038e000000042901000c2a3f5ff0010000000008d +:1038f0001000c29368ff4014000000001c80848ff9 +:103900007000c58f2c44400f000000007400c0af51 +:1039100024010010000000001000c29308004014b1 +:10392000000000001c80848f7000c58f2c44400f65 +:10393000000000007400c0af1a0100100000000079 +:103940001000c3935c000224170062140000000002 +:103950001000c3935c000224090062140000000000 +:103960001800c28f010042241800c2af1800c28f95 +:10397000000042901000c2a3f5ff001000000000fc +:103980001000c29344ff4014000000001c80848f8c +:103990007000c58f2c44400f000000007400c0afc1 +:1039a00000010010000000001f0002244c8282a3ce +:1039b000ffff03247400c3affa00001000000000f2 +:1039c0001800c28f010042241800c2af1800c28f35 +:1039d000000042901000c2a31000c3935c000224b8 +:1039e00007006214000000001f0002244c8282a322 +:1039f000ffff02247400c2afea00001000000000c4 +:103a00001000c2931d004014000000001c80838f32 +:103a10003c82828f340062ac1c80838f3c82828f18 +:103a2000380062ac1c80838f5c000224200062a0fe +:103a3000010002241100c2a31100c2930b00422c0a +:103a40000b004010000000001c80838f1100c29307 +:103a50002118620020000224200062a01100c293fd +:103a6000010042241100c2a3f3ff00100000000077 +:103a70007400c0afcb000010000000007000c38fc6 +:103a80003c82828f340062ac7000c38f3c82828f94 +:103a9000380062ac7000c38f5c000224200062a07a +:103aa000010002241100c2a31100c2930b00422c9a +:103ab000f9fe4010000000007000c38f1100c29397 +:103ac0002118620020000224200062a01100c2938d +:103ad000010042241100c2a3f3ff00100000000007 +:103ae0001100c0a31000c293190040100000000094 +:103af0001000c3935c000224150062100000000057 +:103b00001100c2930c00422c110040100000000074 +:103b100000a0043c1100c393010062241100c2a361 +:103b2000ff006330040f8224211862001000c2934a +:103b3000000062a01800c28f010042241800c2af2a +:103b4000000042901000c2a3e6ff00100000000039 +:103b50001100c3930c0002240f0062140000000047 +:103b60001000c2930c004010000000001000c3932e +:103b70005c00022408006210000000001800c28fe0 +:103b8000010042241800c2af000042901000c2a3fe +:103b9000f3ff00100000000000a0023c1100c393de +:103ba000040f422421106200000040a000a0023c4b +:103bb000040f442421280000a648400f0000000004 +:103bc0000500401400000000ffff03247400c3af91 +:103bd00074000010000000001100c0a31100c29387 +:103be0000b00422c17004010000000001100c3938e +:103bf0001000c227212062007000c38f1100c29301 +:103c00002110620020004290500082a07000c38ffb +:103c10001100c2932120620000a0023c1100c39356 +:103c2000040f42242110620000004290200082a074 +:103c30001100c293010042241100c2a3e7ff00104b +:103c40000000000000a0023c281244247000c58f30 +:103c50002c44400f0000000000a0023c2812442425 +:103c60007000c58f0100062421380000fc31400f90 +:103c70000000000007004010000000000c000224bb +:103c80004c8282a3ffff02247400c2af45000010e3 +:103c90000000000000a0023c28124224300043949f +:103ca0001000022407006210000000001f00022420 +:103cb0004c8282a3ffff03247400c3af39000010bd +:103cc000000000001100c0a31100c2930b00422ca1 +:103cd0000f004010000000007000c38f1100c2935d +:103ce0002120620000a0023c1100c393281242244c +:103cf0002110620020004290200082a01100c29397 +:103d0000010042241100c2a3efff001000000000d8 +:103d10007000c38f00a0023c281242240400428c91 +:103d2000340062ac7000c38f7000c28f3400428ccc +:103d3000380062ac1000c29308004014000000007c +:103d40001c80848f7000c58f2c44400f0000000041 +:103d50007400c0af13000010000000001000c393f7 +:103d60005c0002244cfe6214000000001800c28fa8 +:103d7000010042241800c2af1800c28f0000429018 +:103d80001000c2a31000c293f4ff40140000000012 +:103d90001c80848f7000c58f2c44400f00000000f1 +:103da0007400c0af7400c28f21e8c0038800bf8fc9 +:103db0008400be8f8000b08f9000bd270800e00314 +:103dc00000000000b0ffbd274c00bfaf4800beaff1 +:103dd00021f0a0035000c4af5400c5af5000c28f03 +:103de00005004010000000005400c28f4000c2a334 +:103df00003000010000000000a0002244000c2a3db +:103e00004000c2931000c2a300a0023c281242242a +:103e10001c00c2af2000c0a33000c0af4c8280a302 +:103e20005000c28f060040140000000000a0023cb9 +:103e3000641242241400c2af0b0000100000000006 +:103e40005000c28f1400c2af5400c28f060040144d +:103e5000000000001f0002244c8282a33c00c0af7f +:103e6000b3010010000000001000c3831400c28fd3 +:103e700021106200ffff42241800c2af1c00c48f53 +:103e80001c80858f2c44400f000000001c00c28f56 +:103e9000200043802e0002249600621400000000df +:103ea0001c00c28f210043802e0002249100621466 +:103eb000000000001c00c28f3400428c2400c2affe +:103ec000010002242800c2a71c00c38f1c00c28f5f +:103ed0003400428c380062ac2800c2271c00c48f1a +:103ee0002128400001000624a63b400f00000000ee +:103ef0003800c2af3800c28f060040140000000036 +:103f00001b0002244c8282a33c00c0af8801001039 +:103f1000000000003800c48f0736400f000000008a +:103f2000448282af4482828f060040140000000069 +:103f30001c00c38f3c82828f340062ac04000010ee +:103f4000000000001c00c38f4482828f340062acea +:103f50001c00c38f1c00c28f3400428c380062ac3e +:103f60002800c0a72800c2271c00c48f21284000b9 +:103f700001000624a63b400f000000003800c2af3d +:103f80003800c28f06004014000000001b0002240d +:103f90004c8282a33c00c0af65010010000000000d +:103fa0003800c48f0736400f00000000448282af03 +:103fb0004482838f2400c28f160062140000000028 +:103fc0004482838f2400c28f2a0062140000000004 +:103fd0003800c28f00004390e50002240d006210fb +:103fe000000000003800c28f0b004390080002243c +:103ff00008006210000000003800c28f0b004390e0 +:104000000f000224030062100000000019000010dd +:10401000000000002800c297010042242800c2a727 +:104020002800c2271c00c48f212840002130000036 +:10403000a63b400f000000003800c2af3800c28f1e +:1040400006004014000000001b0002244c8282a3e2 +:104050003c00c0af36010010000000003800c48fe3 +:104060000736400f00000000448282afd0ff0010ee +:10407000000000002c00c0af2c00c28f0b004228b3 +:1040800016004010000000001c00c38f2c00c28fdf +:10409000212062003800c38f2c00c28f21106200e3 +:1040a00000004290200082a01c80838f2c00c28fd1 +:1040b000212062003800c38f2c00c28f21106200c3 +:1040c00000004290200082a02c00c28f01004224f8 +:1040d0002c00c2afe8ff0010000000001c00c38fde +:1040e0002400c28f340062ac1c00c38f2400c28f36 +:1040f000380062ac1c00c28f200043805c000224a8 +:104100000a006214000000001400c38f5c00022447 +:10411000000062a01400c28f010040a01400c28ff2 +:104120003c00c2af02010010000000001c00c28f62 +:104130003400438c3c82828f8400621000000000b7 +:104140000a0002242100c2a31c00c38f2100c283e5 +:104150002110620020004380200002240600621427 +:10416000000000002100c293ffff42242100c2a3ef +:10417000f5ff0010000000002100c2830800422863 +:104180002d004014000000002100c28308004228d6 +:1041900019004014000000003000c6270000c48c45 +:1041a000211880001400c28f213862001c00c58fc6 +:1041b0002100c393ffff62242100c2a32014037ccb +:1041c0002110a200200042900000e2a001008424ff +:1041d0000000c4ac1000c3833000c28feaff621439 +:1041e000000000003000c0af010002242000c2a384 +:1041f000e5ff0010000000003000c5270000a38c80 +:10420000212060001400c28f212082002e00022491 +:10421000000082a0010063240000a3ac1000c3834f +:104220003000c28f04006214000000003000c0aff4 +:10423000010002242000c2a31c00c38f2100c283fe +:104240002110620020004380200002240600621436 +:10425000000000002100c293ffff42242100c2a3fe +:10426000f5ff0010000000002100c2831900400487 +:10427000000000003000c6270000c48c2118800018 +:104280001400c28f213862001c00c58f2100c39327 +:10429000ffff62242100c2a32014037c2110a2008e +:1042a000200042900000e2a0010084240000c4ac81 +:1042b0001000c3833000c28febff621400000000c7 +:1042c0003000c0af010002242000c2a3e6ff0010ae +:1042d000000000003000c5270000a38c21206000f2 +:1042e0001400c28f212082005c000224000082a002 +:1042f000010063240000a3ac1000c3833000c28f10 +:1043000004006214000000003000c0af010002246d +:104310002000c2a31c00c38f1c00c28f3400428c3b +:10432000380062ac1c00c48f5351400f00000000e5 +:104330007eff401000000000080002244c8282a38f +:104340003c00c0af7a000010000000003000c28fb7 +:10435000ffff42243000c2af2c00c0af2000c29348 +:104360004c004010000000003000c28f2a00c2a79d +:104370003000c28f2c00c38f231043001b00401855 +:10438000000000002c00c38f1400c28f21106200b7 +:10439000000042903400c2a32c00c38f1400c28fcf +:1043a000212062003000c38f1400c28f21106200f0 +:1043b00000004290000082a03000c38f1400c28f22 +:1043c000211862003400c293000062a03000c28f46 +:1043d000ffff42243000c2af2c00c28f01004224f4 +:1043e0002c00c2afe2ff0010000000002a00c297bc +:1043f000010042242c00c2af1800c38f1400c28fea +:10440000231062003000c2af3000c28f2c00c38f77 +:10441000231043001b004018000000002c00c38f35 +:104420001400c28f21106200000042903400c2a329 +:104430002c00c38f1400c28f212062003000c38f74 +:104440001400c28f2110620000004290000082a080 +:104450003000c38f1400c28f211862003400c29351 +:10446000000062a03000c28fffff42243000c2afc4 +:104470002c00c28f010042242c00c2afe2ff0010ca +:10448000000000001800c28f000040a026000010ad +:10449000000000003000c28f2a00c2a73000c28f87 +:1044a0002c00c38f231043001b00401800000000a5 +:1044b0002c00c38f1400c28f2110620000004290b4 +:1044c0003400c2a32c00c38f1400c28f21206200cd +:1044d0003000c38f1400c28f211062000000429090 +:1044e000000082a03000c38f1400c28f2118620028 +:1044f0003400c293000062a03000c28fffff42244c +:104500003000c2af2c00c28f010042242c00c2af89 +:10451000e2ff0010000000002a00c2971400c38fc1 +:1045200021104300010040a01400c28f3c00c2af24 +:104530003c00c28f21e8c0034c00bf8f4800be8ff3 +:104540005000bd270800e00300000000d8ffbd2791 +:104550002400bfaf2000beaf21f0a0032800c4afed +:10456000010002241200c2a71200c2272800c48f33 +:104570002128400001000624a63b400f0000000057 +:104580001800c2af1800c28f0500401400000000e0 +:10459000ff0002241c00c2afa700001000000000b2 +:1045a0001800c48f0736400f00000000448282af1d +:1045b0004482828f1b004014000000002800c38f3b +:1045c0005c000224200062a01000c0a31000c2936f +:1045d0000b00422c0b004010000000002800c38f8d +:1045e0001000c2932118620020000224200062a063 +:1045f0001000c293010042241000c2a3f3ff001078 +:10460000000000002800c38f3c82828f340062ac1f +:104610002800c38f3c82828f380062ac8500001076 +:10462000000000004482828f1400c2af2800c38fb4 +:104630004482828f340062ac2800c38f4482828f10 +:10464000380062ac1200c2272800c48f2128400025 +:1046500001000624a63b400f000000001800c2af76 +:104660001800c28f0500401400000000ff00022463 +:104670001c00c2af70000010000000001800c48fc2 +:104680000736400f00000000448282af4482828fd0 +:1046900006004014000000002800c38f3c82828f77 +:1046a000340062ac04000010000000002800c38f3a +:1046b0004482828f340062ac2800c38f2800c28fee +:1046c0003400428c380062ac1200c0a71200c2272e +:1046d0002800c48f2128400001000624a63b400f7b +:1046e000000000001800c2af1800c28f050040147f +:1046f00000000000ff0002241c00c2af4e000010aa +:10470000000000001800c48f0736400f00000000b2 +:10471000448282af4482838f1400c28f16006214d9 +:10472000000000004482838f1400c28f29006214ad +:10473000000000001800c28f00004390e500022432 +:104740000d006210000000001800c28f0b004390a3 +:104750000800022408006210000000001800c28f48 +:104760000b0043900f0002240300621000000000c1 +:1047700018000010000000001200c2272800c48f9b +:104780002128400021300000a63b400f000000001f +:104790001800c2af1800c28f0500401400000000ce +:1047a000ff0002241c00c2af230000100000000024 +:1047b0001200c297010042241200c2a71800c48f41 +:1047c0000736400f00000000448282afd1ff001086 +:1047d000000000001000c0a31000c2930b00422c88 +:1047e0000e004010000000002800c38f1000c2938c +:1047f000212062001800c38f1000c29321104300d3 +:1048000000004290200082a01000c29301004224c8 +:104810001000c2a3f0ff0010000000002800c38faa +:104820001400c28f340062ac2800c38f1400c28f02 +:10483000380062ac1c00c0af1c00c28f21e8c0036e +:104840002400bf8f2000be8f2800bd270800e00392 +:1048500000000000e8ffbd271400bfaf1000beaf8e +:1048600021f0a0031800c4af212000001800c58f5c +:10487000213000002552400f0000000021e8c00355 +:104880001400bf8f1000be8f1800bd270800e00382 +:1048900000000000c8ffbd273400bfaf3000beaf2e +:1048a00021f0a003211080003c00c5af4000c6af3e +:1048b0003800c2a33c00c28f1400c2af00a0023c6b +:1048c000140f42242800c2af4c8280a32a5c400f00 +:1048d0000000000007004010000000001800022443 +:1048e0004c8282a3ffff02242c00c2af9001001073 +:1048f000000000001000c0a31400c28f000042801e +:1049000013004010000000001400c28f000043801c +:104910002e0002240e006210000000001400c28f5e +:10492000000043805c0002240900621000000000c7 +:104930001400c28f010042241400c2af1000c293c1 +:10494000010042241000c2a3ebff00100000000091 +:104950001000c2930900422c070040140000000020 +:104960001f0002244c8282a3ffff02242c00c2af4e +:104970006f010010000000001400c28f000043808f +:104980002e00022420006214000000001400c28fd8 +:10499000010042241400c2af1000c0a31400c28f53 +:1049a000000042800e004010000000001400c28f82 +:1049b000000043805c000224090062100000000037 +:1049c0001400c28f010042241400c2af1000c29331 +:1049d000010042241000c2a3f0ff001000000000fc +:1049e0001000c2930400422c070040140000000095 +:1049f0001f0002244c8282a3ffff02242c00c2afbe +:104a00004b010010000000001400c28f0000438022 +:104a10005c00022406006214000000001400c28f33 +:104a2000010042241400c2aff7ff00100000000094 +:104a30001400c28f00004280aeff4014000000004e +:104a40003c00c28f1400c2af2800c48f1c80858f29 +:104a50002c44400f000000001400c28f0000429060 +:104a60001000c2a31000c3932e000224570062144a +:104a7000000000001400c28f010042241400c2afe5 +:104a80001400c28f000042901000c2a31000c39314 +:104a90002e0002240e006210000000001000c293dd +:104aa0000b004010000000001000c3935c000224c3 +:104ab00007006210000000001f0002244c8282a345 +:104ac000ffff02242c00c2af1901001000000000fb +:104ad0001000c3932e000224230062140000000083 +:104ae0001c80828f3400438c3c82828f07006214ca +:104af000000000001f0002244c8282a3ffff02245a +:104b00002c00c2af0a010010000000001400c28f88 +:104b1000010042241400c2af1400c28f0000429072 +:104b20001000c2a31000c3935c0002240a006210ac +:104b3000000000001000c2930700401000000000b9 +:104b40001f0002244c8282a3ffff02242c00c2af6c +:104b5000f700001000000000029d023cc003442446 +:104b6000764d400f000000001000c3935c0002244b +:104b700009006214000000001400c28f01004224ea +:104b80001400c2af1400c28f000042901000c2a3f4 +:104b9000f5ff0010000000001000c293aeff4014ab +:104ba000000000001c80848f2800c58f2c44400f1b +:104bb000000000001f0002244c8282a3ffff022499 +:104bc0002c00c2afda000010000000001000c393f8 +:104bd0005c0002243b006214000000001c80838ff4 +:104be0003c82828f340062ac1c80838f3c82828f37 +:104bf000380062ac1c80838f5c000224200062a01d +:104c0000010002241000c2a31000c2930b00422c2a +:104c10000b004010000000001c80838f1000c29326 +:104c20002118620020000224200062a01000c2931c +:104c3000010042241000c2a3f3ff00100000000096 +:104c40001400c28f010042241400c2af1400c28fae +:104c5000000042901000c2a31000c3935c00022425 +:104c60000b006214000000001c80848f2800c58f98 +:104c70002c44400f000000001f0002244c8282a33d +:104c8000ffff02242c00c2afa900001000000000aa +:104c90001000c29370ff4014000000001c80848f3d +:104ca0002800c58f2c44400f000000001f00022484 +:104cb0004c8282a3ffff02242c00c2af9c00001094 +:104cc000000000002400c0a31400c28f0000429026 +:104cd0001000c2a31100c0a31000c293190040101d +:104ce000000000001000c3935c0002241500621055 +:104cf000000000001100c2930c00422c1100401073 +:104d0000000000001100c393010062241100c2a33f +:104d1000ff0063301000c227211862001000c29308 +:104d2000080062a01400c28f010042241400c2af28 +:104d30001400c28f000042901000c2a3e6ff0010d2 +:104d4000000000001100c3931000c2272110620070 +:104d5000080040a01800c3832e0002242300621420 +:104d6000000000001900c2830f0040100000000086 +:104d70001900c3832e0002240b0062100000000003 +:104d80001c80848f2800c58f2c44400f0000000039 +:104d90001f0002244c8282a3ffff02242c00c2af1a +:104da00063000010000000001900c3832e000224dd +:104db0000e006214000000001a00c2830b004010b5 +:104dc000000000001c80848f2800c58f2c44400ff9 +:104dd000000000001f0002244c8282a3ffff022477 +:104de0002c00c2af52000010000000001800c227c3 +:104df00021204000764d400f0000000003004010cd +:104e00000000000017000010000000001000c39315 +:104e10005c00022409006214000000001400c28f2c +:104e2000010042241400c2af1400c28f000042905f +:104e30001000c2a3f5ff0010000000001000c29394 +:104e4000a1ff4014000000001c80848f2800c58f43 +:104e50002c44400f000000002c00c0af34000010b4 +:104e6000000000001800c22721204000d353400f4b +:104e70000000000009004014000000001c80848f26 +:104e80002800c58f2c44400f00000000ffff0224c3 +:104e90002c00c2af26000010000000001800c2273e +:104ea00021204000764d400f000000000b00401014 +:104eb000000000001c80848f2800c58f2c44400f08 +:104ec000000000001b0002244c8282a3ffff02248a +:104ed0002c00c2af16000010000000001400c28faa +:104ee000000043805c0002240900621400000000fe +:104ef0001400c28f010042241400c2af1400c28ffc +:104f0000000042901000c2a3f4ff00100000000057 +:104f10001000c2936cff4014000000001c80848fbe +:104f20002800c58f2c44400f000000002c00c0afab +:104f30002c00c28f21e8c0033400bf8f3000be8f29 +:104f40003800bd270800e00300000000c8ffbd27af +:104f50003400bfaf3000beaf21f0a0033800c4afb3 +:104f600000a0023c281242241000c2af1800c0a7c3 +:104f70002400c0a32400c2930c00422c0f00401058 +:104f80000000000000a0023c2400c393040f422450 +:104f9000212062002400c3933800c28f21106200d8 +:104fa00000004290000082a02400c293010042242d +:104fb0002400c2a3efff00100000000000a0023c8c +:104fc000040f442421280000a648400f00000000e0 +:104fd0000600401400000000120002244c8282a34c +:104fe0002800c0af6f000010000000002400c0a324 +:104ff0002400c2930b00422c0f0040100000000060 +:105000001000c38f2400c2932120620000a0023c44 +:105010002400c393040f4224211062000000429038 +:10502000200082a02400c293010042242400c2a3d5 +:10503000efff0010000000001000c38f1c80828f63 +:105040003400428c340062ac1000c38f1c80828f0d +:105050003800428c380062ac1000c28f040040acb3 +:105060001000c28f080040ac1000c38f1c80828fdc +:105070000000428c000062ac1800c2271000c48ff0 +:1050800021284000120006248c3c400f0000000044 +:1050900004004010000000002800c0af41000010d4 +:1050a00000000000d48082930f0040100000000038 +:1050b0001000c28f0000448c212800002130000025 +:1050c00001000724124c400f0000000006004010b1 +:1050d00000000000090002244c8282a32800c0af17 +:1050e00030000010000000001000c28f3400438c1c +:1050f0003c82828f04006214000000002000c0afd8 +:1051000004000010000000001000c28f3400428c28 +:105110002000c2af1000c38f1000c28f3400428c39 +:10512000380062ac1800c2271000c48f212840004c +:1051300001000624a63b400f000000001400c2af8f +:105140001400c28f06004014000000001b0002245f +:105150004c8282a32800c0af1200001000000000a3 +:105160001400c48f0736400f000000001c00c2afbf +:105170001000c28f0000448c1c00c58f2000c68f19 +:105180007054400f000000000500401000000000b7 +:10519000010002242800c2af02000010000000003d +:1051a0002800c0af2800c28f21e8c0033400bf8fa1 +:1051b0003000be8f3800bd270800e003000000006b +:1051c000b0ffbd274c00bfaf4800beaf21f0a00329 +:1051d0005000c4af5400c5af5800c6af1800c22776 +:1051e0003800c2afd88080af200002241200c2a7ce +:1051f0005000c28f0000448c2128000000020624c9 +:10520000d169400f000000002e0002241800c2a344 +:10521000010002241000c2a71000c2970b00422c0c +:105220000b004010000000001000c3971000c227c0 +:105230002118620020000224080062a01000c2971a +:10524000010042241000c2a7f3ff0010000000007c +:10525000100002242300c2a32400c0a35400c28f64 +:105260003200c2a75400c38fff0f023c241062001b +:10527000021402002c00c2a73400c0af3782829310 +:105280002500c2a3388282972600c2a74282829755 +:105290002800c2a72a00c0a72e00c0a73000c0a7c0 +:1052a0001000c0a71000c2971200c3972b10430034 +:1052b0000f004010000000005000c28f1000c39784 +:1052c0000000428c212062001000c3973800c28f7a +:1052d0002110620000004290000082a01000c297de +:1052e000010042241000c2a7eeff001000000000e1 +:1052f0002e0002241900c2a35800c28f3200c2a798 +:105300005800c38fff0f023c2410620002140200f9 +:105310002c00c2a71000c0a71000c2971200c397ac +:105320002b10430011004010000000005000c28ffd +:105330001000c4971200c3970000428c2110620035 +:10534000212044001000c3973800c28f2110620052 +:1053500000004290000082a01000c2970100422489 +:105360001000c2a7ecff0010000000005000c48f26 +:105370005400c58f4c45400f000000003c00c2aff8 +:105380005000c28f3c00c48f0000458c21300000cb +:10539000b05b400f00000000060040140000000059 +:1053a000090002244c8282a34000c0af0300001019 +:1053b00000000000010002244000c2af4000c28f84 +:1053c00021e8c0034c00bf8f4800be8f5000bd27ae +:1053d0000800e00300000000e8ffbd271400bfaf95 +:1053e0001000beaf21f0a0031800c4af2110a00030 +:1053f0001c00c2a31c00c293212000001800c58f0e +:1054000021300000213840000a55400f0000000004 +:1054100021e8c0031400bf8f1000be8f1800bd2705 +:105420000800e00300000000b8ffbd274400bfaf44 +:105430004000beaf21f0a003211880004c00c5af92 +:105440005000c6af2110e0004800c3a35400c2a31f +:1054500000a0023c140f42241000c2af00a0023c86 +:10546000281242241400c2af1c00c0a7029d023cb7 +:10547000c403448cc40343240400638cc403422447 +:105480000800428c2800c4af2c00c3af3000c2af6c +:105490003400c0a34c8280a31000c48f1c80858f71 +:1054a0002c44400f000000004c00c48f764d400f8c +:1054b0000000000007004010000000000c00022463 +:1054c0004c8282a3ffff02243800c2af800200108a +:1054d000000000001c80828f3400438c3c82828f4d +:1054e00009006210000000001c80828f1000c38f32 +:1054f0003400448c3400628c0300821000000000f1 +:105500000b000010000000001c80848f1000c58f6d +:105510002c44400f000000001f0002244c8282a394 +:10552000ffff02243800c2af690200100000000033 +:105530001c00c297010042241c00c2a71c00c22705 +:105540001c80848f2128400001000624a63b400fc8 +:10555000000000001800c2af1800c28f0b004014fa +:10556000000000001c80848f1000c58f2c44400f69 +:10557000000000001b0002244c8282a3ffff0224d3 +:105580003800c2af52020010000000001c00c29799 +:10559000010042241c00c2a71c00c2271c80848f6b +:1055a0002128400021300000a63b400f00000000f1 +:1055b0001800c2af1800c28f0b004014000000009a +:1055c0001c80848f1000c58f2c44400f0000000009 +:1055d0001b0002244c8282a3ffff02243800c2afca +:1055e0003b020010000000005400c2932b00401446 +:1055f000000000001800c28f00004280e801401047 +:10560000000000001800c28f00004390e500022453 +:105610000b006210000000001c80848f1000c58ffa +:105620002c44400f00000000160002244c8282a38c +:10563000ffff02243800c2af250200100000000066 +:105640001c00c297010042241c00c2a71c00c227f4 +:105650001c80848f2128400021300000a63b400f91 +:10566000000000001800c2af1800c28fe1ff401414 +:10567000000000001c80848f1000c58f2c44400f58 +:10568000000000001b0002244c8282a3ffff0224c2 +:105690003800c2af0e02001000000000488280a354 +:1056a0002000c0a748828293bd0140140000000082 +:1056b0001800c28f00004280ee0040100000000081 +:1056c0001800c28f00004390e5000224c100621060 +:1056d000000000001800c28f0b0043900800022455 +:1056e000bc006210000000001800c28f0b00439045 +:1056f0000f000224b7006210000000001800c28fe3 +:105700000b0042901000423070004010000000007a +:105710002000c297010042242000c2a72200c0a39b +:105720002200c2930800422c150040100000000027 +:105730001800c38f2200c293211043000000438051 +:10574000200002240e006210000000002200c3931b +:105750001000c227212062001800c38f2200c293cc +:105760002110430000004290180082a02200c29342 +:10577000010042242200c2a3e9ff00100000000043 +:105780001800c28f08004380200002242500621008 +:10579000000000002200c393010062242200c2a383 +:1057a000ff0063301000c227211862002e0002247f +:1057b000180062a02300c0a32300c2930300422c60 +:1057c00018004010000000001800c38f2300c2938f +:1057d00021106200080043802000022411006210a2 +:1057e000000000002200c393010062242200c2a333 +:1057f000ff0063301000c227212062001800c38f11 +:105800002300c2932110620008004290180082a079 +:105810002300c293010042242300c2a3e6ff00102c +:10582000000000002200c3931000c2272110620074 +:10583000180040a02800c22721204000764d400fcc +:10584000000000000b004010000000001c80848f4e +:105850001000c58f2c44400f000000000c000224f3 +:105860004c8282a3ffff02243800c2af98010010cf +:10587000000000001c80828f1000c38f3400448c15 +:105880003400628c0b008214000000001c80848fa6 +:105890001000c58f2c44400f000000001f000224a0 +:1058a0004c8282a3ffff02243800c2af880100109f +:1058b00000000000020002241c00c2a70100022414 +:1058c000df8082a346000010000000002800c227ed +:1058d00021204000212800000c000624d169400f3f +:1058e000000000002200c0a32200c2930b00422c43 +:1058f0000e004010000000001400c38f2200c2936d +:10590000212062001800c38f2200c293211043009f +:1059100000004290200082a02200c2930100422495 +:105920002200c2a3f0ff0010000000001400c38f8b +:1059300000a0023c04124224000062ac1400c38f99 +:105940001c00c2972c0062a41400c38f1c80828f9d +:105950003400428c340062ac1400c38f1c80828ff0 +:105960003800428c380062ac1400c28f040040ac96 +:105970001400c28f080040ac1c00c2271400c48f62 +:1059800021284000010006248940400f000000004b +:105990000b004010000000001c80848f1000c58f99 +:1059a0002c44400f00000000010002244c8282a31e +:1059b000ffff02243800c2af4501001000000000c4 +:1059c0001c00c297010042241c00c2a70400001062 +:1059d000000000001c00c297010042241c00c2a766 +:1059e000df8082930f00401000000000df8080a362 +:1059f0001c80838f1c80828f3400428c380062ac04 +:105a00001c00c2271c80848f21284000010006242e +:105a1000a63b400f000000001800c2af08000010b5 +:105a2000000000001c00c2271c80848f2128400039 +:105a300021300000a63b400f000000001800c2af5c +:105a40001800c28f17ff4014000000001c80848fd4 +:105a50001000c58f2c44400f000000001b000224e2 +:105a60004c8282a3ffff02243800c2af180100104d +:105a7000000000002000c297c50040100000000098 +:105a80001e00c0a71c80838f1c80828f3400428c34 +:105a9000380062ac1e00c2271c80848f2128400081 +:105aa00001000624a63b400f000000001800c2af12 +:105ab0001800c28f0b004014000000001c80848f6f +:105ac0001000c58f2c44400f000000001b00022472 +:105ad0004c8282a3ffff02243800c2affc000010fa +:105ae000000000001800c48f0736400f00000000bf +:105af0001e00c2a7029d023cc0034424764d400f05 +:105b0000000000000b004010000000001c80848f8b +:105b10001000c58f2c44400f000000000c00022430 +:105b20004c8282a3ffff02243800c2afe8000010bd +:105b300000000000020002241c00c2a71c80838f0a +:105b40001c80828f3400428c380062ac1c00c2275b +:105b50001c80848f2128400001000624a63b400fb2 +:105b6000000000001800c2af1800c28f0b004014e4 +:105b7000000000001c80848f1000c58f2c44400f53 +:105b8000000000001b0002244c8282a3ffff0224bd +:105b90003800c2afce000010000000001800c48f13 +:105ba0000736400f00000000448282af1e00c397fa +:105bb0004482828f11006214000000001e00c3970f +:105bc0004482828f2a006214000000001800c28ff5 +:105bd00000004390e500022408006210000000006d +:105be0001800c28f0b0043900800022403006210cb +:105bf000000000001e000010000000001c00c29702 +:105c0000010042241c00c2a71c00c2271c80848ff4 +:105c10002128400021300000a63b400f000000007a +:105c20001800c2af1800c28f0b0040140000000023 +:105c30001c80848f1000c58f2c44400f0000000092 +:105c40001b0002244c8282a3ffff02243800c2af53 +:105c50009f000010000000001800c48f0736400f9e +:105c600000000000448282afd0ff0010000000005e +:105c70002800c22721204000212800000c00062413 +:105c8000d169400f000000002200c0a32200c2938f +:105c90000b00422c0e004010000000002200c393b5 +:105ca0001000c227212062001800c38f2200c29377 +:105cb0002110430000004290180082a02200c293ed +:105cc000010042242200c2a3f0ff001000000000e7 +:105cd0002800c22721204000bb57400f00000000d1 +:105ce0000b004010000000001c80848f1000c58f46 +:105cf0002c44400f00000000010002244c8282a3cb +:105d0000ffff02243800c2af710000100000000045 +:105d10001c00c297010042241c00c2a71c80838f74 +:105d20001c80828f3400428c380062ac1c00c22779 +:105d30001c80848f2128400001000624a63b400fd0 +:105d4000000000001800c2af1800c28f0b00401402 +:105d5000000000001c80848f1000c58f2c44400f71 +:105d6000000000001b0002244c8282a3ffff0224db +:105d70003800c2af56000010000000002000c2979b +:105d8000ffff42242000c2a746fe001000000000d2 +:105d900001000224488282a342fe0010000000009d +:105da0002800c227212040000c000524714f400f1d +:105db0000000000009004014000000001c80848fd7 +:105dc0001000c58f2c44400f00000000ffff02248c +:105dd0003800c2af3e000010000000002800c227bb +:105de00021204000212800000c000624d169400f2a +:105df000000000002200c0a32200c2930b00422c2e +:105e00000e004010000000002200c3931000c227c3 +:105e1000212062001c80838f2200c2932110620027 +:105e200020004290180082a02200c2930100422468 +:105e30002200c2a3f0ff001000000000029d023cff +:105e4000c0034424764d400f000000000b004010ba +:105e5000000000001c80848f1000c58f2c44400f70 +:105e6000000000000c0002244c8282a3ffff0224e9 +:105e70003800c2af16000010000000002800c22742 +:105e800021204000bb57400f000000000b004010d5 +:105e9000000000001c80848f1000c58f2c44400f30 +:105ea00000000000010002244c8282a3ffff0224b4 +:105eb0003800c2af06000010000000001c80848f74 +:105ec0001000c58f2c44400f000000003800c0af08 +:105ed0003800c28f21e8c0034400bf8f4000be8f4e +:105ee0004800bd270800e0030000000098ffbd2720 +:105ef0006400bfaf6000beaf21f0a0036800c4af74 +:105f00002a5c400f00000000050040100000000067 +:105f1000ffff02245800c2af4b0000100000000039 +:105f20001800c227212040001c80858f2c44400f80 +:105f3000000000001400c0a31400c2930b00422c08 +:105f40000e004010000000001c80838f1400c293dc +:105f5000212062001400c3936800c28f21106200e8 +:105f600000004290200082a01400c293010042244d +:105f70001400c2a3f0ff00100000000000a0023ccb +:105f8000281244241c80858f2c44400f0000000000 +:105f90001c80848f00a0023c2812452401000624a6 +:105fa00021380000fc31400f000000001000c2af9b +:105fb0001000c28f0a004010000000001800c22725 +:105fc0001c80848f212840002c44400f00000000da +:105fd000ffff02245800c2af1b00001000000000a9 +:105fe0001c80828f2c0042241c80848f212840003a +:105ff000010006248940400f000000001000c2afdd +:106000001000c28f09004014000000001800c227d1 +:106010001c80848f212840002c44400f0000000089 +:106020005800c0af08000010000000001800c22790 +:106030001c80848f212840002c44400f0000000069 +:10604000ffff02245800c2af5800c28f21e8c003ee +:106050006400bf8f6000be8f6800bd270800e003aa +:106060000000000098ffbd276400bfaf6000beaf16 +:1060700021f0a0036800c4af6c00c5af7000c6afcc +:106080001000c2275000c2af4c8280a35000c28fc4 +:10609000200042246800c48f21284000010006240b +:1060a0000848400f000000000700401400000000f6 +:1060b000120002244c8282a3ffff02245c00c2afc4 +:1060c000f0000010000000007000c28f300040a0ff +:1060d0005b00c0a35b00c2930c00422c1400401074 +:1060e000000000005b00c3936800c28f21106200b3 +:1060f000000042800e004010000000007000c38fbe +:106100005b00c293212062005b00c3936800c28fd2 +:1061100021106200000042901c0082a05b00c2932c +:10612000010042245b00c2a3eaff0010000000004f +:106130007000c38f5b00c293211062001c0040a05e +:106140007000c38f6c00c28f290062a07000c38fe3 +:106150001c80828f3400428c2c0062ac5000c38fb4 +:1061600000a0023c04124224000062ac5000c28f26 +:10617000040040ac5000c28f080040ac5000c28ff9 +:106180002c0040a45000c38f6c00c28f300062a46a +:106190005000c38f1c80828f3400428c340062ac6c +:1061a0005000c38f1c80828f3800428c380062ac54 +:1061b00000a0023c281244245000c58f2c44400ffc +:1061c000000000005000c48f00a0023c28124524ab +:1061d0000100062401000724fc31400f00000000ec +:1061e0005400c2af5400c28f0700401000000000ee +:1061f0000b0002244c8282a3ffff02245c00c2af8a +:10620000a0000010000000005000c28f2c0042943b +:106210005800c2a75800c2275000c48f2128400050 +:10622000720006240833400f000000005400c2af83 +:106230005400c28f8f004014000000005000c28f35 +:1062400030004394080002245a006210000000004d +:106250005b00c0a35a00c0a35a00c2930800422c9e +:1062600018004010000000005000c38f5a00c29375 +:1062700021106200200043802000022411006210df +:10628000000000007000c38f5b00c2932120430018 +:106290005000c38f5a00c293211062002000429028 +:1062a000000082a05b00c293010042245b00c2a3f5 +:1062b0005a00c293010042245a00c2a3e6ff001014 +:1062c000000000005000c28f2800438020000224fc +:1062d0000d006214000000005000c28f29004380ae +:1062e0002000022408006214000000005000c28f49 +:1062f0002a004380200002240300621400000000f2 +:1063000009000010000000007000c48f5b00c39300 +:10631000010062245b00c2a3ff0062302118440028 +:106320002e000224000062a0080002245a00c2a32a +:106330005a00c2930b00422c1800401000000000cd +:106340005000c38f5a00c293211062002000438086 +:106350002000022411006210000000007000c38fb2 +:106360005b00c293212043005000c38f5a00c293a8 +:106370002110620020004290000082a05b00c293c6 +:10638000010042245b00c2a35a00c29301004224d0 +:106390005a00c2a3e6ff0010000000007000c28f88 +:1063a0005b00c39321106200000040a017000010a2 +:1063b000000000005b00c0a35b00c2930b00422cf6 +:1063c0000e004010000000007000c38f5b00c293fd +:1063d000212043005000c38f5b00c2932110620054 +:1063e00020004290000082a05b00c2930100422482 +:1063f0005b00c2a3f0ff0010000000007000c28f1d +:106400005b00c39321106200000040a07000c38fa6 +:106410005000c28f300042940d0062a07000c38f04 +:106420005000c28f1400428c100062ac7000c48f08 +:106430005000c28f1e004294001c02005000c28f08 +:106440001c00429421106200140082ac7000c38fc3 +:106450005000c28f2c004294180062ac7000c38fb1 +:1064600001000224300062a05c00c0af05000010f3 +:10647000000000001b0002244c8282a3ffff0224c4 +:106480005c00c2af5c00c28f21e8c0036400bf8f14 +:106490006000be8f6800bd270800e0030000000018 +:1064a00098ffbd276400bfaf6000beaf21f0a0031e +:1064b0006800c4af1000c2275000c2af4c8280a356 +:1064c0006800c28f300042900700401400000000b6 +:1064d000070002244c8282a3ffff02245c00c2afab +:1064e000d6000010000000006800c28f1c80838f5f +:1064f0002c00448c3400628c0700821000000000e5 +:106500001f0002244c8282a3ffff02245c00c2af62 +:10651000ca000010000000006800c28f1c00432465 +:106520005000c28f2000422421206000212840001a +:10653000010006240848400f000000000700401436 +:1065400000000000120002244c8282a3ffff0224fc +:106550005c00c2afb9000010000000005000c38f03 +:1065600000a0023c04124224000062ac5000c28f22 +:10657000040040ac5000c28f080040ac5000c38ff4 +:106580006800c28f1800428c010042242c0062a4d3 +:106590005000c38f6800c28f29004290300062a46f +:1065a0005000c38f1c80828f3400428c340062ac58 +:1065b0005000c38f1c80828f3800428c380062ac40 +:1065c00000a0023c281244245000c58f2c44400fe8 +:1065d000000000005000c48f00a0023c2812452497 +:1065e0000100062401000724fc31400f00000000d8 +:1065f0005400c2af5400c28f0700401000000000da +:106600000b0002244c8282a3ffff02245c00c2af75 +:106610008a000010000000005000c28f3000439438 +:10662000080002245a006210000000005800c0a3b5 +:106630005900c0a35900c2930800422c1800401012 +:10664000000000005000c38f5900c2932110620067 +:10665000200043802000022411006210000000008e +:106660006800c38f5800c293212043005000c38f9d +:106670005900c2932110620020004290000082a0c5 +:106680005800c293010042245800c2a35900c2938b +:10669000010042245900c2a3e6ff001000000000e0 +:1066a0005000c28f28004380200002240d00621495 +:1066b000000000005000c28f290043802000022407 +:1066c00008006214000000005000c28f2a004380be +:1066d00020000224030062140000000009000010e2 +:1066e000000000006800c48f5800c39301006224ba +:1066f0005800c2a3ff006230211844002e0002247b +:10670000000062a0080002245900c2a35900c293ed +:106710000b00422c18004010000000005000c38ff6 +:106720005900c293211062002000438020000224ff +:1067300011006210000000006800c38f5800c2936f +:10674000212043005000c38f5900c29321106200e2 +:1067500020004290000082a05800c2930100422411 +:106760005800c2a35900c293010042245900c2a399 +:10677000e6ff0010000000006800c28f5800c393bd +:1067800021106200000040a017000010000000006f +:106790005800c0a35800c2930b00422c0e004010ba +:1067a000000000006800c38f5800c29321204300fe +:1067b0005000c38f5800c293211062002000429005 +:1067c000000082a05800c293010042245800c2a3d6 +:1067d000f0ff0010000000006800c28f5800c39353 +:1067e00021106200000040a06800c38f5000c28fdb +:1067f000300042940d0062a06800c38f5000c28f29 +:106800001400428c100062ac6800c48f5000c28f2c +:106810001e004294001c02005000c28f1c004294d3 +:1068200021106200140082ac6800c38f5000c28f38 +:106830002c004294180062ac5c00c0af5c00c28fb8 +:1068400021e8c0036400bf8f6000be8f6800bd27d1 +:106850000800e00300000000f0ffbd270800beaf05 +:1068600021f0a00388bf023c1061428c0001427cf1 +:106870000000c2af0000c38f000062380100422c4c +:106880000000c2af0000c28f21e8c0030800be8f25 +:106890001000bd270800e00300000000f8ffbd273e +:1068a0000000beaf21f0a0030002022421e8c003d3 +:1068b0000000be8f0800bd270800e00300000000b4 +:1068c000f8ffbd270000beaf21f0a0035082828fe9 +:1068d00021e8c0030000be8f0800bd270800e003c8 +:1068e00000000000f8ffbd270000beaf21f0a003ac +:1068f00088bf033c0061629010004234006162a0d6 +:1069000081bf033c6090629002004234609062a0bc +:1069100088bf033c5060629002004234506062a025 +:1069200088bf043c40608390fdff02242410620075 +:10693000406082a088bf033c00616290080042343e +:10694000006162a021e8c0030000be8f0800bd27df +:106950000800e00300000000e8ffbd271400bfafff +:106960001000beaf21f0a003545c400f00000000f7 +:1069700088bf023c5060439002006334506043a0e3 +:1069800021e8c0031400bf8f1000be8f1800bd2780 +:106990000800e00300000000d0ffbd272c00bfafbf +:1069a0002800beaf21f0a0033000c4af2110a0002a +:1069b0003800c6af3400c2a3080002241000c2a7ea +:1069c00088bf043c50608390fdff022424106200c5 +:1069d000506082a0029d043c3400c39321106000eb +:1069e000401002002110430080180200d4038224ca +:1069f00021106200000042902000c2a33800c28f24 +:106a00001c00c2af029d043c3400c39321106000ff +:106a1000401002002110430080180200d403822499 +:106a200021106200010042901800c2a32000c28f12 +:106a3000400042342000c2af2000c2932120400019 +:106a4000615c400f000000001f00c2932120400045 +:106a5000615c400f000000001e00c2932120400036 +:106a6000615c400f000000001d00c2932120400027 +:106a7000615c400f000000001c00c2932120400018 +:106a8000615c400f000000001800c293212040000c +:106a9000615c400f00000000029d023c3400c39383 +:106aa000d403442421106000401002002110430050 +:106ab00080100200211044000400428c0f0040109e +:106ac00000000000029d023c3400c393d403442420 +:106ad00021106000401002002110430080100200cd +:106ae000211044000400438c0100022403006210c2 +:106af0000000000010000010000000007b5c400f50 +:106b0000000000001400c2a31000c297ffff42243f +:106b10001000c2a71400c393ff0002241a006214dd +:106b2000000000001000c297170040100000000095 +:106b3000f2ff001000000000029d023c3400c393ed +:106b4000d4034424211060004010020021104300af +:106b500080100200211044000400438c0200022433 +:106b600009006214000000007b5c400f0000000080 +:106b70007b5c400f000000001500c2a37b5c400f4f +:106b8000000000001400c2a3029d023c3400c39325 +:106b9000d40344242110600040100200211043005f +:106ba00080100200211044000400438c01000224e4 +:106bb0001f006214000000001400c0a31200c0a354 +:106bc0001200c393ff0002241900621000000000ad +:106bd0001400c2931600401400000000ffff0224be +:106be0001000c2a77b5c400f000000001400c2a38d +:106bf0001000c297ffff42241000c2a71400c293e6 +:106c000006004014000000001000c297030040106e +:106c100000000000f3ff0010000000001200c2930b +:106c2000010042241200c2a3e5ff00100000000092 +:106c3000ff000424615c400f00000000029d043c42 +:106c40003400c39321106000401002002110430063 +:106c500080180200d40382242110620008004290b0 +:106c6000050040140000000088bf023c50604390c3 +:106c700002006334506043a01400c28f3000c38f01 +:106c8000000062ac3000c28f21e8c0032c00bf8f2f +:106c90002800be8f3000bd270800e0030000000080 +:106ca000d0ffbd272c00bfaf2800beaf21f0a0034e +:106cb0003000c4af3400c5af010002241900c2a3e4 +:106cc0003000c28f401202001c00c2af1400c22765 +:106cd00021204000070005241c00c68f665a400f83 +:106ce000000000001400c2930d00401000000000de +:106cf0001400c22721204000070005241c00c68f75 +:106d0000665a400f000000001400c29304004010b7 +:106d1000000000002000c0af620000100000000072 +:106d2000ff0202241000c2a7400002241200c2a7e2 +:106d30001200c29706004010000000001200c29727 +:106d4000ffff42241200c2a7f9ff0010000000005c +:106d50007b5c400f000000001800c2a31000c29727 +:106d6000ffff42241000c2a7400002241200c2a765 +:106d70001200c29706004010000000001200c297e7 +:106d8000ffff42241200c2a7f9ff0010000000001c +:106d90001800c393ff0002240600621400000000e4 +:106da0001000c2970300401000000000e8ff001030 +:106db000000000001000c297070040100000000013 +:106dc0001800c393fe0002240300621400000000b8 +:106dd00004000010000000001900c0a328000010eb +:106de000000000001000c0a71000c2970002422c53 +:106df0001d004010000000003400c28f130040103e +:106e00000000000080bf033cff000224205a62ac57 +:106e100080bf023c105a428c0000427c03004014a8 +:106e200000000000faff0010000000001000c397ef +:106e30003400c28f2118620080bf023c205a428c6d +:106e4000000062a003000010000000007b5c400f07 +:106e5000000000001000c297010042241000c2a7e9 +:106e6000e1ff001000000000ff000424615c400fff +:106e700000000000ff000424615c400f00000000df +:106e8000ff000424615c400f0000000088bf033c49 +:106e90005060629002004234506062a01900c293b8 +:106ea0002000c2af2000c28f21e8c0032c00bf8f9a +:106eb0002800be8f3000bd270800e003000000005e +:106ec000d8ffbd272400bfaf2000beaf21f0a00334 +:106ed0002800c4af2c00c5af2110c0003000c2a3f1 +:106ee000010002241800c2a32800c28f070040142a +:106ef000000000003000c2930400401400000000b5 +:106f00001800c0a361000010000000001400c32797 +:106f10002800c28f401202002120600009000524d1 +:106f200021304000665a400f000000001400c29358 +:106f300004004010000000001800c0a34f00001023 +:106f400000000000fe000424615c400f000000000f +:106f50001000c0a71000c2970002422c160040107b +:106f60000000000080bf043c1000c3972c00c28fbb +:106f70002110620000004290205a82ac80bf023c87 +:106f8000105a428c0000427c0300401400000000b4 +:106f9000faff00100000000080bf023c205a428c23 +:106fa0001200c2a31000c297010042241000c2a721 +:106fb000e8ff001000000000ff000424615c400fa7 +:106fc00000000000ff000424615c400f000000008e +:106fd0007b5c400f000000001200c2a31200c293ad +:106fe0000f0043300500022404006210000000007e +:106ff0001800c0a31e000010000000001000c0a771 +:1070000080bf033cff000224205a62ac80bf023cd8 +:10701000105a428c0000427c030040140000000023 +:10702000faff00100000000080bf023c205a428c92 +:107030001200c2a31000c297010042241000c2a790 +:107040001200c29306004014000000001000c29716 +:107050000300401000000000e9ff001000000000e5 +:107060001000c29702004014000000001800c0a3e6 +:10707000ff000424615c400f0000000088bf023c58 +:107080005060439002006334506043a01800c293e4 +:1070900021e8c0032400bf8f2000be8f2800bd2739 +:1070a0000800e00300000000f8ffbd270000beafad +:1070b00021f0a00388bf023c1061428cc000427cda +:1070c000ff00423021e8c0030000be8f0800bd274a +:1070d0000800e00300000000f0ffbd270800beaf7d +:1070e00021f0a003211080001000c2a31000c29361 +:1070f0000000c2a30000c293ffff42240000c2a30d +:10710000ff004330ff0002240c006210000000006a +:10711000471d02240400c2af0400c28fffff4224b7 +:10712000211840000400c3afffff0224f1ff6210ea +:1071300000000000f8ff0010000000000000000048 +:1071400021e8c0030800be8f0800e0031000bd273f +:10715000f8ffbd270000beaf21f0a00380bf033cb5 +:1071600080bf023c105a428cff7f4230105a62ac02 +:1071700021e8c0030000be8f0800bd270800e0031f +:1071800000000000e0ffbd271c00bfaf1800beaf2d +:1071900021f0a003211080002000c2a380bf023c88 +:1071a000105a428cc000427c0300401400000000d2 +:1071b000faff00100000000080bf033c2000c293d3 +:1071c000205a62acb47d400f000000001000c2a342 +:1071d0002110000021e8c0031c00bf8f1800be8fe3 +:1071e0002000bd270800e00300000000e8ffbd27e5 +:1071f0001400bfaf1000beaf21f0a00380bf023c5f +:10720000105a428cc000427c030040140000000071 +:10721000faff00100000000080bf033cff000224c2 +:10722000205a62acb47d400f00000000ff004230e5 +:1072300021e8c0031400bf8f1000be8f1800bd27c7 +:107240000800e00300000000f8ffbd270000beaf0b +:1072500021f0a0030800c4af80bf023c105a40ac2c +:1072600080bf033c005a629040004234005a62a042 +:1072700080bf043c015a8390feff02242410620068 +:10728000015a82a088bf043c80618390bfff022422 +:1072900024106200806182a088bf043c81618390d9 +:1072a000feff022424106200816182a088bf043c9a +:1072b0008061839080ff022425106200806182a09b +:1072c00080bf043c015a839080ff02242510620095 +:1072d000015a82a021e8c0030000be8f0800bd272c +:1072e0000800e00300000000c0ffbd273c00bfaf66 +:1072f0003800beaf21f0a003010002241200c2a397 +:10730000030002241800c2a788bf033c50606290ab +:1073100002004234506062a080bf023c3000c2af25 +:107320009303023c008742341c00c2af0600023cbb +:10733000801a42342000c2af2000c28f40180200e1 +:107340001c00c28f1b004300f401600012100000fb +:107350002800c2af2000c28f401802001c00c28f5c +:107360001b004300f40160001010000004004010f6 +:10737000000000002800c28f010042242800c2af94 +:107380002800c28f0101422c0300401400000000bd +:10739000000102242800c2af2800c28f0400401060 +:1073a000000000002800c28fffff42242800c2af67 +:1073b0002800c28fff0042302400c2af2400c28fd9 +:1073c000ff0042303000c38f305a62ac80bf033cb4 +:1073d000005a629020004234005a62a02000042427 +:1073e000925c400f0000000001000424365c400f56 +:1073f000000000001000c0a71000c2970a00422c35 +:107400000900401000000000ff000424615c400ff0 +:10741000000000001000c297010042241000c2a723 +:10742000f5ff00100000000088bf043c506083900e +:10743000fdff022424106200506082a00100042499 +:10744000365c400f000000001400c22721204000dd +:107450002128000021300000665a400f0000000083 +:107460001400c393ff000224080062100000000013 +:107470001400c293f7004330010002240300621499 +:10748000000000000a000010000000001200c0a36d +:1074900088bf033c5060629002004234506062a09a +:1074a0001200c2932c00c2af7d000010000000004b +:1074b000ff0f02241000c2a71400c22721204000a1 +:1074c0000100052421300000665a400f0000000032 +:1074d0001000c297ffff42241000c2a71400c293fd +:1074e00006004010000000001000c297030040108a +:1074f00000000000f0ff0010000000001000c29724 +:1075000008004014000000001200c0a388bf023c25 +:107510005060439002006334506043a05e0000104e +:107520000000000002000424365c400f0000000050 +:1075300080bf023c3400c2af9303023c0087423458 +:107540002800c2af3101023c002d42342400c2affa +:107550002400c28f401802002800c28f1b00430085 +:10756000f4016000121000001c00c2af2400c28fa2 +:10757000401802002800c28f1b004300f401600085 +:107580001010000004004010000000001c00c28f1a +:10759000010042241c00c2af1c00c28f0101422c1a +:1075a0000300401400000000000102241c00c2afd0 +:1075b0001c00c28f04004010000000001c00c28f9d +:1075c000ffff42241c00c2af1c00c28fff004230ec +:1075d0002000c2af2000c28fff0042303400c38fb2 +:1075e000305a62ac80bf033c60c00234005a62acc7 +:1075f00080bf033c005a629020004234005a62a0cf +:107600001400c22721204000100005242130000072 +:10761000665a400f000000001400c22721204000dd +:107620000600052400020624665a400f00000000f0 +:10763000ff0002241000c2a71000c2970e004010e5 +:10764000000000002120000021280000285b400fde +:107650000000000021184000010002240600621012 +:10766000000000001000c297ffff42241000c2a7d4 +:10767000f1ff0010000000001000c2970600401447 +:10768000000000001200c0a388bf023c506043907d +:1076900002006334506043a01200c2932c00c2afba +:1076a0002c00c28f21e8c0033c00bf8f3800be8f82 +:1076b0004000bd270800e0030000000000e85d4135 +:1076c00000681a4000701b4090ffbd276c00bbafe4 +:1076d00000601b4082d21a006800bbaf847a5b7fd7 +:1076e00012d000006400baaf10d000006000baaf42 +:1076f00044201b7c00609b405c00bfaf5800beafc5 +:107700005400b9af5000b8af4c00afaf4800aeafb7 +:107710004400adaf4000acaf3c00abaf3800aaaf07 +:107720003400a9af3000a8af2c00a7af2800a6af47 +:107730002400a5af2000a4af1c00a3af1800a2af87 +:1077400021f0a0031081828f1000c2af010002243b +:107750001000c38f34006210000000001000c38fbf +:107760000200622806004010000000001000c28fd6 +:1077700009004010000000006f0000100000000031 +:10778000020002241000c38f2f00621000000000ce +:1077900069000010000000000b0004244560400f49 +:1077a00000000000e48082afe480828f1b0040185c +:1077b00000000000ec80838fe480828f2110620043 +:1077c000ec8082afe880828f01004224e88082afa3 +:1077d000e880828f0a004228100040140000000058 +:1077e000ec80848f6666023c676642341800820033 +:1077f0001010000083180200c31704002310620059 +:107800007c8282afe88080afec8080af01000224f0 +:10781000108182af4800001000000000108180af8e +:1078200045000010000000007c82848fd35f400f71 +:10783000000000005c8282af02000224108182af4f +:107840003d00001000000000145f400f0000000029 +:10785000108180af88bf023c5061428c0000427ca6 +:107860000600401000000000e080828f01004224ea +:10787000e08082af0200001000000000e08080afd6 +:1078800089818283150040140000000088bf023cfb +:107890005060428cc000427c060040140000000092 +:1078a00001000224898182a32080828f0a00422461 +:1078b000208082af88bf023c5060428c8000427cb6 +:1078c000060040140000000001000224898182a308 +:1078d0002080828ff6ff4224208082afac81828399 +:1078e000150040140000000088bf023c5060428c2c +:1078f000c003427c06004014000000000100022486 +:10790000ac8182a3fc80828f01004224fc8082af84 +:1079100088bf023c5060428c0001427c060040144b +:107920000000000001000224ac8182a3fc80828f51 +:10793000ffff4224fc8082af80bf023c100840acb5 +:1079400088bf033c00010224341062ac21e8c0036c +:107950005c00bf8f5800be8f5400b98f5000b88fa5 +:107960004c00af8f4800ae8f4400ad8f4000ac8f0d +:107970003c00ab8f3800aa8f3400a98f3000a88f4d +:107980002c00a78f2800a68f2400a58f2000a48f8d +:107990001c00a38f1800a28f00606041c00000008f +:1079a0006400ba8f130040036000ba8f11004003d7 +:1079b0006c00ba8f00709a406800ba8f7000bd27c3 +:1079c00000609a401800004200e85d41f4ffbd27c6 +:1079d00000601b400800bbaf04201b7c001c7b37f1 +:1079e00000609b4021f0a0030081828f0000c2afa5 +:1079f000010002240000c38f2d006210000000006f +:107a00000000c38f02006228060040100000000042 +:107a10000000c28f09004010000000003f0000106d +:107a200000000000020002240000c38f2e0062103c +:107a30000000000039000010000000006482828f06 +:107a40000f004014000000007082828f0400401874 +:107a5000000000007082828fffff4224708282af9c +:107a60008482828f04004018000000008482828f8c +:107a7000ffff4224848282af01000224648282af2d +:107a800088bf043c1061828c2880838f8410627cc4 +:107a9000106182ac80bf033c05000224200a62ac66 +:107aa00001000224008182af1c00001000000000d1 +:107ab0006482828f050040100000000088bf023cf5 +:107ac0001061439002006334106143a080bf023c08 +:107ad0000a000324200a43ac02000224008182af82 +:107ae0000e000010000000006482828f060040102b +:107af0000000000088bf043c10618390fdff022459 +:107b000024106200106182a080bf033c2480828f19 +:107b1000200a62ac008180af648280af80bf023ceb +:107b2000100a40ac88bf033c00100224341062ac41 +:107b300021e8c0030800ba8f00609a401800004294 +:107b4000e8ffbd271400bfaf1000beaf21f0a003b7 +:107b50002080828f048182af2080828f0f00422894 +:107b600003004010000000000f000224208082afbc +:107b70002080828fd10742280300401400000000bb +:107b8000d0070224208082af2080848f9878400f15 +:107b9000000000002130400021386000029d023cbe +:107ba0002005448c2405458c6b77400f00000000b5 +:107bb000029d063c21204000212860002c05c78c36 +:107bc0002805c68c9675400f00000000212040005b +:107bd000212860003079400f00000000248082af2f +:107be000f480828f100040100000000088bf043c29 +:107bf00010618390feff022424106200106182a0b5 +:107c00002080828f100042280b00401000000000ee +:107c100088bf023c1061439001006334106143a0af +:107c2000050000100000000088bf023c1061439076 +:107c300001006334106143a021e8c0031400bf8f2a +:107c40001000be8f1800bd270800e00300000000f0 +:107c5000e8ffbd271400bfaf1000beaf21f0a003a6 +:107c6000fc80828f0200410400000000fc8080af95 +:107c7000fc80828f2d014228030040140000000088 +:107c80002c010224fc8082afa08182831900401461 +:107c900000000000fc80848f767b400f0000000015 +:107ca0005c82848f21284000db7b400f00000000b5 +:107cb0000300400400000000070000100000000066 +:107cc00088bf023c5061439001006334506143a07f +:107cd0000d0000100000000088bf043c506183903c +:107ce000feff022424106200506182a006000010f2 +:107cf0000000000088bf043c50618390feff022416 +:107d000024106200506182a0888182832600401482 +:107d100000000000fc80828ff6ff422421204000fa +:107d2000767b400f000000005c82848f2128400099 +:107d3000db7b400f00000000120040040000000048 +:107d4000fc80828f0a00422421204000767b400f75 +:107d500000000000212040005c82858fdb7b400f0b +:107d6000000000000700400400000000fc80828f3b +:107d700064004228030040140000000008000010c6 +:107d800000000000f48080af88bf023c1061439087 +:107d900001006334106143a00300001000000000e4 +:107da00001000224f48082af8881838301000224d1 +:107db0002c00621400000000fc80828fffff422430 +:107dc00021204000767b400f000000005c82848f01 +:107dd00021284000db7b400f000000001800400419 +:107de00000000000fc80828f01004224212040001e +:107df000767b400f00000000212040005c82858fd0 +:107e0000db7b400f000000000d004004000000007c +:107e1000fc80828f640042280900401400000000aa +:107e20005c82848f21280000db7b400f0000000073 +:107e300003004010000000000800001000000000d7 +:107e4000f48080af88bf023c10614390010063342e +:107e5000106143a003000010000000000100022494 +:107e6000f48082af6c8183830100022419006214c4 +:107e700000000000fc80828ffbff42242120400094 +:107e8000767b400f000000005c82848f2128400038 +:107e9000db7b400f000000000300400400000000f6 +:107ea000080000100000000088bf043c10618390af +:107eb000dfff022424106200106182a00500001080 +:107ec0000000000088bf023c106143902000633432 +:107ed000106143a0029d023c5c82848f3005458c7a +:107ee000db7b400f0000000003004010000000009a +:107ef0000400001000000000212000006f60400f0f +:107f000000000000029d023c5c82848f3405458c99 +:107f1000db7b400f00000000030040100000000069 +:107f20000400001000000000212000006f60400fde +:107f30000000000021e8c0031400bf8f1000be8fb6 +:107f40001800bd270800e00300000000d0ffbd2797 +:107f50002800bfaf2400beaf2000b0af21f0a003c7 +:107f60003000c4af3000c28f1c004228080040100f +:107f700000000000029d023c3805428c1000c2af98 +:107f80001000c28f1800c2af5a000010000000009d +:107f90003000c28fff0342280c0040140000000094 +:107fa000e080828f33004228080040140000000067 +:107fb000029d023c3c05428c1000c2af1000c28ff3 +:107fc0001800c2af4b000010000000001400c0af4a +:107fd0001400c28f1f00422846004010000000001d +:107fe000029d043c1400c28f80180200a004822469 +:107ff000211062000000428c808282af3000c38f6b +:108000008082828f2a10430035004010000000005b +:108010008082828f548282af029d043c1400c28f02 +:1080200080180200a004822421106200fcff428c10 +:10803000788282af7882838f5482828f231062008d +:10804000688282af3000c38f5482828f2310620017 +:10805000748282af7482848f767b400f00000000b0 +:10806000218040006882848f767b400f00000000f2 +:108070002120000221284000eb7a400f0000000080 +:10808000588282af029d023c5882848f4005458c05 +:108090007d7a400f00000000588282af1400c38f29 +:1080a00021106000801002002110430040100200e7 +:1080b00021204000767b400f00000000212040007e +:1080c0005882858fe079400f000000001000c2af99 +:1080d0001000c28f1800c2af0600001000000000a0 +:1080e0001400c28f010042241400c2afb8ff001078 +:1080f000000000001800c28f21e8c0032800bf8fd5 +:108100002400be8f2000b08f3000bd270800e003a0 +:1081100000000000f0ffbd270800beaf21f0a00363 +:108120001000c4af81bf043c4090828c1000c38f0c +:10813000049c627c409082ac81bf033c00906290c2 +:1081400002004234009062a00000c0af0000c28f65 +:10815000c800422806004010000000000000c28f46 +:10816000010042240000c2aff8ff00100000000030 +:1081700081bf043c00908390fdff02242410620024 +:10818000009082a081bf023c0090428c0000427ca3 +:108190000300401400000000faff0010000000007f +:1081a00081bf023c7090428c21e8c0030800be8f62 +:1081b0001000bd270800e00300000000f0ffbd270d +:1081c0000800beaf21f0a0031000c4af1000c28fa2 +:1081d000010042380100422c0000c2af010002241d +:1081e0000000c38f10006210000000000000c38f69 +:1081f0000200622806004010000000000000c28f4c +:108200001d004010000000003900001000000000b8 +:10821000020002240000c38f2c0062100000000046 +:10822000330000100000000088bf043c1061839000 +:10823000feff022424106200106182a088bf033c6c +:1082400000010224641062ac88bf033c00010224d8 +:10825000681062ac88bf033c00100224641062ac5a +:1082600088bf033c00100224681062ace08080af3d +:108270001f0000100000000088bf043c5061839084 +:10828000feff022424106200506182a088bf033cdc +:108290001061629001004234106162a088bf033c0b +:1082a00000010224641062ac88bf023c681040ac3c +:1082b00088bf033c00100224641062ac88bf023cfb +:1082c000681040ac0a0000100000000088bf033caa +:1082d0001061629001004234106162a088bf033ccb +:1082e00000100224641062ac88bf023c681040aced +:1082f00021e8c0030800be8f1000bd270800e0037e +:1083000000000000d0ffbd272c00bfaf2800beaf8b +:1083100021f0a00388bf043c00618390fdff02248c +:1083200024106200006182a088bf043c0061839039 +:10833000fbff022424106200006182a088bf043c7d +:1083400000618390feff022424106200006182a07d +:10835000bd7d400f000000001000c2af88bf023c8e +:108360000030428c0003427c1c00c2af0b00401462 +:108370000000000088bf033c00100224083062acfb +:1083800088bf023c0030428c0003427c0300401452 +:1083900000000000faff0010000000001c00c28f67 +:1083a0001800c2af1800c28f1400c2af81bf023cd8 +:1083b00030f240ac81bf033c99aa023c556642347e +:1083c00030f262ac81bf033c6655023caa9942344c +:1083d00030f262ac81bf033c1800023c08f062ac92 +:1083e00081bf023c04f040ac81bf033c3333023c0c +:1083f0003333423430f262ac1400c28f1c00c2af7f +:108400001c00c28f150040100000000088bf023c15 +:108410000030428c0003427c2000c2af0b004014ad +:108420000000000088bf033c00100224083062ac4a +:1084300088bf023c0030428c0003427c03004014a1 +:1084400000000000faff0010000000002000c28fb2 +:108450001800c2af040000100000000088bf033cf9 +:1084600000100224043062ac1000c48fcc7d400f99 +:108470000000000080bf023c000840ac80bf033c0d +:1084800070000224080862ac80bf023c100840acb7 +:1084900080bf033cf4010224200862ac88bf033c87 +:1084a0001c000224b41062ac88bf033c10000224fc +:1084b000b81062ac88bf033c00010224341062ace7 +:1084c00080bf033c00800234080862ac88bf033cd4 +:1084d00000010224641062ac88bf023c681040ac0a +:1084e00080bf023c000a40ac80bf033c1000022465 +:1084f000080a62ac80bf023c100a40ac80bf033c5b +:1085000088130224200a62ac88bf033c1c000224aa +:10851000c41062ac88bf033c1c000224c81062accb +:10852000bf7d400f0000000088bf033c0010022404 +:10853000341062ac80bf033c00800234080a62ac95 +:1085400088bf033c00100224641062ac88bf023c68 +:10855000681040ac88bf033c106162900100423457 +:10856000106162a06c8180a34c8180a321e8c003cc +:108570002c00bf8f2800be8f3000bd270800e0030d +:1085800000000000e0ffbd271c00bfaf1800beaf19 +:1085900021f0a0031000c0af21200000f463400fc1 +:1085a0000000000088bf023c5060428cc000427c4a +:1085b0000300401400000000faff0010000000005b +:1085c000208080affc8080afe462400f000000009c +:1085d000010004246f60400f0000000088bf023ccf +:1085e0009061428c4002437c010002242f006214ff +:1085f00000000000d05e400f000000001000c28f9d +:10860000010042241000c2af1000c28fe9034228cb +:10861000f2ff401400000000e462400f0000000080 +:1086200088bf023c5060428cc000427c0400401471 +:10863000000000002080828f0a004224208082af48 +:1086400088bf023c5060428c8000427c0400401491 +:10865000000000002080828ff6ff4224208082af3d +:1086600088bf023c5060428cc003427c040040142e +:1086700000000000fc80828f01004224fc8082af59 +:1086800088bf023c5060428c0001427c04004014d0 +:1086900000000000fc80828fffff4224fc8082af3c +:1086a0001000c0afcdff001000000000212000002e +:1086b0006f60400f0000000021e8c0031c00bf8f66 +:1086c0001800be8f2000bd270800e0030000000056 +:1086d000f0ffbd270800beaf21f0a0031000c4af1b +:1086e0000000c0af1000c28f801802000000c28fcf +:1086f0002a1043000c0040100000000000000000a1 +:108700000000000000000000000000000000000069 +:1087100000000000000000000000c28f01004224a1 +:10872000f0ff00100000c2af21e8c0030800be8fb8 +:108730000800e0031000bd27e8ffbd271400bfaf0d +:108740001000beaf21f0a0031800c4af1800c28f04 +:10875000e80303240210437021204000b461400f5d +:108760000000000021e8c0031400bf8f1000be8f7e +:108770001800bd270800e00300000000f8ffbd2737 +:108780000000beaf21f0a0038481828f1c00401046 +:108790000000000088bf023c1061428c0000427c57 +:1087a0001700401400000000288080af7082828f84 +:1087b0000a004014000000006082828f050040140f +:1087c00000000000e8030224708282af0300001062 +:1087d000000000006082828f708282af90030224ca +:1087e000248082af7082828f030040180000000056 +:1087f000fcff00100000000001000224288082af6e +:1088000021e8c0030000be8f0800bd270800e00378 +:1088100000000000e8ffbd271400bfaf1000beaf8e +:1088200021f0a0038481828f3100401000000000fd +:1088300088bf023c1061428c0000427c2c00401436 +:108840000000000001000224288082af8482828f11 +:108850000a004014000000006c82828f0500401462 +:1088600000000000e8030224848282af03000010ad +:10887000000000006c82828f848282af9003022409 +:10888000248082af8482828f0300401800000000a1 +:10889000fcff0010000000002080848f9878400fbb +:1088a000000000002130400021386000029d023ca1 +:1088b0004805448c4c05458c6b77400f0000000048 +:1088c000029d063c21204000212860005405c78cf1 +:1088d0005005c68c9675400f000000002120400016 +:1088e000212860003079400f00000000248082af12 +:1088f00021e8c0031400bf8f1000be8f1800bd27f1 +:108900000800e00300000000e8ffbd271400bfaf2f +:108910001000beaf21f0a00321200000212800009c +:10892000029d023c3413462421380000d864400fd5 +:1089300000000000010004241c00052400a0023ceb +:10894000bc04462421380000d864400f0000000019 +:108950000200042421280000029d023c4813462402 +:1089600021380000d864400f0000000003000424f8 +:1089700021280000029d023c5813462421380000a3 +:10898000d864400f000000005480838f020002244e +:1089900008006214000000000400042421280000e4 +:1089a000029d023c6413462421380000d864400f25 +:1089b0000000000021e8c0031400bf8f1000be8f2c +:1089c0001800bd270800e00300000000d0ffbd270d +:1089d0002c00bfaf2800beaf21f0a0031000c427b9 +:1089e000029d023c701345243480868f106d400f29 +:1089f00000000000020004245a0005241000c627cd +:108a000021380000d864400f000000001c81828fd4 +:108a10003e004018000000001c81848f767b400fd0 +:108a200000000000029d033c212040008813658c5b +:108a3000eb7a400f000000002000c2af2000c48f7e +:108a4000c978400f0000000021304000213860004c +:108a50001000c427029d023c74134524106d400f82 +:108a600000000000030004244b0005241000c6276a +:108a700021380000d864400f000000002080848f5f +:108a8000767b400f0000000021204000c978400f95 +:108a900000000000029d063c2120400021286000cb +:108aa0009413c78c9013c68ca176400f0000000071 +:108ab0002120400021286000f278400f00000000d3 +:108ac000888282af8882848fc978400f00000000be +:108ad00021304000213860001000c427029d023c74 +:108ae00074134524106d400f00000000040004249e +:108af0004b0005241000c62721380000d864400f21 +:108b00000000000008000010000000000300042422 +:108b10004b000524029d023c8013462421380000ae +:108b2000d864400f00000000e122400f0000000068 +:108b30001623400f000000005480838f020002249f +:108b40000d006214000000002c63400f00000000c4 +:108b5000ac8182830300401000000000d963400f05 +:108b600000000000898182830300401000000000a3 +:108b70009063400f0000000021e8c0032c00bf8f6d +:108b80002800be8f3000bd270800e0030000000071 +:108b9000e8ffbd271400bfaf1000beaf21f0a00357 +:108ba0002120000021280000029d023c34134624ad +:108bb00021380000d864400f0000000001000424a8 +:108bc00021280000029d023c981346242138000011 +:108bd000d864400f0000000088bf023c5061428c06 +:108be0000000427c0a004010000000000500042440 +:108bf00021280000029d023cac13462421380000cd +:108c0000d864400f000000000800001000000000c1 +:108c10000500042421280000029d023cb8134624cc +:108c200021380000d864400f00000000029d023c83 +:108c30005c82848fd813458cdb7b400f00000000e2 +:108c400003004004000000000a00001000000000c3 +:108c50000300042421280000029d023cc413462482 +:108c600021380000d864400f00000000040000100c +:108c700000000000030004245964400f00000000bd +:108c8000d963400f000000002c63400f000000007b +:108c90009063400f0000000021e8c0031400bf8f64 +:108ca0001000be8f1800bd270800e0030000000080 +:108cb000d0ffbd272c00bfaf2800beaf21f0a0031e +:108cc000029d023c5c82848f1414458cdb7b400f38 +:108cd000000000000a00401000000000029d023c5d +:108ce0005c82848f1814458cdb7b400f00000000f1 +:108cf00003004010000000002600001000000000eb +:108d0000070004245964400f00000000029d023c4b +:108d10005c82848f1414458cdb7b400f00000000c4 +:108d200003004010000000000800001000000000d8 +:108d3000070004240a000524029d023cdc1346249b +:108d400021380000d864400f00000000029d023c62 +:108d50005c82848f1814458cdb7b400f0000000080 +:108d600003004010000000002f0000100000000071 +:108d7000070004240a000524029d023cf013462447 +:108d800021380000d864400f0000000026000010c9 +:108d9000000000005c82848fa07b400f0000000078 +:108da0002000c2af1000c427029d023c04144524d9 +:108db0002000c68f106d400f000000000700042443 +:108dc0002d0005241000c62721380000d864400f6c +:108dd0000000000088bf023c5061428c0000427cd1 +:108de0000a004010000000000700042423000524ae +:108df000029d023c0c14462421380000d864400f28 +:108e0000000000000800001000000000070004241b +:108e100023000524029d023c101446242138000042 +:108e2000d864400f0000000021e8c0032c00bf8f71 +:108e30002800be8f3000bd270800e00300000000be +:108e4000d0ffbd272c00bfaf2800beaf21f0a0038c +:108e50002080848f6666023c676642341800820078 +:108e60001010000083180200c317040023106200d2 +:108e70002000c2af1000c427029d023c1c144524f0 +:108e80002000c68f106d400f000000000700042472 +:108e9000550005241000c62721380000d864400f73 +:108ea000000000000400042421280000029d023c70 +:108eb0006413462421380000d864400f00000000ed +:108ec0002080848f767b400f00000000212040002e +:108ed000c978400f00000000029d063c21204000a0 +:108ee000212860002c14c78c2814c68ca176400f52 +:108ef000000000002120400021286000f278400f8f +:108f000000000000888282af8882848fc978400f79 +:108f10000000000021304000213860001000c4270c +:108f2000029d023c74134524106d400f00000000a8 +:108f3000040004244b0005241000c627213800003b +:108f4000d864400f00000000898180a321e8c0039d +:108f50002c00bf8f2800be8f3000bd270800e00323 +:108f600000000000d8ffbd272400bfaf2000beaf27 +:108f700021f0a003fc80828f020041040000000069 +:108f8000fc8080af1000c427029d023c04144524dd +:108f9000fc80868f106d400f000000000700042445 +:108fa000212800001000c62721380000d864400f97 +:108fb00000000000ac8180a321e8c0032400bf8f23 +:108fc0002000be8f2800bd270800e003000000003d +:108fd000e0ffbd271c00bfaf1800beaf21f0a0030b +:108fe000211080002000c2a31000c0a31000c29373 +:108ff0000800422c2000401000000000b0ff0324b5 +:109000001000c29321106200ff0042302120400076 +:109010005768400f00000000212000005768400ff3 +:1090200000000000100004245768400f00000000fa +:109030001100c0a31100c2830a0040040000000018 +:109040002000c293212040007968400f00000000fa +:109050001100c293010042241100c2a3f5ff0010c9 +:10906000000000001000c293010042241000c2a3bf +:10907000deff00100000000021e8c0031c00bf8fcd +:109080001800be8f2000bd270800e003000000008c +:10909000e0ffbd271c00bfaf1800beaf21f0a0034a +:1090a000211080002400c5af2000c2a3b0ff03241c +:1090b0002000c29321106200ff00423021204000b6 +:1090c0005768400f00000000212000005768400f43 +:1090d00000000000100004245768400f000000004a +:1090e0001000c0a31000c2932400c38f2a104300b5 +:1090f0000900401000000000180004247968400fa7 +:10910000000000001000c293010042241000c2a31e +:10911000f4ff0010000000002400c28f1000c2a362 +:109120001000c2830900400400000000212000005c +:109130007968400f000000001000c2930100422433 +:109140001000c2a3f6ff00100000000021e8c003d9 +:109150001c00bf8f1800be8f2000bd270800e00351 +:1091600000000000e0ffbd271c00bfaf1800beaf2d +:1091700021f0a003211080002000c2a3b0ff03242f +:109180002000c29321106200ff00423021204000e5 +:109190005768400f00000000212000005768400f72 +:1091a00000000000100004245768400f0000000079 +:1091b0001000c0a31000c28309004004000000009a +:1091c000212000007968400f000000001000c293c9 +:1091d000010042241000c2a3f6ff001000000000ae +:1091e00021e8c0031c00bf8f1800be8f2000bd27e0 +:1091f0000800e00300000000d8ffbd272400bfaf37 +:109200002000beaf21f0a003211080002800c2a3df +:109210002800c2931c00c2af010002241c00c38faf +:1092200015006210000000001c00c38f02006228bd +:1092300006004010000000001c00c28f0900401012 +:1092400000000000140000100000000002000224d2 +:109250001c00c38f0d006210000000000e00001003 +:1092600000000000029d023c580542241400c2afd9 +:109270000900001000000000029d023c5809422431 +:109280001400c2af0400001000000000029d023c68 +:10929000580d42241400c2af1000c0a31000c293a6 +:1092a0000800422c28004010000000001000c2936b +:1092b000c01102001800c2afb0ff03241000c29317 +:1092c00021106200ff004230212040005768400f0b +:1092d00000000000212000005768400f000000003f +:1092e000100004245768400f000000001100c0a3c4 +:1092f0001100c2830f004004000000001100c3935e +:109300001400c28f211862001800c28f2110620061 +:1093100000004290212040007968400f00000000ca +:109320001100c293010042241100c2a3f0ff0010fb +:10933000000000001000c293010042241000c2a3ec +:10934000d6ff00100000000021e8c0032400bf8ffa +:109350002000be8f2800bd270800e00300000000a9 +:10936000d0ffbd272c00bfaf2800beaf21f0a00367 +:109370003000c4af3400c5af3800c6af2110e000e4 +:109380003c00c2a31c00c0af3400c28f1000c2a3b7 +:109390001000c2930f0042301100c2a31000c2930c +:1093a00002110200100042341200c2a33000c28f2a +:1093b000b0ff032421106200ff0042302120400052 +:1093c0005768400f000000001100c29321204000a8 +:1093d0005768400f000000001200c2932120400097 +:1093e0005768400f000000001400c0af1400c38f86 +:1093f0003800c28f21106200000042909700401098 +:10940000000000001400c38f3800c28f21106200da +:10941000000042905300422c140040100000000055 +:109420002000c5271400c38f3800c28f21106200ae +:109430000000449021108000801802002118640070 +:10944000029d023c5811422460ff42242110620018 +:109450002120a00021284000050006247769400f44 +:10946000000000003c000010000000001400c38f4a +:109470003800c28f21106200000042907f00422c11 +:109480002e004010000000001400c38f3800c28f6f +:1094900021106200000042905c00422c1400401435 +:1094a000000000002000c5271400c38f3800c28fc1 +:1094b00021106200000044902110800080180200fa +:1094c00021186400029d023c581242245cfe422492 +:1094d000211062002120a000212840000500062460 +:1094e0007769400f000000001b0000100000000022 +:1094f0002000c5271400c38f3800c28f21106200de +:10950000000044902110800080180200211864009f +:10951000029d023c5812422461fe42242110620046 +:109520002120a00021284000050006247769400f73 +:109530000000000008000010000000002000c2270a +:1095400021204000029d023c5811452405000624bc +:109550007769400f000000001800c0af1800c28fec +:109560000500422832004010000000001c00c28f9d +:10957000800042281b004010000000003c00c29305 +:109580000a004014000000001800c38f1000c2271a +:109590002110430010004290212040007968400fc4 +:1095a000000000000a000010000000001800c38f37 +:1095b0001000c22721104300100042902710020023 +:1095c000ff004230212040007968400f0000000079 +:1095d0001c00c28f010042241c00c2af0f0000100b +:1095e000000000003000c28fb1ff03242110620090 +:1095f000ff004230212040005768400f000000006b +:109600001800c38f1000c2272110430010004290a1 +:10961000212040007968400f000000001800c28f30 +:10962000010042241800c2afccff0010000000006f +:10963000212000007968400f000000001c00c28f4c +:10964000010042241c00c2af1400c28f010042245a +:109650001400c2af65ff00100000000021e8c00345 +:109660002c00bf8f2800be8f3000bd270800e0030c +:1096700000000000e8ffbd271400bfaf1000beaf20 +:1096800021f0a00321200000f463400f000000003f +:10969000212000000a000524029d023c34134624c8 +:1096a00021380000d864400f0000000001000424ad +:1096b00014000524029d023c301446242138000089 +:1096c000d864400f000000000200042414000524a8 +:1096d000029d023c3814462421380000d864400f13 +:1096e000000000000300042414000524029d023c35 +:1096f0004414462421380000d864400f00000000c4 +:109700000400042414000524029d023c5014462445 +:1097100021380000d864400f000000000500042438 +:1097200014000524029d023c5c14462421380000ec +:10973000d864400f0000000021e8c0031400bf8f70 +:109740001000be8f1800bd270800e00300000000d5 +:10975000e8ffbd271400bfaf1000beaf21f0a0038b +:1097600021200000f463400f0000000021200000d1 +:109770000a000524029d023c3413462421380000cf +:10978000d864400f000000000100042421280000dc +:10979000029d023c6c14462421380000d864400f1e +:1097a000000000000400042421280000029d023c67 +:1097b0007414462421380000d864400f00000000d3 +:1097c0000500042421280000029d023c7c1446244c +:1097d00021380000d864400f000000000600042477 +:1097e00021280000029d023c8414462421380000f8 +:1097f000d864400f0000000021e8c0031400bf8fb0 +:109800001000be8f1800bd270800e0030000000014 +:10981000e8ffbd271400bfaf1000beaf21f0a003ca +:1098200021200000f463400f000000002120000010 +:109830000a000524029d023c34134624213800000e +:10984000d864400f00000000010004241400052427 +:10985000029d023c8c14462421380000d864400f3d +:109860000000000021e8c0031400bf8f1000be8f6d +:109870001800bd270800e00300000000e8ffbd2736 +:109880001400bfaf1000beaf21f0a00301000424fc +:109890005964400f00000000010004241400052456 +:1098a000029d023c5014462421380000d864400f29 +:1098b0000000000021e8c0031400bf8f1000be8f1d +:1098c0001800bd270800e00300000000e8ffbd27e6 +:1098d0001400bfaf1000beaf21f0a0032120000094 +:1098e000f463400f00000000010004242128000060 +:1098f000029d023c9c14462421380000d864400f8d +:109900000000000021e8c0031400bf8f1000be8fcc +:109910001800bd270800e00300000000d8ffbd27a5 +:109920002400bfaf2000beaf21f0a0032800c4afc9 +:109930002c00c5af3000c6af2110e0003400c2a338 +:1099400021200000f463400f000000000100042407 +:1099500021280000029d023cb0144624213800005a +:10996000d864400f000000002800c48fc978400f61 +:109970000000000021304000213860001000c427a2 +:10998000029d023cbc144524106d400f00000000f5 +:1099900003000424212800001000c62721380000fd +:1099a000d864400f000000002c00c48fc978400f1d +:1099b0000000000021304000213860001000c42762 +:1099c000029d023cc4144524106d400f00000000ad +:1099d00004000424212800001000c62721380000bc +:1099e000d864400f000000003400c2831300401010 +:1099f000000000003000c48fc978400f0000000054 +:109a000021304000213860001000c427029d023c34 +:109a1000cc144524106d400f000000000500042404 +:109a2000212800001000c62721380000d864400f0c +:109a300000000000080000100000000005000424e1 +:109a400021280000029d023cd41446242138000045 +:109a5000d864400f0000000021e8c0032400bf8f3d +:109a60002000be8f2800bd270800e0030000000092 +:109a7000e8ffbd271400bfaf1000beaf21f0a00368 +:109a800021200000f463400f0000000021200000ae +:109a900021280000029d023ce014462421380000e9 +:109aa000d864400f000000000200042421280000b8 +:109ab000029d023cec14462421380000d864400f7b +:109ac000000000000400042421280000029d023c44 +:109ad000fc14462421380000d864400f0000000028 +:109ae00021e8c0031400bf8f1000be8f1800bd27ef +:109af0000800e00300000000e8ffbd271400bfaf2e +:109b00001000beaf21f0a0031800c4af1c00c5af09 +:109b10002110c0002000c2a31800c28f0800422cf0 +:109b200073014010000000001800c28f801802006e +:109b3000029d023c14154224211062000000428c58 +:109b400008004000000000002000c393010004242e +:109b50001c00c58f029d023c0c1546242138600074 +:109b6000d864400f00000000020004241c00c58fd0 +:109b7000029d023c1015462421380000d864400f95 +:109b800000000000030004241c00c58f029d023c5d +:109b90001015462421380000d864400f0000000052 +:109ba000040004241c00c58f029d023c10154624ad +:109bb00021380000d864400f000000000500042494 +:109bc0001c00c58f029d023c101546242138000060 +:109bd000d864400f00000000060004241c00c58f5c +:109be000029d023c1015462421380000d864400f25 +:109bf00000000000070004241c00c58f029d023ce9 +:109c00001015462421380000d864400f00000000e1 +:109c10003701001000000000010004241c00c58f63 +:109c2000029d023c1015462421380000d864400fe4 +:109c3000000000002000c393020004241c00c58f14 +:109c4000029d023c0c15462421386000d864400f68 +:109c500000000000030004241c00c58f029d023c8c +:109c60001015462421380000d864400f0000000081 +:109c7000040004241c00c58f029d023c10154624dc +:109c800021380000d864400f0000000005000424c3 +:109c90001c00c58f029d023c10154624213800008f +:109ca000d864400f00000000060004241c00c58f8b +:109cb000029d023c1015462421380000d864400f54 +:109cc00000000000070004241c00c58f029d023c18 +:109cd0001015462421380000d864400f0000000011 +:109ce0000301001000000000010004241c00c58fc7 +:109cf000029d023c1015462421380000d864400f14 +:109d000000000000020004241c00c58f029d023cdc +:109d10001015462421380000d864400f00000000d0 +:109d20002000c393030004241c00c58f029d023c45 +:109d30000c15462421386000d864400f0000000054 +:109d4000040004241c00c58f029d023c101546240b +:109d500021380000d864400f0000000005000424f2 +:109d60001c00c58f029d023c1015462421380000be +:109d7000d864400f00000000060004241c00c58fba +:109d8000029d023c1015462421380000d864400f83 +:109d900000000000070004241c00c58f029d023c47 +:109da0001015462421380000d864400f0000000040 +:109db000cf00001000000000010004241c00c58f2b +:109dc000029d023c1015462421380000d864400f43 +:109dd00000000000020004241c00c58f029d023c0c +:109de0001015462421380000d864400f0000000000 +:109df000030004241c00c58f029d023c101546245c +:109e000021380000d864400f000000002000c393f8 +:109e1000040004241c00c58f029d023c0c1546243e +:109e200021386000d864400f0000000005000424c1 +:109e30001c00c58f029d023c1015462421380000ed +:109e4000d864400f00000000060004241c00c58fe9 +:109e5000029d023c1015462421380000d864400fb2 +:109e600000000000070004241c00c58f029d023c76 +:109e70001015462421380000d864400f000000006f +:109e80009b00001000000000010004241c00c58f8e +:109e9000029d023c1015462421380000d864400f72 +:109ea00000000000020004241c00c58f029d023c3b +:109eb0001015462421380000d864400f000000002f +:109ec000030004241c00c58f029d023c101546248b +:109ed00021380000d864400f000000000400042472 +:109ee0001c00c58f029d023c10154624213800003d +:109ef000d864400f000000002000c3930500042434 +:109f00001c00c58f029d023c0c15462421386000c0 +:109f1000d864400f00000000060004241c00c58f18 +:109f2000029d023c1015462421380000d864400fe1 +:109f300000000000070004241c00c58f029d023ca5 +:109f40001015462421380000d864400f000000009e +:109f50006700001000000000010004241c00c58ff1 +:109f6000029d023c1015462421380000d864400fa1 +:109f700000000000020004241c00c58f029d023c6a +:109f80001015462421380000d864400f000000005e +:109f9000030004241c00c58f029d023c10154624ba +:109fa00021380000d864400f0000000004000424a1 +:109fb0001c00c58f029d023c10154624213800006c +:109fc000d864400f00000000050004241c00c58f69 +:109fd000029d023c1015462421380000d864400f31 +:109fe000000000002000c393060004241c00c58f5d +:109ff000029d023c0c15462421386000d864400fb5 +:10a0000000000000070004241c00c58f029d023cd4 +:10a010001015462421380000d864400f00000000cd +:10a020003300001000000000010004241c00c58f54 +:10a03000029d023c1015462421380000d864400fd0 +:10a0400000000000020004241c00c58f029d023c99 +:10a050001015462421380000d864400f000000008d +:10a06000030004241c00c58f029d023c10154624e9 +:10a0700021380000d864400f0000000004000424d0 +:10a080001c00c58f029d023c10154624213800009b +:10a09000d864400f00000000050004241c00c58f98 +:10a0a000029d023c1015462421380000d864400f60 +:10a0b00000000000060004241c00c58f029d023c25 +:10a0c0001015462421380000d864400f000000001d +:10a0d0002000c393070004241c00c58f029d023c8e +:10a0e0000c15462421386000d864400f00000000a1 +:10a0f00021e8c0031400bf8f1000be8f1800bd27d9 +:10a100000800e00300000000f8ffbd270000beaf1c +:10a1100021f0a0030800c4af80bf033c0800c28f39 +:10a12000205a62ac80bf023c105a428c0000427c34 +:10a130000300401400000000faff001000000000bf +:10a1400080bf023c205a428c21e8c0030000be8f31 +:10a150000800bd270800e00300000000e8ffbd275d +:10a160001400bfaf1000beaf21f0a003211080008b +:10a170001800c2a388bf043c10618390bfff022473 +:10a1800024106200106182a088bf043c506083905c +:10a19000dfff022424106200506082a01800c293e6 +:10a1a000212040004268400f0000000088bf033caf +:10a1b0005060629020004234506062a088bf033c2f +:10a1c0001061629040004234106162a021e8c00337 +:10a1d0001400bf8f1000be8f1800bd270800e003d9 +:10a1e00000000000e8ffbd271400bfaf1000beafa5 +:10a1f00021f0a003211080001800c2a388bf033cf7 +:10a200001061629040004234106162a088bf043c3b +:10a2100050608390dfff022424106200506082a00f +:10a220001800c293212040004268400f0000000047 +:10a2300088bf033c5060629020004234506062a0ae +:10a2400088bf033c1061629040004234106162a0fc +:10a2500021e8c0031400bf8f1000be8f1800bd2777 +:10a260000800e00300000000e0ffbd271c00bfafb6 +:10a270001800beaf21f0a003211080002000c2a36f +:10a280001000c0a31000c2930800422c2000401010 +:10a2900000000000b0ff03241000c29321106200f0 +:10a2a000ff004230212040005768400f00000000ae +:10a2b000212000005768400f000000001000042417 +:10a2c0005768400f000000001100c0a31100c283b6 +:10a2d0000a004004000000002000c293212040003a +:10a2e0007968400f000000001100c2930100422471 +:10a2f0001100c2a3f5ff0010000000001000c2937f +:10a30000010042241000c2a3deff00100000000084 +:10a3100021e8c0031c00bf8f1800be8f2000bd279e +:10a320000800e00300000000e0ffbd271c00bfaff5 +:10a330001800beaf21f0a0031000c0af80bf033ce7 +:10a3400020810234005a62ac88bf043c10618390c3 +:10a35000bfff022424106200106182a088bf043c69 +:10a3600050608390dfff022424106200506082a0be +:10a3700088bf033c106162907f004230106162a090 +:10a380001000c0af1000c28fd007422c0600401052 +:10a39000000000001000c28f010042241000c2af74 +:10a3a000f8ff00100000000088bf043c106183909b +:10a3b00080ff022425106200106182a01000c0af4f +:10a3c0001000c28fd007422c060040100000000091 +:10a3d0001000c28f010042241000c2aff8ff00102d +:10a3e0000000000088bf023c5060439020006334ae +:10a3f000506043a0d50004245768400f00000000bf +:10a40000100004245768400f00000000d30004240b +:10a410005768400f00000000212000005768400fdf +:10a4200000000000a80004245768400f000000004e +:10a430003f0004245768400f00000000d8000424a7 +:10a440005768400f00000000212000005768400faf +:10a4500000000000400004245768400f0000000086 +:10a46000a00004245768400f00000000c800042426 +:10a470005768400f00000000da0004245768400fbe +:10a4800000000000120004245768400f0000000084 +:10a49000810004245768400f00000000f0000424ed +:10a4a0005768400f00000000a40004245768400fc4 +:10a4b00000000000d90004245768400f000000008d +:10a4c000f20004245768400f00000000a600042496 +:10a4d0005768400f00000000260004245768400f12 +:10a4e00000000000010004245768400f0000000035 +:10a4f000212000005768400f0000000021200000cc +:10a500005768400f00000000010004245768400f06 +:10a5100000000000212000009a68400f00000000a9 +:10a520001000c0af1000c28fd007422c06004010b0 +:10a53000000000001000c28f010042241000c2afd2 +:10a54000f8ff001000000000af0004245768400f1f +:10a550000000000021e8c0031c00bf8f1800be8f60 +:10a560002000bd270800e00300000000e8ffbd2731 +:10a570001400bfaf1000beaf21f0a00321200000e7 +:10a58000f463400f00000000010004247e64400fcb +:10a5900000000000c8000424365c400f00000000ea +:10a5a00021200000f463400f000000002120000083 +:10a5b0007e64400f00000000c8000424365c400f99 +:10a5c0000000000021e8c0031400bf8f1000be8f00 +:10a5d0001800bd270800e0030000000021108000e3 +:10a5e0005600c0100c00ca2c4d0040152618a400bf +:10a5f0000300633023380400290060100300e730b3 +:10a600000600e0102330c7000000a3980300a388d1 +:10a610002128a700000083b8212087000f00c33045 +:10a620002338c3001100e010213060002138e5001c +:10a630000000a3980300a3880400a8980700a88836 +:10a640000800a9980b00a9880c00aa980f00aa88f6 +:10a65000000083ac040088ac080089ac1000a5247d +:10a6600010008424f2ffa714fcff8aac0300c3305f +:10a670002338c3002a00e010213060002138e500b3 +:10a680000000a3980300a3880400a52404008424e8 +:10a69000fbffa714fcff83ac2100001000000000aa +:10a6a0000500e0102330c7000000a3982128a70070 +:10a6b000000083b8212087000f00c3302338c30077 +:10a6c0000d00e010213060002138e5000000a38c6f +:10a6d0000400a88c0800a98c0c00aa8c000083ac94 +:10a6e000040088ac080089ac1000a5241000842464 +:10a6f000f6ffa714fcff8aac0300c3302338c30065 +:10a700000700e010213060002138e5000000a38c34 +:10a710000400a52404008424fcffa714fcff83ace0 +:10a720000600c0102138c5000000a3900100a52438 +:10a7300001008424fcffa714ffff83a00800e003ae +:10a7400000000000211080002600c0101000ca2c5c +:10a750001f004015ff00a530005205002528aa0063 +:10a76000005405002528aa0003008330050060106e +:10a77000040007242338e3002330c700000085b815 +:10a78000212087000f00c3302338c3000800e010e9 +:10a79000213060002138e400000085ac040085ac65 +:10a7a000080085ac10008424fbff8714fcff85acf7 +:10a7b0000300c3302338c3000500e01021306000df +:10a7c0002138e40004008424feff8714fcff85acdc +:10a7d0000400c0102138c40001008424feff871447 +:10a7e000ffff85a00800e003000000002540850071 +:10a7f0000300083103000011211080003800001010 +:10a800000000aa900000aa8c0101093c0101293531 +:10a81000c07909002340490124400f0107000011bd +:10a8200024600a0105008811000000000000a52432 +:10a830000000aa902a000010000084240400ab8cc1 +:10a8400000008aac2340690124400f010700001179 +:10a8500024600b0105008811000000000400a524fd +:10a860000000aa901e000010040084240800aa8c96 +:10a8700004008bac2340490124400f010700001164 +:10a8800024600a0105008811000000000800a524ca +:10a890000000aa9012000010080084240c00ab8c69 +:10a8a00008008aac2340690124400f010700001111 +:10a8b00024600b0105008811000000000c00a52495 +:10a8c0000000aa90060000100c0084241000aa8c3e +:10a8d0000c008bac10008424ceff00101000a524c7 +:10a8e0000300401500008aa00800e00300000000fb +:10a8f0000100ab900300601501008ba00800e0038d +:10a90000000000000200aa900300401502008aa087 +:10a910000800e003000000000300ab900300601596 +:10a9200003008ba00800e003000000000400aa90d0 +:10a930000300401504008aa00800e00300000000a6 +:10a940000500ab900300601505008ba00800e00334 +:10a95000000000000600aa900300401506008aa02f +:10a960000800e003000000000700ab900300601542 +:10a9700007008ba00800e003000000000800aa9078 +:10a9800008008424d6ff00100800a52400008a9047 +:10a990002110800003004015000000000800e003c3 +:10a9a0000000022401008a9003004015000000000e +:10a9b0000800e0030100022402008a900300401511 +:10a9c000000000000800e0030200022403008a9057 +:10a9d00003004015822004000800e0030300022465 +:10a9e000010084248020040000008a8c0101093cbd +:10a9f00001012935c07909002340490124400f0194 +:10aa00000600001124600a01040088110000000003 +:10aa100000008a90220000100000842404008b8c27 +:10aa20002340690124400f010600001124600b013e +:10aa3000040088110000000004008a901800001033 +:10aa40000400842408008a8c2340490124400f011b +:10aa50000600001124600a010400881100000000b3 +:10aa600008008a900e000010080084240c008b8cd3 +:10aa70002340690124400f010600001124600b01ee +:10aa800004008811000000000c008a9004000010ef +:10aa90000c00842410008a8cd7ff0010100084243e +:10aaa0000400401500000000000084240800e003ba +:10aab0002310820001008a9004004015000000006d +:10aac000010084240800e0032310820002008a9021 +:10aad0000400401500000000020084240800e00388 +:10aae0002310820003008a90030084240800e003fe +:10aaf00023108200b0ffbd270000a1af0400a2af69 +:10ab00000800a3af0c00a4af1000a5af1400a6afbf +:10ab10001800a7af1c00a8af2000a9af2400aaaf5f +:10ab20002800abaf2c00acaf3000adaf3400aeafff +:10ab30003800afaf3c00b8af4000b9af4400bfaf82 +:10ab4000124000004800a8af104000005000a8af1d +:10ab50000068044000600540526d400f0000000096 +:10ab60005000a88f110000014800a88f13000001b9 +:10ab70000000a18f0400a28f0800a38f0c00a48ff7 +:10ab80001000a58f1400a68f1800a78f1c00a88f97 +:10ab90002000a98f2400aa8f2800ab8f2c00ac8f37 +:10aba0003000ad8f3400ae8f3800af8f3c00b88fcf +:10abb0004000b98f4400bf8f5000bd27c000000087 +:10abc000180000422518a400030062302000401441 +:10abd000214080000400c92c1c0020152138a00051 +:10abe0000000af8cfefe183cfffe053727700f00fb +:10abf0002168e50180800c3c2458ae0180808335bb +:10ac000024506301120040552128e0002148a00093 +:10ac1000212860000000e28cfcffc6240400d92c2f +:10ac2000000082ac0400e7240800201704008424fc +:10ac30000000ed8c27600d002158a90124506c0103 +:10ac400024184501f4ff60500000e28c2128e00048 +:10ac50000e00c010ffffc2240000a790ffffc62413 +:10ac6000000087a00100a524f9ffe014010084245e +:10ac70000600c010ffffc224ffff0324ffff422491 +:10ac8000000080a0fdff4314010084240800e003bd +:10ac9000211000010300823018004014ff00a5308d +:10aca000003a05002540a7000034080025380601b9 +:10acb0008080033c21308000fefe043cfffe89348e +:10acc000808068340000cf8c2610e7012168e901fc +:10acd00027700f0027c8020021c049002458ae0188 +:10ace00024601903245068010300401524188801ca +:10acf000f4ff60500400c6242120c00000008390af +:10ad0000ff00693003002515211080000800e003d2 +:10ad100000000000f9ff6014010084240800e00333 +:10ad200021100000e0ffbd2700a0053c1000b0afdf +:10ad30000000b0241800b2af1400b1af2190800021 +:10ad400000a0113c1c00bfaf216d400f212000026c +:10ad50001c01238e01000424380064ac256d400fd3 +:10ad6000212000021c01228e1000508c0d000012c8 +:10ad70001c012a8e0400028e08004018ffff4724a1 +:10ad800080480700214030010800068d09f8c00006 +:10ad9000040007aef8ff00100400028ef3ff00105d +:10ada0000000108e3400428d0300401000000000af +:10adb00009f8400000000000756d400f212040029e +:10adc000029d073c4d15e6242110860000004590a9 +:10add000200082240100a3300800e0030a10830051 +:10ade000029d073c4d15e624211086000000459089 +:10adf000e0ff82240200a3300800e0030a10830071 +:10ae0000029d053c4d15a324212083000000829063 +:10ae10000800e00307004230029d053c4d15a324c5 +:10ae200021208300000082900800e00303004230ec +:10ae30000800e0038000822c029d053c4d15a324f0 +:10ae400021208300000082900800e00320004230af +:10ae5000029d053c4d15a324212083000000829013 +:10ae60000800e00304004230029d053c4d15a32478 +:10ae700021208300000082900800e0031700423088 +:10ae8000029d053c4d15a3242120830000008290e3 +:10ae90000800e00302004230029d053c4d15a3244a +:10aea00021208300000082800800e00397004230e8 +:10aeb000029d053c4d15a3242120830000008290b3 +:10aec0000800e00310004230029d053c4d15a3240c +:10aed00021208300000082800800e00388004230c7 +:10aee000029d053c4d15a324212083000000829083 +:10aef0000800e00301004230029d053c4d15a324eb +:10af000021208300000082900800e00344004230ca +:10af10000800e0037f0082300800e0032000822464 +:10af20000800e003e0ff8224e8ffbd271000bfaf68 +:10af3000546c400f212800001000bf8f0800e00370 +:10af40001800bd27e8ffbd27212800001000bfaf73 +:10af5000d96b400f0a0006241000bf8f0800e003e1 +:10af60001800bd2700008380213880002150000098 +:10af700021700000215800000e00601021680000c0 +:10af8000029d093c4d1528252110680000004280d3 +:10af900088004330080060500000e3800100e7248f +:10afa0000000ec800300801121188801f8ff0010d8 +:10afb000000062800000e3802b000824030068107a +:10afc0002d000f2404006f14000000002d007838bd +:10afd00001000e2f0100e7241100c014100003240b +:10afe0000000e280300019241c0059140a000624d5 +:10aff0000100e7240000e38078000924080006240b +:10b000000400691001000d2458000c2414006c1475 +:10b01000ff7f023c0100e72410000010100006240e +:10b020000f00c314ff7f023c0000ef8030000824b3 +:10b030000c00e815ffff43340100e7240000e38023 +:10b04000780018240400781001000d2458001924f9 +:10b0500004007914ffff43340100e724ff7f023c22 +:10b06000ffff43341a006600f401c0002148e000ed +:10b070000000e7802400e01012600000029d083c00 +:10b080004d151825217860002110f800000043902c +:10b090000400793007002017d0ffe824030068304f +:10b0a0001900001101006330a9fff924c9ffe82449 +:10b0b0000a4023032a18060101007938c217080044 +:10b0c000253859001100e05401006f2d2a388a01fb +:10b0d0000800e01401000d24080060550100292536 +:10b0e0000250467123c8ea012a102803020040508a +:10b0f0002150480101000b2401002925000027816f +:10b10000e2ffe0542110f80001006f2d2460cf0110 +:10b1100023300a000b50cc000800601121104001c0 +:10b1200022000b2400a00a3c04024bad0300c01512 +:10b130000080023cff7f0e3cffffc2350200a010e2 +:10b140000a488d000000a9ac0800e00300000000e0 +:10b15000e8ffbd271000bfaf1b7c400f00000000c0 +:10b160001000bf8f0800e0031800bd27e8ffbd27cf +:10b170001000bfaf0400828c21188000ffff06245e +:10b18000010004242128400003004610000060aca8 +:10b1900004000010040066ac606d400f0000000069 +:10b1a000212840001000bf8f2110a0000800e003fc +:10b1b0001800bd27e8ffbd271000b0af1400bfafd7 +:10b1c00010008394020062300e0040102180800045 +:10b1d0000000838c0e0060041400bf8f0c00848c70 +:10b1e0000300641023288300626d400f0800048e62 +:10b1f0000800058e0c00068e040005ae030000104a +:10b20000000006aeffff0724040087ac1400bf8fc8 +:10b210001000b08f211000000800e0031800bd27c7 +:10b22000d8ffbd271c00b1af1800b0af2000bfafe2 +:10b230000c00a28c2180a000218880000100052440 +:10b2400006004014212000021000a427626d400f68 +:10b250001000b1a323000010000000ae0000068e15 +:10b26000ffff03240100c5240d00a314000005ae58 +:10b270000800078e00a0083c040405250800e0141f +:10b280008000062410000a96040005ae100049351f +:10b29000000006ae080005ae0c0006ae100009a6c0 +:10b2a0006d6c400f0000000000000e8e04000c8e3c +:10b2b000ffffcd2501008b250a00042400000dae00 +:10b2c000000091a10700241604000bae1000189690 +:10b2d00008000f330300e011212000026d6c400fc5 +:10b2e00000000000211020022000bf8f1c00b18f41 +:10b2f0001800b08f0800e0032800bd27e0ffbd273d +:10b300001000b0af0280c5701800b2af1400b1af2a +:10b310001c00bfaf2188c0002190800011000012e6 +:10b32000212800001000e6942120e0000100c23036 +:10b33000060040104000c3341000e3a400a0043c09 +:10b340000900032407000010040283ac6d6c400f59 +:10b350000000000021280002626d400f2120400201 +:10b36000212820021c00bf8f1800b28f1400b18f5b +:10b370001000b08f2110a0000800e0032000bd27be +:10b3800010008794ffffe330241065004000e6348e +:10b390000600401001000324100086a409000524c3 +:10b3a00000a0043c040285ac211800000800e00362 +:10b3b00021106000c8ffbd27ffffa9242128c0007d +:10b3c0002130e000029d073c21408000ffff0b245c +:10b3d0001000a42782000a24ac17e2243000bfaf7b +:10b3e0002200aba72000aaa71c00a9af1400a8af99 +:10b3f0002800a2af1000a9af356e400f1800a8af0b +:10b400001400a38f3000bf8f3800bd270800e00371 +:10b41000000060a02110a000ff7f053ce8ffbd27d1 +:10b420002138c000ffffa5341000bfafed6c400f06 +:10b43000213040001000bf8f0800e0031800bd2736 +:10b44000e8ffbd272110a000ff7f053c2000a6af2c +:10b450002400a7afffffa5342000a7271000bfaf2f +:10b46000ed6c400f213040001000bf8f0800e0035a +:10b470001800bd270800e003211000000800e003c9 +:10b48000211000000800e003211000000800e00384 +:10b49000211000000800e003211000000800e00374 +:10b4a000211000000800e003211000000800e00364 +:10b4b000211000000800e003211000000800e00354 +:10b4c000211000000800e003ffff02240800e00351 +:10b4d000000000000800e003000000000800e00396 +:10b4e000000000000800e003000000000800e00386 +:10b4f000000000000800e003000000000000828c53 +:10b50000e8ffbd27040040141000bfaf0200032471 +:10b5100009f8a000000083ac1000bf8f21100000cc +:10b520000800e0031800bd270800e003ffff022425 +:10b530000800e003ffff02240800e00321100000e0 +:10b540000800e0032110a000ffff00100000000031 +:10b55000ffff0010000000000800e00300000000f2 +:10b560000800e0030000000000601a40bfff1b3c21 +:10b57000ffff7b3724d05b0300609a401800004235 +:10b580000800e003ffff0224e0ffbd271400b1af75 +:10b590001000b0af1800bfaf2188800008008010f5 +:10b5a0002180a000070000121800bf8f0000248235 +:10b5b000db73400fffff1026faff00100100312659 +:10b5c0001800bf8f1400b18f1000b08f0800e00387 +:10b5d0002000bd27ffff001000000000e0ffbd2796 +:10b5e0001800b2af1400b1af1000b0af1c00bfaf75 +:10b5f000218880002190c0000c00a010ffffb02423 +:10b6000000002482a073400f21284002ffff032482 +:10b61000ffff102603004314010031260400001030 +:10b62000ffff0224f7ff03560000248221100000d0 +:10b630001c00bf8f1800b28f1400b18f1000b08fa4 +:10b640000800e0032000bd27e0ffbd271800b2afcf +:10b650001400b1af1000b0af1c00bfaf2180a0003c +:10b66000219080002188c0000d0000122100022ed0 +:10b67000200007240b3802022128e00021202002ac +:10b6800021304002776d400f23800702ffff032423 +:10b69000f5ff4314ffff0224030000101c00bf8fbe +:10b6a000211000001c00bf8f1800b28f1400b18f52 +:10b6b0001000b08f0800e0032000bd27d0ffbd2799 +:10b6c0001400b1af2188e0004000a78f1800b2af8e +:10b6d0001000b0af0100f2302180c0000100432e05 +:10b6e0001c00b3af2a981102029d063c241073007f +:10b6f0002800b6af2400b5af2000b4af2c00bfaf18 +:10b7000021a0a0007016c624ffff162423283002b3 +:10b7100021a880000400401021180000926d400f05 +:10b720000000000021184000212080022128000292 +:10b730000e0076102130a002776d400f000000004f +:10b740000b0056102a2030020a0040520a802402c0 +:10b75000029d053c7016a6242120a0020300601261 +:10b7600023283002926d400f000000002a20300292 +:10b770000a802402211000022c00bf8f2800b68fff +:10b780002400b58f2000b48f1c00b38f1800b28f37 +:10b790001400b18f1000b08f0800e0033000bd2707 +:10b7a000c8ffbd272c00b5af1c00b1af21a8c00059 +:10b7b0002188e00021300000213800002800b4afcb +:10b7c0002400b3af2000b2af1800b0af3000bfaf5d +:10b7d000219080002198a0004800b48f7379400f19 +:10b7e0004c00b08311004010029d023c6817468c4b +:10b7f0006c17478c21204002a176400f212860025f +:10b8000021204000212860001075400f1000a6275d +:10b810000b000010029d063c000025a20000a48e33 +:10b8200001008324210000100000a3ae9878400f8f +:10b83000d0ff04261000a2af1400a3af029d063c67 +:10b840007017c48c7417c58c1400a78f7379400fc0 +:10b850001000a68f16004104211020022e0006249d +:10b860003000052400008d822660a60101008b2d8a +:10b8700023208b0200008a90ffff942401004825ba +:10b88000204c087c3a0027290800e014000088a01a +:10b89000f4ff9114000085a0dfffa05631000524bd +:10b8a00031000e24ffff2ea2ffff312621102002bf +:10b8b0003000bf8f2c00b58f2800b48f2400b38fc9 +:10b8c0002000b28f1c00b18f1800b08f0800e00379 +:10b8d0003800bd2718fbbd27e404bfafe004beafae +:10b8e000dc04b7afd804b6afd404b5afd004b4af5e +:10b8f000cc04b3afc804b2afc404b1afc004b0af9e +:10b900001800838cec04a5af1000628ce804a4af8f +:10b910000100052409f84000f004a6af9404a0af8c +:10b9200034054010ffff0324ec04a68f0000c48000 +:10b930000100c52429058010ec04a5af25000724cb +:10b9400006008710ec04a88fa073400fe804a58fb1 +:10b950009404a48f1f0500100100832400001281ad +:10b960000b004416ffff0624e804a58fa073400fc8 +:10b9700025000424ec04ac8f9404aa8f01008b25cd +:10b9800001004925ec04abafe7ff00109404a9af18 +:10b990009c04a0af2d0007242b00052420000424c4 +:10b9a0002300032430000224030047169c04ad8fbb +:10b9b000100000100100a835030045169c04ae8f4e +:10b9c0000c0000100200c835030044169c04af8f21 +:10b9d000080000100400e835030043169c04b08ff3 +:10b9e0000400001008000836080042169c04b18fbd +:10b9f00010002836ec04b28f9c04a8af0100532637 +:10ba0000ec04b3afe8ff0010000072822a00142497 +:10ba10000e005416d0ff4526f004a28ffcff1f2411 +:10ba200003005e2424b0df03ec04b98f0000d88e3d +:10ba300001003727ec04b7af9804b8af0000f282da +:10ba40000400d52611000010f004b5af0a00a32ca5 +:10ba5000160060109804a0af0a0003249804ac8f6d +:10ba6000ec04ad8f025883710100aa25ec04aaaf43 +:10ba70002148720100005281d0ff2825d0ff4426c2 +:10ba80000a00872cf5ffe0149804a8af9804a88f4b +:10ba9000070001052e0011249c04b08f23700800bc +:10baa00001000f369c04afaf9804aeaf2e001124f6 +:10bab0002600511668000c24ec04b28f2a000624dc +:10bac00001005326ec04b3af000072820d0046164d +:10bad000d0ff4226f004be8fec04b78f0300d827b6 +:10bae0000100f626fcff192424a81903ec04b6afc4 +:10baf0000000d2820000a68e0400b4260f000010c1 +:10bb0000f004b4af0a005f2c0f00e01321300000f6 +:10bb10000a000324ec04aa8f0220c3700100482508 +:10bb2000ec04a8af2148920000001281d0ff472604 +:10bb30000a00e52cf7ffa014d0ff26250000c3283b +:10bb4000ffff0b240b30630168000c2412004c161d +:10bb50006c001524ec04a58f0100ad800700b21520 +:10bb60009c04b38f9c04b08f0100ae2480000f367c +:10bb70009c04afaf03000010ec04aeaf00017136bf +:10bb80009c04b1afec04b28f01005426ec04b4afb6 +:10bb90002700001000009282120055167100072441 +:10bba000ec04a48f010096800700d2169c04bf8f7e +:10bbb0009c04b98f01009724000838379c04b8af63 +:10bbc00003000010ec04b7af0002fe379c04beafc8 +:10bbd000ec04a58f0100a224ec04a2af1400001015 +:10bbe00000005280090047164c000b24ec04aa8f79 +:10bbf0009c04a88f01004425ec04a4af00009280af +:10bc0000000809350a0000109c04a9af09004b1672 +:10bc1000ec04b18fec04ae8f9c04ac8f0100cd25f9 +:10bc2000ec04adaf000483350000b2819c04a3afe7 +:10bc3000ec04b18f9c04a38f0100302602006f300a +:10bc40000400e011ec04b0affbff1424249874004e +:10bc50009c04b3af9c04a58f0100b5300400a01272 +:10bc6000bcff4326efff172424b0b7009c04b6aff7 +:10bc70003500782c5504001321100000029d053c6e +:10bc800080f803009016a22421f0e2030000d98f6f +:10bc900008002003000000009c04a78f0002f2347b +:10bca0009c04b2af9c04aa8ff7ff0424001048350f +:10bcb000244804010d0000109c04a9af9c04a38f2c +:10bcc00000026b349c04abaf150000100800142474 +:10bcd0009c04ad8f0002ac359c04acaf9c04af8fcc +:10bce000f7ff10242470f0019c04aeaf0c0000108c +:10bcf0000a0014249c04b38f004071360700001022 +:10bd00009c04b1af9c04b58f0040b4369c04b4af22 +:10bd10009c04b78f0802f6369c04b6af10001424ba +:10bd2000ffff18240300d8149c04be8f04000010e9 +:10bd300001000624efff1f2424c8df039c04b9afd1 +:10bd40009c04a58f0010b6300b00c0120008a23072 +:10bd50000c004014f004ab8ff004a98ffcff022408 +:10bd6000030027252410e2000000528c212040020d +:10bd700010000010c32f120009004010f004ad8f16 +:10bd8000f004ab8ff8ff0a240700642524408a00e2 +:10bd90000000048d0400058d070000100800022536 +:10bda000fcff0c240300a32524106c000000448c2d +:10bdb0002128000004004224f004a2af218080006a +:10bdc0002188a0002198c0005f00b2270800c0129f +:10bdd00021b800000700a1042118000023801000f2 +:10bde000238811002b101000238822020100172441 +:10bdf000211800001b001016212800021a007114df +:10be000025101102330000129c04ae8f0040c63191 +:10be10001b00b400f4018002102000000a008f28eb +:10be20000300e05137009124040000103000842406 +:10be300057009024212020020a2006021b00b40093 +:10be4000f4018002000044a2ffff7326ffff522688 +:10be500012a80000eeffa016122800001e0000101d +:10be6000ffff6226251011021a004010c3af140014 +:10be700021282002213080022138a002f47e400fc8 +:10be8000212000020a00582806000017300045242f +:10be90009c04bf8f570059240040fe3337004524cf +:10bea0000a283e03000045a221200002212820028a +:10beb00021308002d57d400f2138a0022180400032 +:10bec0002188600025104300ffff5226e6ff001086 +:10bed000ffff7326ffff6226070040049c04a88f23 +:10bee00030000324ffff4224000043a2fdff410471 +:10bef000ffff52269c04a88f10001331250060120a +:10bf00009c04ae8f2000a5279804a98f23384502f2 +:10bf100021282701080002310c004010c1ffa42491 +:10bf20000800082407008816feff8c2401004b82bd +:10bf300030000a2404006a511000833a0300001004 +:10bf4000c0ffa4241000833a0a2083010900c052d4 +:10bf5000ffff83240600e056ffff84249c04a68f85 +:10bf60000600cd300300a011ffff8324ffff8424cf +:10bf7000ffff8324070062049c04ae8f300002247c +:10bf8000ffff6324000042a2fdff6104ffff522671 +:10bf90009c04ae8f0800c4311600801008000f24e6 +:10bfa00008008f5610001124010050823000032435 +:10bfb0000400035210001124000043a20d000010e1 +:10bfc000ffff52260b009116212840029c04b28fdd +:10bfd000ffffa324004054320200801658000424be +:10bfe00078000424300015240000a4a0ffff722470 +:10bff000000075a01000c012010045260b00e016dd +:10c000002d0002249c04b78f0200f6320300c012f8 +:10c010009c04b98f050000102b0002240400383363 +:10c02000050000530100452620000224000042a222 +:10c03000ffff52260100452623f0a5031f03001031 +:10c040006000c627f004ac8ff8ff0a2407008b2598 +:10c0500024406a010000098d0400078d6000a9af2b +:10c060006400a7af6000b08f6400b18f08000525a1 +:10c070000055337eff077f3af004a5af2300e01799 +:10c08000a004a6af212000022128200221300002b6 +:10c090007379400f21382002070040502120000210 +:10c0a000029d033c9804a78fe804a48f9017652491 +:10c0b0000403001003000624212820022130000080 +:10c0c0007379400f2138000009004304029d043cad +:10c0d000029d063c9c04ad8f9804a78fe804a48fb2 +:10c0e0009c17c52404000624f80200101000adaf10 +:10c0f000941785249c04ae8f9804a78fe804a48f1e +:10c1000004000624f10200101000aeafffff0f2460 +:10c110000400cf14a404a0af0600142413000010e0 +:10c12000a004b4af2800d5281100a01621400002b9 +:10c1300067005e3a4700593a2bb81e002bc0190021 +:10c1400024b0f8020600c016d9ffc2249c04b38fa5 +:10c1500008007f320400e01327000724d9ffc2241f +:10c16000a404a2af27000724a004a7af2140000227 +:10c17000214820026900a0a39004a0afa004be8fb4 +:10c18000a804b2af0a002106b404a0af21500001f8 +:10c19000029d083c7c17058d2d0009242688250268 +:10c1a0007002a9a321404001020000102148200292 +:10c1b0007002a0a38004a627212000011075400f63 +:10c1c000212820016900ad276902ac2721a8600061 +:10c1d000ffff8b250100a32521a04000b804a3afd9 +:10c1e000ac04a3af2198600024000010b004abaff2 +:10c1f0006817108f6c17118f2120c0022128e002d0 +:10c20000213820026b77400f2130000221204000ae +:10c21000212860008004a6271075400f029d173c5e +:10c220008017e68e8417e78e2120400021286000c9 +:10c230008804a2af9875400f8c04a3af2120400062 +:10c240002130000221286000a176400f2138200211 +:10c25000212040003079400f21286000b004af8fca +:10c26000300056240000f6a19004ae8fffffe425b5 +:10c270000100c625b004a4af9004a6af8004b68f19 +:10c280008404b78f21300000213800002120c00233 +:10c290007379400f2128e002d5ff4014029d183c1d +:10c2a000650019246c00591266005f2a0600e0132d +:10c2b000660007244500022467004212470002245a +:10c2c0000300001000000000050047126700022470 +:10c2d000580142126900a68300020010b804b08f12 +:10c2e0009004b28f10004012b804a38fb004a58f41 +:10c2f0006902a9270100a4242b5089000e004011d7 +:10c30000a004ad8f00008b906902ac27010084244b +:10c310002b408c0000006ba2faff00150100732671 +:10c3200005000010a004ad8f30001324000073a09e +:10c3300001007324a004ad8f0600a0152e00042474 +:10c340009c04ae8f0800c6310500c0102120800279 +:10c350002e000424000064a2010073262120800224 +:10c360002128a002213000007379400f21380000fd +:10c370002f004010a004af8f1d00e011212080028b +:10c38000029d113c6817268e6c17278e2120800293 +:10c39000a176400f2128a002212040002128600022 +:10c3a0001075400f8804a6278804a48f8c04a58fdd +:10c3b00021a040003079400f21a8600030005624b1 +:10c3c000ffffde27000076a20800c01301007326dd +:10c3d000212080022128a002213000007379400f23 +:10c3e00021380000e7ff4014029d113c212080020b +:10c3f0002128a002213000007379400f213800006d +:10c400000b004010b804a78fffff772621300000f3 +:10c410007002b027212080022128a0021000b7afaf +:10c420001800b0afe86d400f1400a0afac04a2af8d +:10c43000a801c013ffffc22730000424ffff03241c +:10c44000ffff4224000064a2fdff43140100732695 +:10c45000a10100106900a6839004b88f3900001371 +:10c4600021208002b004a28fb804b98f01005f9030 +:10c470000100432400003fa30500c017010030273e +:10c480009c04b28f080047321800e01001006d24b0 +:10c49000b804aa8f2e000924010049a11200c0137c +:10c4a00002005025b004a88f6902a52702000325c9 +:10c4b0002b1065000a0040100000000000006b9087 +:10c4c000ffffde2700000ba20700c01301001026ab +:10c4d000010063246902ac27f6ff00102b106c00ea +:10c4e0001500c0179004a48f01006d246902a627cf +:10c4f0002b98a601100060129004a48fffff0e2657 +:10c500001000aeaf010075807002b4271400b5af03 +:10c510001800b4afb804a78f21a0000021a8000024 +:10c520009004a62721208002e86d400f2128a00258 +:10c53000ac04a2af9004a48fffff83243d00001041 +:10c540009004a3af2128a002213000007379400f8e +:10c55000213800002b004010b804a78fffff0224f1 +:10c560009004a2af029d0f3c6817e68d6c17e78d13 +:10c5700021208002a176400f2128a0022120400026 +:10c58000212860001075400f8804a6278804b08f0a +:10c590008c04b18f213000002138000021200002de +:10c5a0002128200221a040007379400f21a86000bb +:10c5b000030040149004b68fe9ff0010ffffc2266d +:10c5c000212000023079400f21282002b804b18fc9 +:10c5d00030005024000030a20500c01701003026b2 +:10c5e0009c04b88f080017331300e012212080024a +:10c5f000b804b98f2e001f24020030270d00001050 +:10c6000001003fa3300002240000e2a00500c01793 +:10c610000100f0249c04aa8f080052310600401249 +:10c6200021208002b804a98f2e000524010025a135 +:10c6300002003025212080022128a00221300000a4 +:10c640007379400f213800002f00401000000000d7 +:10c650001d00c01321208002029d0b3c6817668dcf +:10c660006c17678d21208002a176400f2128a0023f +:10c6700021204000212860001075400f8804a62763 +:10c680008804a48f8c04a58f21a040003079400f2e +:10c6900021a8600030004824ffffde27000008a228 +:10c6a0000800c01301001026212080022128a002ca +:10c6b000213000007379400f21380000e7ff40145b +:10c6c000029d0b3c212080022128a0022130000085 +:10c6d0007379400f213800000b004010ac04a78f85 +:10c6e0007002ac27ffff13269004a62721208002aa +:10c6f0002128a0021000b3af1800acafe86d400fc6 +:10c700001400a0afac04a2af0700c013ffffc22704 +:10c7100030000424ffff0324ffff4224000004a292 +:10c72000fdff431401001026b404be8f1400c05353 +:10c730009004a48f9c04a68f0800cd301000a05553 +:10c740009004a48f30000324ac04b58f2ba0b0025a +:10c750000600805200001682ffff102600000e82a5 +:10c76000fbffc3112ba0b002000016822e00cf3aaf +:10c770000100e42d23180402010070249004a48f0a +:10c78000a804b18f02000526000011a20600810452 +:10c790007804a8272d001724232004002130a000ae +:10c7a00004000010010017a22b001824010018a299 +:10c7b0002130a0000a00902817000016213800013f +:10c7c0000a0005241a008500f401a000ffffe724f9 +:10c7d000101000001220000030005f240a00992889 +:10c7e000f8ff20130000ffa0ffffe52430008a249b +:10c7f0002b18a800ffffeaa0b60060102198c00027 +:10c800000000a7900100a5240000c7a02b18a800d5 +:10c81000f9ff00100100c6243000892430000824ec +:10c820000000a8a00100a9a00200a624a9000010f1 +:10c830002198c000a004ab8f010010249004a38fa6 +:10c840000b80cb032a2803021300a014feff4d2601 +:10c8500016006014b004ae8f212080022128a002af +:10c86000213000007379400f213800001e00401075 +:10c87000b804a48f029d0c3c8817868d8c17878d79 +:10c88000212080027379400f2128a0021600410464 +:10c89000b804a48ffeff4d2601001324ffff1e26bf +:10c8a000a804adafecfe0010b404b3af6902a62734 +:10c8b0000100c4252bf086000e00c013000000000c +:10c8c00000008f906902b627010084242b1896007f +:10c8d00000006fa2ffff1026f9ff6014010073260d +:10c8e000040000100000000030001124000091a09e +:10c8f00001009324060000162e0019249c04b88f12 +:10c90000080017330500e012219000002e001924c2 +:10c91000000079a201001224010073262120800268 +:10c920002128a002213000007379400f2138000037 +:10c930004c0040509c04b58f38000012212080022a +:10c94000029d113c6c17278e6817268e21208002cd +:10c95000a176400f2128a002212040008804a627ac +:10c960001075400f212860008804a48f8c04a58fc7 +:10c9700021a040003079400f21a8600030005f24e2 +:10c9800000007fa28804a48f8c04a58f21300000b2 +:10c99000213800007379400f010073261500401400 +:10c9a0009004a28fe7ff4050029d113c120000103e +:10c9b000ffff10266c17278e21208002a176400fe2 +:10c9c0002128a00221204000212860001075400f7e +:10c9d0008804a6278804a48f8c04a58f21a040007a +:10c9e0003079400f21a8600030004a2400006aa27c +:10c9f00001007326ffff102607000012212080028d +:10ca00002128a002213000007379400f2138000056 +:10ca1000e8ff40146817268e212080022128a002fa +:10ca2000213000007379400f213800000d00405084 +:10ca30009c04b58fb804a78fffff68267002a92752 +:10ca400021300000212080022128a0021000a8af80 +:10ca50001800a9afe86d400f1400a0afac04a2af5e +:10ca60009c04b58f0800b4320b0080120000000057 +:10ca700018000012ffff022630000424ffff0324e9 +:10ca8000ffff4224000064a2fdff4314010073264f +:10ca9000110000106900a6830f0040126900a683f0 +:10caa00030000324ac04b28f2b80530206000052e6 +:10cab00000006c82ffff732600006782fbffe3101b +:10cac0002b80530200006c822e008b392b280b0028 +:10cad000219865026900a683b804b08fac04ad8fbd +:10cae0007002a3936900be270b80c6030500601087 +:10caf00023886d02ffff102601003126110000106f +:10cb0000000003a29c04ae8f0200d3310600601225 +:10cb10009c04b68fffff10262b0003240100312652 +:10cb200008000010000003a20400cf320600e0114c +:10cb30009c04bf8fffff102620000424000004a2e5 +:10cb4000010031269c04bf8fa404b98f9804a88fdc +:10cb50000100f433219039020100982e2a984802ee +:10cb600024b813030700e01221200000029d023cbc +:10cb7000e804a48f70164624926d400f23281201fa +:10cb800021204000ffff152405009510e804a68f22 +:10cb900021200002776d400f212820022120400033 +:10cba000a404a58f274004002b5008002b48050043 +:10cbb000248849010600201200000000e804a48f28 +:10cbc000029d103c926d400f501606262120400019 +:10cbd0000c0095109804a78f0b0080122a28f200f1 +:10cbe0000a0060120b3845029804b48f029d153c70 +:10cbf000e804a48f7016a626926d400f2328920297 +:10cc00009804a78f2a28f2000b3845026f00001005 +:10cc10002110e000f004b38ffcff062403007e2601 +:10cc20002458c60300006d8d9c04ac8f9804a78f18 +:10cc3000e804a48f040072257804a52701000624c7 +:10cc40007804ada31000acaf20000010f004b2af28 +:10cc5000f004a48ffcff0324030096242478c3026d +:10cc60000000f18d0400ee25f004aeaf04002016a4 +:10cc700021802002029d173ca417f126218020026a +:10cc8000ffff18240900d814ffffc324636a400f74 +:10cc9000212020020700001021800202060020133c +:10cca00021282002ffff632401001026fbff6304fc +:10ccb0000000198221282002233011029804a78f36 +:10ccc000e804a48f9c04bf8f1000bfafaf6d400f6e +:10ccd000000000003e0000109404ad8f9c04b18f52 +:10cce000000822320d0040109c04ab8ff004a58f89 +:10ccf000fcff07240300b52424a0a7029404a88ff6 +:10cd000000008a8ec34f080004009026f004b0afe4 +:10cd1000000048ad2c000010040049ad0002723143 +:10cd20000b0040529c04a38ff004af8ffcff0e2435 +:10cd30000300f32524306e020000cc8c9404ad8fe8 +:10cd40000400de24f004beaf1f00001000008dad13 +:10cd5000f004a48f000176300900c0120300832480 +:10cd6000fcff022424f862000000f78f9404b88fbf +:10cd70000400f927f004b9af130000100000f8a672 +:10cd80009c04aa8f8000513109002012fcff0c2462 +:10cd9000fcff152424a075000000898e9404a88f40 +:10cda00004009026f004b0af07000010000028a196 +:10cdb00024586c000000678d9404a58f0400722530 +:10cdc000f004b2af0000e5ac211000009404ad8f78 +:10cdd0002118a201d4fa00109404a3afe804ae8f86 +:10cde0009404be8f1000d395ffff032440006632e9 +:10cdf0000a18c603e404bf8fe004be8fdc04b78fbb +:10ce0000d804b68fd404b58fd004b48fcc04b38fbc +:10ce1000c804b28fc404b18fc004b08f2110600069 +:10ce20000800e003e804bd2700a0063ce8ffbd279a +:10ce30001c01c28c1000bfaf211880000400448c7c +:10ce40002130a000356e400f212860001000bf8ff8 +:10ce50000800e0031800bd270800e003ffff0224dc +:10ce60000800e003211080000800e003211000000a +:10ce70000800e003211000000800e0030100022484 +:10ce8000e0ffbd271400b1af1000b0af1800bfaf76 +:10ce90001800a38c2180a0001000628c21888000e3 +:10cea0002120a00009f840000100052419004010cd +:10ceb000ffff03240000078e0a00283affffe62444 +:10cec00021202002212800020100032d0600c004b9 +:10ced000000006ae10000b96c0006a7d2448430196 +:10cee000070020112130200218000c8e0400908dc4 +:10cef00009f8000200000000050000102130400089 +:10cf00000400058e0100a4240000b1a0040004aeba +:10cf10002118c0001800bf8f1400b18f1000b08f0f +:10cf2000211060000800e0032000bd27e8ffbd27b6 +:10cf30001000bfafa073400f000000001000bf8fb3 +:10cf40000800e0031800bd2700a0033ce8ffbd2750 +:10cf50001c01628c1000bfafa073400f0400458c11 +:10cf60001000bf8f0800e0031800bd272024047cb8 +:10cf700080bf033c1062658c0002a27cfdff401064 +:10cf80000000000080bf033c206264ac0800e003a6 +:10cf9000000000004050050042550a00c04a05004c +:10cfa000427d040025482f01c042040000800e3c51 +:10cfb00025482e0140680700426d0d00c062070041 +:10cfc000427d060025608f01c05a060025608e0153 +:10cfd0002470c501ffff4f25fe07e12d56002010ec +:10cfe00000000000ffffaf25fe07e12d6e002010be +:10cff0000000000023384d014b00e0040000000059 +:10d0000042400800c07f090025400f014248090046 +:10d0100042580b00c07f0c0025586f0142600c0085 +:10d020002b780b0123400b012b102f0123482f01dc +:10d030002b782c012578e2010500e01123482c0112 +:10d0400021400b012b780b0121482c0121482f0195 +:10d050002a780001214008012148290121482f0197 +:10d06000ffffe724eeffe1040000000008002015a8 +:10d0700025500d0003000015000000000d000010f9 +:10d0800000000a242548000100000824e0ff4a258a +:10d09000203827710700e0100000000023504701ee +:10d0a000223007000630c8000440e8000448e900c8 +:10d0b000254826011400401d00000000010007243f +:10d0c0002338ea002000e12c0500201400000000b5 +:10d0d0002540090000000924faff0015e0ffe724bd +:10d0e0000800e01000000000253009000640e800bc +:10d0f0000648e90020000f242338e7010430e60049 +:10d100002540060100000a24c2220800407d0900d3 +:10d1100025208f0040280900022b0500007d0a0011 +:10d120002528af002528ae0025100400251805008d +:10d130000800e003000000003b0040150000000074 +:10d140002a780001214008012148290121482f01a6 +:10d1500025782801a3ffe011000000000800201539 +:10d160000000000003000015000000009dff0010fb +:10d1700000000a242548000100000824e0ff4a2599 +:10d180002038277197ffe01000000000235047016e +:10d19000223007000630c8000440e8000448e900d7 +:10d1a00090ff0010254826011b00a015000000007c +:10d1b0002a78600121586b0121608c0121608f0168 +:10d1c00025788b011800e011000000000800801590 +:10d1d00000000000030060150000000085ff001043 +:10d1e00000000d242560600100000b24e0ffad2548 +:10d1f000203887717fffe010000000002368a7013e +:10d20000223007000630cb000458eb000460ec002d +:10d2100078ff00102560860140780c002578eb012e +:10d22000c1ffe01100000000f8ff053cbeff001048 +:10d230000000042440380500423d0700ffffe924b8 +:10d24000fe07212d0c0020100000000002fce72446 +:10d250000f80013cffff21342428a100e03f013c66 +:10d260002528a1000000c7ac2510040025180500e2 +:10d270000800e003000000001300e01400000000bc +:10d280004048050025482401f6ff20110000000059 +:10d290000080013c2440a1000100e724ffffe724b7 +:10d2a0002a488000212084002128a5002128a900e7 +:10d2b0001000013c2b08a100f8ff20140000000022 +:10d2c000e2ff00102528a800f8ff053c0000072415 +:10d2d000e4ff00102520070040480500424d0900ea +:10d2e000ffff2c25fe07812d0f00201000000000fd +:10d2f00021482601ffff2c25fe07812d210020104b +:10d30000000000000f80013cffff21342428a10011 +:10d31000006509002528ac0025100400251805002b +:10d320000800e003000000000063050025608401a0 +:10d33000f9ff80110000000004002011000000002f +:10d34000f8ff053cf4ff001000000424010029252b +:10d350000080013c2450a100ffff29252a608000a5 +:10d36000212084002128a5002128ac001000013cc8 +:10d370002b08a100f8ff201400000000dcff0010c3 +:10d380002528aa00c04205004265040025400c0182 +:10d39000c03a04000080013c254001010080013cae +:10d3a000050020192428a100f07f013c2528a100b8 +:10d3b000d9ff00100000042401000a242350490171 +:10d3c0002000412d0700201400000000e0ff4a214a +:10d3d0002b2007000d00081025380401f8ff00106d +:10d3e00000000834090040110000000022580a0023 +:10d3f00004206701045868010638470106404801c7 +:10d4000002008010253867010200e7340004e72499 +:10d410000004ec2c21400c01c262070001008c3199 +:10d420002338ec00c22207004065080025208c004c +:10d430004060080002630c00b7ff00102528ac0014 +:10d4400025380400254005000080013c2458a10037 +:10d4500040480500424d0900ffff2c25fe07812da5 +:10d46000370020100000000033040a242350490133 +:10d47000350041292f002010000000002000412924 +:10d480000600201400000000e0ff4a2500000424ec +:10d490000628450105000010042845010300401935 +:10d4a000000000000620440104204401234005013f +:10d4b0002338e4000000c4ac0400c5ac080000152b +:10d4c0000b0029250300e014000000000d000010ef +:10d4d000000009242540e00000000724e0ff292582 +:10d4e0002020047107008010000000002348240160 +:10d4f0002250040006504701043887000440880089 +:10d5000025400a01c22207004065080025208c0042 +:10d5100040280800022b0500006509002528ac0002 +:10d520002528ab0025100400251805000800e0039d +:10d53000000000000400cbacfaff00100000c0acfb +:10d54000fcff201100000000f8ff053c000004244f +:10d550000000c4acf3ff00100400c5ac0080013c27 +:10d560002440a10040380500423d0700ff07012488 +:10d570002a00e1100000000033040a242338470188 +:10d580002200e018000000003500e1280800201407 +:10d59000000000002a000015000000002550a40033 +:10d5a00024004015000000002500001000000000cd +:10d5b00005000015000000002b500400232004008b +:10d5c000232805002328aa001f00ea3001000924af +:10d5d00004484901234809002000e12804002014e0 +:10d5e0000000000000000424020000102428a9000c +:10d5f0002420890005000015000000002b500400c5 +:10d6000023200400232805002328aa002510040055 +:10d61000251805000800e003000000000053050085 +:10d62000255044010900401500000000f7ff0010dc +:10d6300000000000f03f053cf4ff0010000004244f +:10d6400025280800f1ff001000000424f8ff053c25 +:10d65000eeff0010000004240080013c2638e100a9 +:10d6600040580500425d0b00c0520500427d040099 +:10d6700025504f01c04a04000080083c2550480155 +:10d680004070070042750e00c06a0700427d060028 +:10d690002568af01c06206002568a801ffff6f255d +:10d6a000fe07e12d8d00201000000000ffffcf25b8 +:10d6b000fe07e12dbb002010000000000080013caf +:10d6c0002428a10023406e012c000011000000005e +:10d6d00015000019000000002000012d0700201493 +:10d6e00000000000e0ff08212b300c0023000d108b +:10d6f0002560a601f8ff001000000d341f00001186 +:10d70000000000002220080004308c0004208d005e +:10d7100006600c0106680d011800c01025608c0021 +:10d720001600001002008c3525580e00234008001a +:10d730002000012d0700201400000000e0ff082158 +:10d740002b3009000d000a1025484601f8ff001093 +:10d7500000000a3409000011000000002220080027 +:10d760000430890004208a000648090106500a0195 +:10d770000200c01025488900020029352678a7003c +:10d780001c00e0050000000021482c012b782c0132 +:10d7900021504d0121504f0102004d1100000000a9 +:10d7a0002b784d013700e0110000000001002f31ff +:10d7b0000200e01100000000020029354248090083 +:10d7c000c07f0a0025482f0142500a000080013c1a +:10d7d0002550410101006b25ff0701242900611537 +:10d7e00000000000f07f013c2528a1003700001058 +:10d7f000000004242b782c0123482c012b104f010e +:10d8000023504f012b784d012578e2010700e011ec +:10d8100023504d010080013c2628a1002b780900ef +:10d820002348090023500a0023504f0108004015e7 +:10d830000000000003002015000000000d00001093 +:10d8400000000b242550200100000924e0ff6b2577 +:10d8500020404871070000110000000023586801b3 +:10d8600022200800062089000448090104500a010a +:10d8700025504401257849010200e0150000000010 +:10d88000000005246800601900000000000429253c +:10d8900000042f2d21504f012b784f0121586f018b +:10d8a000c27a09000100ef3123482f01c22209008a +:10d8b000407d0a0025208f0040780a00027b0f007f +:10d8c0002528af00007d0b002528af00251004009f +:10d8d000251805000800e003000000002a78200158 +:10d8e0002148290121504a012300601521504f0190 +:10d8f000257849011400e0110000000008004015df +:10d9000000000000030020150000000067ff001069 +:10d9100000000b242550200100000924e0ff6b25a6 +:10d920002040487161ff0011000000002358680189 +:10d9300022200800062089000448090104500a0139 +:10d940005aff001025504401ff0701241500c111a2 +:10d95000000000002140e700257806010300e015e3 +:10d9600000000000d9ffe0040000000025100600c0 +:10d97000d8ff001025180700257849012700e01579 +:10d9800000000000ff070124d0ffc11500000000c7 +:10d990002678a7002100e00500000000f3ff00103a +:10d9a000000000002a78800121608c012168ad010f +:10d9b0001700c0152168af012578ac01c3ffe01145 +:10d9c000000000000800a015000000000300801502 +:10d9d0000000000039ff001000000e2425688001bf +:10d9e00000000c24e0ffce252040a87133ff001179 +:10d9f000000000002370c8012220080006208c00cf +:10da000004600c0104680d012cff00102568a401be +:10da10002578ac01d5ffe01100000000f8ff053cbf +:10da2000aaff0010000004240100082423400b0179 +:10da30002000012d0700201400000000e0ff082155 +:10da40002b3009000d000a1025484601f8ff001090 +:10da500000000a3409000011000000002220080024 +:10da60000430890004208a000648090106500a0192 +:10da70000200c010254889000200293583ff0010ec +:10da800000000b244050050042550a00c04a050022 +:10da9000427d040025482f01c042040000800e3c56 +:10daa00025482e0140680700426d0d00c062070046 +:10dab000427d060025608f01c05a060025608e0158 +:10dac0002628a7002428ae00ffff4f25fe07e12de2 +:10dad0004700201000000000ffffaf25fe07e12dea +:10dae0006f0020100000000002fcaf2521504f0104 +:10daf00019002c01123800001070000019000b01f1 +:10db0000122000001030000019002b0112580000f4 +:10db1000106800002130cb002b78cb002138ed00bd +:10db20002138ef000200ed10000000002b78ed001e +:10db30002170cf0119000c011240000010480000b4 +:10db40002130c8002b78c8002138e9002138ef00c7 +:10db50000200e910000000002b78e9002170cf01dd +:10db6000257886000200e011000000000100e73483 +:10db700025480e0006002005254007002a780001f0 +:10db8000214008012148290121482f01ffff4a2592 +:10db9000ffff4f25fe07e12d680020100000000068 +:10dba0000004082500040f2d21482f012b782f0198 +:10dbb00021504f01c27a08000100ef3123400f01cc +:10dbc000c2220800407d090025208f00407809000e +:10dbd000027b0f002528af00007d0a002528af003a +:10dbe00025100400251805000800e00300000000cf +:10dbf0002a78000121400801214829011c00401514 +:10dc000021482f01257828011400e01100000000b0 +:10dc100008002015000000000300001500000000af +:10dc2000adff001000000a24254800010000082470 +:10dc3000e0ff4a2520702e71a7ffc01100000000f0 +:10dc400023504e0122380e000638e8000440c80177 +:10dc50000448c901a0ff001025482701ff0701243f +:10dc60003300a11100000000ddff001000000000e3 +:10dc7000257828012e00e015000000000500a01501 +:10dc80000000000040780c002578eb012800e0112e +:10dc900000000000ff0701242100a1150000000082 +:10dca0002a78600121586b0121608c011900a015b0 +:10dcb00021608f0125788b011400e0110000000025 +:10dcc000080080150000000003006015000000003f +:10dcd00085ff001000000d242560600100000b246a +:10dce000e0ffad25203086717fffc01000000000ee +:10dcf0002368a601227006000670cb010458cb00f1 +:10dd00000460cc0078ff001025608e01b4ff001085 +:10dd10000000042425788b010500e01500000000b8 +:10dd2000f07f013c2528a100adff00100000042475 +:10dd3000f8ff053caaff001000000424f8ff401d76 +:10dd40000000000001000e242370ca012000c12d34 +:10dd50000700201400000000e0ffce212b30080057 +:10dd60000d00091025402601f8ff001000000934bd +:10dd70000900c0110000000022380e000430e80045 +:10dd80000438e9000640c8010648c9010200c01075 +:10dd90002540e800020008350004082500040f2d86 +:10dda00021482f0183ff0010c25709004050050091 +:10ddb00042550a00c04a0500427d040025482f0153 +:10ddc000c042040000800e3c25482e014068070038 +:10ddd000426d0d00c0620700427d060025608f0184 +:10dde000c05a060025608e012628a7002428ae0010 +:10ddf000ffff4f25fe07e12dcb00201000000000a3 +:10de0000ffffaf25fe07e12df40020100000000009 +:10de100023504d01ff034a2542400800c07f0900fe +:10de200025400f0142480900023c0c00f401e000cb +:10de30001b0027011270000010480000ffff863110 +:10de40001900ce0012200000004c0900027c0800de +:10de500025482f012b7824010600e01123482401d6 +:10de6000ffffce2521482c012b082c01fcff2010a0 +:10de700000000000f401e0001b0027011238000040 +:10de8000104800001900c70012200000004c0900d3 +:10de9000ffff0f3125482f012b7824010600e011e8 +:10dea00023482401ffffe72421482c012b082c01e3 +:10deb000fcff20100000000000740e002170c7015c +:10dec0001900cb01123800001020000000000824c7 +:10ded0002b780701234007012b102f0123482f0126 +:10dee0002b7824012578e2010b00e011234824015e +:10def000ffffce2521400b012b780b0121482c017f +:10df000021482f0102002c11000000002b782c0169 +:10df1000f7ffe0110000000006002c1500000000d3 +:10df200025200b002548080000000d242a000010c1 +:10df300025380d00023c0c00f401e0001b00270115 +:10df40001268000010480000ffff86311900cd0064 +:10df500012200000004c0900027c080025482f0117 +:10df60002b7824010600e01123482401ffffad2592 +:10df700021482c012b082c01fcff20100000000080 +:10df8000f401e0001b0027011238000010480000d7 +:10df90001900c70012200000004c0900ffff0f31dc +:10dfa00025482f012b7824010600e0112348240185 +:10dfb000ffffe72421482c012b082c01fcff201037 +:10dfc00000000000006c0d002168a7011900ab01e2 +:10dfd0001238000010200000000008242b780701f0 +:10dfe000234007012b102f0123482f012b782401f8 +:10dff0002578e2010b00e01123482401ffffad2545 +:10e0000021400b012b780b0121482c0121482f01c5 +:10e0100002002c11000000002b782c01f7ffe0110a +:10e02000000000000600c005000000002a78a001e2 +:10e030002168ad012170ce012170cf01ffff4a257b +:10e04000257828010200e011000000000100ad3534 +:10e0500025480e0025400d00ffff4f25fe07e12d4e +:10e0600015002010000000000004082500040f2dfa +:10e0700021482f012b782f0121504f01c27a08002f +:10e080000100ef3123400f01c2220800407d09004a +:10e0900025208f0040780900027b0f002528af0063 +:10e0a000007d0a002528af00251004002518050072 +:10e0b0000800e003000000004400401d00000000d4 +:10e0c00001000e242370ca012000c12d0700201476 +:10e0d00000000000e0ffce212b2008000d000910f9 +:10e0e00025402401f8ff0010000009340900c01188 +:10e0f0000000000022300e000420c8000430c900d7 +:10e100000640c8010648c901020080102540c80029 +:10e11000020008350004082500040f2d21482f01b6 +:10e12000d6ff0010c25709002a78000121400801db +:10e13000214829011700401521482f012578280181 +:10e140001400e0110000000008002015000000008d +:10e15000030000150000000029ff001000000a2441 +:10e160002548000100000824e0ff4a2520702e7198 +:10e1700023ffc0110000000023504e0122300e008a +:10e180000630c8000440c8010448c9011cff001043 +:10e190002548260105004d150000000040780c00c0 +:10e1a0002578eb012b00e01100000000ff0701249f +:10e1b0000a00a11100000000bbff40110000000098 +:10e1c000257828012300e01500000000f07f013cc5 +:10e1d0002528a100b4ff0010000004242a78600163 +:10e1e00021586b0121608c011700a01521608f015f +:10e1f00025788b01f5ffe011000000000800801574 +:10e2000000000000030060150000000000ff001087 +:10e2100000000d242560600100000b24e0ffad2507 +:10e2200020708e71fafec011000000002368ae015c +:10e2300022300e000630cb000458cb010460cc0124 +:10e24000f3fe00102560860125788b010200e011a5 +:10e2500000000000f8ff053c93ff001000000424bc +:10e260000000052425480500253805002530040058 +:10e270000c00c010000000000600c10400000000f7 +:10e280000080093c2b5005002328050023300600a0 +:10e290002330ca001e0407242040c8702338e80039 +:10e2a00004300601c24205004055060025400a011f +:10e2b0004050060002530a0025482a010055070075 +:10e2c00025482a0125100800251809000800e00348 +:10e2d000000000000000052425380500253004005a +:10e2e0000500c010000000001e0407242048c9706b +:10e2f0002338e90004302601c242050040550600db +:10e3000025400a0140480600024b0900005507005d +:10e3100025482a0125100800251809000800e003f7 +:10e3200000000000c23d0400ff00e7300080013c17 +:10e3300024308100ffffe924fe00212d0c00201075 +:10e34000000000008003e724404a0400024b09005b +:10e350002530c900402f0400004d07002530c900ba +:10e3600025100500251806000800e0030000000045 +:10e370000000052421208400f7ff80100000000029 +:10e380000900e01400000000ffffe72421208400c2 +:10e390008000013c2b088100fbff201400000000de +:10e3a000e8ff001000000000ff07072400ff013c09 +:10e3b000010021342b088100e7ff20140000000039 +:10e3c000e5ff0010f8ff063cc03a0500425d04007e +:10e3d0002538eb00c03204000080013c2538e10004 +:10e3e0000080013c2448a10040400500424508004f +:10e3f00080fc0825ffff0b25fe00612d1100201079 +:10e40000000000000200c010000000000100e7341e +:10e410008000e7248000eb2c21400b01025a07000a +:10e4200001006b312338eb0040380700423a070007 +:10e43000c05d08002538eb002510e9000800e00366 +:10e44000000000007f040124070001150000000007 +:10e4500040580700255866010300601100000000c5 +:10e46000f6ff0010c0ff023cff0001290400201449 +:10e4700000000000807f013cf0ff0010251021010a +:10e4800001000a24235048012000412d03002014dc +:10e4900000000000e9ff00102510090020000c24f6 +:10e4a00023608a01045887012530cb0006384701d4 +:10e4b000000008240080013cd2ff00102538e10054 +:10e4c000c03a0500425504002538ea000080013cae +:10e4d0002538e1004050050042550a001e0406247c +:10e4e0002330ca000b00c018000000002000c12c1f +:10e4f0000200201400000000000007340200a10404 +:10e500000638c70023380700251007000800e0037d +:10e510000000000002008010000000000100a5348f +:10e52000f07f013c010021342b08a10003002014de +:10e5300000000000f5ff00100080023cff7f023c5d +:10e54000f2ff0010ffff4234c03a050042550400bc +:10e550002538ea000080013c2538e10040500500e4 +:10e5600042550a001e0406242330ca000b00c004d2 +:10e57000000000002000c12c020020140000000058 +:10e58000000007340200a1040638c7002338070042 +:10e59000251007000800e0030000000002008010c2 +:10e5a000000000000100a534f07f013c010021348f +:10e5b0002b08a1000300201400000000f5ff00104c +:10e5c0000080023cf3ff0010ffff0224feff09243d +:10e5d0004050050040580700255864012558660141 +:10e5e00025504b0103004015000000003c000010c6 +:10e5f00000000224020080104040050001000825b0 +:10e60000e0ff013c010021342b08010136002010fd +:10e61000000000000200c010404007000100082573 +:10e62000e0ff013c010021342b0801012e002010e5 +:10e63000000000001600a104000000000300e00438 +:10e640000000000026000010ffff02242b5086006f +:10e65000232086002b58aa002328aa002b50a700ad +:10e6600025504b01030040112328a7001c00001077 +:10e67000010002242550a400030040110000000006 +:10e6800017000010ffff02241500001000000224f4 +:10e690000300e1040000000011000010010002244a +:10e6a0002b508600232086002b58aa002328aa007e +:10e6b0002b50a70025504b01030040112328a70031 +:10e6c00007000010ffff02242550a40003004011a2 +:10e6d00000000000020000100100022400000224db +:10e6e0000800e00300000000fdff001025100900f5 +:10e6f0000080013c2628a1002510040025180500f3 +:10e700000800e00300000000ff7f013cffff213410 +:10e710002428a10025100400251805000800e003a6 +:10e7200000000000020080104040050001000825a4 +:10e73000e0ff013c010021342b08010103002014fb +:10e74000000000000c000010010002240200c010b4 +:10e750004040070001000825e0ff013c0100213492 +:10e760002b0801010300201400000000020000102b +:10e7700001000224000002240800e0030000000061 +:10e780000080013c2628a100c24d0400ff00293171 +:10e79000c25d0500ff006b310080073c00420400b1 +:10e7a000254007010052050025504701ffff2d2598 +:10e7b000fe00a12d6100201000000000ffff6d256c +:10e7c000fe00a12d770020100000000023602b0127 +:10e7d0000d008005000000002000812903002014a6 +:10e7e000000000001500001002000a2425300a0075 +:10e7f00006508a0104688a011000a611000000007a +:10e800000e00001002004a3525480b0023600c0062 +:10e8100020008129030020140000000007000010e0 +:10e820000200082425300800064088010468880199 +:10e830000200a611000000000200083524608700d5 +:10e84000266885011000a0050000000021400a0193 +:10e850002b680a011700a0110000000001000d3113 +:10e860000200a0110000000002000835424008002c +:10e8700001002925ff0001240e00211500000000e1 +:10e880000c000010000008242b680a010400a011ed +:10e8900023400a012340080003000010266087017e +:10e8a00050000011000000002030067123482601ae +:10e8b0000440c8000e002019000000008000082558 +:10e8c00080000d2d21482d01026a08000100ad31a4 +:10e8d00023400d014040080042420800c06d09007d +:10e8e00025400d0125100c010800e0030000000088 +:10e8f000010006242330c9002000c12c390020105b +:10e90000000000000080013c2540010120000d2492 +:10e910002368a6010448a801020020110640c8008f +:10e92000010008350000092480000d25e3ffa10542 +:10e9300000000000e1ff0010010009240e00201576 +:10e940000000000021400801050000110000000047 +:10e9500020600c7123482c0198ff001004408801ae +:10e96000ff0001240f006111000000000080013c45 +:10e970001800a11400000000216808011b00a01568 +:10e9800000000000ff0001241400611500000000d9 +:10e99000266885001500a005000000000d0000108d +:10e9a00000000000080060150000000021504a012e +:10e9b0000a0040110000000020604c7123586c01d7 +:10e9c00082ff001004508a0121684a010700a01547 +:10e9d00000000000c4ff001025100500c2ff001059 +:10e9e00025100400c0ff001000000224beff00102c +:10e9f000c0ff023cc23d0400ff00e730c24d0500ed +:10ea0000ff00293100800a3c003204002530ca0092 +:10ea10000042050025400a012660850024504c0173 +:10ea2000ffffec24fe00812d2100201000000000db +:10ea3000ffff2c25fe00812d360020100000000075 +:10ea40001900c800125800000200601110300000c8 +:10ea50000100c6340300c00400000000403006007e +:10ea6000ffffe72482ff2c252138ec00ffffec2478 +:10ea7000fe00812d3a002010000000008000c62416 +:10ea80008000cc2c2138ec000262060001008c31a1 +:10ea90002330cc004030060042320600c06507003b +:10eaa0002530cc002510ca000800e003000000005b +:10eab0000d00e014000000002130c6000500c01069 +:10eac000000000002058cb702338eb00d8ff001066 +:10ead00004306601ff0001241f0021110000000026 +:10eae00015000010000000002160c6001a0080150b +:10eaf0000000000004002015000000002160080153 +:10eb00001500801100000000ff0001240f002115f6 +:10eb1000000000000a00201500000000214008014c +:10eb2000050000110000000020580b7123482b0144 +:10eb3000c3ff001004406801dbff001025100a002d +:10eb4000216008010400801500000000807f013c66 +:10eb5000d5ff001025104101d3ff0010c0ff023c7b +:10eb6000faffe01c0000000001000b24235867019d +:10eb70002000612df0ff20100000000020000c2478 +:10eb800023608b01043886010200e0100630660124 +:10eb90000200c634000007248000cc24b7ff8105a2 +:10eba00000000000b5ff00100100072400800b3cae +:10ebb000c2450400ff000831c2550500ff004a317c +:10ebc000003a04002538eb00004a050025482b01d7 +:10ebd0002670850024586e01ffff0e25fe00c12d12 +:10ebe0003f00201000000000ffff4e25fe00c12d59 +:10ebf00053002010000000002b08e900030020143f +:10ec00000000000042380700010008258263090067 +:10ec1000f40180011b00ec00122000001030000005 +:10ec2000ff3f2d311900a401122800008033060097 +:10ec30002b70c5000400c0112330c500ffff8424e1 +:10ec40002130c9002b70c900f40180011b00cc00e9 +:10ec500012380000103000001900a701122800002f +:10ec6000803306002b70c5000400c0112330c5009e +:10ec7000ffffe7242130c9002b70c9008073040016 +:10ec80002138ee000200c010003907000100e7340f +:10ec90007e000e242370ca0121400e01ffff0e25c5 +:10eca000fe00c12d34002010000000008000e72489 +:10ecb0008000ee2c21400e01027207000100ce31cf +:10ecc0002338ee0040380700423a0700c0750800bc +:10ecd0002538ee002510eb000800e00300000000de +:10ece00008000015000000002138e7000500e010d2 +:10ecf000000000002060ec7023400c01baff0010ff +:10ed00000438870104004815000000002170290123 +:10ed10002f00c01100000000ff0001240800411175 +:10ed20000000000012000011000000002170e70048 +:10ed30002700c015000000002200001000000000a5 +:10ed40000800401500000000214829011d00201185 +:10ed50000000000020602c7123504c01a6ff001021 +:10ed600004488901217029011900c0150000000024 +:10ed7000d9ff001025100b001200001d000000003c +:10ed800001000c24236088012000812df8ff201051 +:10ed90000000000020000e242370cc010440c701b5 +:10eda00002000011063887010200e7340000082441 +:10edb0008000ee24bdffc10500000000bbff001075 +:10edc00001000824807f013cc3ff00102510610171 +:10edd000c1ff0010c0ff023c0080013c1200801007 +:10ede0002430810002008104000000002320040080 +:10edf0009e000524203887702328a7000420e40003 +:10ee0000800084248000882c2128a800034204006c +:10ee10000100083123208800402004004222040021 +:10ee2000c045050025208800251086000800e00365 +:10ee3000000000000f008010000000009e0006246b +:10ee4000202885702330c5000420a400800084247d +:10ee50008000872c2130c700023a04000100e7300f +:10ee6000232087004020040042220400c03d060009 +:10ee700025208700251004000800e00300000000a2 +:10ee8000002a04000080013c2528a100c23d0400a6 +:10ee9000ff00e7309e0006242330c7000c00c01896 +:10eea000000000002000c128030020140000000022 +:10eeb0000500001000000224020081040628c5009d +:10eec00023280500251005000800e00300000000cd +:10eed000807f013c010021342b08810003002014b5 +:10eee00000000000f8ff00100080023cff7f023ca1 +:10eef000f5ff0010ffff4234002a04000080013caf +:10ef00002528a100c23d0400ff00e7309e00062432 +:10ef10002330c7000c00c004000000002000c128fe +:10ef2000030020140000000005000010000002246f +:10ef3000020081040628c5002328050025100500cd +:10ef40000800e00300000000807f013c0100213444 +:10ef50002b0881000300201400000000f8ff0010bf +:10ef60000080023cf6ff0010ffff0224feff082491 +:10ef700040300400403805002548c7001b00201120 +:10ef80000000000000ff013c010021342b08c100fb +:10ef9000190020100000000000ff013c0100213496 +:10efa0002b08e10014002010000000000200810482 +:10efb00042300600233006000200a1044238070058 +:10efc000233807002a08c7000300201000000000b3 +:10efd00007000010ffff02242a08e60003002010ab +:10efe00000000000020000100100022400000224c2 +:10eff0000800e00300000000fdff001025100800dd +:10f0000040100400421002000800e003000000006d +:10f010000080013c261081000800e0030000000091 +:10f020004030040000ff013c010021342b08c100e6 +:10f0300003002014000000000a0000100100022458 +:10f040004030050000ff013c010021342b08c100c5 +:10f050000300201400000000020000100100022440 +:10f06000000002240800e00300000000b8ffbd27f4 +:10f070004800a4af4000beaf3400b5af3000b4af1d +:10f080002c00b3af4400bfaf3c00b7af3800b6af01 +:10f090002800b2af2400b1af2000b0af00008880dc +:10f0a000029d063c4d15c424211004010000478038 +:10f0b0004800b38f8800e3304c00a5af1000a0af2c +:10f0c0001400a0af21f000001800a0af21a00000a4 +:10f0d0000800601021a8000001007326000068826b +:10f0e000215004010000498188002531fbffa05414 +:10f0f000010073262d000424d40004112b000c24dd +:10f10000d7000c51010073264d15d724217017012b +:10f110000000cd910400a6311b00c01001000f2497 +:10f12000029d163c1800afaf6817c68e6c17c78ecd +:10f13000d0ff12252128a002a176400f21208002b5 +:10f140002120400221a840009878400f21a06000b3 +:10f15000213040002120a0022128800221386000b7 +:10f160009875400f010073260000688225f0d203d5 +:10f17000219017010000519221a04000040030327c +:10f18000e9ff001621a860002e0016248a001651ff +:10f19000010073261800a48f280080104c00a48f53 +:10f1a0004500063965000d390100ab2d0100cc2c5e +:10f1b00025406c01210000114c00a48f0100732632 +:10f1c000000064822d000e2421280000af008e1064 +:10f1d000213800002b000f24a3008f50010073265c +:10f1e00021c09700000016930400d7320d00e012f2 +:10f1f000029d193c4d15262780900500215045029f +:10f2000040280a00010073262148a40000006482ff +:10f21000211886000000629004005f30f6ffe017be +:10f22000d0ff25251400b18f238005000b2807028d +:10f23000213825021400a7af4c00a48f05008010d0 +:10f240004800ab8f1800ac8f4c00a88f0a986c0157 +:10f25000000013ad1400a28f28004010029d1f3c37 +:10f26000c39f0200029d0f3c26705300029d0d3c7f +:10f270000818e68d0c18e78d2390d30121b04000cb +:10f28000b817b32503000010090003241000001272 +:10f2900021180002ffff702407c01202c0c803003b +:10f2a00001001733214033032120c000f7ffe01293 +:10f2b0002128e0000000068da176400f0400078d94 +:10f2c0002138600021304000f2ff001621180002b2 +:10f2d0006a00c00621208002a176400f2128a002ea +:10f2e00021204000212860002c7d400f2130c002e9 +:10f2f00021a0400021a86000029d1f3c1418f68f39 +:10f30000040080162438b602f07f023c5800e21058 +:10f3100022000324259095020100452e2b501e004b +:10f320002448aa005d002055220015241000a78f54 +:10f330000e00e014211080022118a0024400bf8fab +:10f340004000be8f3c00b78f3800b68f3400b58fb9 +:10f350003000b48f2c00b38f2800b28f2400b18fff +:10f360002000b08f0800e0034800bd272120800264 +:10f37000bc79400f2128a00221a0400021a86000f4 +:10f38000211080022118a0024400bf8f4000be8fd0 +:10f390003c00b78f3800b68f3400b58f3000b48f83 +:10f3a0002c00b38f2800b28f2400b18f2000b08fc3 +:10f3b0000800e0034800bd270000688221f817011b +:10f3c0000000f9930400383372ff0013029d163ccd +:10f3d000010003241800a3af6817c68e6c17c78ef0 +:10f3e000d0ff12252128a002a176400f2120800203 +:10f3f00021204002218040009878400f2188600041 +:10f400002138600021282002212000022130400004 +:10f410009875400f01007326000068821400a98fc0 +:10f420002150170121a0400000004291ffff252537 +:10f430000400473021a8600025f0d203e6ffe01465 +:10f440001400a5af57ff00104500063901007326d0 +:10f450000000688201000b242bff00101000abafee +:10f4600029ff0010000068825dff00100000648228 +:10f4700000a01e3cadff00100402c3af6b77400f2d +:10f480002128a00297ff00102120400001007326d0 +:10f490000000648252ff00100100072400a0143c09 +:10f4a000040295ae21a00000a0ff001021a80000da +:10f4b0000055a77cffffe324fe07622c214080005b +:10f4c0002150c000c007ab7c3f0040100098a97cd1 +:10f4d000029d043c1c18858c01fce4242530250188 +:10f4e0002148c00021788a00c0480900425708001e +:10f4f000ff03e72525482a014100e018c040080025 +:10f50000070006311d00c014c000057d40670900da +:10f51000c2300800ff07e4282540cc0031008010ed +:10f52000c2480900029d033c1c18798c2178000018 +:10f5300024c039012550f80107004051213800004e +:10f5400021100001029d083c2c18058d214040002f +:10f55000247025012148c001c06a0b002520a701a5 +:10f560000035040021600000252088012528c900fd +:10f57000211080000800e0032118a0000300a2244d +:10f580002118000021400201029d183c2bc80201f5 +:10f590002148230124180f8f2148390121680000d8 +:10f5a00024502f012560aa01d9ff8011406709006e +:10f5b000c07709004240080025400e01424809007a +:10f5c000d2ff00100100e7240400e01421108000a5 +:10f5d000253889002900e014026809000800e003ca +:10f5e0002118a000c06a0b00ff07a735002d0700f7 +:10f5f00021200000211080000800e0032118a00055 +:10f6000001001924233027033800d828180000539c +:10f6100001000824232806002000a2302718c0007b +:10f620000660c800041869000668c9004018030095 +:10f63000256083012000c3300b60a3010b68030029 +:10f6400021500001040040140418a8000218090009 +:10f650000440a300251848012b20030021280000a6 +:10f66000254084012548a501a5ff00102138e600aa +:10f6700021480000a2ff00102138e60002fc04240b +:10f680000300a0152018a37120700e712000c3255f +:10f69000f5ff632494ff601021788a002710600032 +:10f6a0000438690006104800043068004210020067 +:10f6b0002538e200200062300b38c2000b30020017 +:10f6c000232083002140c00086ff00102148e00075 +:10f6d00080bf033c105a648c0000827cfdff401008 +:10f6e0000000000080bf033c205a628c0800e00349 +:10f6f000000000000800e00300606241e8ffbd2751 +:10f700001000bfaf006805408000063c2520a60021 +:10f71000006884400010032488bf023cd37d400f62 +:10f72000081043ac1000bf8f0800e0031800bd278d +:10f730000100843003008010000000000800e00396 +:10f74000206060410800e003006060410800e003c1 +:10f75000206062412118e0002140a0002138c00053 +:10f760003a006014216080002b10a6008c0040102d +:10f77000000000002030c670c200c014232806001c +:10f78000023407001b000601f401c000ffffeb304c +:10f7900002740c001248000010c00000125000005b +:10f7a00002482b71007c18002528ee012b68a90067 +:10f7b0001b000601f401c0000900a0512320a9008c +:10f7c0002128a7002b40a70004000015ffff4a25b1 +:10f7d0002bc8a900fc002057ffff4a252320a900c1 +:10f7e0001b008600f401c000ffff83311268000097 +:10f7f00010280000124800000258ab7100140500e8 +:10f80000254043002b600b011b008600f401c00063 +:10f8100009008051005c0a00214007012b300701dc +:10f820000400c014ffffa9252b700b012b380e001c +:10f8300023482701005c0a002520690121300000cf +:10f84000211080000800e0032118c0002b58a300fd +:10f8500021200000faff6015213000002048697067 +:10f860008e0020112b10870120000d242370a90188 +:10f87000045023010678c70125684f0106c8c50159 +:10f8800002540d001b002a03f401400106c0cc0104 +:10f8900004282501ffffaf312570b80004c02c01fa +:10f8a000021c0e000438270112200000105800002e +:10f8b0001260000002408f70004c0b00255823019d +:10f8c0002b3068011b002a03f40140010b00c050db +:10f8d0002318680121586d012b106d01060040149a +:10f8e000ffff8c242b3068010400c010231868012e +:10f8f000ffff8c2521586d01231868011b006a0049 +:10f90000f4014001ffffcb3112480000104000001d +:10f910001230000002482f710024080025408b009f +:10f920002bc809011b006a00f40140010b002053a1 +:10f93000007c0c0021400d012b280d010600a014b5 +:10f94000ffffc6242b7009010400c011007c0c00cd +:10f9500021400d01ffffc624007c0c002520e6019c +:10f960001900870010280000231809012b6065008a +:10f9700009008055ffff8424121000002668a300b0 +:10f980002b5002030100b82d24380a03acffe050cd +:10f9900021300000ffff8424a9ff00102130000067 +:10f9a0004500c01001000a242050ea7049004015ab +:10f9b000200009242328070101000624024c070027 +:10f9c000ffffed301b00a900f401200102cc0c0068 +:10f9d00012500000101800001258000002504d7123 +:10f9e00000240300254099002b700a011b00a90088 +:10f9f000f40120010900c01123780a012140070108 +:10fa00002b2807010400a014ffff6b252b100a010f +:10fa10006b004054ffff6b2523780a011b00e901ae +:10fa2000f4012001ffff983112c8000010400000cf +:10fa30001250000002602d73007408002540d801a8 +:10fa40002b680c011b00e901f40120010900a01141 +:10fa5000001c0b00214007012b4807010500201561 +:10fa6000ffff2a272b380c012b60070023504c0185 +:10fa7000001c0b0025206a00211080000800e00314 +:10fa80002118c0000620a4000418c8002540640006 +:10fa90000460cc003aff00100438c7002b2065003a +:10faa00001004538255085002b200a0021108000d8 +:10fab0000800e0032118c0001b004601f401c0004b +:10fac000123800002050ea70bbff401123280701c4 +:10fad0002000092423782a010438470106c8e801d8 +:10fae000024c07001b002903f40120010670ec0101 +:10faf00004104801ffffed3025784e0002240f006e +:10fb00001230000010280000127000000240cd707a +:10fb1000001c0500255864002bc068011b00290348 +:10fb2000f40120010a00001304604c012158670110 +:10fb30002b50670106004015ffffce242bc0680143 +:10fb40000400001323c86801ffffce252158670178 +:10fb500023c868011b002903f4012001ffffe431e1 +:10fb60001228000010400000123000000250ad705a +:10fb7000001c0800254064002b580a011b002903c3 +:10fb8000f40120010b00601100c40e0021400701a8 +:10fb90002b10070107004014ffffa6242b780a0151 +:10fba0000500e05125300603ffffc6242140070170 +:10fbb00000c40e002530060382ff001023280a012e +:10fbc00095ff00102140070104ff00102128a70025 +:10fbd000e8ffbd272140e0001000b2af0c00b1af3c +:10fbe0000800b0af2190a0032150c0002158800030 +:10fbf000400000152138a0002b10a6005c0040102a +:10fc00002070ce707900c01523280e00024c0a0027 +:10fc10001b00e900f4012001ffff4f3102640b00db +:10fc2000128000001030000002280f72006c0600e5 +:10fc30002530ac012b40c5001b00e900f401200178 +:10fc40000a0000112318c5002130ca002b38ca0051 +:10fc50000600e0142318c5002bc8c5000000383b7f +:10fc60002188ca000b3038022318c5001b00690028 +:10fc7000f4012001ffff713112c8000010c0000024 +:10fc800002582f73007c18002540f1012b380b011e +:10fc90001b006900f40120010a00e01023180b0189 +:10fca00021400a012b480a010600201523180b01e8 +:10fcb0002b100b0121200a0100004a380b408a005a +:10fcc00023180b010660c3010300401221680000e5 +:10fcd00000004cae04004dae0000a28f0400a38fc4 +:10fce0001000b28f0c00b18f0800b08f0800e00345 +:10fcf0001800bd272b70a8000a00c05120700e719b +:10fd00001000b28f0c00b18f0800b08f211080005e +:10fd10002118a0000000a4af0400a5af0800e00374 +:10fd20001800bd273700c01520000f242b6886005f +:10fd30000100ac392b3005012528cc000700a010ac +:10fd40002160600123808a002388e8002b40900016 +:10fd5000233828022158000221606001deff401292 +:10fd60002168e00000004caedbff001004004dae47 +:10fd70007e00c0100100092420704e718200c01561 +:10fd800020000f242330ea00024c0a00ffff4f310d +:10fd90001b00c900f401200102240b0012400000e6 +:10fda0001028000002380f71001c0500252864008f +:10fdb0002b10a7001b00c900f4012001abff40106d +:10fdc0002318a7002128aa002b30aa00a7ffc0549f +:10fdd0002318a7002b80a70000000d3a2160aa007d +:10fde0000b288d01a1ff00102318a7000620a400f6 +:10fdf0000418c701253864000450c60183ff0010b1 +:10fe00000458cb0123c0ee010448c80106c806030c +:10fe10002578390106200503024c0f001b008900dc +:10fe2000f401200106380b030468c501fffff1311e +:10fe300025c8a7010480cb010438ca01021c19009f +:10fe40001230000010600000125800000250d17003 +:10fe5000002c0c002540a3002b100a011b00890078 +:10fe6000f40120010b00405023180a0121400f012a +:10fe70002b100f0106004014ffffcb242b200a019a +:10fe80000400801023180a01ffff6b2521400f0199 +:10fe900023180a011b006900f4012001ffff25332c +:10fea000125000001040000012300000025051714a +:10feb00000640800254085012b880a011b006900a9 +:10fec000f40120010b00201200140b0021400f014f +:10fed0002b680f010700a015ffffc6242bc80a01dd +:10fee0000500201325484600ffffc62421400f01ce +:10fef00000140b00254846001900270110300000af +:10ff000023400a012b580601070060151228000043 +:10ff10002660c8000100912d2b1805022420230221 +:10ff200006008010000000002350a7002b38aa0014 +:10ff30002368cf002330a7012128400166ff40122b +:10ff400023780502232806012b400f022380a800f6 +:10ff50000430100306c0cf012560d8000668d00128 +:10ff600000004cae5cff001004004dae1b002601eb +:10ff7000f401c0001250000020704e7182ffc011c9 +:10ff80002330ea0020000f242380ee010450ca0130 +:10ff900006200702024c0a001b008900f401200120 +:10ffa00006680b020430c701ffff4f312538cd0032 +:10ffb000021c0700126000001040000002308f7128 +:10ffc000002c08002540a3002b1006011b0089000f +:10ffd000f4012001050040100458cb0121400a0122 +:10ffe0002b880a01190020122b1006012318060184 +:10fff0001b006900f4012001ffffe53012680000da +:020000041d02db +:10000000106000000238af7100440c00253005017b +:100010002b20c7001b006900f40120015cff805009 +:100020002330c7002130ca002b80ca0058ff005679 +:100030002330c7002bc8c7000000383b2188ca0006 +:100040000b30380252ff00102330c700000059382f +:0c00500021c00a01e5ff00100b4019035d +:020000040000fa +:020000041d02db +:100060005261704d616e205665723a312e302e38d5 +:1000700000000000496e736572742053442d436183 +:100080007264206f720000003c3c45534320544f83 +:1000900020524553554d4500496e76616c69642088 +:1000a00046696c652054797065000000506c65618c +:1000b0007365206f6e6c7920757365002a2e424639 +:1000c00042206f72202a2e47434f2046696c657389 +:1000d0000000000050415553450000004572726f0a +:1000e00072205445535400004578747275646572eb +:1000f000204f46460000000046696c65204572723c +:100100006f72203a7365656b20707400556e6b6e6c +:100110006f776e204572726f72000000203c45536d +:100120004320544f20524553554d45003c0000009c +:10013000000002430000c8c2546f6f6c3a20506543 +:100140006e000000546f6f6c3a20457874727564cd +:1001500065720000546f6f6c3a2045787472756454 +:1001600065723200546f6f6c3a204e6f7420446594 +:1001700066696e6564000000546f6f6c3a20526fc0 +:100180007574657200000000546f6f6c3a204e6ffa +:100190006e6500007200000046696c652045727251 +:1001a0006f7220202020000046696c65204e6f741d +:1001b00020466f756e6400004f70656e0000000091 +:1001c0002a2e2a0046696e6420466972737420459f +:1001d00072726f72000000004e6f2066696c65736a +:1001e000206f6e20636172640000000046696c65d8 +:1001f00000000000253375006f6600000000004419 +:100200000000fe420000fe4225362e32660000004d +:10021000cdcccccccce45540000020455a20444ff6 +:10022000574e2020202020005920464f525741523f +:1002300044202000484f4d45205820202020000019 +:10024000484f4d452059202020200000484f4d4563 +:10025000205a202020200000484f4d452041424f89 +:100260005254454400000000484f4d4520434f4d37 +:10027000504c455445000000cdcccccccce455408e +:1002800039b4c876be9ff63f0000c84200000000a7 +:10029000cdcccccccce45540000020450000000083 +:1002a000cdcccccccce4554000808443000048c386 +:1002b000000002430000c8c2000000000000e03f50 +:1002c000000000000000e03f000000000000e0bf70 +:1002d00054454d5045524154555245204348414e96 +:1002e00047450000400a019d680c019d680c019d76 +:1002f000680c019d680c019d680c019d680c019db6 +:10030000680c019d680c019d680c019d680c019da5 +:10031000680c019d680c019d680c019d680c019d95 +:10032000680c019d680c019d000c019d680c019ded +:10033000680c019d680c019d680c019d5409019d8c +:10034000680c019d680c019d680c019d680c019d65 +:10035000680c019d680c019d680c019d680c019d55 +:10036000680c019d400a019d680c019d680c019d6f +:10037000680c019d680c019d680c019d680c019d35 +:10038000680c019d680c019d680c019d680c019d25 +:10039000680c019d680c019d680c019d680c019d15 +:1003a000680c019d680c019d000c019d680c019d6d +:1003b000680c019d680c019d680c019d5409019d0c +:1003c0002e2e000020202020202020202020200071 +:1003d0000000000000950000000000000000000088 +:1003e00001f90000000000000000000009af00005b +:1003f00000000000010000000a1b000000000000d7 +:10040000010000000cc3000000000000000000001c +:100410000daf0000020000000000000010ff00000f +:10042000000000000000000011ff000000000000bc +:100430000100000012ff00000000000001000000a9 +:1004400018ff0000000000000100000019ff00007c +:10045000000000000100000020ff0000000000007c +:100460000000000021ff000000000000000000006c +:1004700026df0000010000000000000037730000cc +:1004800000000000000000003a250000030000000a +:10049000000000003b2500000000000000000000fc +:1004a00000040000ff030000fe030000fc03000046 +:1004b000fa030000f7030000f2030000ec03000061 +:1004c000e3030000d8030000c9030000b6030000e6 +:1004d0009f03000083030000610300003b03000052 +:1004e00010030000e1020000af0200007b020000e8 +:1004f0004702000013020000e0010000b10100000b +:10050000840100005a0100003501000013010000c1 +:10051000f4000000d9000000c1000000000000004d +:1005200000000000389c2c41000000000000394011 +:10053000000080bf00c0794400c07944000080bf43 +:10054000000020410000000000000000389c2c4109 +:100550000000000000003940000000000000000022 +:10056000000000000000000000000000000000008b +:10057000000000000000000000000000000000007b +:10058000000000000000000000000000000000006b +:10059000e0e0606060ffff6363e3e3030303ffffea +:1005a000000000000000000000000000000000004b +:1005b000000000000000000000000000000000003b +:1005c000000000000000000000000000000000002b +:1005d000000000000000000000000000000000001b +:1005e000000000000000000000000000000000000b +:1005f00000000000000000000000000000000000fb +:1006000000000000000000000000000000000000ea +:10061000ffffc0c0c0c7c7c6c6ffff060606070764 +:1006200000000000000000000000000000000000ca +:1006300000000000000000000000000000000000ba +:1006400000000000000000000000000000000000aa +:10065000000000000000000000000000000000009a +:10066000000000000000000000000000000000008a +:10067000000000000000000000000000000000007a +:10068000000000000000000000000000000000006a +:10069000000000000000000000000000000000005a +:1006a000000000000000000000000000000000004a +:1006b000000000000000000000000000000000003a +:1006c000000000000000000000000000000000002a +:1006d000000000000000000000000040c0c0c0c0da +:1006e000c0c0c0c0c0c0c0c0c0c0c0c0808000000a +:1006f00000000000000000000000000000000000fa +:1007000000000000000000000000000000000000e9 +:1007100000000000000040c0c0c0c0c0c0c0c08019 +:10072000000000000080c0c0c0c0c0c0c0c0400009 +:1007300000000000000000000000000000000000b9 +:1007400000000000000000000000000000000000a9 +:10075000000000000000000000000000ffffffff9d +:10076000ffffff7171f1f1ffffffffff7f3f00000f +:10077000009c9c9c9c9c9c9c9c9cfcfcfcfcfcf819 +:10078000f0000004fcfcfcfcfcfcf81c1c1cfcfc49 +:10079000fcfcfcf8f00000ffffff0f7ffffffffff6 +:1007a000fce000e0fc3f07ffffffffffffff000052 +:1007b00000009c9c9c9c9c9c9c9c9cfcfcfcfcfcd1 +:1007c000f8f0000000fcfcfcfcfcfcf81c1c1cfc11 +:1007d000fcfcfcfcf8f00000000000407f7f7f7f05 +:1007e0007f7f7f400000073f7f7f7f7f7c704000de +:1007f0003f7f7f7f7f7f7f7171717f7f7f7f7f7f73 +:100800007f400000ffffffffffffff7070707f7fe2 +:100810007f7f7f7f3f00407f7f7f0000031f7f7fc0 +:100820007f7f7f0f0100407f7f7f7f7f7f7f400042 +:10083000003f7f7f7f7f7f7f7171717f7f7f7f7fb1 +:100840007f7f4000407f7f7f7f7f7f7f4000407fb2 +:100850007f7f7f7f7f7f400000000000000000005e +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000007070707070707040000000033 +:100890000000000000000000000000000000000058 +:1008a0000000000000000000000000000000000048 +:1008b0000000000000000000000000000000000038 +:1008c0000000000000000000000000000000000028 +:1008d0000000000000000000000000000000000018 +:1008e0000000000000000000000000000000000008 +:1008f00000000000000000000000000000000000f8 +:1009000000000000000000000000000000000000e7 +:1009100000000000000000000000000000000000d7 +:1009200000000000000000000000000000000000c7 +:1009300000000000000000000000000000000000b7 +:1009400000000000000000000000000000000000a7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:10098000000000000000000000c060301088e45447 +:100990006e6e26f32f272323272ff3266e5664cc63 +:1009a000983020e0800000000000000000000000ff +:1009b0000000000000000000000000000000000037 +:1009c0000000000000000000000000000000000027 +:1009d0000000000000000000000000000000000017 +:1009e0000000000000000000000000000000000007 +:1009f00000000000000000000000000000000000f7 +:100a0000000000000000c0fc472632f93f10080833 +:100a100008f80f0908080808080809ff080808105e +:100a2000173df326655ffcc00000000000000000d9 +:100a300000000000000000000000000000000000b6 +:100a400000000000000000000000000000000000a6 +:100a50000000000000000000000000000000000096 +:100a60000000000000000000000000000000000086 +:100a70000000000000000000000000000000000076 +:100a80000000000000000f74c888107fd030206084 +:100a9000607fc04040404040404040ff60602030a8 +:100aa00010f01f90d8e87c0f00000000000000004c +:100ab0000000000000000000000000000000000036 +:100ac0000000000000000000000000000000000026 +:100ad0000000000000000000000000000000000016 +:100ae0000000000000000000000000000000000006 +:100af00000000000000000000000000000000000f6 +:100b0000000000000000000003070d3b276e5ca8fa +:100b1000c888977cd090101090d03c97d8e8b8cc7b +:100b200067371b0d070100000000000000000000f7 +:100b300000000000000000000000000000000000b5 +:100b400000000000000000000000000000000000a5 +:100b500000000000000000000000000000c0c040d5 +:100b60004040c0c08000c000c0c0c0c08080c00085 +:100b700080c0c0c0c0000000000000c0c0c0c0c035 +:100b800000000000c0c0c0c0c0c0c080000080c065 +:100b9000c0c1c1c1810303c38303010101000080ff +:100ba000c00000000000c0c0404040c0c080000045 +:100bb000c0c000000080c00000c0c0c0c08080c0b5 +:100bc0000080c0c0c0c00000000080c0c0c0c00025 +:100bd000000000000000000000000000003f3f2671 +:100be0002226361f0f003f0000003f3f000000009c +:100bf00033333434343c18000000003f3d04040417 +:100c0000040404003f3f060e1e1e362700061f3058 +:100c1000303030301f06003f030f1c38381c0f03e4 +:100c20003f00000000003f3f262226361f0f000035 +:100c30000001033e03010000000000003f0000002f +:100c4000001f1f3434343434340033333434343cf0 +:100c5000180000000000000000000000000000007c +:100c60000000000000000000000000000000000084 +:100c70000000000000000000000000000000000074 +:100c80000000000080808000e0f0f81818b0a0009c +:100c9000e0f0f818f8f0e000f8f8f810f8f8f018bc +:100ca000f8f8f00000000000000000000000000064 +:100cb0000000000000000000000000000000000034 +:100cc0000000000000000000000000000000000024 +:100cd0000000000000000000000000000000000014 +:100ce0000000000000000000000000000000000004 +:100cf00000000000000000000000000000000000f4 +:100d000000000000030303000001030303010000cf +:100d100000010303030100000303030003030300b6 +:100d200003030300000000000000000000000000ba +:100d300000000000000000000000000000000000b3 +:100d400000000000000000000000000000000000a3 +:100d50000000000000000000000000000000000093 +:100d60000000000000000000000000000000000083 +:100d70000000000000000000000000000000000073 +:100d80000000000000000000000000000000000063 +:100d90000000000000000000000000000000000053 +:100da0000000000000000000000000000000000043 +:100db0000000000000000000000000000000000033 +:100dc0000000000000000000000000000000000023 +:100dd0000000000000000000000000000000000013 +:100de0000000000000000000000000000000000003 +:100df00000000000000000000000000000000000f3 +:100e000000000000000000000000000000000000e2 +:100e100000000000000000000000000000000000d2 +:100e200000000000000000000000000000000000c2 +:100e300000000000000000000000000000000000b2 +:100e400000000000000000000000000000000000a2 +:100e50000000000000000000000000008040202092 +:100e600040800000000000000000000000000000c2 +:100e70000000000000000000000000000000000072 +:100e80000000000000000000000000000000000062 +:100e90000000000000000000000000000000000052 +:100ea0000000000000000000000000000000000042 +:100eb0000000000000000000000000000000000032 +:100ec0000000000000000000000000000000000022 +:100ed00000000000000000000000fc0300c0c0c0d3 +:100ee000c00003fc00000000000000000000000043 +:100ef00000000000000000000000020502003c426b +:100f000081818166000000000000000000000000f8 +:100f100000000000000000000000000000000000d1 +:100f200000000000000000000000000000000000c1 +:100f3000000080402010100808080404040404087d +:100f40000808101020408000000000000000000091 +:100f500000000000000000000000ff0000ffffff95 +:100f6000ff0000ff00000000000000000000000083 +:100f70000000000000000000000000000000808071 +:100f80008080000000000000000000000000000061 +:100f90000000000000000000000000000000000051 +:100fa0008000000080000000000000000000000041 +:100fb000f00e010000000000000080e0e0e0000012 +:100fc000000000000000010ef00000000000000022 +:100fd00000000000000000000000ff0000ffffff15 +:100fe000ff0000ff00000000000000000000000003 +:100ff00000000000000000000000000000007f046e +:10100000040000324a4a7c007e04027c000000009a +:1010100000000000000000000000000000000003cd +:1010200004631c3348300000000000f00808f000a2 +:10103000010e30408804040201010000000000009d +:10104000000000008040300e01e010902000e01011 +:1010500010e000000000000080c0fff0f8ffffff7c +:10106000fff8f0ffc080000000000000000000005a +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010a0000000000000000000000000030404030032 +:1010b0000000000000010102020204040404040212 +:1010c00002020101000000000007090807000708ec +:1010d0000807000000000000ffffffffffffffff09 +:1010e000ffff7f3f1f0f0000000000000000000016 +:1010f000000000000000000000020502003c4281e8 +:101100008181660000000000000000000000000077 +:1011100000000000000000000000000000000000cf +:1011200000000000000000000000000000ff09199e +:10113000294680ff1111110e00ff0678807806ff06 +:10114000000000000000000000000000000000009f +:101150000000000000000000000000000000005f30 +:1011600000000003000300143e143e14242a7f2aca +:1011700012433308666136495522500005030000ca +:10118000001c2241000041221c0014083e081408e3 +:10119000083e0808005030000008080808080060f1 +:1011a00060000020100804023e5149453e04027fc1 +:1011b0000000426151494622414949361814127fc4 +:1011c0001027454545393e49494932010171090712 +:1011d0003649494936264949493e0036360000001d +:1011e000563600000814224100141414141400414f +:1011f00022140802015109063e4159555e7e090933 +:10120000097e7f494949363e414141227f41414162 +:101210003e7f494949417f090909013e4141493a17 +:101220007f0808087f00417f4100304040403f7ff9 +:10123000081422417f404040407f020c027f7f0221 +:1012400004087f3e4141413e7f090909061e2121d4 +:10125000215e7f0909097600264949493201017f4b +:1012600001013f4040403f1f2040201f7f201020b1 +:101270007f41221c224107087008076151494543fc +:10128000007f410000020408102004020102044013 +:1012900040404040000102040020545454787f44f0 +:1012a0004444383844444444384444447f385454d3 +:1012b000541804047e0505085454543c7f08040463 +:1012c0007800447d40002040443d007f10284400c9 +:1012d00000417f40007c047804787c08040478385e +:1012e000444444387c14141408081414147c007cfe +:1012f000080404485454542004043f44443c4040ef +:10130000207c1c2040201c3c4030403c44281028bd +:10131000440c5050503c4464544c44000836414105 +:1013200000007f0000414136080002010204020073 +:10133000000000005261704d616e205665723a31b6 +:101340002e302e3800000000472d436f6465204c7e +:10135000696e653a0000000048656164205370655d +:1013600065643a004578742e20526174653a000035 +:101370002531750025352e31666d6d2f7300000007 +:101380004e6f74205365740000007042000000002e +:1013900079e9263108acac3f4578747275646572a2 +:1013a00020436f6e74726f6c0000000048656174ba +:1013b0006572204f6e200000486561746572204f91 +:1013c00066660000203c31303043204d6f746f72f0 +:1013d000204f4646000000000000c84254454d50d2 +:1013e00045524154555245204552524f520000003b +:1013f000544845524d4953544f52204552524f5232 +:101400000000000025337543000000002a000000a2 +:101410002000000000c07944000080bf25337552d1 +:10142000504d00000000000084471b47acc5a73f9b +:101430004d454e550000000052554e2046494c4542 +:10144000000000004d414e55414c204d4f56450087 +:10145000544f4f4c2053455455500000484f4d4574 +:1014600020544f4f4c204845414400004d414e55bb +:10147000414c0000585f537465703a00595f5374d3 +:1014800065703a005a5f537465703a004155544f85 +:101490003a204c6f6164696e672e2e00484f4d49ab +:1014a0004e4720504c454153452057414954000078 +:1014b0004d4f564520544f3a00000000583d253608 +:1014c0002e326600593d25362e3266005a3d2536ad +:1014d0002e3266004e4f205a204d4f5645000000d8 +:1014e00050726f672e456e6400000000526574757f +:1014f000726e20746f204d656e7500003c3c3c2080 +:101500005072657373204573632e00003e00000027 +:1015100020200000f0a0019d489b019d189c019d8a +:10152000e89c019db89d019d889e019d589f019d4d +:1015300028a0019d000000006cb1019d20b2019d1a +:10154000b4b1019dfcb2019d80b3019d002020201b +:101550002020202020202828282828202020202063 +:10156000202020202020202020202020208010103b +:10157000101010101010101010101010100404048f +:10158000040404040404041010101010101041414d +:10159000414141410101010101010101010101013b +:1015a000010101010101010110101010101042424f +:1015b000424242420202020202020202020202020b +:1015c00002020202020202021010101020000000ab +:1015d000000000000000000000000000000000000b +:1015e00000000000000000000000000000000000fb +:1015f00000000000000000000000000000000000eb +:1016000000000000000000000000000000000000da +:1016100000000000000000000000000000000000ca +:1016200000000000000000000000000000000000ba +:1016300000000000000000000000000000000000aa +:10164000000000000000000000000000000000009a +:10165000303030303030303030303030303030308a +:10166000303030303030303030303030303030307a +:10167000202020202020202020202020202020206a +:10168000202020202020202020202020202020205a +:1016900098bc019d44c0019dc8cd019d44c0019de1 +:1016a000c8cd019dc8cd019dc8cd019dc8cd019d6e +:1016b000c8cd019dc8cd019dc8cd019dbcbc019d7b +:1016c00004bd019dc8cd019dc8cd019dc8cd019d22 +:1016d000c8cd019dd0bc019dc8cd019dc8cd019d47 +:1016e000f4bc019dc8cd019dc8cd019dc8cd019d13 +:1016f000c8cd019dc8cd019dc8cd019dc8cd019d1e +:10170000c8cd019dc8cd019dc8cd019d14cc019dc2 +:10171000a4bc019d44c0019d44c0019d44c0019de5 +:10172000c8cd019da4bc019dc8cd019dc8cd019d22 +:10173000c8cd019dc8cd019ddccc019dc8bc019ddb +:1017400010bd019dc8cd019dc8cd019d50cc019d0e +:10175000c8cd019ddcbc019dc8cd019dc8cd019dba +:101760001cbd019d0000000000000000000024409e +:101770000000000000001040000000000000008099 +:101780007b14ae47e17a843f2d431cebe2361a3fcf +:101790004e614e002b496e66000000002d496e66ba +:1017a00000000000286e756c6c29000058ce019d69 +:1017b00060ce019d68ce019d70ce019d78ce019dc9 +:1017c000000000000000144000000000000039404c +:1017d00000000000008883400000000084d717410b +:1017e0000080e03779c34142176e05b5b5b8934420 +:1017f000f5f93fe9034f3849321d30f948778252f5 +:101800003cbf737fdd4f1565000000000000f03f16 +:10181000ffffffffffffff7f000000000000100040 +:101820000000000000000001ffffffffffff0f00ae +:020000040000fa +:020000041d02db +:101830000c00000000000000010001041f0c1d004e +:101840000c0000001400000054f7019d7c0400000f +:101850000c00000000000000010001041f0c1d002e +:101860001c00000014000000d0fb019d8c0400004f +:10187000440e185011107c11117d11127e000000d1 +:020000040000fa +:020000041d02db +:1018800000000000ffffffff00000000000000005c +:101890000000000000000000000000000000000048 +:1018a000840000a0a00000a0bc0000a0800000a058 +:1018b0007c0300a001000000000000000000000008 +:1018c0000000000000000000000000000000000018 +:1018d0000000000000000000000000000000000008 +:1018e00000000000000000000000000000000000f8 +:1018f00000000000000000000000000000000000e8 +:1019000000000000ffffffffffffffff00000000df +:101910000004000009100000000000003815029dbe +:10192000ffffffff000000000000000000040000b7 +:101930000a100100000000003815029dffffffffa4 +:101940000000000000000000000000000200020093 +:10195000000000003815029dfdffffff00000000a1 +:101960000000000000000000000000000000000077 +:041970000000000073 +:020000040000fa +:020000041d02db +:10197400010000001e000000ffff00000100000045 +:10198400ffff0000ffffffffc80e00a09001000052 +:0c199400f5ff000001000000200000a092 +:00000001FF diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan1_0_9-factory.hex b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan1_0_9-factory.hex new file mode 100644 index 00000000..263668a1 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/RapMan1_0_9-factory.hex @@ -0,0 +1,15109 @@ +:020000041D00DD
+:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10501000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10502000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10503000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10504000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10505000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10506000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10507000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10508000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10509000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1050A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1050B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1050C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1050D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1050E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1050F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10510000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10511000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10512000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10513000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10514000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10515000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10516000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10517000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10518000029D1A3C4CAC5A27080040030000000066
+:10519000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1051A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1051B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1051C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1051D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1051E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1051F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10520000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10521000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10522000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10523000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10524000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10525000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10526000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10527000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10528000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10529000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1052A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1052B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1052C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1052D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1052E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1052F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10530000F05D400B00000000FFFFFFFFFFFFFFFF0D
+:10531000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10532000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10533000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10534000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10535000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10536000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10537000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10538000B35E400B00000000FFFFFFFFFFFFFFFFC9
+:10539000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1053A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1053B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1053C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1053D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10540000C826400B00000000FFFFFFFFFFFFFFFF6B
+:10541000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10542000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10543000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10544000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10545000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10546000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10547000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10548000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10549000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1054A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1054B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1054C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1054D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1054E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1054F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10550000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10551000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10552000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10553000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10554000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10555000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10556000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10557000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10558000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10559000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1055A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1055B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1055C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1055D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1055E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1055F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10560000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10561000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10562000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10563000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10564000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10565000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10566000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10567000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10568000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10569000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1056A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1056B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1056C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1056D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1056E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1056F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10570000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10571000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10572000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10573000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10574000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10575000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10576000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10577000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10578000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10579000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1057A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1057B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1057C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1057D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1057E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1057F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10580000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10581000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10582000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10583000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10584000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10585000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10586000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10587000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10588000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10589000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1058A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1058B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1058C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1058D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1058E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1058F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10590000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10591000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10592000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10593000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10594000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10595000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10596000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10597000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10598000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10599000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1059A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1059B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1059C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1059D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1059E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1059F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:105A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:105A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:105A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:105A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:105A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:105A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:105A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:105A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:105A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:105A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:105AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:105AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:105AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:105AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:105AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:105AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:105B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:105B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:105B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:105B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:105B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:105B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:105B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:105B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:105B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:105B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:105BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:105BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:105BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:105BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:105BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:105BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:105C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:105C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:105C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:105C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:105C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:105C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:105C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:105C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:105C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:105C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:105CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:105CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:105CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:105CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:105CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:105CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:105D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:105D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:105D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:105D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:105D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:105D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:105D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:105D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:105D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:105D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:105DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:105DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:105DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:105DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:105DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:105DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:105E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:105E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:105E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:105E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:105E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:105E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:105E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:105E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:105E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:105E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:105EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:105EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:105EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:105ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:105EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:105EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:105F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:105F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:105F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:105F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:105F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:105F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:105F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:105F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:105F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:105F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:105FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:105FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:105FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:105FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:105FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:105FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10600000009D1A3C90645A270800400300000000DD
+:10601000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10602000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10603000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10604000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10605000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10606000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10607000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10608000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10609000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1060A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1060B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1060C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1060D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1060E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1060F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10610000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10611000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10612000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10613000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10614000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10615000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10616000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10617000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10618000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10619000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1061A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1061B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1061C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1061D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1061E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10620000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10621000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10622000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10624000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10625000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10626000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10627000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10628000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10629000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1062A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1062B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1062C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1062D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1062E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1062F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10630000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10631000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10632000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10633000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10634000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10635000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10636000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10637000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10638000029D1A3CA8B65A270800400300000000EE
+:10639000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1063A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1063B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1063C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10644000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10645000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10646000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10647000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10648000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1064900000601A40C0045A7F05004013000000004D
+:1064A000029D1A3CC0B65A270800400300000000B5
+:1064B00001A01D3C0080BD2701A01C3CF0809C2752
+:1064C0000260094020582001801E2A7D8449497DB0
+:1064D0000260894000E0DC4102608B40029D083C84
+:1064E000B0B6082509F800010000000000A0083C33
+:1064F0002001082500A0093C84122925060000106F
+:1065000000000000000000AD040000AD080000AD78
+:106510000C0000AD100008252B080901F9FF20141C
+:1065200000000000029D083C801A082500A0093CDC
+:106530000000292500A00A3C20014A250500001082
+:106540000000000000000B8D00002BAD04000825AA
+:10655000040029252B082A01FAFF2014000000005E
+:106560000000093C000029251D002011000000004A
+:10657000029D083CA01B082500A0093C00202925FD
+:1065800000A00A3C00204A2500000B8D00002BAD26
+:1065900004000825040029252B082A01FAFF2014ED
+:1065A000000000000000093C0020292588BF0A3CAB
+:1065B00010204A25000049AD0100093C0080292532
+:1065C00088BF0A3C20204A25000049AD0100093C53
+:1065D0000080292588BF0A3C30204A25000049ADAB
+:1065E00000488040FFFF0A2400588A40009D093C73
+:1065F00000502925017889400000093C0100292527
+:1066000000000A2444492A7D01608A408000093C38
+:1066100000688940008008408005097D404C0900E1
+:10662000006008405800013C244001012540280139
+:1066300000608840029D083CB8B6082509F80001B2
+:106640000000000000600840BFFF013CFFFF213454
+:106650002440010100608840000084300000A53023
+:10666000009D083C006A08250800000100000000A9
+:10667000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10668000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10669000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1066A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1066B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1066C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1066D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1066E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1066F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10670000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10671000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10672000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10673000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10674000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10675000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10676000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10677000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10678000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10679000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1067A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1067B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1067C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1067D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1067E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1067F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10680000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10681000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10682000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10683000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10684000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10685000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10686000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10687000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10688000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10689000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1068A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1068B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1068C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1068D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1068E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10697000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:106A0000861A400F000000009F6B400F000000003E
+:106A1000FFFF001000000000E0FFBD271C00BFAF1B
+:106A20001800BEAF21F0A003AD1C400F0000000015
+:106A3000B169400F0000000088BF023C5060428CEA
+:106A4000C000427C0300401400000000FAFF001068
+:106A500000000000131E400F000000001000C2AF35
+:106A60001000C28F1400C2AF010002241400C38FB3
+:106A700018006210000000001400C38F020062289A
+:106A800006004010000000001400C28F0D004010EE
+:106A900000000000E8FF00100000000002000224D7
+:106AA0001400C38F100062100000000003000224D5
+:106AB0001400C38F1400621000000000DEFF0010FD
+:106AC00000000000C61A400F00000000DAFF0010AE
+:106AD00000000000010004244B23400F00000000D0
+:106AE000D5FF0010000000005480838302000224C0
+:106AF000D1FF621400000000A261400F00000000FE
+:106B0000CDFF001000000000D024400F0000000066
+:106B1000C9FF001000000000D0FFBD272C00BFAF50
+:106B20002800BEAF21F0A003448180A3851D400F43
+:106B300000000000010140100000000021200000C2
+:106B40003564400F00000000212000000A000524E9
+:106B5000029D023C30024624213800001965400F96
+:106B60000000000088BF023C5060428CC000427CA4
+:106B70000300401400000000FAFF001000000000B5
+:106B8000575A400F00000000190040140000000098
+:106B90000200042421280000029D023C44024624F5
+:106BA000213800001965400F000000000400042493
+:106BB00021280000029D023C580246242138000092
+:106BC0001965400F00000000FA000424775C400FB4
+:106BD0000000000088BF023C9061428C4002427C71
+:106BE000E7FF401400000000D40000100000000087
+:106BF000020004249A64400F0000000004000424F2
+:106C00009A64400F00000000F61E400F00000000D4
+:106C100088BF023C5060428CC000427C030040149C
+:106C200000000000FAFF00100000000088BF023CD6
+:106C30009061428C4002427C03004014000000003E
+:106C4000BE000010000000006480838F0300022457
+:106C500007006210000000006480838F010002249E
+:106C600003006210000000007F0000100000000020
+:106C7000D024400F0000000003004014000000007A
+:106C8000AE0000100000000003000224508082AF1C
+:106C9000212000003564400F000000008362400F97
+:106CA00000000000C728400F00000000010004247D
+:106CB0009B24400F0000000088BF023C9061428C82
+:106CC0004002427C2100401400000000D51B400F10
+:106CD0000000000088BF023C9061428C4002427C70
+:106CE0000300401400000000FAFF00100000000044
+:106CF000CC81838FF081828F0E0062100000000033
+:106D00003C80838301000224F9FF6214000000002C
+:106D1000F081828F01004324CC81828FF4FF6214C2
+:106D200000000000CC81828FF08182AFF0FF001064
+:106D3000000000009080848F9480858F21300000B7
+:106D4000213800009F1E400F00000000B462400F79
+:106D500000000000EF20400F0000000000A0023CF7
+:106D60008804422401004390280002240300621496
+:106D700000000000F7FF0010000000005221400F4B
+:106D8000000000005481838399818683648182831B
+:106D90001000A2AF4081828F1400A2AF7C81828359
+:106DA0001800A2AF9C81828F1C00A2AF5581828304
+:106DB0002000A2AF3C81828F2400A2AF212060007E
+:106DC0002C81858F1881878F8D2D400F000000004A
+:106DD0006822400F000000005480838302000224D8
+:106DE0000300621400000000115F400F000000006B
+:106DF00088BF023C5061428C4001427C0600401436
+:106E00000000000001000224448182A36881828F77
+:106E10000A004224688182AF88BF023C5061428CE4
+:106E20000001427C06004014000000000100022422
+:106E3000448182A36881828FF6FF4224688182AFF9
+:106E40003C808283010042382B1802004080828FF0
+:106E50002B100200251062002200401000000000EC
+:106E600095FF001000000000212000003564400F55
+:106E7000000000000200042421280000029D023CC2
+:106E800068024624213800001965400F0000000008
+:106E90000300042421280000029D023C7C024624B9
+:106EA000213800001965400F000000000400042490
+:106EB00021280000029D023C8C024624213800005B
+:106EC0001965400F0000000088BF023C9061428CB1
+:106ED0004002427C0300401000000000FAFF001056
+:106EE0000000000021200000B060400F0000000002
+:106EF000212000009B24400F000000003081828F81
+:106F00005C8182AF5C81848F4F3F400F00000000A6
+:106F1000AD1C400F00000000F266400F00000000B2
+:106F200088BF023C9061428C4002427C03004010CA
+:106F300000000000FAFF00100000000021E8C0037C
+:106F40002C00BF8F2800BE8F3000BD270800E00353
+:106F500000000000E8FFBD271400BFAF1000BEAF67
+:106F600021F0A00388BF023C9061428C4002427C29
+:106F70000300401400000000FAFF001000000000B1
+:106F8000040004249A64400F00000000050004245B
+:106F90009A64400F00000000060004249A64400F29
+:106FA000000000000500042421280000029D023C8E
+:106FB000A4024624213800001965400F000000009B
+:106FC00001000224A08182A32881848F6081858FA3
+:106FD0008081868F213800009F1E400F0000000036
+:106FE0000500042421280000029D023C580246248A
+:106FF000213800001965400F000000001A64400F9E
+:10700000000000006D63400F00000000F401042444
+:10701000775C400F0000000088BF023C9061428C0A
+:107020004002427C0300401000000000F3FF00100B
+:1070300000000000A08180A3050004249A64400F92
+:107040000000000001000424B060400F00000000B8
+:107050008F30400F0000000021E8C0031400BF8FF4
+:107060001000BE8F1800BD270800E00300000000DC
+:10707000E0FFBD271C00BFAF1800BEAF21F0A0038A
+:107080002000C4AF020004249A64400F00000000F6
+:10709000030004249A64400F00000000040004244C
+:1070A0009A64400F00000000050004249A64400F19
+:1070B00000000000060004249A64400F0000000055
+:1070C000070004249A64400F000000002000C28FD3
+:1070D0001000C2AF1000C38F070060100000000056
+:1070E000010002241000C38F220062100000000083
+:1070F0003F000010000000000300042421280000CD
+:10710000029D023CAC024624213800001965400F64
+:107110000000000054808383020002240B006214EC
+:107120000000000021200000B060400F00000000BF
+:107130000400042421280000029D023CB8024624D9
+:10714000213800001965400F000000002881848F5D
+:107150006081858F8081868F213800009F1E400FBF
+:1071600000000000010002243C8082A327000010E0
+:10717000000000000300042421280000029D023CBE
+:10718000C8024624213800001965400F00000000A5
+:1071900054808383020002240B006214000000006C
+:1071A00021200000B060400F000000000400042413
+:1071B00021280000029D023CB8024624213800002C
+:1071C0001965400F000000002881848F6081858F41
+:1071D0008081868F213800009F1E400F0000000034
+:1071E000010002243C8082A308000010000000007F
+:1071F0000300042421280000029D023CDC024624F6
+:10720000213800001965400F00000000050004242B
+:1072100021280000029D023CEC0246242138000097
+:107220001965400F0000000096000424775C400FB1
+:10723000000000000500042421280000029D023CFB
+:10724000FC024624213800001965400F00000000B0
+:1072500096000424775C400F0000000088BF023CC9
+:107260009061428C4002427C03004010000000000C
+:10727000E6FF00100000000088BF023C9061428CD5
+:107280004002427C0300401400000000FAFF00109E
+:1072900000000000297E400F0000000021E8C0032C
+:1072A0001C00BF8F1800BE8F2000BD270800E00320
+:1072B00000000000E8FFBD271400BFAF1000BEAF04
+:1072C00021F0A00381BF033C609062902000423413
+:1072D000609062A088BF043C40608390DFFF02247E
+:1072E00024106200406082A088BF043C006183904B
+:1072F000BFFF022424106200006182A088BF033C0B
+:10730000006162907F004230006162A081BF043C56
+:1073100061908390F7FF022424106200619082A0A4
+:1073200088BF033C4160629008004234416062A023
+:1073300081BF043C61908390EFFF0224241062001F
+:10734000619082A088BF033C41606290100042348B
+:10735000416062A081BF033C6090629001004234B2
+:10736000609062A088BF033C40606290010042349C
+:10737000406062A081BF033C609062900400423490
+:10738000609062A081BF033C60906290080042342C
+:10739000609062A081BF033C609062901000423414
+:1073A000609062A081BF043C6190839080FF0224C2
+:1073B00025106200619082A088BF033C406062900B
+:1073C00004004234406062A088BF033C4060629089
+:1073D00008004234406062A088BF033C4060629075
+:1073E00010004234406062A088BF043C416083903A
+:1073F00080FF022425106200416082A088BF033C08
+:107400004061629010004234406162A088BF033C3A
+:107410004061629020004234406162A088BF033C1A
+:107420008161629002004234816162A088BF033CA6
+:10743000E061629010004234E06162A088BF033CCA
+:10744000E061629020004234E06162A088BF033CAA
+:10745000E061629040004234E06162A088BF033C7A
+:10746000E161629010004234E16162A088BF033C98
+:10747000E261629002004234E26162A088BF033C94
+:10748000E261629004004234E26162A088BF033C82
+:10749000E161629008004234E16162A088BF033C70
+:1074A000C060629010004234C06062A088BF033C9C
+:1074B0008160629020004234816062A088BF033CFA
+:1074C0008160629040004234816062A088BF033CCA
+:1074D000E161629020004234E16162A088BF033C18
+:1074E000E061629002004234E06162A088BF033C28
+:1074F000E061629001004234E06162A081BF023C21
+:10750000009040AC81BF023C109040AC81BF033C76
+:10751000021F0224209062AC81BF023C509040AC1C
+:1075200081BF043C0190839080FF022425106200FB
+:10753000019082A088BF043C40618390FEFF02243A
+:1075400024106200406182A088BF043C5061839097
+:10755000FEFF022424106200506182A088BF043C18
+:1075600000618390DFFF022424106200006182A08A
+:1075700088BF043C10618390DFFF02242410620066
+:10758000106182A088BF043CC1608390F7FF022491
+:1075900024106200C16082A088BF043CD160839047
+:1075A000F7FF022424106200D16082A080BF023C59
+:1075B000007040ACC728400F000000000261400F7F
+:1075C000000000002069400F00000000157E400F01
+:1075D00000000000448180A3688180AF029D023CCE
+:1075E0000003428C288182AF029D023C0403428C3E
+:1075F000608182AF21100000808182AF21E8C0034A
+:107600001400BF8F1000BE8F1800BD270800E003D4
+:1076100000000000D8FFBD272400BFAF2000BEAF90
+:1076200021F0A0031000C0AF1400C0A31000C28F4F
+:107630001F004014000000000C0004248660400F6E
+:1076400000000000448082AF4C80838F4480828F92
+:10765000211062004C8082AF4880828F010042245A
+:10766000488082AF4880828F04004228EFFF401498
+:10767000000000004C80828F1800C2AF1800C28F3B
+:1076800004004104000000001800C38F03006324BD
+:107690001800C3AF1800C38F831003001000C2AFDF
+:1076A000488080AF4C8080AFE0FF001000000000F9
+:1076B0001000C28F0E004004000000001000C28FB6
+:1076C000C90042280A004010000000000100022406
+:1076D0001400C2A30100042414000524029D023CEE
+:1076E00008034624213800001965400F00000000FF
+:1076F0001000C28FC80042280E0040140000000095
+:107700001000C28F910142280A00401000000000C2
+:10771000020002241400C2A3010004241400052462
+:10772000029D023C14034624213800001965400FD5
+:10773000000000001000C28F900142280E0040148B
+:10774000000000001000C28F590242280A004010B9
+:1077500000000000030002241400C2A3010004245E
+:1077600014000524029D023C240346242138000015
+:107770001965400F000000001000C28F5802422817
+:107780000E004014000000001000C28F21034228A8
+:107790000A00401000000000040002241400C2A3EC
+:1077A0000100042414000524029D023C34034624F5
+:1077B000213800001965400F000000001000C28F42
+:1077C000200342280E004014000000001000C28F69
+:1077D000E90342280A0040100000000005000224CE
+:1077E0001400C2A30100042414000524029D023CDD
+:1077F00048034624213800001965400F00000000AE
+:107800001000C28FFC034228090040140000000051
+:107810001400C0A30100042414000524029D023CAE
+:1078200058034624213800001965400F000000006D
+:107830001400C28321E8C0032400BF8F2000BE8F44
+:107840002800BD270800E00300000000E0FFBD277E
+:107850001C00BFAF1800BEAF21F0A0031000C0AFE6
+:10786000851D400F00000000548082A3DE65400F9C
+:1078700000000000271E400F000000001000C2AFF3
+:107880001000C28F21E8C0031C00BF8F1800BE8FFC
+:107890002000BD270800E00300000000E0FFBD2736
+:1078A0001C00BFAF1800BEAF21F0A0031000C0AF96
+:1078B00088BF023C5060428CC000437C010002241F
+:1078C0006700621400000000050004240F62400FEE
+:1078D0000000000088BF023C5060428C0001427CE6
+:1078E0001300401400000000050004240F62400F44
+:1078F0000000000088BF023C5060428C0001427CC6
+:107900000300401400000000FAFF00100000000017
+:107910001000C28F010042241000C2AF1000C28FBD
+:107920000400422802004014000000001000C0AF14
+:1079300088BF023C5060428CC003427C130040145C
+:1079400000000000050004240F62400F000000004A
+:1079500088BF023C5060428CC003427C030040144C
+:1079600000000000FAFF0010000000001000C28FAD
+:10797000FFFF42241000C2AF1000C28F0300410479
+:1079800000000000030002241000C2AF1000C28FEC
+:107990001400C2AF010002241400C38F1B00621048
+:1079A000000000001400C38F02006228060040108F
+:1079B000000000001400C28F0D0040100000000005
+:1079C000BBFF001000000000020002241400C38F5F
+:1079D0001500621000000000030002241400C38F91
+:1079E0001800621000000000B1FF0010000000004D
+:1079F0000200042421280000010006241467400F1F
+:107A000000000000AAFF0010000000000300042492
+:107A100021280000010006241467400F0000000028
+:107A2000A3FF00100000000004000424212800002F
+:107A3000010006241467400F000000009CFF0010A6
+:107A40000000000005000424212800000100062495
+:107A50001467400F0000000095FF001000000000B8
+:107A60001000C28F21E8C0031C00BF8F1800BE8F1A
+:107A70002000BD270800E00300000000D0FFBD2764
+:107A80002C00BFAF2800BEAF21F0A0033000C4AF70
+:107A90003400C5AF3800C6AF2110E0003C00C2A3DF
+:107AA00088BF033C0100023C641062AC88BF033C09
+:107AB0000100023C681062AC01000224608082AFC9
+:107AC00047000224548182A32C8180AF58000224F5
+:107AD000998182A33000C28F188182AF590002249D
+:107AE000648182A33400C28F408182AF3C00C28394
+:107AF00007004010000000005A0002247C8182A38D
+:107B00003800C28F9C8182AF04000010000000008A
+:107B10007C8180A3211000009C8182AF460002245A
+:107B2000558182A3211000003C8182AF5481838360
+:107B300099818683648182831000A2AF4081828F05
+:107B40001400A2AF7C8182831800A2AF9C81828F37
+:107B50001C00A2AF558182832000A2AF3C81828F9E
+:107B60002400A2AF212060002C81858F1881878F8F
+:107B70008D2D400F00000000548180A32C8180AF28
+:107B8000998180A321100000188182AF648180A3B5
+:107B900021100000408182AF7C8180A32110000071
+:107BA0009C8182AF558180A3211000003C8182AF6F
+:107BB000608080AFFA000424775C400F0000000072
+:107BC00021E8C0032C00BF8F2800BE8F3000BD27E6
+:107BD0000800E00300000000E8FFBD271400BFAF6D
+:107BE0001000BEAF21F0A0033C808383010002247B
+:107BF00006006214000000003C8080A3308180AF4A
+:107C0000408080AF308080AF348080AFEA31400F59
+:107C1000000000000300401400000000FBFF001003
+:107C200000000000501F400F0000000088BF023C11
+:107C30009061428C4002427C03004014000000002E
+:107C400039000010000000009220400F00000000EA
+:107C5000648082AF00A0023CBC044424029D023C2C
+:107C6000640345242042400F000000005C8182AF85
+:107C70005C81828F308182AF5C81828F00004238CC
+:107C80000100422C2510420020004010000000009E
+:107C90000200042421280000029D023C68034624BF
+:107CA000213800001965400F000000000300042483
+:107CB00028000524029D023C780346242138000058
+:107CC0001965400F00000000040004242128000072
+:107CD000029D023C58024624213800001965400FDD
+:107CE00000000000FA000424775C400F0000000050
+:107CF00088BF023C9061428C4002427CE4FF401409
+:107D00000000000008000010000000000200042431
+:107D10005A000524029D023C8803462421380000B5
+:107D20001965400F0000000021E8C0031400BF8F58
+:107D30001000BE8F1800BD270800E00300000000FF
+:107D400080FFBD277C00BFAF7800BEAF21F0A0034D
+:107D5000200002244800C2A3029D023C9003428CF2
+:107D60005000C2AF010002245800C2AF5C00C0AF97
+:107D70006000C0AF5000C2274800C39321204000DC
+:107D8000212860001000C6275A58400F000000004C
+:107D90005800C2AF5800C28F3700401400000000E6
+:107DA000010002246C8082AF1000C4276959400F83
+:107DB000000000005800C2AF5800C28F04004014F9
+:107DC000000000006C80828F010042246C8082AF32
+:107DD0005800C28F0300401400000000F2FF0010A2
+:107DE000000000006000C28F23004014000000006B
+:107DF0005000C2274800C393212040002128600082
+:107E00001000C6275A58400F000000005800C2AFAB
+:107E100001000224688082AF010002245C00C2AF2E
+:107E20005C00C28F6C80838F2A1043000A004010D0
+:107E3000000000001000C4276959400F0000000036
+:107E40005800C2AF5C00C28F010042245C00C2AF88
+:107E5000F3FF0010000000006C80828F688082AF0A
+:107E600002000424212800001000C6272138000049
+:107E70001965400F000000005800C28F220040101A
+:107E8000000000006C8080AF688080AF0200042496
+:107E900021280000029D023C940346242138000062
+:107EA0001965400F00000000030004242128000091
+:107EB000029D023CA8034624213800001965400FAA
+:107EC000000000000500042421280000029D023C5F
+:107ED00058024624213800001965400F00000000B8
+:107EE000FA000424775C400F0000000088BF023CC9
+:107EF0009061428C4002427CE4FF4014000000008C
+:107F0000CB000010000000005800C28FA5004014F4
+:107F10000000000088BF023C5060428C0001427C9F
+:107F2000330040140000000088BF023C5060428CC7
+:107F30000001427C0300401400000000FAFF001022
+:107F4000000000001E000424775C400F00000000C9
+:107F50001000C4276959400F000000005800C2AF4C
+:107F60005800C28F0F004014000000006880828F0C
+:107F70006C80838F2A106200050040100000000012
+:107F80006C80828F688082AF1000001000000000BB
+:107F90006880828F01004224688082AF0B0000104D
+:107FA000000000005000C2274800C3932120400079
+:107FB000212860001000C6275A58400F000000001A
+:107FC0005800C2AF01000224688082AF020004247E
+:107FD0009A64400F000000000200042421280000E1
+:107FE0001000C627213800001965400F000000006E
+:107FF00088BF023C5060428CC003427C3F0040146A
+:108000000000000088BF023C5060428CC003427CEC
+:108010000300401400000000FAFF00100000000000
+:108020001E000424775C400F000000001000C427ED
+:108030006959400F000000005800C2AF5800C28FBD
+:108040000300401400000000F8FF001000000000D2
+:108050005000C2274800C39321204000212860001F
+:108060001000C6275A58400F000000005800C2AF49
+:108070006880828FFFFF4224688082AF6880828F91
+:1080800005004014000000006C80828F688082AF81
+:10809000010002246000C2AF010002245C00C2AFF4
+:1080A0005C00C28F6880838F2A1043000A00401052
+:1080B000000000001000C4276959400F00000000B4
+:1080C0005800C2AF5C00C28F010042245C00C2AF06
+:1080D000F3FF001000000000020004249A64400F27
+:1080E0000000000002000424212800001000C62720
+:1080F000213800001965400F00000000060004242C
+:1081000021280000029D023CBC03462421380000C7
+:108110001965400F000000006800C22721204000C0
+:10812000029D023CC40345246880868F666D400F23
+:10813000000000006800C22706000424190005247E
+:1081400021304000213800001965400F0000000078
+:108150000600042441000524029D023CC803462475
+:10816000213800001965400F000000006800C22798
+:1081700021204000029D023CC40345246C80868F70
+:10818000666D400F000000006800C227060004244E
+:108190005A00052421304000213800001965400FA5
+:1081A0000000000088BF023C9061428C4002427C8B
+:1081B00003004014000000001D000010000000003B
+:1081C00088BF023C5060428CC000427C01004238B3
+:1081D0000100432C5800C28F000042380100422C9D
+:1081E00024106200030040100000000046FF001051
+:1081F0000000000088BF023C5060428CC000437CFD
+:10820000010002240300621400000000D9FE0010E7
+:108210000000000000A0023CBC0444241000C5275C
+:10822000516A400F000000002000C28F488182AFD9
+:1082300021E8C0037C00BF8F7800BE8F8000BD277F
+:108240000800E00300000000F0FFBD270800BEAFFB
+:1082500021F0A003080002240100C2A30100C29380
+:10826000500040100000000000A0023C0100C39339
+:10827000BC04422421106200000043802E0002242E
+:10828000430062140000000000A0023C0100C39300
+:10829000BC044224211062000100428047004238A1
+:1082A0000100442C00A0023C0100C393BC04422402
+:1082B0002110620002004280430042380100422C3B
+:1082C0002420820000A0023C0100C393BC0442248D
+:1082D00021106200030042804F0042380100422C0E
+:1082E000241082000700401000000000010002245A
+:1082F0000000C2A3010002240400C2AF2900001044
+:108300000000000000A0023C0100C393BC04422412
+:108310002110620001004280420042380100442CDA
+:1083200000A0023C0100C393BC044224211062005F
+:1083300002004280460042380100422C2420820084
+:1083400000A0023C0100C393BC044224211062003F
+:1083500003004280420042380100422C2410820077
+:108360000700401000000000030002240000C2A328
+:10837000030002240400C2AF0A0000100000000045
+:108380000000C0A30400C0AF060000100000000001
+:108390000100C293FFFF42240100C2A3AFFF0010FF
+:1083A000000000000400C28F21E8C0030800BE8F57
+:1083B0001000BD270800E00300000000D0FFBD272B
+:1083C0002C00BFAF2800BEAF21F0A00301000224A3
+:1083D0002000C2AF2400C0AF3C8080A33081828FD8
+:1083E0005C8182AF3480828F01004224348082AF6E
+:1083F00000A0033C3E000224880462A05C81848FBC
+:108400003080858F21300000464A400F0000000078
+:108410000600401000000000010004241C1C400F56
+:1084200000000000010002243C8082A33C80828383
+:108430003F004014000000009881842701000524BB
+:10844000010006245C81878F7E47400F00000000FA
+:10845000408082AF00A0023C2000C38F88044224E9
+:108460002118620098818293000062A02000C28FD0
+:10847000010042242000C2AF988183832800022497
+:108480001500621400000000988184270100052473
+:10849000010006245C81878F7E47400F00000000AA
+:1084A000408082AF5C81848F6E47400F00000000E7
+:1084B0000300401000000000070000100000000052
+:1084C000988183830A0002240300621000000000E8
+:1084D000EDFF0010000000005C81848F6E47400FAC
+:1084E0000000000008004010000000005C81848F44
+:1084F0004F3F400F00000000010002243C8082A397
+:108500000700001000000000988183830A00022405
+:108510000300621000000000C7FF00100000000010
+:108520005C81848FCC43400F00000000308082AF1C
+:1085300021E8C0032C00BF8F2800BE8F3000BD276C
+:108540000800E00300000000E0FFBD271C00BFAFF3
+:108550001800BEAF21F0A003010002241000C2AF3A
+:108560001400C0AF01000224388082AF00A0023C9A
+:1085700088044224010043900D0002240300621489
+:1085800000000000DC000010000000003880838F35
+:108590000100022427006214000000001400C28FB2
+:1085A0000A0040140000000000A0023C1000C38F2D
+:1085B000880442242110620000004290548182A36A
+:1085C0001000C28F010042241000C2AF1400C38FFC
+:1085D000348182272120620000A0023C1000C38F5A
+:1085E000880442242110620000004290000082A012
+:1085F0001400C28F010042241400C2AF00A0023C4C
+:108600001000C38F880442242110620000004390B0
+:108610002000022407006214000000001000C28F36
+:10862000010042241000C2AF1400C0AF02000224B7
+:10863000388082AF3880838F0200022427006214C2
+:10864000000000001400C28F0A0040140000000067
+:1086500000A0023C1000C38F880442242110620055
+:1086600000004290998182A31000C28F0100422431
+:108670001000C2AF1400C38FA481822721206200A2
+:1086800000A0023C1000C38F880442242110620025
+:1086900000004290000082A01400C28F010042241A
+:1086A0001400C2AF00A0023C1000C38F8804422413
+:1086B0002110620000004390200002240700621491
+:1086C000000000001000C28F010042241000C2AF61
+:1086D0001400C0AF03000224388082AF3880838F3B
+:1086E0000300022427006214000000001400C28F5F
+:1086F0000A0040140000000000A0023C1000C38FDC
+:10870000880442242110620000004290648182A308
+:108710001000C28F010042241000C2AF1400C38FAA
+:10872000748182272120620000A0023C1000C38FC8
+:10873000880442242110620000004290000082A0C0
+:108740001400C28F010042241400C2AF00A0023CFA
+:108750001000C38F8804422421106200000043905F
+:108760002000022407006214000000001000C28FE5
+:10877000010042241000C2AF1400C0AF0400022464
+:10878000388082AF3880838F04000224270062146F
+:10879000000000001400C28F0A0040140000000016
+:1087A00000A0023C1000C38F880442242110620004
+:1087B000000042907C8182A31000C28F01004224FD
+:1087C0001000C2AF1400C38F908182272120620065
+:1087D00000A0023C1000C38F8804422421106200D4
+:1087E00000004290000082A01400C28F01004224C9
+:1087F0001400C2AF00A0023C1000C38F88044224C2
+:10880000211062000000439020000224070062143F
+:10881000000000001000C28F010042241000C2AF0F
+:108820001400C0AF05000224388082AF3880838FE7
+:108830000500022419006214000000001400C28F19
+:108840000A0040140000000000A0023C1000C38F8A
+:10885000880442242110620000004290558182A3C6
+:108860001000C28F010042241000C2AF1400C38F59
+:10887000208182272120620000A0023C1000C38FCB
+:10888000880442242110620000004290000082A06F
+:108890001400C28F010042241400C2AF00A0023CA9
+:1088A0001000C38F8804422421106200000043900E
+:1088B0000A00022403006214000000000E000010F1
+:1088C000000000001000C28F010042241000C2AF5F
+:1088D00000A0023C1000C38F8804422421106200D3
+:1088E000000043900D00022403006210000000000D
+:1088F0001EFF00100000000034818427276C400F09
+:10890000000000002C8182AFA4818427206C400FDE
+:108910000000000021204000212860004879400F1D
+:1089200000000000188182AF74818427206C400F02
+:108930000000000021204000212860004879400FFD
+:1089400000000000408182AF90818427206C400F9E
+:108950000000000021204000212860004879400FDD
+:10896000000000009C8182AF20818427206C400F92
+:108970000000000021204000212860004879400FBD
+:10898000000000003C8182AF21E8C0031C00BF8FC3
+:108990001800BE8F2000BD270800E0030000000083
+:1089A000F0FFBD270800BEAF21F0A0033100022474
+:1089B0000000C2AF0000C28F0B004010000000009A
+:1089C00000A0023C0000C38F8804422421106200F2
+:1089D000000040A00000C28FFFFF42240000C2AF91
+:1089E000F4FF0010000000000000C28F03004014DC
+:1089F0000000000000A0023C880440A0548180A335
+:108A0000070002240000C2AF0000C28F0A0040101D
+:108A1000000000000000C38F348182272110620013
+:108A2000000040A00000C28FFFFF42240000C2AF40
+:108A3000F5FF0010000000000000C28F020040148B
+:108A400000000000348180A3998180A307000224E4
+:108A50000000C2AF0000C28F0A00401000000000FA
+:108A60000000C38FA481822721106200000040A073
+:108A70000000C28FFFFF42240000C2AFF5FF0010CC
+:108A8000000000000000C28F02004014000000003F
+:108A9000A48180A3648180A3070002240000C2AFE8
+:108AA0000000C28F0A004010000000000000C38FC9
+:108AB0007481822721106200000040A00000C28F54
+:108AC000FFFF42240000C2AFF5FF001000000000CD
+:108AD0000000C28F0200401400000000748180A3D7
+:108AE0007C8180A3070002240000C2AF0000C28F77
+:108AF0000A004010000000000000C38F9081822710
+:108B000021106200000040A00000C28FFFFF42243D
+:108B10000000C2AFF5FF0010000000000000C28F8F
+:108B20000200401400000000908180A3558180A3C2
+:108B3000070002240000C2AF0000C28F0A004010EC
+:108B4000000000000000C38F2081822721106200F6
+:108B5000000040A00000C28FFFFF42240000C2AF0F
+:108B6000F5FF0010000000000000C28F020040145A
+:108B700000000000208180A321E8C0030800BE8F10
+:108B80001000BD270800E00300000000E0FFBD2743
+:108B90001C00BFAF1800BEAF21F0A00321100000E1
+:108BA0001000C2AFF081828FCC81838F2A106200C7
+:108BB0000A00401000000000F081838FCC81828F7A
+:108BC0002310620021204000CC7B400F00000000F9
+:108BD0001000C2AF0900001000000000F081838F78
+:108BE000CC81828F231062000002422421204000A9
+:108BF000CC7B400F000000001000C2AF029D023C81
+:108C00001000C48FCC03458C417B400F0000000056
+:108C10001000C2AF029D023C1000C48FD003458CEF
+:108C2000D37A400F000000001000C2AF1000C48FC4
+:108C3000F67B400F000000000600042421284000BD
+:108C40006564400F0000000021E8C0031C00BF8FD6
+:108C50001800BE8F2000BD270800E00300000000C0
+:108C6000D8FFBD272000BFAF1C00BEAF1800B0AFBB
+:108C700021F0A003211000001000C2AF3080848FCB
+:108C8000CC7B400F00000000218040004881848F91
+:108C9000CC7B400F00000000212000022128400072
+:108CA000417B400F000000001000C2AF029D023C5B
+:108CB0001000C48FD403458CD37A400F000000000D
+:108CC0001000C2AF029D023CD403448C1000C58F3B
+:108CD000317C400F00000000030040040000000051
+:108CE0000400001000000000029D023CD403428CEE
+:108CF0001000C2AF1000C48FF67B400F00000000D0
+:108D000005000424212840006564400F0000000095
+:108D100021E8C0032000BF8F1C00BE8F1800B08F59
+:108D20002800BD270800E00300000000C8FFBD27A1
+:108D30003400BFAF3000BEAF21F0A003211080008F
+:108D40003800C2A3211000002000C2AF2110000093
+:108D50002400C2AF211000002800C2AFCC81838F55
+:108D6000F081828F0300621000000000FBFF001002
+:108D70000000000088BF033C0100023C641062ACAC
+:108D800088BF023C681040AC60EA02348C8182AF3C
+:108D9000A48080A3A58080A3A68080A301000424D2
+:108DA0009B24400F000000001566400F00000000EB
+:108DB00088BF023C5060428CC000427C03004014DB
+:108DC00000000000FAFF00100000000088BF023C15
+:108DD0009061428C4002437C01000224170162141E
+:108DE0000000000001000224A88082AF8C81828FE5
+:108DF000E903422804004014000000008C81828FA7
+:108E0000B5FF42248C8182AF8C81828F650042281D
+:108E100004004014000000008C81828FFBFF42247C
+:108E20008C8182AF8C81828F200342280300401006
+:108E300000000000200302248C8182AF88BF023C26
+:108E40005060428CC000427C0400401400000000CE
+:108E5000088280AF01000224A48082A388BF023C64
+:108E60005060428C8000427C0500401400000000ED
+:108E700001000224088282AF01000224A48082A3A0
+:108E800088BF023C5060428CC000427C070040100A
+:108E90000000000088BF023C5060428C8000427C91
+:108EA0000200401000000000A48080A388BF023CA4
+:108EB0005060428CC003427C04004014000000005B
+:108EC000E88180AF01000224A58082A388BF023C14
+:108ED0005060428C0001427C0500401400000000FC
+:108EE00001000224E88182AF01000224A58082A350
+:108EF00088BF023C5060428CC003427C0700401097
+:108F00000000000088BF023C5060428C0001427C9F
+:108F10000200401000000000A58080A388BF023C32
+:108F20005061428C4001427C04004014000000006B
+:108F3000F48180AF01000224A68082A388BF023C96
+:108F40005061428C0001427C05004014000000008A
+:108F500001000224F48182AF01000224A68082A3D2
+:108F600088BF023C5061428C4001427C07004010A7
+:108F70000000000088BF023C5061428C0001427C2E
+:108F80000200401000000000A68080A3A48082831D
+:108F90000900401400000000A580828306004014F0
+:108FA00000000000A680828303004014000000003F
+:108FB00060EA02348C8182AF3800C28383FF4010A4
+:108FC0000000000088BF023CD060428C0001427C5F
+:108FD0000A00401000000000020004244B00052499
+:108FE000029D023CD8034624213800001965400F39
+:108FF000000000000800001000000000020004242F
+:109000004B000524029D023CE00346242138000069
+:109010001965400F0000000088BF023C9060428C40
+:109020004003427C0A0040100000000003000424BA
+:109030004B000524029D023CD80346242138000041
+:109040001965400F0000000008000010000000003B
+:10905000030004244B000524029D023CE003462447
+:10906000213800001965400F0000000088BF023C55
+:109070009060428C8003427C0A0040100000000097
+:10908000040004244B000524029D023CD80346241E
+:10909000213800001965400F000000000800001092
+:1090A00000000000040004244B000524029D023C43
+:1090B000E0034624213800001965400F000000003D
+:1090C000B881848FCC7B400F00000000212040003D
+:1090D0001F79400F00000000029D063C2120400047
+:1090E00021286000F403C78CF003C68CC177400FC1
+:1090F0000000000021204000212860004879400F36
+:10910000000000002000C2AF2000C48F1F79400F74
+:109110000000000021304000213860001000C4270A
+:10912000029D023CE8034524666D400F00000000EC
+:1091300005000424400005241000C6272138000043
+:109140001965400F00000000EC81848FCC7B400F3C
+:1091500000000000212040001F79400F00000000A7
+:10916000029D063C2120400021286000F403C78CAA
+:10917000F003C68CC177400F0000000021204000A2
+:10918000212860004879400F000000002400C2AF91
+:109190002400C48F1F79400F0000000021304000E0
+:1091A000213860001000C427029D023CE8034524DA
+:1091B000666D400F000000000600042440000524F6
+:1091C0001000C627213800001965400F000000007C
+:1091D000C081848FCC7B400F00000000029D033CC7
+:1091E00021204000F803658C417B400F0000000007
+:1091F0002800C2AF2800C48F1F79400F0000000074
+:1092000021304000213860001000C427029D023C3C
+:10921000E8034524666D400F0000000007000424A9
+:10922000400005241000C627213800001965400FB2
+:1092300000000000E5FE001000000000A88080AFE4
+:1092400088BF023C0100033C641043AC88BF023C71
+:10925000681040AC21E8C0033400BF8F3000BE8FDF
+:109260003800BD270800E00300000000F8FFBD271C
+:109270000000BEAF21F0A0030800C4AF0800C38FF8
+:1092800001000224180062140000000088BF043CA2
+:10929000D0608390F7FF022424106200D06082A087
+:1092A00088BF043CD1608390FBFF0224241062003D
+:1092B000D16082A088BF043C51608390DFFF02240C
+:1092C00024106200516082A088BF033C0100023C70
+:1092D000641062AC88BF033C0100023C681062ACC1
+:1092E000120000100000000088BF033CD0606290B4
+:1092F00008004234D06062A088BF033CD160629015
+:1093000004004234D16062A088BF033C5160629087
+:1093100020004234516062A088BF033C0100023C3F
+:10932000641062AC88BF023C681040AC21E8C00306
+:109330000000BE8F0800BD270800E0030000000009
+:10934000E0FFBD271C00BFAF1800BEAF21F0A00397
+:109350008966400F00000000A48080A3A58080A340
+:10936000A68080A3C728400F00000000010004244D
+:109370009B24400F0000000001000224A88082AF5F
+:10938000F40102248C8182AF030004242128000010
+:10939000029D023CFC034624213800001965400F61
+:1093A0000000000001000224F48182AF01000224C9
+:1093B000A68082A31000C0AF1000C38F0300023C40
+:1093C0003F0D42342A104300060040140000000004
+:1093D0001000C28F010042241000C2AFF6FF00103F
+:1093E00000000000A68080A30300042421280000C0
+:1093F000029D023C08044624213800001965400FF4
+:1094000000000000E80302248C8182AF01000224E6
+:10941000E88182AF01000224A58082A31000C0AFC2
+:109420001000C28F5FEA03342A1062000600401465
+:10943000000000001000C28F010042241000C2AFE3
+:10944000F7FF001000000000A58080A303000424A3
+:1094500021280000029D023C14044624213800000B
+:109460001965400F00000000E80302248C8182AFE0
+:1094700088BF023CD060428C0001427C2100401435
+:109480000000000088BF023C9061428C4002427C98
+:109490001C0040100000000001000224088282AF7E
+:1094A00088BF023CD060428C0001427C0A0040141C
+:1094B0000000000088BF023C9061428C4002427C68
+:1094C000050040100000000001000224A48082A3D7
+:1094D000F3FF001000000000A48080A31000C0AFC4
+:1094E0001000C28F204E4228E1FF40100000000013
+:1094F0001000C28F010042241000C2AFF8FF00101C
+:109500000000000001000224A48082A31000C0AF6C
+:109510001000C28F102742280600401000000000F3
+:109520001000C28F010042241000C2AFF8FF0010EB
+:1095300000000000A48080A360EA02348C8182AF26
+:1095400088BF023CD060428C0001427C2600401063
+:109550000000000088BF023C9061428C4002427CC7
+:109560002100401000000000088280AF88BF023C4C
+:10957000D060428C0001427C0A00401000000000D4
+:1095800088BF023C9061428C4002427C0500401042
+:109590000000000001000224A48082A3F3FF001059
+:1095A00000000000A48080A31000C0AF1000C28F94
+:1095B000D007422806004010000000001000C28FB3
+:1095C000010042241000C2AFF8FF001000000000AC
+:1095D000D2D10224B88182AFB881828FBC8182AFA0
+:1095E000D7FF001000000000030004242128000021
+:1095F000029D023C20044624213800001965400FDA
+:1096000000000000E80302248C8182AF88BF023C86
+:109610009060428C4003427C200040140000000017
+:1096200088BF023C9061428C4002427C1B0040108B
+:1096300000000000E88180AF88BF023C9060428C4F
+:109640004003427C0A0040140000000088BF023C36
+:109650009061428C4002427C0500401000000000F6
+:1096600001000224A58082A3F3FF00100000000087
+:10967000A58080A31000C0AF1000C28F204E4228EA
+:10968000E2FF4010000000001000C28F01004224E1
+:109690001000C2AFF8FF001000000000010002241B
+:1096A000A58082A31000C0AF1000C28F10274228EF
+:1096B00006004010000000001000C28F010042248C
+:1096C0001000C2AFF8FF001000000000A58080A3CA
+:1096D00060EA02348C8182AF88BF023C9060428C89
+:1096E0004003427C270040100000000088BF023C7D
+:1096F0009061428C4002427C220040100000000039
+:1097000001000224E88182AF88BF023C9060428C55
+:109710004003427C0A0040100000000088BF023C69
+:109720009061428C4002427C050040100000000025
+:1097300001000224A58082A3F3FF001000000000B6
+:10974000A58080A31000C0AF1000C28FD0074228B0
+:1097500006004010000000001000C28F01004224EB
+:109760001000C2AFF8FF00100000000035220224F4
+:10977000EC8182AFEC81828FD48182AFD6FF001062
+:10978000000000000300042421280000029D023C88
+:109790002C044624213800001965400F0000000009
+:1097A000F40102248C8182AF88BF023C9060428C1D
+:1097B0008003427C200040140000000088BF023C6F
+:1097C0009061428C4002427C1B004010000000006F
+:1097D000F48180AF88BF023C9060428C8003427C61
+:1097E0000A0040140000000088BF023C9061428CD7
+:1097F0004002427C050040100000000001000224ED
+:10980000A68082A3F3FF001000000000A68080A3C2
+:109810001000C0AF1000C28FD0074228E2FF4010F6
+:10982000000000001000C28F010042241000C2AFEF
+:10983000F8FF00100000000001000224A68082A3AF
+:109840001000C0AF1000C28F102742280600401041
+:10985000000000001000C28F010042241000C2AFBF
+:10986000F8FF001000000000A68080A388130224E7
+:109870008C8182AF88BF023C9060428C8003427C26
+:10988000260040100000000088BF023C9061428C1E
+:109890004002427C21004010000000000100022430
+:1098A000F48182AF88BF023C9060428C8003427C8E
+:1098B0000A0040100000000088BF023C9061428C0A
+:1098C0004002427C0500401000000000010002241C
+:1098D000A68082A3F3FF001000000000A68080A3F2
+:1098E0001000C0AF1000C28FD00742280600401001
+:1098F000000000001000C28F010042241000C2AF1F
+:10990000F8FF001000000000C08180AFC081828F8E
+:10991000E08182AFD7FF001000000000A88080AF78
+:1099200088BF033C0100023C641062AC88BF023C6B
+:10993000681040AC88BF023C9061428C4002427C7F
+:109940001700401400000000030004242128000038
+:10995000029D023C38044624213800001965400F5E
+:10996000000000001000C0AF1000C38F1E00023CBA
+:109970007F8442342A104300060040140000000097
+:109980001000C28F010042241000C2AFF6FF001089
+:10999000000000001400C0AF16000010000000001E
+:1099A0000300042421280000029D023C48044624B0
+:1099B000213800001965400F000000001000C0AF02
+:1099C0001000C38F1E00023C7F8442342A104300E3
+:1099D00006004014000000001000C28F0100422465
+:1099E0001000C2AFF6FF00100000000001000224CA
+:1099F0001400C2AF1400C28F21E8C0031C00BF8F47
+:109A00001800BE8F2000BD270800E0030000000002
+:109A1000E8FFBD271400BFAF1000BEAF21F0A003C8
+:109A200001000224C08082AF01000224C48082AF02
+:109A3000C88080AFF40102248C8182AF2881848F9A
+:109A40001F79400F00000000029D063C21204000CD
+:109A5000212860005C04C78C5804C68CF776400F40
+:109A60000000000021204000212860004879400FBC
+:109A700000000000E48182AF6081848F1F79400F75
+:109A800000000000029D063C2120400021286000CB
+:109A90005C04C78C5804C68CF776400F00000000A9
+:109AA00021204000212860004879400F000000007C
+:109AB000D88182AFE481848F032D400F0000000025
+:109AC000B48182AFD881848F032D400F0000000045
+:109AD000048282AF88BF033C0100023C641062AC88
+:109AE00088BF033C0100023C681062ACA52A400F0D
+:109AF00000000000C08080AFC48080AFFA00042462
+:109B0000775C400F0000000021E8C0031400BF8F05
+:109B10001000BE8F1800BD270800E0030000000001
+:109B200000E85D4100681A4000701B40C0FFBD277F
+:109B30003C00BBAF00601B4082D21A003800BBAFB4
+:109B4000847A5B7F44201B7C00609B403400BEAF66
+:109B50003000A4AF2C00A3AF2800A2AF21F0A003D7
+:109B60000400C0A3A880828F98004010000000006D
+:109B7000A080828F0800C2AF010002240800C38FBA
+:109B800026006210000000000800C38F0200622857
+:109B900006004010000000000800C28F09004010BD
+:109BA00000000000820000100000000002000224FB
+:109BB0000800C38F6B006210000000007C000010E2
+:109BC0000000000088BF043CD060828C0882838F34
+:109BD000C439627CD06082AC88BF043CD060828C87
+:109BE000E881838F444A627CD06082AC88BF043CA9
+:109BF0005060828CF481838F444A627C506082ACD6
+:109C000080BF033C05000224200C62AC010002244A
+:109C1000A08082AF6600001000000000A480828354
+:109C2000120040100000000088BF033CD06062902A
+:109C300004004234D06062A00882828F0600401483
+:109C400000000000B881828F01004224B88182AFF9
+:109C50000B00001000000000B881828FFFFF42243B
+:109C6000B88182AF060000100000000088BF043CED
+:109C7000D0608390FBFF022424106200D06082A099
+:109C8000A5808283120040100000000088BF033CC2
+:109C9000D160629001004234D16062A0E881828F7D
+:109CA0000600401400000000EC81828F0100422475
+:109CB000EC8182AF0B00001000000000EC81828F6D
+:109CC000FFFF4224EC8182AF06000010000000007C
+:109CD00088BF043CD1608390FEFF02242410620000
+:109CE000D16082A0A6808283120040100000000094
+:109CF00088BF033C5160629001004234516062A011
+:109D0000F481828F0600401400000000C081828F21
+:109D100001004224C08182AF0B000010000000004F
+:109D2000C081828FFFFF4224C08182AF06000010F5
+:109D30000000000088BF043C51608390FEFF0224B5
+:109D400024106200516082A080BF023C0A000324FC
+:109D5000200C43AC02000224A08082AF140000104B
+:109D60000000000080BF033C8C81828F200C62AC1D
+:109D700088BF043CD0608390FBFF02242410620063
+:109D8000D06082A088BF043CD1608390FEFF022493
+:109D900024106200D16082A088BF043C516083908F
+:109DA000FEFF022424106200516082A0A08080AFD8
+:109DB00080BF023C100C40AC88BF033C0100023C59
+:109DC000341062AC48010010000000009C80828FBB
+:109DD0002400C2AF010002242400C38FA50062103A
+:109DE000000000002400C38F02006228060040101B
+:109DF000000000002400C28F090040100000000095
+:109E00003401001000000000020002242400C38F6F
+:109E10000D016210000000002E0100100000000083
+:109E2000B081828F8C00401400000000CC81838FB1
+:109E3000F081828F880062100000000000A0043CC6
+:109E4000CC81828F80180200C80482242110620015
+:109E50000000428CD08182AF00A0043CCC81828F74
+:109E600080180200C804822421106200000040AC67
+:109E7000CC81828F01004224CC8182AFCC81828F41
+:109E80000C00C2AF0C00C38F1000C3AF1000C28F14
+:109E900004004104000000001000C38FFF01632490
+:109EA0001000C3AF1000C38F431203004012020022
+:109EB0000C00C38F23106200CC8182AF010002240A
+:109EC000B08182AF0008023C0000C2AF0300022450
+:109ED0000400C2A3D081828F0000C38F24104300EE
+:109EE0002A004010000000000400C2931400C2AF1A
+:109EF000050002241400C38F170062100000000048
+:109F00001400C38F06006228070040100000000004
+:109F1000030002241400C38F090062100000000037
+:109F20004200001000000000070002241400C38F4C
+:109F30000F006210000000003C0000100000000054
+:109F400088BF023C5160439002006334516043A0DB
+:109F5000360000100000000088BF023CD160439032
+:109F600002006334D16043A0300000100000000004
+:109F700088BF043CD060839080FF022425106200DB
+:109F8000D06082A029000010000000000400C293ED
+:109F90001800C2AF050002241800C38F1800621019
+:109FA000000000001800C38F060062280700401060
+:109FB00000000000030002241800C38F0900621093
+:109FC000000000001900001000000000070002243B
+:109FD0001800C38F11006210000000001300001071
+:109FE0000000000088BF043C51608390FDFF022404
+:109FF00024106200516082A00C00001000000000DC
+:10A0000088BF043CD1608390FDFF022424106200CD
+:10A01000D16082A0050000100000000088BF023C53
+:10A02000D06043907F006330D06043A00400C293AF
+:10A03000020042240400C2A30000C28F801002006C
+:10A040000000C2AF0000C28F0300401000000000FB
+:10A05000A0FF00100000000080BF023C05000324A8
+:10A06000200C43AC010002249C8082AF99000010B8
+:10A0700000000000B081828F6C00401000000000E2
+:10A080000004023C0000C2AF020002240400C2A38C
+:10A09000D081828F0000C38F241043002D00401018
+:10A0A000000000000400C2931C00C2AF04000224A0
+:10A0B0001C00C38F17006210000000001C00C38F3B
+:10A0C0000500622807004010000000000200022482
+:10A0D0001C00C38F0900621000000000480000103F
+:10A0E00000000000060002241C00C38F1100621053
+:10A0F00000000000420000100000000088BF023C89
+:10A100005160439001006334516043A03C00001053
+:10A110000000000088BF033CD1606290010042341F
+:10A12000D16062A0010002240600C2A33400001026
+:10A130000000000088BF033CD060629004004234FD
+:10A14000D06062A0010002240500C2A32C00001010
+:10A15000000000000400C2932000C2AF04000224EB
+:10A160002000C38F18006210000000002000C38F81
+:10A1700005006228070040100000000002000224D1
+:10A180002000C38F09006210000000001C000010B6
+:10A1900000000000060002242000C38F120062109D
+:10A1A00000000000160000100000000088BF043C02
+:10A1B00051608390FEFF022424106200516082A04F
+:10A1C0000F0000100000000088BF043CD1608390A5
+:10A1D000FEFF022424106200D16082A00600C0A30A
+:10A1E000070000100000000088BF043CD06083908E
+:10A1F000FBFF022424106200D06082A00500C0A3EF
+:10A200000400C293020042240400C2A30000C28FD3
+:10A21000801002000000C2AF0000C28F0300401097
+:10A22000000000009AFF00100000000080BF023C08
+:10A230000A000324200C43AC020002249C8082AF5D
+:10A240002400001000000000B081828F0C0040103C
+:10A2500000000000FFFF02340000C2AFD081838FF6
+:10A260000000C28F241062000C8082AF80BF033CCC
+:10A270000C80828F200C62AC0400001000000000F3
+:10A2800080BF033C88130224200C62AC88BF043CCE
+:10A29000D0608390FBFF022424106200D06082A073
+:10A2A00088BF043CD1608390FEFF0224241062002A
+:10A2B000D16082A088BF043C51608390FEFF0224DD
+:10A2C00024106200516082A09C8080AFB08180AF7A
+:10A2D000D08180AF80BF023C100C40AC88BF033CF3
+:10A2E0000100023C341062AC21E8C0033400BE8F90
+:10A2F0003000A48F2C00A38F2800A28F0060604143
+:10A30000C00000003C00BA8F00709A403800BA8F3D
+:10A310004000BD2700609A4018000042E8FFBD27BA
+:10A320001400BFAF1000BEAF21F0A00380BF033CFC
+:10A3300030800234000662AC81BF043C00F283909E
+:10A34000F7FF02242410620000F282A081BF033CC8
+:10A350006190629001004234619062A088BF043C29
+:10A3600041608390FEFF022424106200416082A0BD
+:10A3700081BF033C6190629002004234619062A010
+:10A3800088BF043C41608390FDFF022424106200DA
+:10A39000416082A081BF033C619062902000423402
+:10A3A000619062A088BF043C41608390DFFF02247B
+:10A3B00024106200416082A088BF033CC0606290AC
+:10A3C00010004234C06062A088BF043CC16083902A
+:10A3D000FEFF022424106200C16082A088BF043CFA
+:10A3E000C1608390FDFF022424106200C16082A03E
+:10A3F00088BF043CC1608390FBFF022424106200EC
+:10A40000C16082A088BF033C81606290200042341A
+:10A41000816062A088BF043CC0608390FBFF02247F
+:10A4200024106200C06082A088BF033CC0606290BC
+:10A430007F004230C06062A088BF043CC06083904F
+:10A44000F7FF022424106200C06082A088BF033C92
+:10A450008160629040004234816062A088BF033C0A
+:10A46000D060629008004234D06062A088BF033C94
+:10A47000D160629004004234D16062A088BF033C86
+:10A480005160629020004234516062A080BF023C63
+:10A49000000C40AC80BF033C10000224080C62ACEE
+:10A4A00080BF023C100C40AC80BF033CF40102248E
+:10A4B000200C62AC88BF033C1C000224D41062ACA8
+:10A4C00088BF033C1C000224D81062AC157E400FEC
+:10A4D0000000000088BF033C0100023C341062AC65
+:10A4E00080BF033C00800234080C62AC88BF033C90
+:10A4F0000100023C641062AC88BF023C681040ACB2
+:10A50000CC8180AFF08180AF708180AF508180AF0F
+:10A5100021E8C0031400BF8F1000BE8F1800BD27B4
+:10A520000800E00300000000E0FFBD271C00BFAFF3
+:10A530001800BEAF21F0A0032000C4AF2400C5AFB7
+:10A540002000C28F1C8182AF2400C28FF88182AFAD
+:10A550002000C38F8888023C89884234180062003A
+:10A56000101000002110430043210200C317030014
+:10A57000231082002000C2AF2000C28F09004010CB
+:10A580000000000006DF03342000C28F1A006200C2
+:10A59000F4014000121000008C8182AF0300001013
+:10A5A00000000000D00702248C8182AF5081828F8E
+:10A5B00005004018000000005081828F748082AF37
+:10A5C0000300001000000000EE020224748082AF3D
+:10A5D0008C81848FEE78400F00000000029D063CC5
+:10A5E00021204000212860006404C78C6004C68CD0
+:10A5F000F776400F00000000212040002128600075
+:10A600008679400F00000000708082AF7D818283D8
+:10A610001A004014000000007081828F050040186D
+:10A62000000000007081828F8C8182AF03000010D7
+:10A6300000000000EE0202248C8182AF4C818283F4
+:10A6400015004014000000001080838F01000224D8
+:10A6500003006214000000002062400F00000000B0
+:10A6600088BF023C1061439001006334106143A035
+:10A67000108080AF08000010000000001080828F62
+:10A6800003004014000000004662400F000000007C
+:10A6900001000224108082AF6080828F120040107F
+:10A6A000000000007081828F070040180000000049
+:10A6B0007081828F8C8182AF7081828F708082AF37
+:10A6C0000500001000000000EE0202248C8182AF21
+:10A6D000EE020224708082AF88BF023C106143907A
+:10A6E00001006334106143A021E8C0031C00BF8F48
+:10A6F0001800BE8F2000BD270800E0030000000006
+:10A70000E8FFBD271400BFAF1000BEAF21F0A003CB
+:10A710001800C4AF2110A0001C00C2A31800C38FF2
+:10A720001400022403006210000000002100001049
+:10A7300000000000029D023C3082848F6804458C3A
+:10A74000D37A400F00000000E48182AF029D023CFA
+:10A750001882848F6804458CD37A400F0000000073
+:10A76000D88182AF029D023C2482848F6804458C8C
+:10A77000D37A400F000000000C8282AFE481848F06
+:10A78000032D400F00000000B48182AFD881848F78
+:10A79000032D400F00000000048282AF0C82848FE2
+:10A7A000032D400F00000000DC8182AF310000105B
+:10A7B000000000003082848F1F79400F00000000ED
+:10A7C000029D063C21204000212860007404C78CB3
+:10A7D0007004C68CF776400F000000002120400076
+:10A7E000212860004879400F00000000E48182AF1A
+:10A7F0001882848F1F79400F00000000029D063CE4
+:10A8000021204000212860007404C78C7004C68C8D
+:10A81000F776400F00000000212040002128600052
+:10A820004879400F00000000D88182AF029D023CB1
+:10A830002482848F7804458CD37A400F0000000076
+:10A840000C8282AFE481848F032D400F0000000052
+:10A85000B48182AFD881848F032D400F00000000A7
+:10A86000048282AF0C82848F032D400F0000000011
+:10A87000DC8182AF21E8C0031400BF8F1000BE8FBF
+:10A880001800BD270800E00300000000D8FFBD2726
+:10A890002400BFAF2000BEAF21F0A003BC81838F96
+:10A8A000B881828F23106200AC8082AFD481838F05
+:10A8B000EC81828F23106200B08082AFE081838FB1
+:10A8C000C081828F23106200B48082AFB88180AFD4
+:10A8D000EC8180AFC08180AFAC80848FEE78400F78
+:10A8E00000000000029D063C21204000212860005D
+:10A8F0008404C78C8004C68CC177400F0000000020
+:10A9000021204000212860004879400F000000000D
+:10A910001000C2AFB080848FEE78400F00000000BE
+:10A92000029D063C21204000212860008404C78C41
+:10A930008004C68CC177400F000000002120400039
+:10A94000212860004879400F000000001400C2AFC9
+:10A95000B480848F6666023C6766423418008200C9
+:10A9600010100000831A0200C317040023106200B5
+:10A9700021204000CC7B400F000000001800C2AF37
+:10A98000029D023C1000C48F8804458C387A400F29
+:10A9900000000000288182AF029D023C1400C48F99
+:10A9A0008C04458C387A400F00000000608182AF33
+:10A9B0001800C48F21280000387A400F00000000E2
+:10A9C000808182AF21E8C0032400BF8F2000BE8FAA
+:10A9D0002800BD270800E00300000000F8FFBD27A5
+:10A9E0000000BEAF21F0A003B881838FBC81828FAD
+:10A9F0000700621000000000BC81838FAC80828F52
+:10AA000023186200B881828F21104300B88182AF81
+:10AA1000EC81838FD481828F0700621000000000D8
+:10AA2000D481838FB080828F23186200EC81828F63
+:10AA300021104300EC8182AFC081838FE081828F3F
+:10AA40000700621000000000E081838FB480828FD5
+:10AA500023186200C081828F21104300C08182AF21
+:10AA6000029D023C9004428C288182AF029D023CF0
+:10AA70009404428C608182AF21100000808182AFFB
+:10AA800021E8C0030000BE8F0800BD270800E003D6
+:10AA900000000000E0FFBD271C00BFAF1800BEAFE4
+:10AAA00021F0A003EC81828F1000A2AFC081828FC1
+:10AAB0001400A2AFB481848F0482858FDC81868FDD
+:10AAC000B881878FBB2A400F00000000A52C400FE3
+:10AAD0000000000021E8C0031C00BF8F1800BE8FDB
+:10AAE0002000BD270800E0030000000098FFBD27FC
+:10AAF0006400BFAF6000BEAF21F0A0036800C4AF28
+:10AB00006C00C5AF7000C6AF7400C7AF1000C0AF17
+:10AB1000010002241400C2AF010002241800C2AFD9
+:10AB2000010002241C00C2AF7400C38F6800C28FF2
+:10AB3000231062002000C2AF7800C38F6C00C28F68
+:10AB4000231062002400C2AF7C00C38F7000C28F4C
+:10AB5000231062002800C2AF2000C38F2000C28FE4
+:10AB6000211062002C00C2AF2400C38F2400C28FCA
+:10AB7000211062003000C2AF2800C38F2800C28FAE
+:10AB8000211062003400C2AF6800C28F3800C2AF2B
+:10AB90006C00C28F3C00C2AF7000C28F4000C2AFD9
+:10ABA0004400C0AF4800C0AF4C00C0AF5000C0AFC1
+:10ABB0005400C0AF5800C0AF5C00C0A3C080828FFB
+:10ABC00003004014000000002000C0AF2C00C0AF04
+:10ABD000C480828F03004014000000002400C0AF36
+:10ABE0003000C0AFC880828F030040140000000016
+:10ABF0002800C0AF3400C0AF2000C28F070040144F
+:10AC0000000000007400C28F6800C2AFB881828F5C
+:10AC1000B48182AF7880828F308282AF2400C28F6D
+:10AC200007004014000000007800C28F6C00C2AF23
+:10AC3000EC81828F048282AF7C80828F188282AF07
+:10AC40002800C28F07004014000000007C00C28F63
+:10AC50007000C2AFC081828FDC8182AF8080828F22
+:10AC6000248282AF2000C28F130041040000000044
+:10AC700088BF033CD06062907F004230D06062A009
+:10AC80007F0003245C00C293241043005C00C2A335
+:10AC9000FFFF02241400C2AF2000C28F2310020065
+:10ACA0002000C2AF2C00C28F231002002C00C2AFC4
+:10ACB0000A0000100000000088BF043CD0608390B0
+:10ACC00080FF022425106200D06082A05C00C39344
+:10ACD00080FF0224251062005C00C2A32400C28F02
+:10ACE000140041040000000088BF043CD160839040
+:10ACF000FDFF022424106200D16082A05C00C39397
+:10AD0000DFFF0224241062005C00C2A3FFFF0224C4
+:10AD10001800C2AF2400C28F231002002400C2AF6B
+:10AD20003000C28F231002003000C2AF08000010B4
+:10AD30000000000088BF033CD160629002004234F2
+:10AD4000D16062A05C00C293200042345C00C2A3C8
+:10AD50002800C28F120041040000000088BF033C9D
+:10AD60005160629002004234516062A05C00C29364
+:10AD7000080042345C00C2A3FFFF02241C00C2AFE3
+:10AD80002800C28F231002002800C2AF3400C28FF7
+:10AD9000231002003400C2AF0A00001000000000BF
+:10ADA00088BF043C51608390FDFF022424106200A0
+:10ADB000516082A05C00C393F7FF0224241062005C
+:10ADC0005C00C2A32000C28F000042380100432C67
+:10ADD0002400C28F000042380100422C241062007F
+:10ADE00006004010000000002800C28F0300401041
+:10ADF000000000007480828F8C8182AF2800C38F96
+:10AE00002000C28F2A106200010044382800C38F3E
+:10AE10002400C28F2A1062000100423824108200F0
+:10AE20000300401000000000010002241000C2AF27
+:10AE30002000C38F2800C28F2A106200010044380E
+:10AE40002000C38F2400C28F2A1062000100423804
+:10AE500024108200030040100000000002000224C1
+:10AE60001000C2AF2400C38F2000C28F2A106200DE
+:10AE7000010044382400C38F2800C28F2A106200CA
+:10AE8000010042382410820003004010000000003E
+:10AE9000030002241000C2AF2000C28F000042381D
+:10AEA0000100432C2400C28F000042380100422CD4
+:10AEB000241862002800C28F000042380100422C92
+:10AEC0002410620002004010000000001000C0AF1B
+:10AED0001000C38F010002244A0062140000000029
+:10AEE0004000C38F1C00C28F211062004000C2AF1F
+:10AEF0004400C38F2C00C28F211062004400C2AFF7
+:10AF00004800C38F3000C28F211062004800C2AFDA
+:10AF10004400C38F2800C28F2A1043000E00401047
+:10AF2000000000003800C38F1400C28F211062009F
+:10AF30003800C2AF4400C38F3400C28F23106200B8
+:10AF40004400C2AF010002245000C2AF5C00C293B3
+:10AF5000400042345C00C2A34800C28F2800C38F67
+:10AF60002A1062000E004010000000003C00C38F59
+:10AF70001800C28F211062003C00C2AF4800C38F8E
+:10AF80003400C28F231062004800C2AF01000224C7
+:10AF90005400C2AF5C00C293100042345C00C2A3F4
+:10AFA0005C00C293040042345C00C2A35C00C39303
+:10AFB0005000C28F202C027C5400C28F2014027CCF
+:10AFC00021206000213040003A2D400F0000000099
+:10AFD0005000C0AF5400C0AF5800C0AF5C00C39376
+:10AFE000ABFF0224241062005C00C2A34000C38FA8
+:10AFF0007C00C28F0300621000000000B8FF001048
+:10B00000000000001000C38F020002244A006214F6
+:10B01000000000003800C38F1400C28F21106200AE
+:10B020003800C2AF4C00C38F3400C28F21106200C1
+:10B030004C00C2AF4800C38F3000C28F21106200A5
+:10B040004800C2AF4C00C38F2000C28F2A104300BB
+:10B050000E004010000000004000C38F1C00C28F93
+:10B06000211062004000C2AF4C00C38F2C00C28F81
+:10B07000231062004C00C2AF010002245800C2AF8E
+:10B080005C00C293040042345C00C2A34800C28F3B
+:10B090002000C38F2A1062000E0040100000000044
+:10B0A0003C00C38F1800C28F211062003C00C2AF69
+:10B0B0004800C38F2C00C28F231062004800C2AF2B
+:10B0C000010002245400C2AF5C00C293100042345D
+:10B0D0005C00C2A35C00C293400042345C00C2A387
+:10B0E0005C00C3935000C28F202C027C5400C28F9E
+:10B0F0002014027C21206000213040003A2D400FB6
+:10B10000000000005000C0AF5400C0AF5800C0AFF6
+:10B110005C00C393ABFF0224241062005C00C2A356
+:10B120003800C38F7400C28F03006210000000005B
+:10B13000B8FF0010000000001000C38F03000224BD
+:10B140004E006214000000003C00C38F7800C28FE4
+:10B150004A006210000000003C00C38F1800C28F3C
+:10B16000211062003C00C2AF4400C38F2C00C28F8C
+:10B17000211062004400C2AF4C00C38F3400C28F64
+:10B18000211062004C00C2AF4400C38F2400C28F64
+:10B190002A1043000E004010000000003800C38F4A
+:10B1A0001400C28F211062003800C2AF4400C38F68
+:10B1B0003000C28F231062004400C2AF010002249D
+:10B1C0005000C2AF5C00C293400042345C00C2A396
+:10B1D0004C00C28F2400C38F2A1062000E00401062
+:10B1E000000000004000C38F1C00C28F21106200CD
+:10B1F0004000C2AF4C00C38F3000C28F23106200EA
+:10B200004C00C2AF010002245800C2AF5C00C293E0
+:10B21000040042345C00C2A35C00C29310004234BC
+:10B220005C00C2A35C00C3935000C28F202C027C40
+:10B230005400C28F2014027C212060002130400085
+:10B240003A2D400F000000005000C0AF5400C0AFC6
+:10B250005800C0AF5C00C393ABFF0224241062000F
+:10B260005C00C2A33C00C38F7800C28F0300621051
+:10B2700000000000B8FF00100000000021E8C0033B
+:10B280006400BF8F6000BE8F6800BD270800E00328
+:10B2900000000000F8FFBD270000BEAF21F0A003B2
+:10B2A000B481828FB88182AF0482828FEC8182AFB9
+:10B2B000DC81828FC08182AF8480828F908082AF58
+:10B2C0008880828F948082AF8C80828F988082AFBA
+:10B2D0007880828F848082AF7C80828F888082AFEA
+:10B2E0008080828F8C8082AF3082828F788082AF24
+:10B2F0001882828F7C8082AF2482828F808082AF8E
+:10B3000021100000008282AF21100000C88182AFAE
+:10B3100021100000C48182AF21100000E48182AFBF
+:10B3200021100000D88182AF211000000C8282AF72
+:10B33000B48180AF048280AFDC8180AF21E8C0039C
+:10B340000000BE8F0800BD270800E00300000000D9
+:10B35000D0FFBD272C00BFAF2800BEAF21F0A00357
+:10B360003000C4AF3000C48F1F79400F00000000D0
+:10B3700021204000212860001000C6276675400F7C
+:10B38000000000001800C2AF1C00C3AF1000C48F43
+:10B390001400C58F8679400F000000002000C2AF66
+:10B3A000029D023C9804448C9C04458C1800C68F76
+:10B3B0001C00C78FC979400F00000000030040182F
+:10B3C0000000000008000010000000002000C28FF4
+:10B3D000010042242000C2AF2000C28F2400C2AF6F
+:10B3E00003000010000000002000C28F2400C2AF44
+:10B3F0002400C28F21E8C0032C00BF8F2800BE8F1D
+:10B400003000BD270800E00300000000D0FFBD278A
+:10B410002C00BFAF2800BEAF21F0A0033000C4AFA6
+:10B420003000C48F1F79400F000000002120400031
+:10B43000212860001000C6276675400F000000003C
+:10B440001800C2AF1C00C3AF1000C48F1400C58F1A
+:10B450008679400F000000002000C2AF029D023C30
+:10B46000A004448CA404458C1800C68F1C00C78F10
+:10B47000C979400F000000000300401800000000E0
+:10B4800004000010000000002000C28F01004224D0
+:10B490002000C2AF029D023C1800C48F1C00C58F63
+:10B4A000A804468CAC04478CC979400F000000000A
+:10B4B000030040180000000004000010000000001D
+:10B4C0002000C28FFFFF42242000C2AF2000C28FA5
+:10B4D00021E8C0032C00BF8F2800BE8F3000BD279D
+:10B4E0000800E00300000000E0FFBD271800BEAF29
+:10B4F00021F0A003211080002118A0002120C0000D
+:10B500002000C2A32400C3A32800C4A30000C0AF2E
+:10B510002000C2930000C2AF0000C28F00160200DC
+:10B520000000C2AF2400C2830800401000000000E9
+:10B530002800C28305004010000000007080828F48
+:10B540000400C2AF03000010000000008C81828F55
+:10B550000400C2AF0000C28F0400C38F2510430057
+:10B560000000C2AFF081828F010042240800C2AF08
+:10B570000800C28F0C00C2AF0C00C38F040061042E
+:10B58000000000000C00C48FFF0184240C00C4AF35
+:10B590000C00C38F43120300401202000800C48F46
+:10B5A00023188200CC81828F030062140000000007
+:10B5B000ECFF00100000000000A0043CF081828F2E
+:10B5C00080180200C8048224211862000000C28F83
+:10B5D000000062ACF081828F01004224F08182AFD2
+:10B5E000F081828F1000C2AF1000C38F1400C3AF70
+:10B5F0001400C48F04008104000000001400C28FF6
+:10B60000FF0142241400C2AF1400C38F4312030091
+:10B61000401202001000C48F23108200F08182AF1C
+:10B6200021E8C0031800BE8F2000BD270800E003FA
+:10B6300000000000E0FFBD271C00BFAF1800BEAF38
+:10B6400021F0A003214080002400C5AF2128C000C4
+:10B650002C00C7AF3000C28F3800C38F4000C48FAA
+:10B660002000C8A32800C5A31000C2A31100C3A3D3
+:10B670001200C4A3CC81838FF081828F0E006210F0
+:10B68000000000003C80838301000224F9FF621463
+:10B6900000000000F081828F01004324CC81828F62
+:10B6A000F4FF621400000000CC81828FF08182AF31
+:10B6B000F0FF00100000000021100000308282AF77
+:10B6C0002800C38358000224030062140000000015
+:10B6D0002C00C28F308282AF1000C3835800022436
+:10B6E00003006214000000003400C28F308282AF79
+:10B6F0001100C383580002240300621400000000FC
+:10B700003C00C28F308282AF1200C38358000224F3
+:10B7100003006214000000004400C28F308282AF38
+:10B720002800C283580042380100432C1000C28315
+:10B73000580042380100422C251862001100C283D3
+:10B74000580042380100422C251862001200C283C2
+:10B75000580042380100422C2510620005004010BC
+:10B760000000000001000224C08082AF020000102F
+:10B7700000000000C08080AF21180000188283AF55
+:10B780002800C38359000224030062140000000053
+:10B790002C00C28F188282AF1000C383590002248C
+:10B7A00003006214000000003400C28F188282AFD0
+:10B7B0001100C3835900022403006214000000003A
+:10B7C0003C00C28F188282AF1200C383590002244A
+:10B7D00003006214000000004400C28F188282AF90
+:10B7E0002800C283590042380100432C1000C28354
+:10B7F000590042380100422C251862001100C28312
+:10B80000590042380100422C251862001200C28300
+:10B81000590042380100422C2510620005004010FA
+:10B820000000000001000224C48082AF020000106A
+:10B8300000000000C48080AF21100000248282AF8D
+:10B840002800C3835A000224030062140000000091
+:10B850002C00C28F248282AF1000C3835A000224BE
+:10B8600003006214000000003400C28F248282AF03
+:10B870001100C3835A000224030062140000000078
+:10B880003C00C28F248282AF1200C3835A0002247C
+:10B8900003006214000000004400C28F248282AFC3
+:10B8A0002800C2835A0042380100432C1000C28392
+:10B8B0005A0042380100422C251862001100C28350
+:10B8C0005A0042380100422C251862001200C2833F
+:10B8D0005A0042380100422C251062000500401039
+:10B8E0000000000001000224C88082AF02000010A6
+:10B8F00000000000C88080AF211800001C8283AFC8
+:10B900002800C383490002240300621400000000E1
+:10B910002C00C28F1C8282AF1000C3834900022416
+:10B9200003006214000000003400C28F1C8282AF4A
+:10B930001100C383490002240300621400000000C8
+:10B940003C00C28F1C8282AF1200C38349000224D4
+:10B9500003006214000000004400C28F1C8282AF0A
+:10B960002800C283490042380100432C1000C283E2
+:10B97000490042380100422C251862001100C283A0
+:10B98000490042380100422C251862001200C2838F
+:10B99000490042380100422C251062000500401089
+:10B9A0000000000001000224CC8082AF02000010E1
+:10B9B00000000000CC8080AF21100000208282AF08
+:10B9C0002800C3834A000224030062140000000020
+:10B9D0002C00C28F208282AF1000C3834A00022451
+:10B9E00003006214000000003400C28F208282AF86
+:10B9F0001100C3834A000224030062140000000007
+:10BA00003C00C28F208282AF1200C3834A0002240E
+:10BA100003006214000000004400C28F208282AF45
+:10BA20002800C2834A0042380100432C1000C28320
+:10BA30004A0042380100422C251862001100C283DE
+:10BA40004A0042380100422C251862001200C283CD
+:10BA50004A0042380100422C2510620005004010C7
+:10BA60000000000001000224D08082AF020000101C
+:10BA700000000000D08080AF2800C383460002246D
+:10BA800005006214000000002C00C48FF67B400FFC
+:10BA900000000000B88082AF1000C383460002247B
+:10BAA00005006214000000003400C48FF67B400FD4
+:10BAB00000000000B88082AF1100C383460002245A
+:10BAC00005006214000000003C00C48FF67B400FAC
+:10BAD00000000000B88082AF1200C3834600022439
+:10BAE00005006214000000004400C48FF67B400F84
+:10BAF00000000000B88082AF21180000288283AFC8
+:10BB00002800C383500002240300621400000000D8
+:10BB10002C00C28F288282AF1000C3835000022401
+:10BB200003006214000000003400C28F288282AF3C
+:10BB30001100C383500002240300621400000000BF
+:10BB40003C00C28F288282AF1200C38350000224BF
+:10BB500003006214000000004400C28F288282AFFC
+:10BB6000211000002C8282AF2800C38353000224DE
+:10BB700003006214000000002C00C28F2C8282AFF0
+:10BB80001000C3835300022403006214000000006D
+:10BB90003400C28F2C8282AF1100C3835300022471
+:10BBA00003006214000000003C00C28F2C8282AFB0
+:10BBB0001200C3835300022403006214000000003B
+:10BBC0004400C28F2C8282AF2000C3831400C3AF15
+:10BBD000470002241400C38F070062100000000019
+:10BBE0004D0002241400C38F4800621000000000C2
+:10BBF000A4000010000000002400C28F148282AF55
+:10BC00001482828F0300401400000000A72F400F11
+:10BC1000000000001482838F0100022403006214DC
+:10BC200000000000C62F400F000000001482838F28
+:10BC3000020002240300621400000000EC2F400FF9
+:10BC4000000000001482838F0300022403006214AA
+:10BC5000000000000330400F000000001482838FBA
+:10BC60000400022403006214000000001A30400F98
+:10BC7000000000001482838F140002240300621469
+:10BC8000000000003630400F000000001482838F57
+:10BC90001500022403006214000000004030400F31
+:10BCA000000000001482838F1C0002240300621431
+:10BCB000000000004A30400F000000001482838F13
+:10BCC0005A00022403006214000000005230400FAA
+:10BCD000000000001482838F5B00022403006214C2
+:10BCE000000000005E30400F000000001482838FCF
+:10BCF0005C00022463006214000000006630400F04
+:10BD0000000000005F000010000000002400C28F4F
+:10BD1000108282AF148280AFB88080AF1082838F90
+:10BD20006500022403006214000000007430400F1C
+:10BD3000000000001082838F670002240300621459
+:10BD4000000000008230400F000000001082838F4E
+:10BD50006800022403006214000000008F30400FCE
+:10BD6000000000001082838F6A0002240300621426
+:10BD700000000000D330400F000000001082838FCD
+:10BD80006B0002240300621400000000E130400F49
+:10BD9000000000001082838F6C00022403006214F4
+:10BDA00000000000EF30400F000000001082838F81
+:10BDB000DC00022403006214000000000D31400F7B
+:10BDC000000000001082838FDD0002240300621453
+:10BDD000000000001A31400F000000001082838F25
+:10BDE000DE00022403006214000000002631400F30
+:10BDF000000000001082838FDF0002240300621421
+:10BE0000000000004031400F000000001082838FCE
+:10BE1000E000022403006214000000005A31400FC9
+:10BE2000000000001082838FE100022403006214EE
+:10BE3000000000006431400F000000001082838F7A
+:10BE4000E200022403006214000000006D31400F84
+:10BE5000000000001082838FE300022403006214BC
+:10BE600000000000A531400F000000001082838F09
+:10BE7000E40002240300621400000000DD31400FE2
+:10BE80000000000021E8C0031C00BF8F1800BE8F17
+:10BE90002000BD270800E00300000000E8FFBD27E8
+:10BEA0001400BFAF1000BEAF21F0A003B880828F96
+:10BEB0000300401400000000C0030224B88082AFD9
+:10BEC000B880848F1082858F4A29400F00000000BF
+:10BED00054808383010002240300621400000000E8
+:10BEE000010002247D8182A3BC80848F2128000070
+:10BEF000C029400F00000000A52A400F00000000EC
+:10BF000021E8C0031400BF8F1000BE8F1800BD27AA
+:10BF10000800E00300000000E8FFBD271400BFAFE9
+:10BF20001000BEAF21F0A003B880828F0300401440
+:10BF300000000000F0000224B88082AF44818283B8
+:10BF40000500401000000000B880828F6881838F58
+:10BF500021104300B88082AFB880848F1082858F13
+:10BF60004A29400F0000000054808383010002240E
+:10BF70000300621400000000010002247D8182A3FE
+:10BF8000BC80848F21280000C029400F00000000E1
+:10BF9000A52A400F0000000021E8C0031400BF8F55
+:10BFA0001000BE8F1800BD270800E003000000004D
+:10BFB000E8FFBD271400BFAF1000BEAF21F0A00303
+:10BFC000B880828F0300401400000000F0000224BB
+:10BFD000B88082AFB880848F1082858F4A29400F45
+:10BFE00000000000BC80848F01000524C029400FA0
+:10BFF0000000000021E8C0031400BF8F1000BE8FB6
+:10C000001800BD270800E00300000000E8FFBD277E
+:10C010001400BFAF1000BEAF21F0A003B880828F24
+:10C020000300401400000000F0000224B88082AF3A
+:10C03000B880848F1082858F4A29400F000000004D
+:10C04000BC80848F01000524C029400F000000003F
+:10C0500021E8C0031400BF8F1000BE8F1800BD2759
+:10C060000800E00300000000E0FFBD271C00BFAF98
+:10C070001800BEAF21F0A0031000C0AF2882848F4B
+:10C0800021280000317C400F000000000300401414
+:10C09000000000000A000010000000002882848FC9
+:10C0A000F67B400F00000000C8000324021043701C
+:10C0B0001000C2AF1000C48F0F62400F00000000DC
+:10C0C00021E8C0031C00BF8F1800BE8F2000BD27D1
+:10C0D0000800E00300000000F8FFBD270000BEAF2D
+:10C0E00021F0A00314000224BC8082AF21E8C00329
+:10C0F0000000BE8F0800BD270800E003000000001C
+:10C10000F8FFBD270000BEAF21F0A00315000224F8
+:10C11000BC8082AF21E8C0030000BE8F0800BD27AD
+:10C120000800E00300000000F8FFBD270000BEAFDC
+:10C1300021F0A00321E8C0030000BE8F0800BD2746
+:10C140000800E00300000000E8FFBD271400BFAFB7
+:10C150001000BEAF21F0A003772A400F00000000BE
+:10C1600021E8C0031400BF8F1000BE8F1800BD2748
+:10C170000800E00300000000F8FFBD270000BEAF8C
+:10C1800021F0A00321E8C0030000BE8F0800BD27F6
+:10C190000800E00300000000E8FFBD271400BFAF67
+:10C1A0001000BEAF21F0A003A72F400F0000000039
+:10C1B000232A400F0000000021E8C0031400BF8FB5
+:10C1C0001000BE8F1800BD270800E003000000002B
+:10C1D000F8FFBD270000BEAF21F0A0035480838389
+:10C1E0000200022403006214000000000100022487
+:10C1F0007D8182A321E8C0030000BE8F0800BD2717
+:10C200000800E00300000000F8FFBD270000BEAFFB
+:10C2100021F0A003548083830200022402006214F0
+:10C22000000000007D8180A321E8C0030000BE8FD4
+:10C230000800BD270800E00300000000E8FFBD275C
+:10C240001400BFAF1000BEAF21F0A0035480838361
+:10C2500002000224370062140000000004000424DD
+:10C260009A64400F00000000050004249A64400F07
+:10C2700000000000060004249A64400F0000000043
+:10C280000500042421280000029D023CB00446243D
+:10C29000213800001965400F00000000F48080AFD5
+:10C2A00001000224888182A32C82848F212800002F
+:10C2B000317C400F0000000003004014000000002B
+:10C2C00005000010000000002C82848FF67B400FD8
+:10C2D00000000000FC8082AF8426400F00000000B8
+:10C2E00001000424B060400F000000006D63400FA7
+:10C2F000000000001A64400F00000000D163400FEE
+:10C3000000000000F480828F06004014000000004E
+:10C31000FC80828F0300401000000000F3FF00103B
+:10C3200000000000888180A3050004249A64400F67
+:10C330000000000021E8C0031400BF8F1000BE8F72
+:10C340001800BD270800E00300000000F8FFBD272B
+:10C350000000BEAF21F0A003010002246C8182A383
+:10C3600088BF033C1061629020004234106162A0DB
+:10C3700021E8C0030000BE8F0800BD270800E003CD
+:10C3800000000000F8FFBD270000BEAF21F0A003B1
+:10C390006C8180A388BF043C10618390DFFF02247E
+:10C3A00024106200106182A021E8C0030000BE8F4B
+:10C3B0000800BD270800E00300000000E8FFBD27DB
+:10C3C0001400BFAF1000BEAF21F0A00354808383E0
+:10C3D000020002241100621400000000212000006D
+:10C3E0002C82858F317C400F000000000300400448
+:10C3F0000000000005000010000000002C82848F67
+:10C40000F67B400F00000000208082AF115F400FDC
+:10C410000000000001000224898182A321E8C003FA
+:10C420001400BF8F1000BE8F1800BD270800E00366
+:10C4300000000000F8FFBD270000BEAF21F0A00300
+:10C4400088BF043CD1608390F7FF0224241062006F
+:10C45000D16082A021E8C0030000BE8F0800BD2784
+:10C460000800E00300000000F8FFBD270000BEAF99
+:10C4700021F0A00388BF023CD160439008006334E0
+:10C48000D16043A021E8C0030000BE8F0800BD2793
+:10C490000800E00300000000E8FFBD271400BFAF64
+:10C4A0001000BEAF21F0A003548083830200022459
+:10C4B0000D00621400000000212000002C82858FF6
+:10C4C000317C400F00000000030040040000000029
+:10C4D00005000010000000002C82848FF67B400FC6
+:10C4E00000000000708182AF21E8C0031400BF8FFC
+:10C4F0001000BE8F1800BD270800E00300000000F8
+:10C50000E8FFBD271400BFAF1000BEAF21F0A003AD
+:10C5100054808383020002240D0062140000000096
+:10C52000212000002C82858F317C400F000000000C
+:10C53000030040040000000005000010000000009F
+:10C540002C82848FF67B400F00000000508182AF68
+:10C5500021E8C0031400BF8F1000BE8F1800BD2754
+:10C560000800E00300000000F8FFBD270000BEAF98
+:10C5700021F0A003010002244C8182A321E8C00322
+:10C580000000BE8F0800BD270800E0030000000087
+:10C59000F8FFBD270000BEAF21F0A0034C8180A3AF
+:10C5A00021E8C0030000BE8F0800BD270800E0039B
+:10C5B00000000000D8FFBD272400BFAF2000BEAFA1
+:10C5C0001C00B1AF1800B0AF21F0A003CC81838F65
+:10C5D000F081828F0E006210000000003C80838397
+:10C5E00001000224F9FF621400000000F081828F34
+:10C5F00001004324CC81828FF4FF6214000000000C
+:10C60000CC81828FF08182AFF0FF0010000000002B
+:10C61000D51B400F0000000088BF023C9061428C97
+:10C620004002427C0300401400000000FAFF0010AA
+:10C63000000000009080848F1F79400F00000000F0
+:10C6400021804000218860009480848F1F79400FF2
+:10C65000000000001000A0AF1400A0AF21200002D5
+:10C660002128200221304000213860009F1E400F09
+:10C670000000000021E8C0032400BF8F2000BE8F0F
+:10C680001C00B18F1800B08F2800BD270800E00300
+:10C6900000000000E8FFBD271400BFAF1000BEAFD0
+:10C6A00021F0A00354808383020002242B00621433
+:10C6B0000000000001000224848182AF21200000DC
+:10C6C0002C82858F317C400F000000000300400465
+:10C6D000000000000D000010000000002C82848F7C
+:10C6E0001F79400F00000000212040002128600039
+:10C6F000AD75400F0000000021204000212860009F
+:10C700008679400F00000000608282AF2120000087
+:10C710002882858F317C400F000000000300400418
+:10C72000000000000D000010000000002882848F2F
+:10C730001F79400F000000002120400021286000E8
+:10C74000AD75400F0000000021204000212860004E
+:10C750008679400F000000006C8282AF21E8C003A0
+:10C760001400BF8F1000BE8F1800BD270800E00323
+:10C7700000000000F8FFBD270000BEAF21F0A003BD
+:10C78000548083830200022402006214000000002F
+:10C79000848180AF21E8C0030000BE8F0800BD2760
+:10C7A0000800E00300000000E0FFBD271C00BFAF51
+:10C7B0001800BEAF21F0A0031000C0AF1000C28F60
+:10C7C000030042280B004010000000001000C38F3F
+:10C7D000348282272118620001000224000062A036
+:10C7E0001000C28F010042241000C2AFF3FF0010FE
+:10C7F00000000000DE8080A37A5A400F0000000095
+:10C8000000A0023C041244244734400F0000000002
+:10C8100030004014000000001C80838F00A0023C08
+:10C8200004124224000062AC1C80828F0C0040A4E1
+:10C830001C80828F0E0040A41C80828F100040ACB0
+:10C840001C80828F140040AC1C80838F5C0002240B
+:10C85000200062A0010002241000C2AF1000C28FAD
+:10C860000B0042280B004010000000001C80838F4A
+:10C870001000C28F2118620020000224200062A054
+:10C880001000C28F010042241000C2AFF3FF00105D
+:10C89000000000001C80828F2C0040A41C80838F2D
+:10C8A00010000224300062A41C80838F3C82828F9F
+:10C8B000340062AC1C80838F3C82828F380062AC73
+:10C8C0004C8280A3010002241400C2AF02000010B9
+:10C8D000000000001400C0AF1400C28F21E8C003A4
+:10C8E0001C00BF8F1800BE8F2000BD270800E0038A
+:10C8F00000000000C8FFBD273000BFAF2C00BEAF56
+:10C900002800B0AF21F0A0033800C4AF3C00C5AF91
+:10C910002110C0002118E0004000C2A34400C3A3BE
+:10C920003800C28F2C0042941400C2A70B000224CE
+:10C930001800C2AF3800C38F3800C28F3400428C59
+:10C94000380062AC3C00C28F3000429427100200D5
+:10C950001200C2A71400C2970D004014000000008E
+:10C960001400C2273800C48F21284000010006248B
+:10C97000E73B400F000000001300401400000000DF
+:10C980001B0002241800C2AF0F00001000000000BE
+:10C990001400C2970F0042300B004010000000004E
+:10C9A0001400C2273800C48F21284000010006244B
+:10C9B000E73B400F000000000300401400000000AF
+:10C9C0001B0002241800C2AF1800C38F1B000224F2
+:10C9D000CC006210000000001800C28FC900401097
+:10C9E000000000001400C2273800C48F2128400036
+:10C9F000C73F400F000000001600C2A31600C393FB
+:10CA0000020002240300621400000000BD000010B8
+:10CA1000000000001600C293B100401400000000A6
+:10CA20003800C28F300042941000C2A71000C29795
+:10CA30003F0042301000C2A74400C2932000C2AFA2
+:10CA40002000C38F070060100000000001000224D6
+:10CA50002000C38F2D00621000000000A400001011
+:10CA6000000000001000C39708000224A00062101C
+:10CA7000000000001800C0AF6D0002241C00C2A31B
+:10CA80001700C0A31700C2930B00422C980040105F
+:10CA9000000000003800C38F1700C293211062000D
+:10CAA000200042901C00C2A33C00C38F1700C29319
+:10CAB00021106200200042901D00C2A31C00C293FE
+:10CAC00021204000C66B400F000000002180400084
+:10CAD0001D00C29321204000C66B400F00000000E3
+:10CAE00005000212000000000B0002241800C2AF73
+:10CAF0007F000010000000001700C29301004224D4
+:10CB00001700C2A3DFFF0010000000001000C39751
+:10CB10001200C29724106200FFFF423074004014DC
+:10CB2000000000001000C3970F0002247000621084
+:10CB3000000000001800C0AF6D0002241C00C2A35A
+:10CB40003C00C28F200043802A0002242E00621085
+:10CB5000000000001700C0A31700C2930800422C79
+:10CB600029004010000000003800C38F1700C29356
+:10CB700021106200200042901C00C2A33C00C38F21
+:10CB80001700C29321106200200042901D00C2A332
+:10CB90001D00C3932A000224030062140000000059
+:10CBA00019000010000000001D00C3933F00022484
+:10CBB00010006210000000001C00C2932120400001
+:10CBC000C66B400F00000000218040001D00C29392
+:10CBD00021204000C66B400F00000000050002123B
+:10CBE000000000000B0002241800C2AF0600001075
+:10CBF000000000001700C293010042241700C2A3E6
+:10CC0000D5FF0010000000003C00C28F28004380C8
+:10CC10002A00022436006210000000001800C28FB3
+:10CC20003300401400000000080002241700C2A3D3
+:10CC30001700C2930B00422C2D0040100000000092
+:10CC40003800C38F1700C293211062002000429069
+:10CC50001C00C2A33C00C38F1700C29321106200C6
+:10CC6000200042901D00C2A31D00C3932A0002248D
+:10CC700003006214000000001D000010000000000E
+:10CC80001D00C3933F00022410006210000000004A
+:10CC90001C00C29321204000C66B400F0000000022
+:10CCA000218040001D00C29321204000C66B400F30
+:10CCB0000000000005000212000000000B0002242A
+:10CCC0001800C2AF0A000010000000001700C29355
+:10CCD000010042241700C2A3D5FF0010000000008D
+:10CCE0004000C29302004014000000001800C0AFD2
+:10CCF0001400C297010042241400C2A736FF00109E
+:10CD0000000000001800C28F21E8C0033000BF8F70
+:10CD10002C00BE8F2800B08F3800BD270800E0032C
+:10CD200000000000D0FFBD272C00BFAF2800BEAF21
+:10CD300021F0A0033000C4AF3400C5AF2110C00003
+:10CD40003800C2A31C00C0AF3000C28F0000428C6C
+:10CD50001000C2AF1000C28F2100429005004014A5
+:10CD600000000000070002241C00C2AF8600001073
+:10CD7000000000003000C38F3000C28F3400428CAE
+:10CD8000380062AC3400C28F000042940C004014A2
+:10CD9000000000003000C48F3400C58F010006245D
+:10CDA000E73B400F000000001300401400000000AB
+:10CDB0001B0002241C00C2AF0F0000100000000086
+:10CDC0003400C28F000042940F0042300A0040102D
+:10CDD000000000003000C48F3400C58F010006241D
+:10CDE000E73B400F0000000003004014000000007B
+:10CDF0001B0002241C00C2AF3000C48F3400C58F5A
+:10CE0000C73F400F000000001400C2A31400C293EB
+:10CE100005004010000000000B0002241C00C2AFFF
+:10CE200059000010000000003000C28F100040AC1C
+:10CE30003000C38F3000C28F0400428C080062AC07
+:10CE40003000C28F0C0040A43000C28F0E0040A4FE
+:10CE50001400C393010002240500621400000000C6
+:10CE60000B0002241C00C2AF2400001000000000D0
+:10CE70003000C28F1000C48F0800458C8D45400FD4
+:10CE8000000000001800C2AFDC808293090040104F
+:10CE9000000000004547400F000000000500401062
+:10CEA00000000000090002242000C2AF380000107A
+:10CEB000000000003000C28FD88082AF1880838FBE
+:10CEC0001800C28F0D00621000000000DE8080A3F9
+:10CED0001000C28F1800C48F0000458C695B400FA2
+:10CEE00000000000030040140000000008000224BD
+:10CEF0001C00C2AF1800C28F188082AF3000C48FF0
+:10CF00001800838CFBFF022424106200180082ACFE
+:10CF10003800C3837700022407006210000000007D
+:10CF20003800C38361000224030062100000000087
+:10CF30000C000010000000003000C38F1800628C4D
+:10CF400001004234180062AC3000C48F1800838C9A
+:10CF5000FDFF022424106200180082AC0A000010B9
+:10CF6000000000003000C48F1800838CFEFF0224F4
+:10CF700024106200180082AC3000C38F1800628C4D
+:10CF800002004234180062AC1C00C28F2000C2AF05
+:10CF90002000C28F21E8C0032C00BF8F2800BE8F65
+:10CFA0003000BD270800E00300000000C8FFBD27D7
+:10CFB0003400BFAF3000BEAF21F0A0033800C4AFD3
+:10CFC0003C00C5AF2000C0A33800C28F0000428CD7
+:10CFD0002400C2AF2400C28F200042902800C2AFBC
+:10CFE000010002242800C38F0F006210000000001F
+:10CFF000030002242800C38F030062100000000019
+:10D000000F00001000000000FF0F023CF8FF423448
+:10D010001C00C2AFFF0F023CFFFF42341800C2AF3A
+:10D020000B00001000000000F80F02241C00C2AF2B
+:10D03000FFFF02341800C2AF05000010000000001E
+:10D04000F8FF02341C00C2AFFFFF02341800C2AF69
+:10D050003800C28F0800428C1400C2AF2400C48F75
+:10D060001400C58F314B400F000000001000C2AF0C
+:10D070001000C38F1800C28F05006214000000006A
+:10D08000080002242000C2A31000001000000000CD
+:10D090002400C28F1800438C1000C28F2B10430055
+:10D0A00003004014000000000A0002242000C2A374
+:10D0B0001000C28F1C00C38F2B10430003004014CC
+:10D0C000000000003C0002242000C2A33800C38FEF
+:10D0D0001000C28F080062AC3C00C28FFFFF4224E8
+:10D0E0003C00C2AF06004010000000002000C293C8
+:10D0F0000300401400000000D5FF001000000000F5
+:10D100002000C29321E8C0033400BF8F3000BE8FDF
+:10D110003800BD270800E00300000000E0FFBD2745
+:10D120001C00BFAF1800BEAF21F0A0032000C4AFA9
+:10D130001000C0A32000C28F210040A02000C38F98
+:10D1400000A0023CC80C4224000062ACFB5C400F13
+:10D1500000000000211840000100022407006210B6
+:10D1600000000000060002241000C2A306000224F2
+:10D170004C8282A312000010000000002000C48F27
+:10D180007734400F000000001000C2A31000C293CB
+:10D190000B004014000000002000C48F5535400FE4
+:10D1A000000000001000C2A31000C293040040144D
+:10D1B000000000002000C38F01000224210062A0B3
+:10D1C0001000C29321E8C0031C00BF8F1800BE8F5F
+:10D1D0002000BD270800E00300000000D0FFBD27AD
+:10D1E0002C00BFAF2800BEAF21F0A0033000C4AFB9
+:10D1F0001400C0A33000C28F212000000000458C25
+:10D20000695B400F0000000021184000010002246B
+:10D210000700621000000000080002241400C2A3EE
+:10D22000080002244C8282A3C1000010000000000C
+:10D230003000C28F0000428C1800C2AF1800C28FAD
+:10D24000FE014390550002247000621400000000AB
+:10D250001800C28FFF014390AA0002246B006214E1
+:10D26000000000003000C28F0000448C360005240E
+:10D270003A45400F000000002118400046000224FB
+:10D280002D006214000000003000C28F0000448CAA
+:10D29000370005243A45400F0000000021184000E7
+:10D2A0004100022424006214000000003000C28FFC
+:10D2B0000000448C380005243A45400F000000006F
+:10D2C00021184000540002241B00621400000000DA
+:10D2D0003000C28F0000448C390005243A45400FCD
+:10D2E00000000000211840003100022412006214E6
+:10D2F000000000003000C28F0000448C260005248E
+:10D300003A45400F00000000211840002900022487
+:10D3100009006214000000003000C28F040040AC1D
+:10D320003000C38F02000224200062A01C00C0AFA6
+:10D3300081000010000000003000C28F0000448C0B
+:10D34000520005243A45400F00000000211840001B
+:10D35000460002242D006214000000003000C28F3D
+:10D360000000448C530005243A45400F00000000A3
+:10D370002118400041000224240062140000000033
+:10D380003000C28F0000448C540005243A45400F01
+:10D390000000000021184000540002241B00621409
+:10D3A000000000003000C28F0000448C55000524AE
+:10D3B0003A45400F000000002118400033000224CD
+:10D3C00012006214000000003000C28F0000448C84
+:10D3D000420005243A45400F00000000211840009B
+:10D3E0002900022409006214000000003000C28FEE
+:10D3F000040040AC3000C38F03000224200062A070
+:10D400001C00C0AF4C000010000000003000C28FB4
+:10D410000000428C1000C2AF1000C28FFE0143908A
+:10D420005500022408006214000000001000C28FA2
+:10D43000FF014390AA0002240300621400000000D0
+:10D440000700001000000000040002244C8282A3A8
+:10D45000040002241400C2A33500001000000000E4
+:10D460003000C48F1000C28FC9014388C6014398A1
+:10D4700021106000040082AC1000C28FC2014290F3
+:10D480001500C2A31500C2932000C2AF2000C38FB5
+:10D490000F00622C22004010000000000100022456
+:10D4A0002000C38F041062002400C2AF2400C38F89
+:10D4B0005040623010004014000000002400C38F70
+:10D4C0000018623011004014000000002400C38FD7
+:10D4D0000200623003004014000000001000001041
+:10D4E000000000003000C38F01000224200062A071
+:10D4F0000F000010000000003000C38F0200022463
+:10D50000200062A00A000010000000003000C38F5D
+:10D5100003000224200062A00500001000000000AB
+:10D52000050002244C8282A3050002241400C2A339
+:10D530001400C2931C00C2AF1C00C28F21E8C003BC
+:10D540002C00BF8F2800BE8F3000BD270800E003ED
+:10D5500000000000C0FFBD273800BFAF3400BEAFE1
+:10D560003000B0AF21F0A0034000C4AF1C00C0A346
+:10D570004000C28F4000C38F0400448C0000658CC3
+:10D58000695B400F000000002118400001000224E8
+:10D590000700621000000000080002244C8282A3F1
+:10D5A000080002241C00C2A3D300001000000000E9
+:10D5B0004000C28F0000428C2000C2AF2000C28F0A
+:10D5C000FE01439055000224080062140000000090
+:10D5D0002000C28FFF014390AA00022403006214BE
+:10D5E00000000000070000100000000003000224FB
+:10D5F0004C8282A3030002241C00C2A3BE000010C0
+:10D60000000000004000C28F0000448C0E00052482
+:10D610004945400F000000002600C2A74000D08FFF
+:10D620004000C28F0000448C0D0005243A45400F95
+:10D63000000000001F0002A24000C48F4000C28F03
+:10D640002600C3970400428C21104300080082ACDE
+:10D650004000D08F4000C28F0000448C1000052491
+:10D660003A45400F000000001E0002A24000D08F8B
+:10D670004000C28F0000448C160005244945400F2D
+:10D68000000000001C0002A64000C28F1C00429453
+:10D6900008004014000000004000D08F4000C28FFE
+:10D6A0000000448C240005246845400F0000000061
+:10D6B0001C0002A64000C48F4000C58F4000C28FEE
+:10D6C0001E0043904000C28F1C00429402186270FA
+:10D6D0000800A28C211043000C0082AC4000D08FC7
+:10D6E0004000C28F0000448C110005244945400FC2
+:10D6F00000000000140002A64000C28F0000448C0D
+:10D70000130005244945400F000000001400C2AF7B
+:10D710001400C28F07004014000000004000C28FB8
+:10D720000000448C200005246845400F00000000E4
+:10D730001400C2AF4000C28F0000448C0B000524CF
+:10D740004945400F000000002400C2A72400C297F2
+:10D7500007004010000000002400C2970100423082
+:10D76000030040140000000007000010000000004B
+:10D77000030002244C8282A3030002242800C2AFCB
+:10D780005F000010000000004000C28F14004294AF
+:10D79000401902002400C29721106200FFFF4324B9
+:10D7A0002400C2971A006200F40140001210000029
+:10D7B0001000C2AF2600C4974000C28F1E004390E5
+:10D7C0004000C28F1C004294021062702118820037
+:10D7D0001000C28F211862001400C28F2310430072
+:10D7E0001800C2AF4000C48F4000C28F1F0043909A
+:10D7F0001800C28F1B004300F401600012100000EB
+:10D80000180082AC4000C28F1800428CF50F422CE9
+:10D8100006004010000000004000C38F01000224F9
+:10D82000200062A00F000010000000004000C28F26
+:10D830001800438CF4FF02342B1043000600401400
+:10D84000000000004000C38F02000224200062A0FC
+:10D8500004000010000000004000C38F03000224F9
+:10D86000200062A04000C28F2000439003000224E9
+:10D870000F006214000000004000C28F0000448CC2
+:10D880002C0005246845400F000000003C8282AF58
+:10D890004000C48F4000C28F0C00438C1000C28F28
+:10D8A00021106200100082AC0B000010000000008C
+:10D8B0003C8280AF4000C58F4000C48F4000C28FC3
+:10D8C0001400429402110200FFFF43300C00828CCE
+:10D8D000211043001000A2AC2400C39700020224D0
+:10D8E0000500621000000000030002241C00C2A317
+:10D8F000030002244C8282A31C00C2932800C2AF02
+:10D900002800C28F21E8C0033800BF8F3400BE8FCB
+:10D910003000B08F4000BD270800E0030000000089
+:10D92000F0FFBD270800BEAF21F0A0031000C4AF78
+:10D930000000C0AF1000C28F140042940000C2AFBC
+:10D940000000C28F001402000000C2AF1000C28F9E
+:10D950001A0043940000C28F251043000000C2AF9C
+:10D960000000C28F21E8C0030800BE8F1000BD2751
+:10D970000800E00300000000D8FFBD272400BFAF6F
+:10D980002000BEAF21F0A0032800C4AF2C00C5AF1B
+:10D990001400C0AF2800C28F070040100000000034
+:10D9A0002C00C28F0200422C030040140000000033
+:10D9B0000500001000000000FFFF02241C00C2AFA1
+:10D9C000F6000010000000002C00C28FFFFF43246F
+:10D9D0002800C28F2B1062000500401000000000DC
+:10D9E000FFFF02241C00C2AFEC000010000000008A
+:10D9F000DC80829309004010000000004547400F82
+:10DA0000000000000500401000000000FFFF02249D
+:10DA10001C00C2AFE10000100000000000A0023CAA
+:10DA2000C80C44242128000000020624276A400F65
+:10DA30000000000000A0023CC80C42241000C2AF4D
+:10DA40002800C28F1800C2AF1800C48F1505023C11
+:10DA50005B56423419008200101800002310830026
+:10DA600042100200211062004213020080130200E3
+:10DA70001400C2AF1800C58F1505023C5B56423436
+:10DA80001900A200101800002310A3004210020089
+:10DA90002110620042230200211080008019020040
+:10DAA0002318640000120300231043002310A20077
+:10DAB0001800C2AF1800C48F1004023C0541423464
+:10DAC0001900820010180000231083004210020089
+:10DAD0002110620042110200801902001400C28F5E
+:10DAE000251043001400C2AF1800C48F1004023C7C
+:10DAF00005414234190082001018000023108300F1
+:10DB00004210020021106200421902002110600040
+:10DB10008011020023104300231082001800C2AFBE
+:10DB20001800C28F010043241400C28F2510430047
+:10DB30001400C2AF00A0023CC80C43241400C28FE2
+:10DB400002140200BF0162A000A0023CC80C4324E2
+:10DB50001400C28F02120200C00162A000A0023CA9
+:10DB6000C80C43241400C28FC10162A01000C28FF0
+:10DB70002C00C48F2800C38F23188300CD0143A835
+:10DB8000CA0143B81000C28FCD014388CA0143982F
+:10DB9000211060003910422C0600401000000000E7
+:10DBA0001000C38F01000224C20162A01200001005
+:10DBB000000000001000C28FCD014388CA014398C5
+:10DBC0003F00023C5FFD42342B104300060040142E
+:10DBD000000000001000C38F06000224C20162A0F2
+:10DBE0000500001000000000FFFF02241C00C2AF6F
+:10DBF0006A000010000000001000C28F2800C38FD0
+:10DC0000C90143A8C60143B82800C38F2C00C28FA6
+:10DC100021106200FFFF42241800C2AF1800C48F19
+:10DC20001505023C5B5642341900820010180000B2
+:10DC300023108300421002002110620042130200F0
+:10DC4000801302001400C2AF1800C58F1505023CF6
+:10DC50005B5642341900A200101800002310A300E4
+:10DC600042100200211062004223020021108000B5
+:10DC700080190200231864000012030023104300DF
+:10DC80002310A2001800C2AF1800C48F1004023C79
+:10DC9000054142341900820010180000231083004F
+:10DCA000421002002110620042110200801902009D
+:10DCB0001400C28F251043001400C2AF1800C48F97
+:10DCC0001004023C05414234190082001018000083
+:10DCD000231083004210020021106200421902004A
+:10DCE00021106000801102002310430023108200E5
+:10DCF0001800C2AF1800C28F010043241400C28F65
+:10DD0000251043001400C2AF00A0023CC80C4324FD
+:10DD10001400C28F02140200C30162A000A0023CE2
+:10DD2000C80C43241400C28F02120200C40162A076
+:10DD300000A0023CC80C43241400C28FC50162A09D
+:10DD40001000C28FBE0140A01000C38F55000224F6
+:10DD5000FE0162A01000C38FAAFF0224FF0162A08F
+:10DD60002120000000A0023CC80C4524010006242C
+:10DD7000F15B400F00000000211840000100022468
+:10DD80000500621000000000FFFF02241C00C2AF6B
+:10DD900002000010000000001C00C0AF1C00C28F79
+:10DDA00021E8C0032400BF8F2000BE8F2800BD27BC
+:10DDB0000800E0030000000068FFBD279400BFAF2B
+:10DDC0009000BEAF21F0A003211080009C00C5AFE1
+:10DDD000A000C6AF9800C2A32800C2275000C2AF5F
+:10DDE0004C8280A35000C38F00A0023CC80C422488
+:10DDF000000062AC7A5A400F00000000FB5C400F4C
+:10DE000000000000211840000100022407006210F9
+:10DE100000000000060002244C8282A3FFFF0224BF
+:10DE20006400C2AF7E03001000000000212000004B
+:10DE300000A0023CC80C4524695B400F00000000B4
+:10DE400007004014000000001B0002244C8282A343
+:10DE5000FFFF03246400C3AF710300100000000043
+:10DE60005000C28F0000428C2000C2AF2000C28F41
+:10DE7000FE014390550002245A0062140000000085
+:10DE80002000C28FFF014390AA00022455006214B3
+:10DE9000000000005000C28F0000448C36000524B2
+:10DEA0003A45400F000000002118400046000224BF
+:10DEB00043006214000000005000C28F0000448C38
+:10DEC000370005243A45400F0000000021184000AB
+:10DED000410002243A006214000000005000C28F8A
+:10DEE0000000448C380005243A45400F0000000033
+:10DEF0002118400054000224310062140000000088
+:10DF00005000C28F0000448C390005243A45400F70
+:10DF10000000000021184000310002242800621493
+:10DF2000000000005000C28F0000448C2600052431
+:10DF30003A45400F0000000021184000290002244B
+:10DF40001F006214000000009800C2836800C2AF86
+:10DF50006800C38F0D006010000000000100022463
+:10DF60006800C38F03006210000000001D00001055
+:10DF7000000000001F0002244C8282A3FFFF022445
+:10DF80006400C2AF26030010000000005000C28FE2
+:10DF9000040040AC5000C48F5535400F0000000015
+:10DFA00010004010000000001B0002244C8282A3DD
+:10DFB000FFFF03246400C3AF19030010000000003A
+:10DFC00000A0023CC80C42241000C2AF5000C48F15
+:10DFD0001000C28FC9014388C60143982110600018
+:10DFE000040082AC9800C2838400C2AF8400C38F57
+:10DFF0000902601000000000010002248400C38FA9
+:10E0000003006210000000000E020010000000007B
+:10E010001000C28FCD014388CA01439821106000CF
+:10E020001400C2AF1400C28F3910422C2D004010D2
+:10E03000000000005000C38F01000224200062A0F5
+:10E040001000C38F01000224C20162A02120000041
+:10E0500000A0023CC80C452401000624F15B400FDF
+:10E060000000000007004014000000000900022426
+:10E070004C8282A3FFFF02246400C2AFE8020010BA
+:10E08000000000001400C28F2810422C060040142B
+:10E09000000000005000C38F020002241F0062A095
+:10E0A00004000010000000005000C38F0100022493
+:10E0B0001F0062A000A0023CC80C442421280000DC
+:10E0C00000020624276A400F0000000000A0023C66
+:10E0D000C80C4324320002243A0062A04D00001014
+:10E0E000000000001400C38F3F00023C5FFD42347B
+:10E0F0002B10430041004014000000005000C38F6B
+:10E1000002000224200062A01000C38F0600022437
+:10E11000C20162A02120000000A0023CC80C4524DE
+:10E1200001000624F15B400F0000000007004014CE
+:10E1300000000000090002244C8282A3FFFF032498
+:10E140006400C3AFB6020010000000001400C28FCC
+:10E15000E8FD42241800C2AF5000C38F0100022422
+:10E160001F0062A01800C28FEDFF03342B10620065
+:10E170000B004010000000005000C38F5000C28F01
+:10E180001F004290401002001F0062A01800C28FC2
+:10E19000421002001800C2AFF2FF001000000000A1
+:10E1A0005000C28F1F0042908100422C0700401493
+:10E1B00000000000040002244C8282A3FFFF02241E
+:10E1C0006400C2AF960200100000000000A0023CF4
+:10E1D000C80C44242128000000020624276A400FAE
+:10E1E0000000000000A0023CC80C432436000224BA
+:10E1F0003A0062A00700001000000000170002248F
+:10E200004C8282A3FFFF03246400C3AF840200108A
+:10E21000000000005000C28F1F0042904018020012
+:10E220001400C28F21106200DFFF42245800C2AFE9
+:10E230005000C28F200043900100022409006214A4
+:10E24000000000005000C28F1F00439055010224BF
+:10E2500002106270020042245C00C2AF060000108F
+:10E26000000000005000C28F1F0042900012020008
+:10E27000020042245C00C2AF5C00C38F5800C28F12
+:10E2800021106200FFFF43245C00C28F1B0062006C
+:10E29000F4014000121000005800C2AF00A0033C7F
+:10E2A000EBFF0224C80C62A000A0023CC80C43246F
+:10E2B0003C000224010062A000A0023CC80C4324E0
+:10E2C00090FF0224020062A000A0023CC80C43247C
+:10E2D0004D000224030062A000A0023CC80C4324AD
+:10E2E00043000224040062A000A0023CC80C4324A6
+:10E2F00048000224050062A000A0023CC80C432490
+:10E3000050000224060062A000A0023CC80C432476
+:10E3100020000224070062A000A0023CC80C432495
+:10E3200046000224080062A000A0023CC80C43245E
+:10E3300041000224090062A000A0023CC80C432452
+:10E34000540002240A0062A000A0023CC80C42242F
+:10E350000B0040A000A0023CC80C43240200022491
+:10E360000C0062A000A0023CC80C43245000C28FE5
+:10E370001F0042900D0062A000A0023CC80C432484
+:10E38000080002240E0062A000A0023CC80C422437
+:10E390000F0040A05000C38F5000C28F0400428C79
+:10E3A00008004224080062AC00A0023CC80C4324D0
+:10E3B00002000224100062A05000C38F0200022459
+:10E3C0001E0062A000A0023CC80C4224110040A024
+:10E3D00000A0023CC80C432402000224120062A0E8
+:10E3E0005000C38F00020224140062A400A0023C6B
+:10E3F000C80C4224130040A000A0023CC80C4224D8
+:10E40000140040A000A0023CC80C4324F8FF0224E2
+:10E41000150062A000A0023CC80C43245800C28F23
+:10E42000160062A000A0023CC80C43245800C28F12
+:10E4300002120200170062A05000C38F5800C28F62
+:10E440001C0062A400A0023CC80C43243F0002242C
+:10E45000180062A000A0023CC80C4224190040A091
+:10E4600000A0023CC80C4324FFFF02241A0062A053
+:10E4700000A0023CC80C42241B0040A000A0023CAB
+:10E48000C80C43245000C28F0400428C1C0062A0C0
+:10E4900000A0023CC80C43245000C28F0400428CF0
+:10E4A000021202001D0062A000A0023CC80C43241E
+:10E4B0005000C28F0400428C021402001E0062A0B1
+:10E4C00000A0023CC80C43245000C28F0400428CC0
+:10E4D000021602001F0062A000A0023CC80C4324E8
+:10E4E0001400C28F200062A000A0023CC80C43248C
+:10E4F0001400C28F02120200210062A000A0023CA0
+:10E50000C80C43241400C28F02140200220062A02F
+:10E5100000A0023CC80C43241400C28F0216020063
+:10E52000230062A000A0023CC80C4224240040A0AA
+:10E5300000A0023CC80C4224250040A000A0023CE0
+:10E54000C80C432429000224260062A000A0023C3B
+:10E55000C80C44249C00C28FFFFF032424104300F6
+:10E56000270082A000A0023CC80C42246C00C2AF6D
+:10E570009C00C28F7000C2AF7000C28F04004104C3
+:10E58000000000007000C38FFF0063247000C3AF61
+:10E590007000C38F03120300FFFF03242410430005
+:10E5A0006C00C38F280062A000A0023CC80C42246B
+:10E5B0007400C2AF9C00C28F7800C2AF7800C28FD7
+:10E5C0000500410400000000FFFF02347800C38F03
+:10E5D000211862007800C3AF7800C38F03140300D2
+:10E5E000FFFF0324241043007400C38F290062A09E
+:10E5F00000A0023CC80C42247C00C2AF9C00C28F29
+:10E600008000C2AF8000C28F0600410400000000FD
+:10E61000FF00023CFFFF42348000C38F21186200DC
+:10E620008000C3AF8000C38F03160300FFFF0324E5
+:10E63000241043007C00C38F2A0062A0A000C28F78
+:10E6400029004010000000006000C0A36000C393D8
+:10E65000A000C28F21106200000042801300401011
+:10E66000000000006000C2930B00422C0F0040101D
+:10E670000000000000A0023C6000C393C80C4224CC
+:10E68000212062006000C393A000C28F21106200AD
+:10E69000000042902B0082A06000C293010042243F
+:10E6A0006000C2A3E9FF0010000000006000C293F8
+:10E6B0000B00422C1B0040100000000000A0043C96
+:10E6C0006000C393010062246000C2A3FF006330B6
+:10E6D000C80C822421186200200002242B0062A0B2
+:10E6E000F2FF0010000000006000C0A36000C293B1
+:10E6F0000B00422C0B0040100000000000A0023C68
+:10E700006000C393C80C4224211062002B0040A07B
+:10E710006000C293010042246000C2A3F3FF001016
+:10E720000000000000A0023CC80C43244600022464
+:10E73000360062A000A0023CC80C43244100022421
+:10E74000370062A000A0023CC80C432454000224FD
+:10E75000380062A000A0023CC80C4324310002240F
+:10E76000390062A000A0023CC80C4324200002240F
+:10E770003B0062A000A0023CC80C432420000224FD
+:10E780003C0062A000A0023CC80C432420000224EC
+:10E790003D0062A000A0023CC80C432455000224A6
+:10E7A000FE0162A000A0023CC80C4324AAFF022480
+:10E7B000FF0162A05000C48F5000C58F5000C28F6F
+:10E7C0001E0043905000C28F1C00429402186270D9
+:10E7D0000800A28C211043000C0082AC5000C28FB4
+:10E7E0000400448C00A0023CC80C452421300000E9
+:10E7F000F15B400F00000000180040140000000012
+:10E80000090002244C8282A3FFFF02246400C2AFED
+:10E8100003010010000000005000C48F5535400F68
+:10E82000000000000D004010000000001B0002244A
+:10E830004C8282A3FFFF03246400C3AFF8000010E2
+:10E84000000000001F0002244C8282A3FFFF02246C
+:10E850006400C2AFF20000100000000000A0023C03
+:10E86000C80C44242128000000020624276A400F17
+:10E870000000000000A0033CF8FF0224C80C62A0C6
+:10E8800000A0023CC80C4324FFFF0224010062A048
+:10E8900000A0023CC80C4324FFFF0224020062A037
+:10E8A0005000C28F20004390020002240500621431
+:10E8B0000000000000A0023CC80C4324FFFF02241B
+:10E8C000030062A05000C28F1E004290FFFF42244E
+:10E8D0005400C2A75400C397FFFF0234190062100E
+:10E8E000000000005000C48F5400C3975000C28F36
+:10E8F0001C004294021862700800828C2110620091
+:10E900002120400000A0023CC80C4524213000001A
+:10E91000F15B400F00000000050040140000000003
+:10E92000FFFF02246400C2AFBD0000100000000021
+:10E930005400C297FFFF42245400C2A7E5FF001015
+:10E940000000000000A0023CC80C44242128000064
+:10E9500004000624276A400F000000005000C28F08
+:10E960000800428C010042246000C2A36000C593ED
+:10E970005000C48F5000C28F1C0043940800828C4A
+:10E98000211062002B10A2002500401000000000A2
+:10E990005000C28F1E004290FFFF42245400C2A7C5
+:10E9A0005400C397FFFF02341800621000000000FB
+:10E9B0006000C4935400C3975000C28F1C0042945F
+:10E9C00002106270211082002120400000A0023C51
+:10E9D000C80C452421300000F15B400F000000000E
+:10E9E0000500401400000000FFFF02246400C2AFD5
+:10E9F0008B000010000000005400C297FFFF42246B
+:10EA00005400C2A7E6FF0010000000006000C2939F
+:10EA1000010042246000C2A3D4FF001000000000E7
+:10EA20005000C28F1400429440110200FF014224A2
+:10EA30008800C2AF8800C38F04006104000000009A
+:10EA40008800C28FFF0142248800C2AF8800C38FB4
+:10EA5000431203001C00C2AF010002246000C2A3E5
+:10EA60006000C2931C00C38F2B104300160040109F
+:10EA7000000000005000C28F6000C3930C00428C65
+:10EA8000211062002120400000A0023CC80C452457
+:10EA900021300000F15B400F000000000500401431
+:10EAA00000000000FFFF02246400C2AF5C00001001
+:10EAB000000000006000C293010042246000C2A375
+:10EAC000E7FF001000000000A000C28F46004010C9
+:10EAD000000000006000C0A36000C393A000C28FCC
+:10EAE000211062000000428013004010000000006E
+:10EAF0006000C2930B00422C0F0040100000000089
+:10EB000000A0023C6000C393C80C42242120620094
+:10EB10006000C393A000C28F2110620000004290E9
+:10EB2000000082A06000C293010042246000C2A3E2
+:10EB3000E9FF0010000000006000C2930B00422CAF
+:10EB40000C0040100000000000A0043C6000C393D3
+:10EB5000010062246000C2A3FF006330C80C82245D
+:10EB60002118620020000224000062A0F2FF0010C1
+:10EB70000000000000A0023CC80C4324080002244E
+:10EB80000B0062A000A0023CC80C43241100022428
+:10EB9000110062A000A0023CC80C43241100022412
+:10EBA000130062A000A0023CC80C43241100022400
+:10EBB000170062A05000C28F0C00448C00A0023CE1
+:10EBC000C80C452421300000F15B400F000000001C
+:10EBD0001200401400000000FFFF03246400C3AFD4
+:10EBE0000F000010000000005000C28F0C00448C89
+:10EBF00000A0023CC80C452421300000F15B400F0E
+:10EC0000000000000500401400000000FFFF022487
+:10EC10006400C2AF02000010000000006400C0AF3A
+:10EC20006400C28F21E8C0039400BF8F9000BE8FA4
+:10EC30009800BD270800E00300000000D0FFBD27BA
+:10EC40002C00BFAF2800BEAF21F0A0033000C4AF3E
+:10EC50003400C5AF3000C28F0000428C1000C2AF3C
+:10EC60003000C28F3800428C1C00C2AF3400C28F0B
+:10EC700000004294021102001500C2A31000C28FCE
+:10EC8000200042902000C2AF2000C38F0100622804
+:10EC90001F004014000000002000C38F0300622802
+:10ECA0001000401400000000030002242000C38F65
+:10ECB00003006210000000001500001000000000BA
+:10ECC0001000C28F1500C3931F0042901B0062000A
+:10ECD000F4014000101000001500C2A30C00001049
+:10ECE000000000001C00C38F3C82828F080062106D
+:10ECF000000000001000C28F1500C3931F00429057
+:10ED00001B006200F4014000101000001500C2A3B7
+:10ED10001000C48F1C00C58F8D45400F00000000FF
+:10ED20001800C2AF1500C3931800C28F21106200F3
+:10ED30001000C38F212040000000658C21300000AE
+:10ED4000F15B400F000000000400401400000000D0
+:10ED50001400C0A303000010000000000100022402
+:10ED60001400C2A31400C29321E8C0032C00BF8F7B
+:10ED70002800BE8F3000BD270800E003000000001F
+:10ED8000D0FFBD272C00BFAF2800BEAF21F0A003ED
+:10ED90003000C4AF3400C5AF1C00C0AF3400C28F18
+:10EDA000200042902400C2AF020002242400C38F3E
+:10EDB00019006210000000002400C38F03006228C5
+:10EDC0000700401000000000010002242400C38F4F
+:10EDD0001700621000000000190000100000000081
+:10EDE000030002242400C38F03006210000000000F
+:10EDF0001300001000000000FF0F023CFFFF423430
+:10EE00001800C2AFFF0F023CF8FF42341400C2AF3B
+:10EE10000B00001000000000FFFF02341800C2AF1A
+:10EE2000F8FF02341400C2AF05000010000000001B
+:10EE3000FFFF02341800C2AFF80F02241400C2AF63
+:10EE40003000C28F07004010000000003000C38F68
+:10EE50000100022403006210000000000500001001
+:10EE600000000000020002241C00C2AF35000010A8
+:10EE7000000000001C00C28F32004014000000009F
+:10EE80003400C48F3000C58F314B400F00000000AC
+:10EE90001000C2AF1000C38F1800C28F05006214AB
+:10EEA00000000000010002241C00C2AFF1FF0010AE
+:10EEB000000000001000C28F07004010000000009A
+:10EEC0001000C38F01000224030062100000000044
+:10EED0000500001000000000020002241C00C2AF68
+:10EEE000E4FF0010000000001000C28F1400C38F68
+:10EEF0002B10430003004014000000000200022415
+:10EF00001C00C2AF3400C48F3000C58F2130000018
+:10EF100021380000534C400F000000002118400031
+:10EF20001800C28F030062140000000001000224D8
+:10EF30001C00C2AF1000C28F3000C2AFCDFF001066
+:10EF4000000000003400C48F2128000021300000A0
+:10EF500001000724534C400F000000001C00C38F29
+:10EF600002000224050062140000000001000224D7
+:10EF70002000C2AF02000010000000002000C0AF5F
+:10EF80002000C28F21E8C0032C00BF8F2800BE8F55
+:10EF90003000BD270800E00300000000C0FFBD27CF
+:10EFA0003C00BFAF3800BEAF21F0A0034000C4AFAB
+:10EFB0004400C5AF2110C0004800C2A34000C28F6A
+:10EFC0000000428C1400C2AF4000C28F3400428C5B
+:10EFD0001C00C2AF4000C28F3800428C2400C2AF78
+:10EFE0004400C28F00004294021102002800C2A314
+:10EFF0001400C28F200042903000C2AF3000C38F97
+:10F000000100622823004014000000003000C38F7C
+:10F0100003006228130040140000000003000224D3
+:10F020003000C38F030062100000000019000010C0
+:10F03000000000001400C28F2800C3931F004290FC
+:10F040001B006200F4014000101000002800C2A361
+:10F05000FF0F023CF8FF42342000C2AF0D00001049
+:10F06000000000001C00C28F0800401000000000DB
+:10F070001400C28F2800C3931F0042901B0062003F
+:10F08000F4014000101000002800C2A3F8FF023471
+:10F090002000C2AF4800C2930600401400000000E8
+:10F0A0004400C28F000042940F0042308F00401491
+:10F0B000000000002800C293060040140000000079
+:10F0C0004400C28F000042941000422C0600401001
+:10F0D000000000004800C29303004014000000003C
+:10F0E0002C000010000000001C00C28F040040141F
+:10F0F000000000002400C0AF260000100000000047
+:10F100004800C2930D004010000000004400C38F6F
+:10F110001400C28F1F00429000110200000063948F
+:10F12000FFFF42301B006200F4014000121000009B
+:10F130002900C2A303000010000000000100022407
+:10F140002900C2A32900C293120040100000000051
+:10F150001400C48F2400C58F314B400F0000000005
+:10F160002400C2AF2400C38F2000C28F2B10620086
+:10F170000300401400000000060000100000000022
+:10F180002900C293FFFF42242900C2A3EDFF001013
+:10F19000000000002400C28F2000C38F2B1043000A
+:10F1A0004D004010000000004000C38F2400C28FBB
+:10F1B000380062AC1400C48F2400C58F8D45400F09
+:10F1C000000000001800C2AF2400C38F3C82828F71
+:10F1D00011006214000000002800C3931800C28FC1
+:10F1E000211862001400C28F1000428C2B106200A4
+:10F1F00009004014000000001400C28F200043905A
+:10F200000300022404006210000000001000C0AFE0
+:10F210003F00001000000000DC80829308004010D6
+:10F22000000000004547400F0000000004004010AF
+:10F23000000000002C00C0AF3700001000000000EC
+:10F24000D88080AFDE8080A32800C3931800C28FCF
+:10F25000211062001400C38F212040000000658C43
+:10F26000695B400F000000002118400001000224EB
+:10F2700004006210000000001000C0AF1200001077
+:10F28000000000004800C2930C0040100000000085
+:10F290001400C48F4400C28F000042940F0042301B
+:10F2A000FFFF4230401902000000828C2110430011
+:10F2B0001000C2AF04000010000000001400C28F54
+:10F2C0000000428C1000C2AFFFFF0224188082AF02
+:10F2D0000F0000100000000001000224DD8082A366
+:10F2E0001000C0AF0A000010000000001400C48F1E
+:10F2F0004400C28F000042940F004230FFFF4230B2
+:10F30000401902000000828C211043001000C2AF9F
+:10F310001000C28F2C00C2AF2C00C28F21E8C003A6
+:10F320003C00BF8F3800BE8F4000BD270800E003BF
+:10F3300000000000D0FFBD272C00BFAF2800BEAFEB
+:10F3400021F0A0033000C4AF3400C5AF2110C000CD
+:10F350003800C2A31400C0AF4C8280A31000C0A329
+:10F360001000C2930B00422C0E0040100000000061
+:10F370001000C3931000C227212062003000C38F09
+:10F380001000C2932110620020004290080082A069
+:10F390001000C293010042241000C2A3F0FF00102D
+:10F3A000000000003400C28F000040A43000C48F71
+:10F3B0003400C58F443D400F000000001300401092
+:10F3C000000000001800C2273800C3933000C48F2B
+:10F3D000212840003400C68F21386000DF3D400FF7
+:10F3E000000000001400C2AF1400C28F09004014D6
+:10F3F000000000003000C48F0E3D400F00000000F0
+:10F400001400C2AF0300001000000000140002242A
+:10F410001400C2AF1400C28F4C8282A31400C28FAA
+:10F4200021E8C0032C00BF8F2800BE8F3000BD270D
+:10F430000800E00300000000D0FFBD272C00BFAF94
+:10F440002800BEAF21F0A0033000C4AF3000C28F4F
+:10F450002C0042941C00C2A71400C2273000C48FA5
+:10F46000212840009044400F000000001000C2AF6F
+:10F470001000C28F1F004014000000001C00C227B3
+:10F480003000C48F212840007D40400F0000000064
+:10F490002000C2AF2000C38F1400C28F1A0062A4E4
+:10F4A0001400C38FFF0F023C241062001800C2AF8B
+:10F4B0001800C28F021402001800C2AF2000C38FD0
+:10F4C0001800C28F140062A41C00C2273000C48F31
+:10F4D000212840000F3B400F000000002118400091
+:10F4E0000100022403006210000000000900022451
+:10F4F0001000C2AF1000C28F21E8C0032C00BF8FE4
+:10F500002800BE8F3000BD270800E0030000000087
+:10F51000D0FFBD272C00BFAF2800BEAF21F0A00355
+:10F520003000C4AF3400C5AF010002241000C2A3F4
+:10F530003000C38F3000C28F3400428C380062AC80
+:10F540003000C48F3400C58F01000624E73B400F14
+:10F55000000000001C00C2AF1C00C28F0500401458
+:10F56000000000001B0002241000C2A37400001061
+:10F57000000000001000C393010002246D0062141B
+:10F58000000000001100C0A33400C28F00004294AC
+:10F590001400C2A73000C48F3400C58F2130000092
+:10F5A000E73B400F000000001C00C2AF1C00C28FF0
+:10F5B000000042901200C2A33400C38F3400C28FF7
+:10F5C0000000429401004224000062A41200C39390
+:10F5D000E500022404006210000000001200C29343
+:10F5E0000C004014000000001C00C28F09004010F5
+:10F5F000000000001100C293010042241100C2A3C8
+:10F60000FF0042300300401400000000E1FF001042
+:10F61000000000001C00C28F3C00401400000000ED
+:10F620003000C28F3800428C1800C2AF1800C38F60
+:10F630003C82828F20006214000000003000C28FE4
+:10F640000000428C20004390030002240500621059
+:10F6500000000000020002241000C2A3C5FF001039
+:10F66000000000003000C38F1800C28F080062AC99
+:10F670003000C48F01000524853E400F00000000CB
+:10F68000211840001500022405006214000000004B
+:10F69000020002241000C2A3B6FF00100000000008
+:10F6A0003400C38F1400C297000062A41000C0A3EE
+:10F6B000B0FF0010000000003000C38F1800C28FA0
+:10F6C000080062AC3000C48F01000524853E400F65
+:10F6D00000000000211840001500022405006214FB
+:10F6E00000000000020002241000C2A3A1FF0010CD
+:10F6F000000000003400C38F1400C297000062A411
+:10F700001000C0A39BFF0010000000001100C39375
+:10F710000100022497FF6214000000001000C0A343
+:10F720003400C38F1400C297000062A491FF001040
+:10F73000000000003400C38F1400C297000062A4D0
+:10F740001000C293050040140000000001000224D4
+:10F750002000C2AF02000010000000002000C0AF77
+:10F760002000C28F21E8C0032C00BF8F2800BE8F6D
+:10F770003000BD270800E00300000000D8FFBD27CF
+:10F780002400BFAF2000BEAF21F0A0032800C4AF0B
+:10F790002C00C5AF3000C6AF2110E0003400C2A37A
+:10F7A0001000C0A32800C38F2800C28F3400428CF1
+:10F7B000380062AC2800C48F3000C58F01000624D9
+:10F7C000E73B400F000000001400C2AF1400C28FDE
+:10F7D00005004014000000001B0002241800C2AF06
+:10F7E0005A000010000000001400C48F2C00C58FC8
+:10F7F0000B000624476B400F000000003400C39349
+:10F800001200022406006214000000001400C38FDE
+:10F81000100002240B0062A0040000100000000091
+:10F820001400C38F200002240B0062A01400C28FBA
+:10F830000C0040A01400C28F140040A41400C28F1A
+:10F840001A0040A41400C28F1C0040AC5A3E400F66
+:10F85000000000001400C38F378282930D0062A065
+:10F860001400C38F388282970E0062A41400C38FE5
+:10F8700042828297100062A43400C39312000224D3
+:10F880000C006210000000001400C38F4A828297AF
+:10F89000120062A41400C38F4E828297160062A4E5
+:10F8A0001400C38F40828297180062A407000010E2
+:10F8B000000000001400C28F120040A41400C28F88
+:10F8C000160040A41400C28F180040A42800C38F63
+:10F8D0001400C28F1C00428C140062AC2800C38F3D
+:10F8E0001400C28F0E0042941C0062A42800C38F33
+:10F8F0001400C28F100042941E0062A42800C38F1F
+:10F900001400C28F0B004290300062A42800C38F05
+:10F910003000C28F000042942C0062A42800C48FE3
+:10F920003000C58F0F3B400F000000002118400041
+:10F9300001000224030062100000000009000224FC
+:10F940001000C2A31000C2931800C2AF1800C28FEB
+:10F9500021E8C0032400BF8F2000BE8F2800BD27F0
+:10F960000800E00300000000E0FFBD271800BEAF64
+:10F9700021F0A0030800DEAF0400C2270C00C2AFD4
+:10F9800080BF023C3002428C1400C2AF80BF023CF8
+:10F990002002428C1000C2AF0800C38F80BF023C1F
+:10F9A0002002428C000062AC0C00C38F80BF023C7E
+:10F9B0003002428C000062AC0C00C28F1400C38F76
+:10F9C0000000428CEEFF6214000000000800C28FAD
+:10F9D0001000C38F0000428CE9FF62140000000099
+:10F9E0000200C3970000C29725106200388282A7E8
+:10F9F0000600C3970000C29725106200408282A7CC
+:10FA000021E8C0031800BE8F2000BD270800E003D6
+:10FA100000000000D8FFBD272400BFAF2000BEAF0C
+:10FA200021F0A0032800C4AF2110A0002C00C2A325
+:10FA30002800C28F0000428C1000C2AF2800C28F85
+:10FA40000800428C1400C2AF2800C48FDD3E400F76
+:10FA5000000000001400C2AF1400C28F0500401463
+:10FA600000000000150002241C00C2AF3A00001084
+:10FA7000000000001000C28F20004390010002240B
+:10FA800009006214000000001000C48F1400C58F2C
+:10FA9000F80F062421380000534C400F00000000EE
+:10FAA00015000010000000001000C28F20004390DD
+:10FAB0000200022409006214000000001000C48F3C
+:10FAC0001400C58FF8FF063421380000534C400F56
+:10FAD0000000000008000010000000001000C48FAB
+:10FAE0001400C58FFF0F023CF8FF46342138000098
+:10FAF000534C400F000000002800C28F0800428CC9
+:10FB00001800C2AF1000C48F1800C58F1400C68F34
+:10FB100021380000534C400F000000002800C38F24
+:10FB20001400C28F080062AC2C00C39301000224B1
+:10FB300008006214000000001000C48F1400C58F7C
+:10FB4000EF44400F000000001C00C2AF0200001094
+:10FB5000000000001C00C0AF1C00C28F21E8C003E1
+:10FB60002400BF8F2000BE8F2800BD270800E003BF
+:10FB700000000000C8FFBD273400BFAF3000BEAF9B
+:10FB800021F0A0033800C4AF1400C0AF3800C28F0A
+:10FB90000000428C1000C2AF3800C28F0800428CB7
+:10FBA0001800C2AF1000C28F200042902800C2AFE0
+:10FBB000020002242800C38F190062100000000018
+:10FBC0002800C38F030062280700401000000000D7
+:10FBD000010002242800C38F1700621000000000FB
+:10FBE0001900001000000000030002242800C38F49
+:10FBF000030062100000000013000010000000006D
+:10FC0000FF0F023CF7FF42342000C2AFFF0F023C5F
+:10FC1000FFFF42342400C2AF0B00001000000000C0
+:10FC2000F7FF02342000C2AFFFFF02342400C2AF4E
+:10FC30000500001000000000F70F02242000C2AFF2
+:10FC4000FFFF02342400C2AF1800C28F0200422C12
+:10FC50000300401000000000020002241800C2AFA0
+:10FC60001800C28F1C00C2AF1000C48F1800C58FCF
+:10FC7000314B400F000000001800C28F28004010D8
+:10FC8000000000001000C48F1800C58F314B400FDA
+:10FC9000000000001400C2AF1400C38F2400C28F04
+:10FCA00004006214000000001800C0AF1C00001027
+:10FCB000000000001400C28F030040140000000088
+:10FCC00017000010000000001800C28F010042243D
+:10FCD0001800C2AF1400C38F2000C28F0900621049
+:10FCE000000000001000C28F1800438C1800C28F63
+:10FCF0002B10430003004010000000000300001020
+:10FD000000000000020002241800C2AF1800C38FD8
+:10FD10001C00C28FD8FF6214000000001800C0AFA2
+:10FD20001800C28F21E8C0033400BF8F3000BE8F9F
+:10FD30003800BD270800E00300000000D8FFBD2701
+:10FD40002400BFAF2000BEAF21F0A0032800C4AF45
+:10FD5000480002241400C2AF4C8280A32800C28F46
+:10FD60002C0042941000C2A72800C28F1800428CB9
+:10FD70000000427C4200401000000000DC808293C2
+:10FD80000A004010000000004547400F000000003E
+:10FD90000600401000000000090002244C8282A3EB
+:10FDA000FFFF0224570000101C00C2AF2800C28FC2
+:10FDB0000000448C2128000021300000534C400FEB
+:10FDC000010007242800C48F7D40400F1000C52784
+:10FDD0001800C2AF1800C28F0800401400000000D5
+:10FDE0001B0002244C8282A3FFFF02241400C2AF36
+:10FDF0001400C28F430000101C00C2AF5A3E400FD7
+:10FE0000000000001800C38F4E828297160062A483
+:10FE10001800C38F40828297180062A4000000007F
+:10FE20001800C38F2800C28F1400428C1C0062ACE3
+:10FE30001800C38F2800C28F300042940B0062A0CC
+:10FE40002800C48F0F3B400F1000C527030040104F
+:10FE500000000000050000101400C0AF09000224DB
+:10FE60004C8282A3FFFF02241400C2AF2800C48F7B
+:10FE70001800838CFEFF022424106200180082AC5C
+:10FE80001200C0A71200C2970300422C16004010B7
+:10FE9000000000001200C397211060000011020052
+:10FEA000231043008018020000A0023C501142249D
+:10FEB000211862002800C28F0700621400000000B1
+:10FEC0001200C397348282272118620001000224A5
+:10FED00005000010000062A01200C2970100422439
+:10FEE000E8FF00101200C2A71400C38F48000224CC
+:10FEF00002006214000000001400C0AF1400C28FA2
+:10FF00001C00C2AF1C00C28F21E8C0032400BF8FB9
+:10FF10002000BE8F0800E0032800BD27D0FFBD27CA
+:10FF20002800BFAF2400BEAF2000B0AF21F0A00377
+:10FF30003000C4AF3400C5AF1800C0A33400C28F76
+:10FF4000000042940F0042301100401400000000F5
+:10FF50003400C28F000042940D00401000000000E9
+:10FF60003000C38F3000C28F3400428C380062AC46
+:10FF70003000C48F3400C58F01000624E73B400FDA
+:10FF8000000000001000C2AF0700001000000000D9
+:10FF90003000C48F3400C58F21300000E73B400F94
+:10FFA000000000001000C2AF1000C28F000042909D
+:10FFB0001500C2A31000C28F040040100000000012
+:10FFC0001500C29305004014000000000200022446
+:10FFD0001700C2A37F000010000000001500C393AB
+:10FFE000E500022405006214000000000100022464
+:10FFF0001700C2A377000010000000001000C28F9D
+:020000041D01DC
+:100000000B0042901500C2A31400C0A31400C293B9
+:100010000800422C18004010000000001000C38FA0
+:100020001400C29321104300000042901600C2A3A6
+:100030001600C29321204000CE6B400F000000004C
+:100040001600C2A33000C48F1800C39301006224BD
+:100050001800C2A3FF006230211882001600C2936C
+:10006000200062A01400C293010042241400C2A325
+:10007000E6FF0010000000001000C28F0B0042904D
+:100080001500C2A31000C28F080042901600C2A340
+:100090001400C0A31400C2930300422C18004010A7
+:1000A000000000001000C38F1400C29321106200F2
+:1000B000080042901600C2A31600C29321204000FF
+:1000C000CE6B400F000000001600C2A33000C48FAA
+:1000D0001800C393010062241800C2A3FF0062301D
+:1000E000211882001600C293200062A01400C2935F
+:1000F000010042241400C2A3E6FF0010000000002B
+:100100003000C38F3400C28F000042942C0062A4E0
+:100110001000C28F000042901500C2A31500C393C7
+:10012000E500022405006214000000000100022422
+:100130001700C2A302000010000000001700C0A3B7
+:100140003000C38F1000C28F1C00428C140062ACC0
+:100150003000D08F1000C48F4836400F00000000E0
+:10016000040002AE1000C28F0B0042901500C2A323
+:100170003000C38F1500C293300062A41500C293F3
+:10018000100042300B004010000000003000C38F10
+:100190001000C28F0E0042941C0062A43000C38F76
+:1001A0001000C28F100042941E0062A409000010CB
+:1001B000000000003000C38F1000C28F1600429470
+:1001C0001C0062A43000C38F1000C28F180042943C
+:1001D0001E0062A41700C29321E8C0032800BF8F4D
+:1001E0002400BE8F2000B08F3000BD270800E00340
+:1001F00000000000D8FFBD272400BFAF2000BEAF25
+:1002000021F0A0032800C4AF2C00C5AF2800C38F85
+:100210002800C28F3400428C380062AC2800C48FA2
+:100220002C00C58F01000624E73B400F00000000B2
+:100230001000C2AF1000C28F040040140000000084
+:100240001800C0AF31000010000000001000C28F85
+:10025000000042901400C2A31400C2930200401494
+:10026000000000001000C0AF1000C28F2500401039
+:10027000000000001400C393E5000224040062148F
+:10028000000000001000C0AF1E00001000000000C1
+:100290001000C28F0B0042901400C2A31400C3933D
+:1002A0000F00022417006214000000002C00C38F0E
+:1002B0002C00C28F0000429401004224000062A47E
+:1002C0002800C48F2C00C58F21300000E73B400F71
+:1002D000000000001000C2AF1000C28F04004014E4
+:1002E000000000001800C0AF08000010000000006F
+:1002F0001000C28F0B0042901400C2A3E7FF001051
+:10030000000000001000C28F1800C2AF1800C28F9A
+:1003100021E8C0032400BF8F2000BE8F2800BD2726
+:100320000800E00300000000D0FFBD272C00BFAF95
+:100330002800BEAF21F0A0033000C4AF3400C5AF29
+:100340002110C0003800C2A31800C0AF3000C28F17
+:100350000000428C2000C2AF3000C28F3400428CBB
+:100360001C00C2AF3000C38F1C00C28F380062ACCB
+:100370003000C48F3400C58F01000624E73B400FD6
+:10038000000000001000C2AF1000C28F0700401430
+:1003900000000000010002244C8282A31B00022402
+:1003A0002400C2AF45000010000000001000C28F02
+:1003B000000042901400C2A31000C28F040040103D
+:1003C000000000001400C29305004014000000006B
+:1003D0000B0002241800C2AF2E0000100000000025
+:1003E0001400C393E500022405006214000000001D
+:1003F0000B0002241800C2AF26000010000000000D
+:100400001000C28F0B0042901400C2A31000C38FD3
+:10041000E5FF0224000062A01000C48F4836400FA0
+:10042000000000001C00C2AF1800C28F070040147B
+:10043000000000003000C48F3400C58F0F3B400F18
+:10044000000000000500401400000000010002242C
+:100450001800C2AF0F000010000000001C00C38F86
+:100460003C82828F0B006210000000003800C293B3
+:1004700008004010000000001C00C48F2000C58F41
+:10048000603B400F00000000000042380100422C99
+:100490001800C2AF1800C28F040040140000000012
+:1004A0004C8280A303000010000000000100022421
+:1004B0004C8282A31800C28F2400C2AF2400C28FD6
+:1004C00021E8C0032C00BF8F2800BE8F3000BD275D
+:1004D0000800E00300000000C0FFBD273C00BFAFE4
+:1004E0003800BEAF21F0A0034000C4AF4400C5AF48
+:1004F0001100C0A3010002242800C2A74C8280A3DF
+:100500004400C28F070040140000000019000224BC
+:100510004C8282A3FFFF02243000C2AFD100001042
+:10052000000000004400C28F200042244000C48F1D
+:1005300021284000213000004948400F0000000001
+:100540000700401400000000120002244C8282A325
+:10055000FFFF02243000C2AFC20000100000000004
+:100560001000C0A31000C2930B00422C0E004010DC
+:10057000000000001000C3931000C2272120620079
+:100580004400C38F1000C2932110620020004290EB
+:10059000080082A01000C293010042241000C2A3F0
+:1005A000F0FF0010000000004400C28F2C004294B5
+:1005B0002A00C2A72800C0A74400C38F4400C28FEE
+:1005C0003400428C380062AC2800C2274400C48F3B
+:1005D0002128400001000624E73B400F00000000F6
+:1005E0002C00C2AF2C00C28F070040140000000096
+:1005F0001B0002244C8282A3FFFF02243000C2AF02
+:1006000098000010000000001000C0A31000C2936A
+:100610000B00422C12004010000000002C00C38F81
+:100620001000C293212043001000C3931000C22782
+:1006300021106200000083800800428003006210E5
+:1006400000000000010002241100C2A31000C293A8
+:10065000010042241000C2A3ECFF001000000000C3
+:100660001100C29307004014000000001100022492
+:100670004C8282A3FFFF02243000C2AF7900001039
+:10068000000000001100C0A3DD8080A32800C22765
+:100690004400C48F2128400021300000E73B400F78
+:1006A000000000002C00C2AF2C00C28F0D004014CF
+:1006B00000000000DD808393010002240300621427
+:1006C0000000000032000010000000001B000224A7
+:1006D0004C8282A3FFFF02243000C2AF61000010F1
+:1006E000000000002C00C28F000042800300401474
+:1006F0000000000026000010000000001000C0A351
+:100700001000C2930B00422C1200401000000000A9
+:100710002C00C38F1000C293212043001000C3930C
+:100720001000C22721106200000083800800428070
+:100730000300621000000000010002241100C2A3A7
+:100740001000C293010042241000C2A3ECFF00106D
+:10075000000000001100C2930700401400000000D8
+:10076000110002244C8282A3FFFF02243000C2AF9A
+:100770003C000010000000001100C0A32800C29738
+:10078000010042242800C2A7C0FF001000000000A2
+:100790002A00C2972800C2A74400C38F4400C28F1A
+:1007A0003400428C380062AC2800C2274400C48F59
+:1007B000212840007D40400F000000002C00C2AF07
+:1007C0002C00C28F07004014000000001B00022410
+:1007D0004C8282A3FFFF02243000C2AF2100001030
+:1007E000000000001000C0A31000C2930B00422CB8
+:1007F0000E004010000000002C00C38F1000C293B8
+:10080000212043004400C38F1000C29321106200D6
+:1008100020004290000082A01000C29301004224F8
+:100820001000C2A3F0FF0010000000002800C22743
+:100830004400C48F212840000F3B400F00000000FF
+:100840000700401400000000090002244C8282A32B
+:10085000FFFF02243000C2AF0200001000000000C1
+:100860003000C0AF3000C28F21E8C0033C00BF8F12
+:100870003800BE8F4000BD270800E00300000000E4
+:10088000D0FFBD272C00BFAF2800BEAF21F0A003D2
+:100890003000C4AF3400C5AF1000C0AF1400C0AF0B
+:1008A0001400C28F030042281B004010000000000B
+:1008B0001400C38F3482822721106200000042900E
+:1008C00010004010000000001400C38F3482822703
+:1008D00021106200000040A01400C38F21106000AE
+:1008E00000110200231043008018020000A0023C07
+:1008F00050114224211062001000C2AF0600001007
+:10090000000000001400C28F010042241400C2AF96
+:10091000E3FF0010000000001000C28F060040142A
+:1009200000000000200002244C8282A32000C0AFFF
+:1009300078010010000000001000C28F2000422447
+:100940003000C48F21284000213000004948400F6A
+:10095000000000000B004014000000001400C38FD2
+:10096000348282272118620001000224000062A064
+:10097000120002244C8282A32000C0AF6501001047
+:10098000000000003400C28F000042901800C2A393
+:100990001000C38F00A0023C04124224000062AC8D
+:1009A0001000C28F040040AC1000C28F080040ACA1
+:1009B0001000C28F2C0040A41000C38F200002241E
+:1009C000300062A41000C38F1C80828F3400428CE0
+:1009D000340062AC1000C38F1C80828F3800428CC0
+:1009E000380062AC00A0023C281244241000C58FDD
+:1009F0006D44400F000000001000C48F00A0023CB6
+:100A00002812452401000624213800003D32400F01
+:100A100000000000DB004014000000001800C2933A
+:100A2000BFFF42242400C2AF2400C38F3700622CD2
+:100A3000CE004010000000002400C28F8018020089
+:100A4000029D023CC4044224211062000000428C3A
+:100A500008004000000000001000C28F2C004294EB
+:100A60001A00C2A71A00C2271000C48F2128400014
+:100A700001000624CA40400F000000001C00C2AF65
+:100A80001C00C28F0C014014000000001A00C22795
+:100A90001000C48F2128400021300000CD3C400FC1
+:100AA000000000001C00C2AF1C00C28F02014014F5
+:100AB000000000001A00C2271000C48F2128400047
+:100AC000770006244933400F000000001C00C2AF2D
+:100AD0001000C28F300042941000423005004010D8
+:100AE000000000001F0002244C8282A3FF000224A9
+:100AF0001C00C2AF1C00C28FEF00401400000000B9
+:100B00001000C48F2128000002000624464A400F2E
+:100B1000000000001C00C2AF3400C28F01004380FF
+:100B20002B000224E4006214000000001000C28FB9
+:100B30001800438C02006334180043ACDE00001040
+:100B4000000000001000C28F1400428C2D004010E5
+:100B5000000000001000C28F2C0042941A00C2A7AF
+:100B60001A00C2271000C48F2128400077000624F5
+:100B70004933400F000000001C00C2AF1000C28FBC
+:100B80003000429410004230050040100000000088
+:100B90001F0002244C8282A3FF0002241C00C2AF6B
+:100BA0001C00C28FC4004014000000001000C48F5D
+:100BB0002128000002000624464A400F00000000E1
+:100BC0001C00C2AF1C00C28F0300401000000000D8
+:100BD0001A0002244C8282A33400C28F0100438099
+:100BE0002B000224B4006214000000001000C28F29
+:100BF0001800438C02006334180043ACAE000010B0
+:100C0000000000001000C28F2C0042941A00C2A7FE
+:100C10001A00C2271000C48F2128400001000624BA
+:100C2000CA40400F000000001C00C2AF1C00C28F71
+:100C3000A1004014000000001A00C2271000C48F59
+:100C40002128400021300000CD3C400F0000000072
+:100C50001C00C2AF1C00C28F9700401400000000AF
+:100C60001A00C2271000C48F2128400077000624F4
+:100C70004933400F000000001C00C2AF1000C28FBB
+:100C80003000429410004230050040100000000087
+:100C90001F0002244C8282A3FF0002241C00C2AF6A
+:100CA0001C00C28F84004014000000001000C48F9C
+:100CB0002128000002000624464A400F00000000E0
+:100CC0001C00C2AF1C00C28F0300401000000000D7
+:100CD0001A0002244C8282A33400C28F0100438098
+:100CE0002B00022474006214000000001000C28F68
+:100CF0001800438C02006334180043AC6E000010EF
+:100D0000000000001000C28F2C0042941A00C2A7FD
+:100D10001A00C2271000C48F212840007200062448
+:100D20004933400F000000001C00C2AF3400C28FE6
+:100D3000010043802B0002245F00621400000000C9
+:100D40001000C28F30004294100042305A0040140C
+:100D5000000000001000C28F1800438C01006334B3
+:100D6000180043AC54000010000000001F000224D3
+:100D70004C8282A3FF0002241C00C2AF4E00001070
+:100D8000000000001000C48F00A0023C281245247F
+:100D90006D44400F000000001800C3937700022448
+:100DA0000F006210000000001800C39357000224D7
+:100DB0000B006210000000001800C39361000224C1
+:100DC00007006210000000001800C39341000224D5
+:100DD0000300621000000000350000100000000059
+:100DE0001A00C0A71A00C2271000C48F2128400093
+:100DF00021300000CD3C400F000000001C00C2AFBD
+:100E00001C00C28F2C004014000000001A00C227F2
+:100E10001000C48F21284000770006244933400F7A
+:100E2000000000001C00C2AF1000C28F30004294CE
+:100E30001000423005004010000000001F00022496
+:100E40004C8282A3FF0002241C00C2AF1C00C28F90
+:100E500019004014000000001000C48F2128000079
+:100E600002000624464A400F000000001C00C2AFEA
+:100E70001C00C28F03004010000000001A00022472
+:100E80004C8282A33400C28F010043802B000224D5
+:100E900009006214000000001000C28F1800438C8B
+:100EA00002006334180043AC03000010000000008F
+:100EB0000B0002241C00C2AF6B5C400F000000005E
+:100EC00006004010000000001000C48F1800838C42
+:100ED000FEFF022424106200180082AC1C00C28FA6
+:100EE00009004010000000001400C38F34828227E4
+:100EF0002118620001000224000062A01000C0AFAF
+:100F000002000010000000004C8280A31000C28F7D
+:100F10002000C2AF2000C28F21E8C0032C00BF8F89
+:100F20002800BE8F3000BD270800E003000000004D
+:100F3000F8FFBD270000BEAF21F0A0030800C4AF3A
+:100F40004C8280A30800C28F1000428C21E8C003AD
+:100F50000000BE8F0800BD270800E003000000006D
+:100F6000D8FFBD272400BFAF2000BEAF21F0A003F3
+:100F70002800C4AF00A0023C140F42241000C2AFEE
+:100F80004C8280A36B5C400F000000000700401003
+:100F900000000000180002244C8282A3FFFF0224FC
+:100FA0001800C2AF58000010000000001000C28FEF
+:100FB000200042242800C48F212840002130000056
+:100FC0004948400F000000000700401400000000E6
+:100FD000120002244C8282A3FFFF02241800C2AF39
+:100FE00049000010000000001000C38F00A0023C68
+:100FF00004124224000062AC1000C28F040040AC16
+:101000001000C28F080040AC1000C28F2C0040A41A
+:101010001000C38F20000224300062A41000C38F90
+:101020001C80828F3400428C340062AC1000C38F6D
+:101030001C80828F3800428C380062AC00A0023CD9
+:10104000281244241000C58F6D44400F000000009A
+:101050001000C48F00A0023C281245240100062481
+:10106000213800003D32400F000000001400C2AFE4
+:101070001400C28F07004010000000000B00022483
+:101080004C8282A3FFFF02241800C2AF1E00001092
+:10109000000000001000C28F300042941000423067
+:1010A0000700401000000000130002244C8282A3BD
+:1010B000FFFF02241800C2AF130000100000000060
+:1010C0001000C28F2C0042241000C48F2128400041
+:1010D00001000624CA40400F000000001400C2AF07
+:1010E0001400C28F04004014000000001800C0AFBC
+:1010F0000500001000000000010002244C8282A3C1
+:10110000FFFF02241800C2AF1800C28F21E8C003FD
+:101110002400BF8F2000BE8F2800BD270800E003F9
+:1011200000000000E8FFBD271400BFAF1000BEAFF5
+:1011300021F0A0031800C4AFDC80829303004010AC
+:10114000000000004547400F000000001800C28F5B
+:10115000100040AC1800C28F0E0040A41800C28FCF
+:101160000C0040A41800C38F1800C28F0400428CEA
+:10117000080062ACD88080AF21E8C0031400BF8FA4
+:101180001000BE8F1800BD270800E003000000001B
+:10119000F8FFBD270000BEAF21F0A0034C82829370
+:1011A00021E8C0030000BE8F0800BD270800E0034F
+:1011B00000000000E8FFBD271000BEAF21F0A00333
+:1011C0001800C4AF1C00C5AF1800C28F0400C2AF26
+:1011D0001C00C28F0800C2AF3C0002240000C2A362
+:1011E0000C00C0A30C00C2930000C3932B1043005B
+:1011F0000E004010000000000C00C3930400C28FDA
+:10120000212062000C00C3930800C28F21106200ED
+:1012100000004290000082A00C00C2930100422412
+:101220000C00C2A3EFFF00100000000021E8C00383
+:101230001000BE8F1800BD270800E003000000006A
+:10124000E0FFBD271C00BFAF1800BEAF21F0A00318
+:101250002000C4AF2400C5AF1400C0AF2000C28F6F
+:101260000000428C1000C2AF2000C48FDD3E400F52
+:1012700000000000211840002400C28F000043AC91
+:101280002400C28F0000428C0500401400000000C2
+:10129000150002241400C2AF41000010000000003D
+:1012A0001000C28F2000439001000224100062143D
+:1012B000000000002400C28F1000C48F0000458C85
+:1012C000F80F062421380000534C400F00000000A6
+:1012D00021184000FFFF02342800621400000000C3
+:1012E000090002241400C2AF240000100000000016
+:1012F0001000C28F200043900200022410006214EC
+:10130000000000002400C28F1000C48F0000458C34
+:10131000F8FF063421380000534C400F0000000055
+:1013200021184000FFFF0234140062140000000086
+:10133000090002241400C2AF1000001000000000D9
+:101340002400C28F1000C48F0000458CFF0F023CA8
+:10135000F8FF463421380000534C400F00000000D5
+:1013600021184000FF0F023CFFFF423403006214CB
+:1013700000000000090002241400C2AF1400C28F54
+:1013800007004014000000002400C28F1000C48F2A
+:101390000000458CEF44400F000000001400C2AF75
+:1013A0001400C28F21E8C0031C00BF8F1800BE8F3D
+:1013B0002000BD270800E00300000000D8FFBD2783
+:1013C0002400BFAF2000BEAF21F0A0032800C4AFAF
+:1013D0002C00C5AF1800C0A32800C48F2C00C58FF7
+:1013E0008D45400F000000001400C2AFDC808293E6
+:1013F00009004010000000004547400F00000000B9
+:101400000500401000000000090002241C00C2AFCB
+:101410002E00001000000000D88080AFDE80829394
+:1014200009004014000000002800C28F0000448C16
+:101430002128000000020624276A400F0000000057
+:1014400001000224DE8082A31000C0A32800C28F06
+:101450001F0043901000C2932B104300190040104E
+:10146000000000001800C2931600401400000000A5
+:101470001400C3270000628C212040000100422498
+:10148000000062AC2800C28F0000458C21300000B3
+:10149000F15B400F00000000211840000100022411
+:1014A0000300621000000000090002241800C2A31B
+:1014B0001000C293010042241000C2A3E3FF0010F9
+:1014C000000000001800C2931C00C2AF1C00C28FB5
+:1014D00021E8C0032400BF8F2000BE8F2800BD2755
+:1014E0000800E00300000000F8FFBD270000BEAFC9
+:1014F00021F0A0030800C4AF2110A0000C00C2A777
+:101500000C00C3970800C28F2110620000004290B7
+:1015100021E8C0030000BE8F0800BD270800E003DB
+:1015200000000000F0FFBD270800BEAF21F0A003BF
+:101530001000C4AF2110A0001400C2A71400C3976C
+:101540001000C28F21106200000042900000C2A370
+:101550001400C3971000C28F211062000100429056
+:101560000100C2A30100C2930200C2A70200C297F9
+:10157000001202000200C2A70000C3930200C2973B
+:10158000251043000200C2A70200C29721E8C00351
+:101590000800BE8F1000BD270800E0030000000017
+:1015A000E0FFBD271C00BFAF1800BEAF21F0A003B5
+:1015B0002000C4AF2110A0002400C2A72400C297BD
+:1015C0002000C48F212840004945400F0000000042
+:1015D0001000C2A72400C29702004224FFFF42303D
+:1015E0002000C48F212840004945400F0000000022
+:1015F0001200C2A71200C2971400C2AF1400C28F1B
+:10160000001402001400C2AF1000C3971400C28F70
+:10161000251043001400C2AF1400C28F21E8C0039C
+:101620001C00BF8F1800BE8F2000BD270800E003FC
+:1016300000000000F0FFBD270800BEAF21F0A003AE
+:101640001000C4AF1400C5AF1000C28F200042903C
+:101650000400C2AF0400C38F010062282F004014B1
+:10166000000000000400C38F030062281200401431
+:1016700000000000030002240400C38F0300621076
+:101680000000000025000010000000001400C28FC0
+:10169000FEFF43241000C28F1F00429002186270A8
+:1016A0001000C28F1000428C211062000000C2AFF7
+:1016B0001A000010000000001400C28F0700401044
+:1016C000000000001400C38F010002240300621018
+:1016D0000000000008000010000000001000C28F91
+:1016E0000C00438C1400C28F211062000000C2AFB6
+:1016F0000A000010000000001400C28FFEFF432407
+:101700001000C28F1F004290021862701000C28F3A
+:101710001000428C211062000000C2AF0000C28F96
+:1017200021E8C0030800BE8F1000BD270800E003B9
+:1017300000000000D8FFBD272400BFAF2000BEAFCF
+:1017400021F0A0032800C4AF2110A0002C00C2A3E8
+:101750004C8280A32C00C393D8FF02242410620083
+:1017600007004010000000001F0002244C8282A3EA
+:10177000FFFF02241800C2AF3C0000100000000070
+:101780002800C28F2C0042941000C2A72800C38FEB
+:101790002800C28F3400428C380062AC2800C48F0D
+:1017A0001000C5277D40400F000000001400C2AFAC
+:1017B0001400C28F07004014000000001B00022428
+:1017C0004C8282A3FFFF02241800C2AF2700001042
+:1017D000000000001400C28F0B004290080042304D
+:1017E00007004010000000001F0002244C8282A36A
+:1017F000FFFF02241800C2AF1C0000100000000010
+:101800002800C28F30004294100042300700401080
+:10181000000000001400C28F2C00C393100063343A
+:101820000B0043A004000010000000001400C38F50
+:101830002C00C2930B0062A02800C48F1000C527A3
+:101840000F3B400F000000000700401400000000A4
+:10185000090002244C8282A3FFFF02241800C2AFB9
+:1018600002000010000000001800C0AF1800C28F76
+:1018700021E8C0032400BF8F2000BE8F2800BD27B1
+:101880000800E00300000000C0FFBD273C00BFAF20
+:101890003800BEAF21F0A0034000C4AF4400C5AF84
+:1018A0004800C6AF4C00C7AF4400C38F4800C28F8A
+:1018B000021062701000C2AF4000C28F1400C2AFAD
+:1018C0001C00C0AF3000C0A74C00C28F1800428C73
+:1018D0000000427C08004014000000001D000224AB
+:1018E0004C8282A3090002241C00C2AF3400C0AFA6
+:1018F00001010010000000001000C28F040040141D
+:10190000000000003400C0AFFB0000100000000029
+:101910006B5C400F00000000080040100000000059
+:10192000180002244C8282A3180002241C00C2AFBB
+:101930003400C0AFF000001000000000DE8080A383
+:101940004C00C28F0000428C1800C2AF4C00C28F06
+:101950000E0042942000C2A74C00C28F1000428C9F
+:101960002800C2AF4C00C28F1800C48F0800458CFD
+:101970008D45400F000000002400C2AF4C00C28F14
+:101980000C0043942400C28F211043002400C2AFF6
+:10199000D880838F4C00C28F0F00621000000000BF
+:1019A000DC8082930A004010000000004547400F91
+:1019B00000000000060040100000000009000224A2
+:1019C0004C8282A33400C0AFCB00001000000000A6
+:1019D0004C00C28FD88082AF1880838F2400C28FC2
+:1019E0001B00621000000000DC8082930A0040109F
+:1019F000000000004547400F0000000006004010B6
+:101A000000000000090002244C8282A33400C0AF11
+:101A1000B900001000000000DE8080A31800C28F13
+:101A20002400C48F0000458C695B400F000000005B
+:101A300005004014000000001B0002244C8282A319
+:101A4000080002241C00C2AF2400C28F188082AF9D
+:101A50004C00C28F1400428C2C00C2AF1C00C28FFD
+:101A600096004014000000001000C28F9300401048
+:101A7000000000002800C38F2C00C28F05006214F4
+:101A8000000000004C00C28F1800438C0400633437
+:101A9000180043AC2000C3970002022462006214C5
+:101AA00000000000010002243200C2A3DC80829307
+:101AB0000A004010000000004547400F00000000F1
+:101AC0000600401000000000090002244C8282A39E
+:101AD0003400C0AF88000010000000002000C0A744
+:101AE0004C00C38F4C00C28F0C0042940100422472
+:101AF0000C0062A44C00C38F1800C28F1F004290DC
+:101B00000C006394FFFF42301500621400000000D7
+:101B10004C00C28F0C0040A44C00C28F1800428CB5
+:101B20008000427C09004010000000004C00C48F7F
+:101B300021280000853E400F000000001C00C2AFBD
+:101B40003200C0A306000010000000004C00C48F4B
+:101B500001000524EB33400F000000001C00C2AF61
+:101B60001C00C38F15000224060062140000000050
+:101B7000150002244C8282A33400C0AF5E00001026
+:101B8000000000001C00C28F27004014000000006D
+:101B90004C00C28F1800C48F0800458C8D45400F43
+:101BA000000000002400C2AF4C00C28F0C00439420
+:101BB0002400C28F211043002400C2AF4C00C28F0A
+:101BC000D88082AF3200C2931500401000000000A0
+:101BD0001800C28F2400C48F0000458C695B400F41
+:101BE000000000000A004014000000001B00022456
+:101BF0004C8282A3080002241C00C2AFFFFF022413
+:101C0000188082AF3400C0AF3B000010000000001D
+:101C10002400C28F188082AF030000100000000073
+:101C20002400C28F188082AF1C00C28F8BFF40142B
+:101C3000000000001800C48F2000C3970100622438
+:101C40002000C2A7FFFF63300000828C21186200D1
+:101C50001400C28F00004290000062A01400C28FE6
+:101C6000010042241400C2AF2800C28F01004224A8
+:101C70002800C2AF1000C28FFFFF42241000C2AF85
+:101C80003000C297010042243000C2A74C00C28F2E
+:101C90001800428C8000427C0400401000000000CC
+:101CA0002C00C28F010042242C00C2AF010002248C
+:101CB000DC8082A369FF0010000000004C00C38F8D
+:101CC0002000C2970E0062A44C00C38F2800C28F70
+:101CD000100062AC4C00C38F2C00C28F140062ACA9
+:101CE0003000C3974400C28F1B006200F401400023
+:101CF000121000003400C2AF3400C28F21E8C003CC
+:101D00003C00BF8F3800BE8F4000BD270800E003B5
+:101D100000000000D8FFBD272400BFAF2000BEAFE9
+:101D200021F0A003D880828F1800C2AF1800C28FA4
+:101D30000000428C1400C2AF1800C28F1400C48F80
+:101D40000800458C8D45400F000000001000C2AF18
+:101D50001800C28F0C0043941000C28F2110430062
+:101D60001000C2AF1400C28F1000C48F0000458C59
+:101D700021300000F15B400F00000000050040141E
+:101D800000000000090002241C00C2AF0300001084
+:101D900000000000DC8080A31C00C0AF1C00C28FCC
+:101DA00021E8C0032400BF8F2000BE8F2800BD277C
+:101DB0000800E00300000000F8FFBD270000BEAFF0
+:101DC00021F0A0030800C4AF4C8280A30800C28F9A
+:101DD0000800C38F1000448C1400628C261082000F
+:101DE0000100422C21E8C0030000BE8F0800BD277F
+:101DF0000800E00300000000C0FFBD273C00BFAFAB
+:101E00003800BEAF21F0A0034000C4AF4400C5AF0E
+:101E10004800C6AF4C00C7AF4400C38F4800C28F14
+:101E2000021062701000C2AF4000C28F1400C2AF37
+:101E30002800C0AF2C00C0A74C8280A34C00C28FEA
+:101E40000000428C1800C2AF4C00C28F0E004294BA
+:101E50002400C2A74C00C28F1000428C1C00C2AFED
+:101E60004C00C28F1800428C4000427C0600401497
+:101E7000000000001E0002244C8282A33000C0AF8C
+:101E8000A100001000000000DC8082930A004010D6
+:101E9000000000004547400F000000000600401011
+:101EA00000000000090002244C8282A33000C0AF71
+:101EB0009500001000000000D880838F4C00C28F76
+:101EC00023006210000000002400C39700020224D7
+:101ED0001F006210000000004C00C28FD88082AF4B
+:101EE0004C00C28F1800C48F0800458C8D45400FF0
+:101EF000000000002000C2AF4C00C28F0C004394D1
+:101F00002000C28F211043002000C2AFDE8080A3DA
+:101F10001800C28F2000C48F0000458C695B400F01
+:101F20000000000008004014000000000800022427
+:101F30004C8282A3080002242800C2AF3000C0AF48
+:101F400071000010000000002000C28F188082AFD6
+:101F50001000C28F60004010000000004C00C28FD3
+:101F60001400438C1C00C28F0700621400000000A4
+:101F70003D0002244C8282A33D0002242800C2AF0F
+:101F800055000010000000002400C3970002022446
+:101F900039006214000000002400C0A74C00C38F69
+:101FA0004C00C28F0C004294010042240C0062A439
+:101FB0004C00C38F1800C28F1F0042900C00639426
+:101FC000FFFF42300F006214000000004C00C28F7F
+:101FD0000C0040A44C00C48F01000524EB33400FDB
+:101FE000000000002800C2AF2800C28F050040108A
+:101FF000000000000F0002244C8282A33600001073
+:10200000000000004C00C28F1800C48F0800458CEF
+:102010008D45400F000000002000C2AF4C00C28F71
+:102020000C0043942000C28F211043002000C2AF57
+:102030004C00C28FD88082AFDE8080A31800C28F90
+:102040002000C48F0000458C695B400F0000000039
+:102050000700401400000000080002244C8282A304
+:10206000080002242800C2AF1B000010000000007E
+:102070002000C28F188082AF1400C58F1800C48F53
+:102080002400C397010062242400C2A7FFFF63302D
+:102090000000828C21106200000042900000A2A08B
+:1020A0001400C28F010042241400C2AF1C00C28F72
+:1020B000010042241C00C2AF2C00C2970100422440
+:1020C0002C00C2A71000C28FFFFF42241000C2AF35
+:1020D0009FFF0010000000004C00C38F2400C29737
+:1020E0000E0062A44C00C38F1C00C28F100062ACB3
+:1020F0002C00C3974400C28F1B006200F401400013
+:10210000121000003000C2AF3000C28F21E8C003BF
+:102110003C00BF8F3800BE8F4000BD270800E003A1
+:1021200000000000C0FFBD273800BFAF3400BEAFC5
+:102130003000B0AF21F0A0034000C4AF4400C5AFF1
+:102140002110C0004800C2A32800C0A32800C293E9
+:102150000B00422C0B004010000000002800C3932D
+:102160004400C28F2118620020000224000062A0F7
+:102170002800C293010042242800C2A3F3FF0010EC
+:10218000000000004000C28F000043802E000224A7
+:1021900005006210000000004000C28F0000428075
+:1021A00004004014000000002C00C0AF73000010B9
+:1021B000000000004000C48FB96A400F000000001A
+:1021C0001400C2A71400C2970D00422C0800401052
+:1021D000000000001800C227212040004000C58FE9
+:1021E000516A400F000000000400001000000000D1
+:1021F0002C00C0AF61000010000000001800C227D2
+:102200004800C39321204000212860007749400FF7
+:102210000000000004004014000000002C00C0AFCB
+:1022200056000010000000001800C22721204000C6
+:102230002E0005247B6B400F000000001000C2AF91
+:102240001000C28F0F004010000000001000C28F6D
+:10225000000040A01000C28F010042241000C2AF55
+:102260001000C48FB96A400F000000000400422C27
+:1022700004004014000000002C00C0AF3F0000101C
+:10228000000000001800C22721204000B96A400F5A
+:10229000000000000900422C04004014000000006F
+:1022A0002C00C0AF35000010000000002800C0A3C3
+:1022B0002800D0931800C22721204000B96A400F9F
+:1022C000000000002B1002020E0040100000000071
+:1022D0002800C3934400C28F212062002800C393CA
+:1022E0001000C2272110620008004290000082A066
+:1022F0002800C293010042242800C2A3ECFF001072
+:10230000000000001000C28F1A0040100000000002
+:102310001000C28F00004280160040100000000034
+:102320002800C0A32800D0931000C48FB96A400FC2
+:10233000000000002B1002020E0040100000000000
+:102340002800C3934400C28F212062002800C39359
+:102350001000C28F2110620000004290080082A08D
+:102360002800C293010042242800C2A3EDFF001000
+:1023700000000000010002242C00C2AF2C00C28F1C
+:1023800021E8C0033800BF8F3400BE8F3000B08F0B
+:102390004000BD270800E00300000000C8FFBD2783
+:1023A0003400BFAF3000BEAF21F0A0033800C4AF8F
+:1023B0002110A0003C00C2A33C00C2933800C48F8F
+:1023C000212840007749400F00000000040040141D
+:1023D000000000002800C0AF7900001000000000DD
+:1023E0001000C0A31000C2930800422C1B00401034
+:1023F000000000001000C3933800C28F211062005B
+:10240000000043802E00022414006210000000002F
+:102410001000C3933800C28F211062000000428078
+:102420000E004010000000001000C3931000C227EF
+:10243000212062001000C3933800C28F2110620077
+:1024400000004290080082A01000C29301004224C4
+:102450001000C2A3E3FF0010000000001000C293B0
+:102460001100C2A31000C2930800422C0B004010C0
+:10247000000000001000C393010062241000C2A3FA
+:10248000FF0063301000C2272118620020000224E0
+:10249000080062A0F3FF0010000000001100C393C9
+:1024A0003800C28F21106200000043802E000224F9
+:1024B0001A006214000000001100C29301004224BF
+:1024C0001100C2A31100C3933800C28F2110620013
+:1024D0000000428011004010000000001000C39373
+:1024E000010062241000C2A3FF0063301000C22765
+:1024F000212062001100C393010062241100C2A3D5
+:10250000FF0063303800C28F21106200000042904B
+:10251000080082A0EBFF0010000000001000C29332
+:102520000B00422C0B004010000000001000C39371
+:10253000010062241000C2A3FF0063301000C22714
+:102540002118620020000224080062A0F3FF00109E
+:10255000000000002300C0A31800C3832000022451
+:1025600003006214000000005F0002241800C2A3F0
+:102570001000C0A31000C2930C00422C0E004010AB
+:10258000000000001000C3933800C28F21206200B9
+:102590001000C3931000C22721106200080042906F
+:1025A000000082A01000C293010042241000C2A3C8
+:1025B000F0FF001000000000010002242800C2AF5C
+:1025C0002800C28F21E8C0033400BF8F3000BE8FC7
+:1025D0003800BD270800E00300000000D8FFBD2739
+:1025E0002400BFAF2000BEAF21F0A0032800C4AF7D
+:1025F0002110A0002C00C2A31800C0A32800C48F83
+:10260000B96A400F000000001000C2AF1400C0AF54
+:102610001400C28F1000C38F2A104300B500401071
+:10262000000000001400C38F2800C28F2110620038
+:1026300000004280210042280800401000000000F5
+:102640001400C38F2800C28F211062000000438055
+:102650000500022469006214000000001400C38F0A
+:102660002800C28F21106200000043802200022453
+:1026700062006210000000001400C38F2800C28FA7
+:1026800021106200000043802B0002245B006210D6
+:10269000000000001400C38F2800C28F21106200C8
+:1026A000000043802C00022454006210000000004F
+:1026B0001400C38F2800C28F2110620000004380E5
+:1026C0002F0002244D006210000000001400C38F90
+:1026D0002800C28F21106200000043803A000224CB
+:1026E00046006210000000001400C38F2800C28F53
+:1026F00021106200000043803B0002243F00621072
+:10270000000000001400C38F2800C28F2110620057
+:10271000000043803C0002243800621000000000EA
+:102720001400C38F2800C28F211062000000438074
+:102730003D00022431006210000000001400C38F2D
+:102740002800C28F21106200000043803E00022456
+:102750002A006210000000001400C38F2800C28FFE
+:1027600021106200000043805B00022423006210FD
+:10277000000000001400C38F2800C28F21106200E7
+:10278000000043805C0002241C0062100000000076
+:102790001400C38F2800C28F211062000000438004
+:1027A0005D00022415006210000000001400C38FB9
+:1027B0002800C28F21106200000043807C000224A8
+:1027C0000E006210000000001400C38F2800C28FAA
+:1027D00021106200000043802E0002240A006214CF
+:1027E000000000001800C3930100022403006210DF
+:1027F0000000000004000010000000001C00C0AF3A
+:102800003E000010000000002C00C2931400401491
+:10281000000000001400C38F2800C28F2110620046
+:10282000000043802A0002240A0062100000000019
+:102830001400C38F2800C28F211062000000438063
+:102840003F0002240300621000000000040000109A
+:10285000000000001C00C0AF2800001000000000B5
+:102860001400C38F2800C28F211062000000438033
+:102870002E00022403006214000000000100022464
+:102880001800C2A31400C38F2800C28F2110620059
+:102890000000428061004228110040140000000046
+:1028A0001400C38F2800C28F2110620000004280F4
+:1028B0007B0042280A004010000000001400C38F73
+:1028C0002800C28F212062001400C38F2800C28F0D
+:1028D0002110620000004290E0FF4224000082A02C
+:1028E0001400C28F010042241400C2AF48FF001040
+:1028F00000000000010002241C00C2AF1C00C28FB7
+:1029000021E8C0032400BF8F2000BE8F2800BD2710
+:102910000800E00300000000C8FFBD273400BFAF7F
+:102920003000BEAF21F0A0033800C4AF3C00C5AFFB
+:102930004000C6AF3C00C28F2000C2AF3800C28F3B
+:102940000000428C1800C2AF4000C28F2800C2AF06
+:10295000010002242800C38F07006210000000005D
+:10296000020002242800C38F0A0062100000000049
+:102970000D000010000000003800C28F2000C38F3F
+:102980001000428C211062002000C2AF060000102F
+:10299000000000003800C28F1400438C2000C28F5A
+:1029A000231062002000C2AFDC8082930B00401035
+:1029B000000000004547400F0000000007004010E5
+:1029C00000000000090002244C8282A3FFFF0224C1
+:1029D0002400C2AFB4000010000000003800C28F15
+:1029E0000400428C1400C2AF3800C38F1400C28FA1
+:1029F000080062AC3800C28F1400428C1400C2AFD1
+:102A00002000C38F1400C28F2B104300070040101A
+:102A1000000000001F0002244C8282A3FFFF032459
+:102A20002400C3AFA0000010000000003800C48FD5
+:102A30001800838CFBFF022424106200180082AC73
+:102A40003800C38F2000C28F100062AC2000C28FFC
+:102A50002C00C2AF2C00C28F040041040000000013
+:102A60002C00C38FFF0163242C00C3AF2C00C38F45
+:102A7000431203001000C2AF1000C28F401A0200C0
+:102A80002000C28F231043002000C2AF3800C38F44
+:102A90002000C28F0E0062A41800C28F1F00439056
+:102AA0001000C28F1B004300F401600012100000F0
+:102AB0001400C2AF1800C28F1F0043901400C28FD1
+:102AC000021862701000C28F231043001000C2AFC2
+:102AD0003800C38F1000C28F0C0062A41400C28F94
+:102AE00051004010000000003800C48F1400C58F52
+:102AF000EB33400F000000001C00C2A31C00C29377
+:102B000049004010000000001C00C3933C00022458
+:102B10003F006214000000003800C28F1800428C91
+:102B20000000427C1C004010000000003800C38FF1
+:102B30003800C28F0400428C080062AC1400C38FBE
+:102B40000100022408006210000000001400C28F7F
+:102B5000FFFF42243800C48F21284000EB33400F90
+:102B6000000000001C00C2A33800C48F2128000010
+:102B7000853E400F000000002B00401000000000C8
+:102B80000F0002244C8282A3FFFF02242400C2AF64
+:102B900045000010000000003800C38F3800C28FCD
+:102BA0000400428C080062AC1400C28FFFFF422474
+:102BB0003800C48F21284000EB33400F0000000094
+:102BC0001C00C2A31C00C2930700401000000000BC
+:102BD0000F0002244C8282A3FFFF03242400C3AF12
+:102BE00031000010000000003800C38F00020224F2
+:102BF0000E0062A43800C38F1800C28F1F004290DD
+:102C0000FFFF42240C0062A4070000100000000037
+:102C10000F0002244C8282A3FFFF02242400C2AFD3
+:102C200021000010000000003800C28F1800C48F7F
+:102C30000800458C8D45400F000000001400C2AF15
+:102C40003800C28F0C0042941000C2AF1400C38F32
+:102C50001000C28F211062001400C2AFD88080AF74
+:102C6000DE8080A31800C28F1400C48F0000458C42
+:102C7000695B400F000000000700401400000000E6
+:102C80001B0002244C8282A3FFFF03242400C3AF55
+:102C900005000010000000001400C28F188082AFF1
+:102CA0004C8280A32400C0AF2400C28F21E8C0035F
+:102CB0003400BF8F3000BE8F3800BD270800E0030E
+:102CC00000000000C0FFBD273C00BFAF3800BEAF12
+:102CD00021F0A0034000C4AF4400C5AFDE8080A354
+:102CE0004000C28F200042903000C2AF0100022499
+:102CF0003000C38F120062100000000003000224A5
+:102D00003000C38F03006210000000001D0000109F
+:102D1000000000004400C28F801002001400C2AF07
+:102D2000FF0F023CFFFF42342400C2AFFF0F023C02
+:102D3000F8FF42342800C2AF190000100000000064
+:102D40004400C38F21106000401002002110430096
+:102D50001400C2AF1400C28F010042301000C2A3A1
+:102D60001400C28F421002001400C2AFFFFF0234F1
+:102D70002400C2AFF80F02242800C2AF08000010E0
+:102D8000000000004400C28F401002001400C2AFD7
+:102D9000FFFF02342400C2AFF8FF02342800C2AFA4
+:102DA0004000C48F1400C28F421A02000800828CB7
+:102DB000211043001800C2AF1400C28FFF0142303F
+:102DC0001400C2AF1480838F1800C28F6C0062148D
+:102DD000000000004000C28F200043900300022446
+:102DE00009006214000000001400C38F00A0023C20
+:102DF000500F4224211062000000428C1C00C2AF20
+:102E0000C2000010000000004000C28F200043906C
+:102E10000200022409006214000000001400C38FA5
+:102E200000A0023C500F4224211062000000429496
+:102E30001C00C2AFB5000010000000004000C28FAF
+:102E40002000439001000224B00062140000000042
+:102E50001400C38F00A0023C500F422421106200D6
+:102E6000000042901C00C2AF1000C293040040104A
+:102E7000000000001C00C28F021102001C00C2AF43
+:102E80001400C28F01004224FF0142301400C2AF7F
+:102E90001400C28F2200401400000000D4808293EE
+:102EA0000D004010000000004000C48F21280000E9
+:102EB0002130000001000724534C400F00000000A7
+:102EC00005004010000000002400C28F2C00C2AF9B
+:102ED00097000010000000001800C28F010042247B
+:102EE0002120400000A0023C500F4524695B400FA8
+:102EF000000000000700401400000000FFFF023443
+:102F0000148082AF2400C28F2C00C2AF8800001052
+:102F1000000000001800C28F01004224148082AF1C
+:102F20001400C38F00A0023C500F42242110620005
+:102F3000000042902000C2AF1000C2930800401071
+:102F4000000000002000C28F001902001C00C28F88
+:102F5000211043001C00C2AF6C00001000000000F4
+:102F60002000C28F0F004230001A02001C00C28FE6
+:102F7000211043001C00C2AF6400001000000000DC
+:102F8000D48082930D004010000000004000C48FE8
+:102F9000212800002130000001000724534C400F7D
+:102FA0000000000005004010000000002400C28F57
+:102FB0002C00C2AF5E000010000000001800C48F9B
+:102FC00000A0023C500F4524695B400F0000000048
+:102FD0000700401400000000FFFF0234148082AF9D
+:102FE0002400C28F2C00C2AF51000010000000006E
+:102FF0001800C28F148082AF4000C28F200043901F
+:103000000300022409006214000000001400C38FB2
+:1030100000A0023C500F4224211062000000428CAC
+:103020001C00C2AF39000010000000004000C28F39
+:1030300020004390020002240900621400000000F6
+:103040001400C38F00A0023C500F422421106200E4
+:10305000000042941C00C2AF2C00001000000000D1
+:103060004000C28F20004390010002242700621418
+:10307000000000001400C38F00A0023C500F422447
+:1030800021106200000042901C00C2AF1000C293E9
+:1030900004004010000000001C00C28F021102005A
+:1030A0001C00C2AF1400C28F01004224FF01423055
+:1030B0001400C2AF1400C38F00A0023C500F422482
+:1030C00021106200000042902000C2AF1000C293A5
+:1030D00008004010000000002000C28F001902000C
+:1030E0001C00C28F211043001C00C2AF070000105B
+:1030F000000000002000C28F0F004230001A0200C2
+:103100001C00C28F211043001C00C2AF1C00C28FE4
+:103110002800C38F2B104300030040140000000060
+:103120002800C28F1C00C2AF1C00C28F2C00C2AF8F
+:103130002C00C28F21E8C0033C00BF8F3800BE8F37
+:103140004000BD270800E00300000000C8FFBD27C5
+:103150003400BFAF3000BEAF21F0A0033800C4AFD1
+:103160003C00C5AF4000C6AF2110E0004400C2A340
+:103170003800C28F20004390030002241000621028
+:10318000000000003800C28F20004390020002249B
+:103190000B006210000000003800C28F2000439036
+:1031A000010002240600621000000000FF0F023C34
+:1031B000FFFF42342400C2AF4101001000000000B4
+:1031C0003800C28F200042902800C2AF2800C38F71
+:1031D0000100622812004014000000002800C38F84
+:1031E000030062280C0040140000000003000224C9
+:1031F0002800C38F030062100000000008000010C8
+:1032000000000000FF0F023CFFFF42342000C2AF6D
+:103210000300001000000000FFFF02342000C2AFD6
+:10322000DE8080A34400C293240040100000000010
+:103230001000C0A31480828F1800C2AF3800C28F64
+:103240001E0043901000C2932B1043001700401043
+:10325000000000001480848F00A0023C500F452421
+:1032600021300000F15B400F000000000500401419
+:10327000000000002000C28F2400C2AF1001001027
+:10328000000000001000C293010042241000C2A3FD
+:103290003800C28F1C0043941800C28F21104300D5
+:1032A0001800C2AFE5FF001000000000D48080A32A
+:1032B0002400C0AF02010010000000003800C28FDF
+:1032C000200042902C00C2AF010002242C00C38FCA
+:1032D0000C00621000000000030002242C00C38FC9
+:1032E0000300621000000000130000100000000046
+:1032F0003C00C28F801002001400C2AF1100001009
+:10330000000000003C00C38F21106000401002004C
+:10331000211043001400C2AF1400C28F01004230DC
+:103320001100C2A31400C28F421002001400C2AFE9
+:1033300004000010000000003C00C28F401002009A
+:103340001400C2AF3800C48F1400C28F421A0200AA
+:103350000800828C211043001C00C2AF1400C28FF1
+:10336000FF0142301400C2AF1480838F1C00C28F53
+:103370003300621000000000D480829321004010CE
+:10338000000000001000C0A31480828F1800C2AF9C
+:103390003800C28F1E0043901000C2932B104300D0
+:1033A00017004010000000001480848F00A0023C31
+:1033B000500F452421300000F15B400F0000000059
+:1033C00005004014000000002000C28F2400C2AF9E
+:1033D000BB000010000000001000C2930100422456
+:1033E0001000C2A33800C28F1C0043941800C28F83
+:1033F000211043001800C2AFE5FF001000000000DC
+:10340000D48080A31C00C48F00A0023C500F452430
+:10341000695B400F0000000007004014000000003E
+:10342000FFFF0234148082AF2000C28F2400C2AF9D
+:10343000A3000010000000001C00C28F148082AFA7
+:103440003800C28F2000439003000224230062143E
+:10345000000000001400C38F00A0023C500F422463
+:10346000211862004000C28F000062A01400C38FC8
+:1034700000A0023C510F4224211862004000C28F7C
+:1034800000FF423002120200000062A01400C38F4D
+:1034900000A0023C520F4224212062004000C38F52
+:1034A000FF00023C2410620002140200000082A00F
+:1034B0001400C38F00A0023C530F4224212062005D
+:1034C0004000C38F000F023C24106200021602006D
+:1034D000000082A077000010000000003800C28FBA
+:1034E000200043900200022411006214000000003A
+:1034F0001400C38F00A0023C500F42242118620028
+:103500004000C28F000062A01400C38F00A0023CE4
+:10351000510F4224211862004000C28F00FF423048
+:1035200002120200000062A0620000100000000011
+:103530003800C28F20004390010002245D00621415
+:10354000000000001400C38F00A0023C500F422472
+:1035500021106200000042901200C2A31100C29329
+:103560000A004010000000004000C28F0F004230EF
+:10357000001902001200C2930F00423025106200B1
+:103580001200C2A303000010000000004000C28F20
+:103590001200C2A31400C38F00A0023C500F4224AB
+:1035A000211862001200C293000062A01400C28FB2
+:1035B00001004224FF0142301400C2AF1400C28F48
+:1035C0001F004014000000003800C48F21280000B4
+:1035D0002130000001000724534C400F0000000080
+:1035E00005004010000000002000C28F2400C2AF80
+:1035F00033000010000000001C00C28F01004224B4
+:103600002120400000A0023C500F4524695B400F80
+:10361000000000000700401400000000FFFF02341B
+:10362000148082AF2000C28F2400C2AF240000109B
+:10363000000000001C00C28F01004224148082AFF1
+:103640001400C38F00A0023C500F422421106200DE
+:10365000000042901200C2A31100C2930600401065
+:10366000000000004000C28F021102001200C2A33D
+:103670000A000010000000004000C28F0212020089
+:103680000F0044301200C393F0FF022424106200A4
+:1036900021188000251062001200C2A31400C38FFD
+:1036A00000A0023C500F4224211862001200C29375
+:1036B000000062A001000224D48082A32400C0AFD5
+:1036C0002400C28F21E8C0033400BF8F3000BE8FBA
+:1036D0003800BD270800E00300000000E8FFBD2718
+:1036E0001400BFAF1000BEAF21F0A0031800C4AF9C
+:1036F000212000001800C58F21300000C74D400F69
+:103700000000000021E8C0031400BF8F1000BE8F2E
+:103710001800BD270800E0030000000070FFBD276F
+:103720008800BFAF8400BEAF8000B0AF21F0A0031F
+:10373000211080009400C5AF9800C6AF9000C2A3CE
+:10374000010002241200C2A79400C28F1800C2AF69
+:103750002000C2277000C2AF7000C48F1C80858F0C
+:103760006D44400F000000004C8280A31800C28FFF
+:10377000000042901000C2A31000C2930700401442
+:10378000000000001F0002244C8282A3FFFF0224DD
+:103790007400C2AFC4010010000000001000C39309
+:1037A0007800C3AF2E0002247800C38F0700621098
+:1037B000000000005C0002247800C38FC10062108A
+:1037C0000000000007010010000000001800C28F78
+:1037D000010042241800C2AF1800C28F00004290BE
+:1037E0001000C2A31000C3932E0002248B006214A9
+:1037F000000000001800C28F010042241800C2AF70
+:103800001800C28F000042901000C2A37000C28F47
+:103810003400438C3C82828F070062140000000059
+:103820001F0002244C8282A3FFFF02247400C2AF57
+:103830009D010010000000007000C38F7000C28F57
+:103840003400428C380062AC010002241200C2A78E
+:103850001200C2277000C48F2128400001000624F6
+:10386000E73B400F000000001400C2AF1400C28FFD
+:1038700007004014000000001B0002244C8282A3B9
+:10388000FFFF03247400C3AF870100100000000095
+:103890007000D08F1400C48F4836400F0000000025
+:1038A000340002AE7000C38F7000C28F3400428CAF
+:1038B000380062AC7000C28F3400428C1C0040148F
+:1038C000000000007000C28F5C000324200043A0B1
+:1038D000010002241100C2A31100C2930B00422C6C
+:1038E0000B004010000000007000C38F1100C29355
+:1038F0002118620020000224200062A01100C2935F
+:10390000010042241100C2A3F3FF001000000000D8
+:103910007000C38F3C82828F380062AC7000C38F0E
+:103920003C82828F340062AC17000010000000005F
+:103930007000C38F2E000224200062A07000C38F8D
+:103940002E000224210062A0020002241100C2A362
+:103950001100C2930B00422C0B004010000000002D
+:103960007000C38F1100C29321186200200002244E
+:10397000200062A01100C293010042241100C2A3E2
+:10398000F3FF0010000000001200C0A71200C227C1
+:103990007000C48F2128400001000624E73B400F3F
+:1039A0000000000007004014000000001B0002247B
+:1039B0004C8282A3FFFF02247400C2AF3A010010C0
+:1039C000000000001000C3935C0002240900621490
+:1039D000000000001800C28F010042241800C2AF8E
+:1039E0001800C28F000042901000C2A3F5FF001023
+:1039F000000000001000C29368FF401400000000A7
+:103A00001C80848F7000C58F6D44400F0000000043
+:103A10007400C0AF24010010000000001000C29329
+:103A200008004014000000001C80848F7000C58FC7
+:103A30006D44400F000000007400C0AF1A01001078
+:103A4000000000001000C3935C0002241700621401
+:103A5000000000001000C3935C00022409006214FF
+:103A6000000000001800C28F010042241800C2AFFD
+:103A70001800C28F000042901000C2A3F5FF001092
+:103A8000000000001000C29344FF4014000000003A
+:103A90001C80848F7000C58F6D44400F00000000B3
+:103AA0007400C0AF00010010000000001F000224DD
+:103AB0004C8282A3FFFF03247400C3AFFA000010FE
+:103AC000000000001800C28F010042241800C2AF9D
+:103AD0001800C28F000042901000C2A31000C393D0
+:103AE0005C00022407006214000000001F00022492
+:103AF0004C8282A3FFFF02247400C2AFEA000010D0
+:103B0000000000001000C2931D00401400000000DF
+:103B10001C80838F3C82828F340062AC1C80838F38
+:103B20003C82828F380062AC1C80838F5C00022450
+:103B3000200062A0010002241100C2A31100C29360
+:103B40000B00422C0B004010000000001C80838FF3
+:103B50001100C2932118620020000224200062A0FC
+:103B60001100C293010042241100C2A3F3FF001010
+:103B7000000000007400C0AFCB0000100000000087
+:103B80007000C38F3C82828F340062AC7000C38FA0
+:103B90003C82828F380062AC7000C38F5C000224CC
+:103BA000200062A0010002241100C2A31100C293F0
+:103BB0000B00422CF9FE4010000000007000C38F83
+:103BC0001100C2932118620020000224200062A08C
+:103BD0001100C293010042241100C2A3F3FF0010A0
+:103BE000000000001100C0A31000C2931900401093
+:103BF000000000001000C3935C0002241500621056
+:103C0000000000001100C2930C00422C1100401073
+:103C10000000000000A0043C1100C39301006224D6
+:103C20001100C2A3FF006330040F82242118620038
+:103C30001000C293000062A01800C28F010042244D
+:103C40001800C2AF000042901000C2A3E6FF0010AF
+:103C5000000000001100C3930C0002240F00621446
+:103C6000000000001000C2930C0040100000000093
+:103C70001000C3935C0002240800621000000000E2
+:103C80001800C28F010042241800C2AF0000429009
+:103C90001000C2A3F3FF00100000000000A0023CCF
+:103CA0001100C393040F422421106200000040A0C1
+:103CB00000A0023C040F442421280000E748400FE4
+:103CC000000000000500401400000000FFFF032476
+:103CD0007400C3AF74000010000000001100C0A306
+:103CE0001100C2930B00422C17004010000000008E
+:103CF0001100C3931000C227212062007000C38FFF
+:103D00001100C2932110620020004290500082A056
+:103D10007000C38F1100C2932120620000A0023CFA
+:103D20001100C393040F422421106200000042904E
+:103D3000200082A01100C293010042241100C2A3FE
+:103D4000E7FF00100000000000A0023C28124424FD
+:103D50007000C58F6D44400F0000000000A0023CC1
+:103D6000281244247000C58F010006242138000069
+:103D70003D32400F0000000007004010000000002E
+:103D80000C0002244C8282A3FFFF02247400C2AF05
+:103D9000450000100000000000A0023C2812422450
+:103DA000300043941000022407006210000000005D
+:103DB0001F0002244C8282A3FFFF03247400C3AFC0
+:103DC00039000010000000001100C0A31100C293D0
+:103DD0000B00422C0F004010000000007000C38F49
+:103DE0001100C2932120620000A0023C1100C39385
+:103DF000281242242110620020004290200082A05C
+:103E00001100C293010042241100C2A3EFFF001071
+:103E1000000000007000C38F00A0023C2812422462
+:103E20000400428C340062AC7000C38F7000C28FFB
+:103E30003400428C380062AC1000C2930800401479
+:103E4000000000001C80848F7000C58F6D44400FFF
+:103E5000000000007400C0AF13000010000000005C
+:103E60001000C3935C0002244CFE621400000000AA
+:103E70001800C28F010042241800C2AF1800C28F80
+:103E8000000042901000C2A31000C293F4FF40143F
+:103E9000000000001C80848F7000C58F6D44400FAF
+:103EA000000000007400C0AF7400C28F21E8C0039E
+:103EB0008800BF8F8400BE8F8000B08F9000BD2728
+:103EC0000800E00300000000B0FFBD274C00BFAFBA
+:103ED0004800BEAF21F0A0035000C4AF5400C5AFEE
+:103EE0005000C28F05004010000000005400C28F37
+:103EF0004000C2A303000010000000000A000224DA
+:103F00004000C2A34000C2931000C2A300A0023C24
+:103F1000281242241C00C2AF2000C0A33000C0AF52
+:103F20004C8280A35000C28F0600401400000000A5
+:103F300000A0023C641242241400C2AF0B00001027
+:103F4000000000005000C28F1400C2AF5400C28FA6
+:103F500006004014000000001F0002244C8282A3CF
+:103F60003C00C0AFB3010010000000001000C3838C
+:103F70001400C28F21106200FFFF42241800C2AF5C
+:103F80001C00C48F1C80858F6D44400F0000000012
+:103F90001C00C28F200043802E0002249600621471
+:103FA000000000001C00C28F210043802E0002246C
+:103FB00091006214000000001C00C28F3400428C8B
+:103FC0002400C2AF010002242800C2A71C00C38F36
+:103FD0001C00C28F3400428C380062AC2800C2271B
+:103FE0001C00C48F2128400001000624E73B400F3D
+:103FF000000000003800C2AF3800C28F0600401435
+:10400000000000001B0002244C8282A33C00C0AFD1
+:1040100088010010000000003800C48F4836400FAF
+:1040200000000000448282AF4482828F0600401468
+:10403000000000001C00C38F3C82828F340062AC01
+:1040400004000010000000001C00C38F4482828F17
+:10405000340062AC1C00C38F1C00C28F3400428C41
+:10406000380062AC2800C0A72800C2271C00C48FFB
+:104070002128400001000624E73B400F000000001B
+:104080003800C2AF3800C28F0600401400000000A4
+:104090001B0002244C8282A33C00C0AF65010010CB
+:1040A000000000003800C48F4836400F00000000B8
+:1040B000448282AF4482838F2400C28F1600621430
+:1040C000000000004482838F2400C28F2A00621403
+:1040D000000000003800C28F00004390E500022479
+:1040E0000D006210000000003800C28F0B004390EA
+:1040F0000800022408006210000000003800C28F8F
+:104100000B0043900F000224030062100000000027
+:1041100019000010000000002800C297010042248E
+:104120002800C2A72800C2271C00C48F21284000F5
+:1041300021300000E73B400F000000003800C2AF14
+:104140003800C28F06004014000000001B0002244B
+:104150004C8282A33C00C0AF36010010000000007A
+:104160003800C48F4836400F00000000448282AF00
+:10417000D0FF0010000000002C00C0AF2C00C28F48
+:104180000B00422816004010000000001C00C38FE6
+:104190002C00C28F212062003800C38F2C00C28FF8
+:1041A0002110620000004290200082A01C80838FBA
+:1041B0002C00C28F212062003800C38F2C00C28FD8
+:1041C0002110620000004290200082A02C00C28FCB
+:1041D000010042242C00C2AFE8FF001000000000E4
+:1041E0001C00C38F2400C28F340062AC1C00C38F3C
+:1041F0002400C28F380062AC1C00C28F20004380B4
+:104200005C0002240A006214000000001400C38F46
+:104210005C000224000062A01400C28F010040A0D4
+:104220001400C28F3C00C2AF020100100000000069
+:104230001C00C28F3400438C3C82828F8400621049
+:10424000000000000A0002242100C2A31C00C38F4A
+:104250002100C2832110620020004380200002243C
+:1042600006006214000000002100C293FFFF4224F8
+:104270002100C2A3F5FF0010000000002100C2834E
+:10428000080042282D004014000000002100C283D5
+:104290000800422819004014000000003000C62722
+:1042A0000000C48C211880001400C28F21386200E5
+:1042B0001C00C58F2100C393FFFF62242100C2A30D
+:1042C0002014037C2110A200200042900000E2A0F4
+:1042D000010084240000C4AC1000C3833000C28FEE
+:1042E000EAFF6214000000003000C0AF01000224A9
+:1042F0002000C2A3E5FF0010000000003000C52729
+:104300000000A38C212060001400C28F21208200B5
+:104310002E000224000082A0010063240000A3AC50
+:104320001000C3833000C28F04006214000000003C
+:104330003000C0AF010002242000C2A31C00C38FC4
+:104340002100C2832110620020004380200002244B
+:1043500006006214000000002100C293FFFF422407
+:104360002100C2A3F5FF0010000000002100C2835D
+:1043700019004004000000003000C6270000C48C73
+:10438000211880001400C28F213862001C00C58FE4
+:104390002100C393FFFF62242100C2A32014037CE9
+:1043A0002110A200200042900000E2A0010084241D
+:1043B0000000C4AC1000C3833000C28FEBFF621456
+:1043C000000000003000C0AF010002242000C2A3A2
+:1043D000E6FF0010000000003000C5270000A38C9D
+:1043E000212060001400C28F212082005C00022482
+:1043F000000082A0010063240000A3AC1000C3836E
+:104400003000C28F04006214000000003000C0AF12
+:10441000010002242000C2A31C00C38F1C00C28F15
+:104420003400428C380062AC1C00C48F9451400FA1
+:10443000000000007EFF4010000000000800022481
+:104440004C8282A33C00C0AF7A0000100000000044
+:104450003000C28FFFFF42243000C2AF2C00C0AF3B
+:104460002000C2934C004010000000003000C28FBA
+:104470002A00C2A73000C28F2C00C38F2310430034
+:104480001B004018000000002C00C38F1400C28FD6
+:1044900021106200000042903400C2A32C00C38FA0
+:1044A0001400C28F212062003000C38F1400C28F1D
+:1044B0002110620000004290000082A03000C38FF3
+:1044C0001400C28F211862003400C293000062A061
+:1044D0003000C28FFFFF42243000C2AF2C00C28FD9
+:1044E000010042242C00C2AFE2FF001000000000D7
+:1044F0002A00C297010042242C00C2AF1800C38FCB
+:104500001400C28F231062003000C2AF3000C28F8F
+:104510002C00C38F231043001B0040180000000034
+:104520002C00C38F1400C28F211062000000429043
+:104530003400C2A32C00C38F1400C28F212062005C
+:104540003000C38F1400C28F21106200000042901F
+:10455000000082A03000C38F1400C28F21186200B7
+:104560003400C293000062A03000C28FFFFF4224DB
+:104570003000C2AF2C00C28F010042242C00C2AF19
+:10458000E2FF0010000000001800C28F000040A0F1
+:1045900026000010000000003000C28F2A00C2A7D1
+:1045A0003000C28F2C00C38F231043001B00401823
+:1045B000000000002C00C38F1400C28F2110620085
+:1045C000000042903400C2A32C00C38F1400C28F9D
+:1045D000212062003000C38F1400C28F21106200BE
+:1045E00000004290000082A03000C38F1400C28FF0
+:1045F000211862003400C293000062A03000C28F14
+:10460000FFFF42243000C2AF2C00C28F01004224C1
+:104610002C00C2AFE2FF0010000000002A00C29789
+:104620001400C38F21104300010040A01400C28F6A
+:104630003C00C2AF3C00C28F21E8C0034C00BF8FDA
+:104640004800BE8F5000BD270800E00300000000B6
+:10465000D8FFBD272400BFAF2000BEAF21F0A003CC
+:104660002800C4AF010002241200C2A71200C22712
+:104670002800C48F2128400001000624E73B400F9A
+:10468000000000001800C2AF1800C28F05004014DF
+:1046900000000000FF0002241C00C2AFA7000010B1
+:1046A000000000001800C48F4836400F00000000D2
+:1046B000448282AF4482828F1B00401400000000BD
+:1046C0002800C38F5C000224200062A01000C0A359
+:1046D0001000C2930B00422C0B00401000000000A1
+:1046E0002800C38F1000C29321186200200002240A
+:1046F000200062A01000C293010042241000C2A357
+:10470000F3FF0010000000002800C38F3C82828F5E
+:10471000340062AC2800C38F3C82828F380062ACC8
+:1047200085000010000000004482828F1400C2AF98
+:104730002800C38F4482828F340062AC2800C38F6C
+:104740004482828F380062AC1200C2272800C48FD6
+:104750002128400001000624E73B400F0000000034
+:104760001800C2AF1800C28F0500401400000000FE
+:10477000FF0002241C00C2AF700000100000000007
+:104780001800C48F4836400F00000000448282AFFA
+:104790004482828F06004014000000002800C38F6E
+:1047A0003C82828F340062AC0400001000000000E4
+:1047B0002800C38F4482828F340062AC2800C38FEC
+:1047C0002800C28F3400428C380062AC1200C0A7AF
+:1047D0001200C2272800C48F2128400001000624AF
+:1047E000E73B400F000000001800C2AF1800C28F66
+:1047F0000500401400000000FF0002241C00C2AFAE
+:104800004E000010000000001800C48F4836400F12
+:1048100000000000448282AF4482838F1400C28F64
+:1048200016006214000000004482838F1400C28FBF
+:1048300029006214000000001800C28F000043909D
+:10484000E50002240D006210000000001800C28F75
+:104850000B004390080002240800621000000000D2
+:104860001800C28F0B0043900F0002240300621057
+:104870000000000018000010000000001200C22715
+:104880002800C48F2128400021300000E73B400F62
+:10489000000000001800C2AF1800C28F05004014CD
+:1048A00000000000FF0002241C00C2AF2300001023
+:1048B000000000001200C297010042241200C2A7AB
+:1048C0001800C48F4836400F00000000448282AFB9
+:1048D000D1FF0010000000001000C0A31000C29320
+:1048E0000B00422C0E004010000000002800C38F77
+:1048F0001000C293212062001800C38F1000C293E1
+:104900002110430000004290200082A01000C293BA
+:10491000010042241000C2A3F0FF001000000000BC
+:104920002800C38F1400C28F340062AC2800C38FEC
+:104930001400C28F380062AC1C00C0AF1C00C28FD4
+:1049400021E8C0032400BF8F2000BE8F2800BD27B0
+:104950000800E00300000000E8FFBD271400BFAF1F
+:104960001000BEAF21F0A0031800C4AF212000004A
+:104970001800C58F213000006652400F0000000073
+:1049800021E8C0031400BF8F1000BE8F1800BD27A0
+:104990000800E00300000000C8FFBD273400BFAFDF
+:1049A0003000BEAF21F0A003211080003C00C5AF55
+:1049B0004000C6AF3800C2A33C00C28F1400C2AF93
+:1049C00000A0023C140F42242800C2AF4C8280A3F6
+:1049D0006B5C400F0000000007004010000000006A
+:1049E000180002244C8282A3FFFF02242C00C2AFD5
+:1049F00090010010000000001000C0A31400C28F3E
+:104A00000000428013004010000000001400C28F1C
+:104A1000000043802E0002240E00621000000000FF
+:104A20001400C28F000043805C0002240900621061
+:104A3000000000001400C28F010042241400C2AF25
+:104A40001000C293010042241000C2A3EBFF00102B
+:104A5000000000001000C2930900422C070040141F
+:104A6000000000001F0002244C8282A3FFFF0224EA
+:104A70002C00C2AF6F010010000000001400C28FB4
+:104A8000000043802E000224200062140000000079
+:104A90001400C28F010042241400C2AF1000C0A352
+:104AA0001400C28F000042800E0040100000000081
+:104AB0001400C28F000043805C00022409006210D1
+:104AC000000000001400C28F010042241400C2AF95
+:104AD0001000C293010042241000C2A3F0FF001096
+:104AE000000000001000C2930400422C0700401494
+:104AF000000000001F0002244C8282A3FFFF02245A
+:104B00002C00C2AF4B010010000000001400C28F47
+:104B1000000043805C0002240600621400000000D4
+:104B20001400C28F010042241400C2AFF7FF00102E
+:104B3000000000001400C28F00004280AEFF40144D
+:104B4000000000003C00C28F1400C2AF2800C48FD8
+:104B50001C80858F6D44400F000000001400C28F40
+:104B6000000042901000C2A31000C3932E00022444
+:104B700057006214000000001400C28F010042249C
+:104B80001400C2AF1400C28F000042901000C2A3F4
+:104B90001000C3932E0002240E00621000000000DB
+:104BA0001000C2930B004010000000001000C393DF
+:104BB0005C00022407006210000000001F000224B5
+:104BC0004C8282A3FFFF02242C00C2AF1901001007
+:104BD000000000001000C3932E0002242300621482
+:104BE000000000001C80828F3400438C3C82828F46
+:104BF00007006214000000001F0002244C8282A300
+:104C0000FFFF02242C00C2AF0A01001000000000C8
+:104C10001400C28F010042241400C2AF1400C28FDE
+:104C2000000042901000C2A31000C3935C00022455
+:104C30000A006210000000001000C293070040103C
+:104C4000000000001F0002244C8282A3FFFF022408
+:104C50002C00C2AFF700001000000000029D023CD3
+:104C6000A0054424B74D400F000000001000C3937E
+:104C70005C00022409006214000000001400C28FCE
+:104C8000010042241400C2AF1400C28F0000429001
+:104C90001000C2A3F5FF0010000000001000C29336
+:104CA000AEFF4014000000001C80848F2800C58FD8
+:104CB0006D44400F000000001F0002244C8282A3BC
+:104CC000FFFF02242C00C2AFDA0000100000000039
+:104CD0001000C3935C0002243B006214000000003B
+:104CE0001C80838F3C82828F340062AC1C80838F57
+:104CF0003C82828F380062AC1C80838F5C0002246F
+:104D0000200062A0010002241000C2A31000C29380
+:104D10000B00422C0B004010000000001C80838F11
+:104D20001000C2932118620020000224200062A01B
+:104D30001000C293010042241000C2A3F3FF001030
+:104D4000000000001400C28F010042241400C2AF12
+:104D50001400C28F000042901000C2A31000C39341
+:104D60005C0002240B006214000000001C80848F91
+:104D70002800C58F6D44400F000000001F00022472
+:104D80004C8282A3FFFF02242C00C2AFA9000010B6
+:104D9000000000001000C29370FF401400000000EB
+:104DA0001C80848F2800C58F6D44400F00000000D8
+:104DB0001F0002244C8282A3FFFF02242C00C2AFFA
+:104DC0009C000010000000002400C0A31400C28F4B
+:104DD000000042901000C2A31100C0A31000C293B3
+:104DE00019004010000000001000C3935C00022472
+:104DF00015006210000000001100C2930C00422C4C
+:104E000011004010000000001100C3930100622453
+:104E10001100C2A3FF0063301000C22721186200F6
+:104E20001000C293080062A01400C28F0100422447
+:104E30001400C2AF1400C28F000042901000C2A341
+:104E4000E6FF0010000000001100C3931000C2270D
+:104E500021106200080040A01800C3832E00022425
+:104E600023006214000000001900C2830F004010EC
+:104E7000000000001900C3832E0002240B00621002
+:104E8000000000001C80848F2800C58F6D44400FF7
+:104E9000000000001F0002244C8282A3FFFF0224B6
+:104EA0002C00C2AF63000010000000001900C38393
+:104EB0002E0002240E006214000000001A00C283BB
+:104EC0000B004010000000001C80848F2800C58F5C
+:104ED0006D44400F000000001F0002244C8282A39A
+:104EE000FFFF02242C00C2AF52000010000000009F
+:104EF0001800C22721204000B74D400F00000000DD
+:104F00000300401000000000170000100000000027
+:104F10001000C3935C00022409006214000000002A
+:104F20001400C28F010042241400C2AF1400C28FCB
+:104F3000000042901000C2A3F5FF00100000000026
+:104F40001000C293A1FF4014000000001C80848F59
+:104F50002800C58F6D44400F000000002C00C0AF3A
+:104F600034000010000000001800C227212040007B
+:104F70001454400F0000000009004014000000001D
+:104F80001C80848F2800C58F6D44400F00000000F6
+:104F9000FFFF02242C00C2AF26000010000000001A
+:104FA0001800C22721204000B74D400F000000002C
+:104FB0000B004010000000001C80848F2800C58F6B
+:104FC0006D44400F000000001B0002244C8282A3AD
+:104FD000FFFF02242C00C2AF1600001000000000EA
+:104FE0001400C28F000043805C0002240900621498
+:104FF000000000001400C28F010042241400C2AF60
+:105000001400C28F000042901000C2A3F4FF0010F1
+:10501000000000001000C2936CFF4014000000006C
+:105020001C80848F2800C58F6D44400F0000000055
+:105030002C00C0AF2C00C28F21E8C0033400BF8F0A
+:105040003000BE8F3800BD270800E00300000000DC
+:10505000C8FFBD273400BFAF3000BEAF21F0A003B2
+:105060003800C4AF00A0023C281242241000C2AF96
+:105070001800C0A72400C0A32400C2930C00422C37
+:105080000F0040100000000000A0023C2400C39369
+:10509000040F4224212062002400C3933800C28FF1
+:1050A0002110620000004290000082A02400C29300
+:1050B000010042242400C2A3EFFF00100000000002
+:1050C00000A0023C040F442421280000E748400FC0
+:1050D000000000000600401400000000120002243E
+:1050E0004C8282A32800C0AF6F00001000000000B7
+:1050F0002400C0A32400C2930B00422C0F004010D8
+:10510000000000001000C38F2400C2932120620021
+:1051100000A0023C2400C393040F4224211062002B
+:1051200000004290200082A02400C293010042248B
+:105130002400C2A3EFFF0010000000001000C38F86
+:105140001C80828F3400428C340062AC1000C38F0C
+:105150001C80828F3800428C380062AC1000C28FF5
+:10516000040040AC1000C28F080040AC1000C38F98
+:105170001C80828F0000428C000062AC1800C227A5
+:105180001000C48F2128400012000624CD3C400F9F
+:105190000000000004004010000000002800C0AF24
+:1051A0004100001000000000D48082930F004010E6
+:1051B000000000001000C28F0000448C2128000075
+:1051C0002130000001000724534C400F0000000074
+:1051D0000600401000000000090002244C8282A357
+:1051E0002800C0AF30000010000000001000C28F87
+:1051F0003400438C3C82828F040062140000000063
+:105200002000C0AF04000010000000001000C28F9A
+:105210003400428C2000C2AF1000C38F1000C28F38
+:105220003400428C380062AC1800C2271000C48FD2
+:105230002128400001000624E73B400F0000000049
+:105240001400C2AF1400C28F06004014000000001A
+:105250001B0002244C8282A32800C0AF1200001061
+:10526000000000001400C48F4836400F000000000A
+:105270001C00C2AF1000C28F0000448C1C00C58F00
+:105280002000C68FB154400F000000000500401000
+:1052900000000000010002242800C2AF020000103C
+:1052A000000000002800C0AF2800C28F21E8C00322
+:1052B0003400BF8F3000BE8F3800BD270800E003E8
+:1052C00000000000B0FFBD274C00BFAF4800BEAFDC
+:1052D00021F0A0035000C4AF5400C5AF5800C6AFC2
+:1052E0001800C2273800C2AFD88080AF2000022447
+:1052F0001200C2A75000C28F0000448C2128000079
+:1053000000020624276A400F000000002E0002243D
+:105310001800C2A3010002241000C2A71000C29707
+:105320000B00422C0B004010000000001000C3973F
+:105330001000C2272118620020000224080062A089
+:105340001000C297010042241000C2A7F3FF001012
+:1053500000000000100002242300C2A32400C0A308
+:105360005400C28F3200C2A75400C38FFF0F023C0B
+:1053700024106200021402002C00C2A73400C0AF47
+:10538000378282932500C2A3388282972600C2A763
+:10539000428282972800C2A72A00C0A72E00C0A779
+:1053A0003000C0A71000C0A71000C2971200C3971A
+:1053B0002B1043000F004010000000005000C28F6F
+:1053C0001000C3970000428C212062001000C39798
+:1053D0003800C28F2110620000004290000082A0BD
+:1053E0001000C297010042241000C2A7EEFF001077
+:1053F000000000002E0002241900C2A35800C28F32
+:105400003200C2A75800C38FFF0F023C2410620075
+:10541000021402002C00C2A71000C0A71000C297FF
+:105420001200C3972B104300110040100000000031
+:105430005000C28F1000C4971200C3970000428C26
+:1054400021106200212044001000C3973800C28F51
+:105450002110620000004290000082A01000C2975C
+:10546000010042241000C2A7ECFF00100000000061
+:105470005000C48F5400C58F8D45400F00000000C0
+:105480003C00C2AF5000C28F3C00C48F0000458C6E
+:1054900021300000F15B400F0000000006004014C6
+:1054A00000000000090002244C8282A34000C0AF2B
+:1054B0000300001000000000010002244000C2AF01
+:1054C0004000C28F21E8C0034C00BF8F4800BE8F50
+:1054D0005000BD270800E00300000000E8FFBD27E2
+:1054E0001400BFAF1000BEAF21F0A0031800C4AF7E
+:1054F0002110A0001C00C2A31C00C29321200000A8
+:105500001800C58F21300000213840004B55400F56
+:105510000000000021E8C0031400BF8F1000BE8F00
+:105520001800BD270800E00300000000B8FFBD27F9
+:105530004400BFAF4000BEAF21F0A003211880009F
+:105540004C00C5AF5000C6AF2110E0004800C3A317
+:105550005400C2A300A0023C140F42241000C2AFAA
+:1055600000A0023C281242241400C2AF1C00C0A7B5
+:10557000029D023CA405448CA40543240400638CD2
+:10558000A40542240800428C2800C4AF2C00C3AFFD
+:105590003000C2AF3400C0A34C8280A31000C48F7F
+:1055A0001C80858F6D44400F000000004C00C48FAC
+:1055B000B74D400F00000000070040100000000041
+:1055C0000C0002244C8282A3FFFF02243800C2AFE9
+:1055D00080020010000000001C80828F3400438C89
+:1055E0003C82828F09006210000000001C80828FC4
+:1055F0001000C38F3400448C3400628C030082108E
+:10560000000000000B000010000000001C80848FD0
+:105610001000C58F6D44400F000000001F000224E1
+:105620004C8282A3FFFF02243800C2AF690200103F
+:10563000000000001C00C297010042241C00C2A709
+:105640001C00C2271C80848F2128400001000624F2
+:10565000E73B400F000000001800C2AF1800C28FE7
+:105660000B004014000000001C80848F1000C58FC8
+:105670006D44400F000000001B0002244C8282A3F6
+:10568000FFFF02243800C2AF5202001000000000E9
+:105690001C00C297010042241C00C2A71C00C227A4
+:1056A0001C80848F2128400021300000E73B400F00
+:1056B000000000001800C2AF1800C28F0B00401499
+:1056C000000000001C80848F1000C58F6D44400FC7
+:1056D000000000001B0002244C8282A3FFFF022472
+:1056E0003800C2AF3B020010000000005400C2931B
+:1056F0002B004014000000001800C28F0000428000
+:10570000E8014010000000001800C28F0000439024
+:10571000E50002240B006210000000001C80848F52
+:105720001000C58F6D44400F0000000016000224D9
+:105730004C8282A3FFFF02243800C2AF2502001072
+:10574000000000001C00C297010042241C00C2A7F8
+:105750001C00C2271C80848F2128400021300000BB
+:10576000E73B400F000000001800C2AF1800C28FD6
+:10577000E1FF4014000000001C80848F1000C58FE2
+:105780006D44400F000000001B0002244C8282A3E5
+:10579000FFFF02243800C2AF0E020010000000001C
+:1057A000488280A32000C0A748828293BD01401494
+:1057B000000000001800C28F00004280EE00401080
+:1057C000000000001800C28F00004390E500022492
+:1057D000C1006210000000001800C28F0B0043904F
+:1057E00008000224BC006210000000001800C28FF4
+:1057F0000B0043900F000224B7006210000000006D
+:105800001800C28F0B004290100042307000401010
+:10581000000000002000C297010042242000C2A71F
+:105820002200C0A32200C2930800422C15004010A1
+:10583000000000001800C38F2200C2932110430013
+:1058400000004380200002240E00621000000000CF
+:105850002200C3931000C227212062001800C38FCA
+:105860002200C2932110430000004290180082A041
+:105870002200C293010042242200C2A3E9FF0010CB
+:10588000000000001800C28F08004380200002249E
+:1058900025006210000000002200C3930100622472
+:1058A0002200C2A3FF0063301000C227211862004B
+:1058B0002E000224180062A02300C0A32300C2937C
+:1058C0000300422C18004010000000001800C38F95
+:1058D0002300C293211062000800438020000224AC
+:1058E00011006210000000002200C3930100622436
+:1058F0002200C2A3FF0063301000C22721206200F3
+:105900001800C38F2300C293211062000800429048
+:10591000180082A02300C293010042242300C2A3E6
+:10592000E6FF0010000000002200C3931000C22711
+:1059300021106200180040A02800C227212040004A
+:10594000B74D400F000000000B00401000000000A9
+:105950001C80848F1000C58F6D44400F0000000034
+:105960000C0002244C8282A3FFFF02243800C2AF45
+:1059700098010010000000001C80828F1000C38F6F
+:105980003400448C3400628C0B0082140000000050
+:105990001C80848F1000C58F6D44400F00000000F4
+:1059A0001F0002244C8282A3FFFF02243800C2AFF2
+:1059B0008801001000000000020002241C00C2A7A1
+:1059C00001000224DF8082A34600001000000000D6
+:1059D0002800C22721204000212800000C000624B6
+:1059E000276A400F000000002200C0A32200C293DB
+:1059F0000B00422C0E004010000000001400C38F6A
+:105A00002200C293212062001800C38F2200C2939B
+:105A10002110430000004290200082A02200C29387
+:105A2000010042242200C2A3F0FF00100000000089
+:105A30001400C38F00A0023C04124224000062AC98
+:105A40001400C38F1C00C2972C0062A41400C38FE3
+:105A50001C80828F3400428C340062AC1400C38FEF
+:105A60001C80828F3800428C380062AC1400C28FD8
+:105A7000040040AC1400C28F080040AC1C00C227D8
+:105A80001400C48F2128400001000624CA40400FA2
+:105A9000000000000B004010000000001C80848FFC
+:105AA0001000C58F6D44400F00000000010002246B
+:105AB0004C8282A3FFFF02243800C2AF45010010D0
+:105AC000000000001C00C297010042241C00C2A775
+:105AD00004000010000000001C00C29701004224D6
+:105AE0001C00C2A7DF8082930F004010000000005E
+:105AF000DF8080A31C80838F1C80828F3400428CC7
+:105B0000380062AC1C00C2271C80848F2128400012
+:105B100001000624E73B400F000000001800C2AF60
+:105B200008000010000000001C00C2271C80848FA9
+:105B30002128400021300000E73B400F000000001A
+:105B40001800C2AF1800C28F17FF401400000000F9
+:105B50001C80848F1000C58F6D44400F0000000032
+:105B60001B0002244C8282A3FFFF02243800C2AF34
+:105B700018010010000000002000C297C50040106E
+:105B8000000000001E00C0A71C80838F1C80828F35
+:105B90003400428C380062AC1E00C2271C80848F07
+:105BA0002128400001000624E73B400F00000000D0
+:105BB0001800C2AF1800C28F0B0040140000000094
+:105BC0001C80848F1000C58F6D44400F00000000C2
+:105BD0001B0002244C8282A3FFFF02243800C2AFC4
+:105BE000FC000010000000001800C48F4836400F71
+:105BF000000000001E00C2A7029D023CA005442434
+:105C0000B74D400F000000000B00401000000000E6
+:105C10001C80848F1000C58F6D44400F0000000071
+:105C20000C0002244C8282A3FFFF02243800C2AF82
+:105C3000E800001000000000020002241C00C2A7BF
+:105C40001C80838F1C80828F3400428C380062ACB1
+:105C50001C00C2271C80848F2128400001000624DC
+:105C6000E73B400F000000001800C2AF1800C28FD1
+:105C70000B004014000000001C80848F1000C58FB2
+:105C80006D44400F000000001B0002244C8282A3E0
+:105C9000FFFF02243800C2AFCE0000100000000059
+:105CA0001800C48F4836400F00000000448282AFC5
+:105CB0001E00C3974482828F11006214000000000E
+:105CC0001E00C3974482828F2A00621400000000E5
+:105CD0001800C28F00004390E50002240800621003
+:105CE000000000001800C28F0B004390080002243F
+:105CF00003006210000000001E0000100000000001
+:105D00001C00C297010042241C00C2A71C00C2272D
+:105D10001C80848F2128400021300000E73B400F89
+:105D2000000000001800C2AF1800C28F0B00401422
+:105D3000000000001C80848F1000C58F6D44400F50
+:105D4000000000001B0002244C8282A3FFFF0224FB
+:105D50003800C2AF9F000010000000001800C48F80
+:105D60004836400F00000000448282AFD0FF001090
+:105D7000000000002800C227212040002128000048
+:105D80000C000624276A400F000000002200C0A378
+:105D90002200C2930B00422C0E00401000000000B5
+:105DA0002200C3931000C227212062001800C38F75
+:105DB0002200C2932110430000004290180082A0EC
+:105DC0002200C293010042242200C2A3F0FF00106F
+:105DD000000000002800C22721204000FC57400F8F
+:105DE000000000000B004010000000001C80848FA9
+:105DF0001000C58F6D44400F000000000100022418
+:105E00004C8282A3FFFF02243800C2AF7100001051
+:105E1000000000001C00C297010042241C00C2A721
+:105E20001C80838F1C80828F3400428C380062ACCF
+:105E30001C00C2271C80848F2128400001000624FA
+:105E4000E73B400F000000001800C2AF1800C28FEF
+:105E50000B004014000000001C80848F1000C58FD0
+:105E60006D44400F000000001B0002244C8282A3FE
+:105E7000FFFF02243800C2AF5600001000000000EF
+:105E80002000C297FFFF42242000C2A746FE001058
+:105E90000000000001000224488282A342FE00109C
+:105EA000000000002800C227212040000C0005242B
+:105EB000B24F400F00000000090040140000000035
+:105EC0001C80848F1000C58F6D44400F00000000BF
+:105ED000FFFF02243800C2AF3E00001000000000A7
+:105EE0002800C22721204000212800000C000624A1
+:105EF000276A400F000000002200C0A32200C293C6
+:105F00000B00422C0E004010000000002200C39342
+:105F10001000C227212062001C80838F2200C293C0
+:105F20002110620020004290180082A02200C2933B
+:105F3000010042242200C2A3F0FF00100000000074
+:105F4000029D023CA0054424B74D400F0000000014
+:105F50000B004010000000001C80848F1000C58FD3
+:105F60006D44400F000000000C0002244C8282A30C
+:105F7000FFFF02243800C2AF16000010000000002E
+:105F80002800C22721204000FC57400F00000000DD
+:105F90000B004010000000001C80848F1000C58F93
+:105FA0006D44400F00000000010002244C8282A3D7
+:105FB000FFFF02243800C2AF0600001000000000FE
+:105FC0001C80848F1000C58F6D44400F00000000BE
+:105FD0003800C0AF3800C28F21E8C0034400BF8F33
+:105FE0004000BE8F4800BD270800E003000000000D
+:105FF00098FFBD276400BFAF6000BEAF21F0A003D3
+:106000006800C4AF6B5C400F00000000050040104A
+:1060100000000000FFFF02245800C2AF4B00001038
+:10602000000000001800C227212040001C80858F3E
+:106030006D44400F000000001400C0A31400C29380
+:106040000B00422C0E004010000000001C80838FCB
+:106050001400C293212062001400C3936800C28F11
+:106060002110620000004290200082A01400C29320
+:10607000010042241400C2A3F0FF00100000000041
+:1060800000A0023C281244241C80858F6D44400FE0
+:10609000000000001C80848F00A0023C28124524D0
+:1060A00001000624213800003D32400F00000000AE
+:1060B0001000C2AF1000C28F0A00401000000000A4
+:1060C0001800C2271C80848F212840006D44400F97
+:1060D00000000000FFFF02245800C2AF1B000010A8
+:1060E000000000001C80828F2C0042241C80848FC2
+:1060F0002128400001000624CA40400F0000000093
+:106100001000C2AF1000C28F090040140000000050
+:106110001800C2271C80848F212840006D44400F46
+:10612000000000005800C0AF080000100000000090
+:106130001800C2271C80848F212840006D44400F26
+:1061400000000000FFFF02245800C2AF5800C28FB9
+:1061500021E8C0036400BF8F6000BE8F6800BD27C8
+:106160000800E0030000000098FFBD276400BFAFF7
+:106170006000BEAF21F0A0036800C4AF6C00C5AFE3
+:106180007000C6AF1000C2275000C2AF4C8280A37F
+:106190005000C28F200042246800C48F2128400094
+:1061A000010006244948400F000000000700401489
+:1061B00000000000120002244C8282A3FFFF022490
+:1061C0005C00C2AFF0000010000000007000C28F41
+:1061D000300040A05B00C0A35B00C2930C00422CC7
+:1061E00014004010000000005B00C3936800C28FE1
+:1061F00021106200000042800E00401000000000EC
+:106200007000C38F5B00C293212062005B00C393C8
+:106210006800C28F21106200000042901C0082A022
+:106220005B00C293010042245B00C2A3EAFF00109E
+:10623000000000007000C38F5B00C2932110620059
+:106240001C0040A07000C38F6C00C28F290062A0A8
+:106250007000C38F1C80828F3400428C2C0062AC93
+:106260005000C38F00A0023C04124224000062AC24
+:106270005000C28F040040AC5000C28F080040ACF8
+:106280005000C28F2C0040A45000C38F6C00C28FFE
+:10629000300062A45000C38F1C80828F3400428C77
+:1062A000340062AC5000C38F1C80828F3800428C57
+:1062B000380062AC00A0023C281244245000C58F74
+:1062C0006D44400F000000005000C48F00A0023C4D
+:1062D0002812452401000624010007243D32400F06
+:1062E000000000005400C2AF5400C28F07004010ED
+:1062F000000000000B0002244C8282A3FFFF022456
+:106300005C00C2AFA0000010000000005000C28F6F
+:106310002C0042945800C2A75800C2275000C48FD6
+:1063200021284000720006244933400F000000007D
+:106330005400C2AF5400C28F8F0040140000000010
+:106340005000C28F30004394080002245A006210AB
+:10635000000000005B00C0A35A00C0A35A00C29313
+:106360000800422C18004010000000005000C38FAD
+:106370005A00C293211062002000438020000224B2
+:1063800011006210000000007000C38F5B00C29318
+:10639000212043005000C38F5A00C2932110620095
+:1063A00020004290000082A05B00C29301004224C2
+:1063B0005B00C2A35A00C293010042245A00C2A348
+:1063C000E6FF0010000000005000C28F280043804C
+:1063D000200002240D006214000000005000C28F53
+:1063E00029004380200002240800621400000000FD
+:1063F0005000C28F2A004380200002240300621450
+:106400000000000009000010000000007000C48FB0
+:106410005B00C393010062245B00C2A3FF006230F3
+:10642000211844002E000224000062A0080002246B
+:106430005A00C2A35A00C2930B00422C180040100D
+:10644000000000005000C38F5A00C2932110620068
+:106450002000438020000224110062100000000090
+:106460007000C38F5B00C293212043005000C38F94
+:106470005A00C2932110620020004290000082A0C6
+:106480005B00C293010042245B00C2A35A00C29386
+:10649000010042245A00C2A3E6FF001000000000E1
+:1064A0007000C28F5B00C39321106200000040A007
+:1064B00017000010000000005B00C0A35B00C29347
+:1064C0000B00422C0E004010000000007000C38F33
+:1064D0005B00C293212043005000C38F5B00C29336
+:1064E0002110620020004290000082A05B00C29355
+:1064F000010042245B00C2A3F0FF00100000000076
+:106500007000C28F5B00C39321106200000040A0A6
+:106510007000C38F5000C28F300042940D0062A003
+:106520007000C38F5000C28F1400428C100062AC08
+:106530007000C48F5000C28F1E004294001C0200E5
+:106540005000C28F1C00429421106200140082ACE3
+:106550007000C38F5000C28F2C004294180062ACB0
+:106560007000C38F01000224300062A05C00C0AF45
+:1065700005000010000000001B0002244C8282A3D2
+:10658000FFFF02245C00C2AF5C00C28F21E8C003A1
+:106590006400BF8F6000BE8F6800BD270800E00365
+:1065A0000000000098FFBD276400BFAF6000BEAFD1
+:1065B00021F0A0036800C4AF1000C2275000C2AF92
+:1065C0004C8280A36800C28F3000429007004014C4
+:1065D00000000000070002244C8282A3FFFF022477
+:1065E0005C00C2AFD6000010000000006800C28F3F
+:1065F0001C80838F2C00448C3400628C0700821036
+:10660000000000001F0002244C8282A3FFFF02242E
+:106610005C00C2AFCA000010000000006800C28F1A
+:106620001C0043245000C28F20004224212060001F
+:1066300021284000010006244948400F00000000C6
+:106640000700401400000000120002244C8282A3C4
+:10665000FFFF02245C00C2AFB90000100000000080
+:106660005000C38F00A0023C04124224000062AC20
+:106670005000C28F040040AC5000C28F080040ACF4
+:106680005000C38F6800C28F1800428C0100422462
+:106690002C0062A45000C38F6800C28F2900429072
+:1066A000300062A45000C38F1C80828F3400428C63
+:1066B000340062AC5000C38F1C80828F3800428C43
+:1066C000380062AC00A0023C281244245000C58F60
+:1066D0006D44400F000000005000C48F00A0023C39
+:1066E0002812452401000624010007243D32400FF2
+:1066F000000000005400C2AF5400C28F07004010D9
+:10670000000000000B0002244C8282A3FFFF022441
+:106710005C00C2AF8A000010000000005000C28F71
+:1067200030004394080002245A0062100000000068
+:106730005800C0A35900C0A35900C2930800422CBE
+:1067400018004010000000005000C38F5900C29391
+:1067500021106200200043802000022411006210FA
+:10676000000000006800C38F5800C293212043003E
+:106770005000C38F5900C293211062002000429044
+:10678000000082A05800C293010042245800C2A316
+:106790005900C293010042245900C2A3E6FF001031
+:1067A000000000005000C28F280043802000022417
+:1067B0000D006214000000005000C28F29004380C9
+:1067C0002000022408006214000000005000C28F64
+:1067D0002A0043802000022403006214000000000D
+:1067E00009000010000000006800C48F5800C39327
+:1067F000010062245800C2A3FF0062302118440047
+:106800002E000224000062A0080002245900C2A346
+:106810005900C2930B00422C1800401000000000E9
+:106820005000C38F5900C2932110620020004380A2
+:106830002000022411006210000000006800C38FD5
+:106840005800C293212043005000C38F5900C293C7
+:106850002110620020004290000082A05800C293E4
+:10686000010042245800C2A35900C29301004224EF
+:106870005900C2A3E6FF0010000000006800C28FAC
+:106880005800C39321106200000040A017000010C0
+:10689000000000005800C0A35800C2930B00422C17
+:1068A0000E004010000000006800C38F5800C29323
+:1068B000212043005000C38F5800C2932110620072
+:1068C00020004290000082A05800C29301004224A0
+:1068D0005800C2A3F0FF0010000000006800C28F43
+:1068E0005800C39321106200000040A06800C38FCD
+:1068F0005000C28F300042940D0062A06800C38F28
+:106900005000C28F1400428C100062AC6800C48F2B
+:106910005000C28F1E004294001C02005000C28F23
+:106920001C00429421106200140082AC6800C38FE6
+:106930005000C28F2C004294180062AC5C00C0AFC3
+:106940005C00C28F21E8C0036400BF8F6000BE8F6F
+:106950006800BD270800E00300000000F0FFBD272D
+:106960000800BEAF21F0A00388BF023C1061428C3A
+:106970000001427C0000C2AF0000C38F00006238FB
+:106980000100422C0000C2AF0000C28F21E8C0030A
+:106990000800BE8F1000BD270800E00300000000C3
+:1069A000F8FFBD270000BEAF21F0A00300020224C3
+:1069B00021E8C0030000BE8F0800BD270800E003E7
+:1069C00000000000F8FFBD270000BEAF21F0A003CB
+:1069D0005082828F21E8C0030000BE8F0800BD27CF
+:1069E0000800E00300000000F8FFBD270000BEAF74
+:1069F00021F0A00388BF033C006162901000423484
+:106A0000006162A081BF033C60906290020042344A
+:106A1000609062A088BF033C5060629002004234E4
+:106A2000506062A088BF043C40608390FDFF022458
+:106A300024106200406082A088BF033C0061629025
+:106A400008004234006162A021E8C0030000BE8F4C
+:106A50000800BD270800E00300000000E8FFBD2794
+:106A60001400BFAF1000BEAF21F0A003955C400F33
+:106A70000000000088BF023C506043900200633475
+:106A8000506043A021E8C0031400BF8F1000BE8FE8
+:106A90001800BD270800E00300000000D0FFBD275C
+:106AA0002C00BFAF2800BEAF21F0A0033000C4AF60
+:106AB0002110A0003800C6AF3400C2A30800022491
+:106AC0001000C2A788BF043C50608390FDFF0224E1
+:106AD00024106200506082A0029D043C3400C393E5
+:106AE00021106000401002002110430080180200B5
+:106AF000B405822421106200000042902000C2A34D
+:106B00003800C28F1C00C2AF029D043C3400C39306
+:106B10002110600040100200211043008018020084
+:106B2000B405822421106200010042901800C2A323
+:106B30002000C28F400042342000C2AF2000C29328
+:106B400021204000A25C400F000000001F00C29303
+:106B500021204000A25C400F000000001E00C293F4
+:106B600021204000A25C400F000000001D00C293E5
+:106B700021204000A25C400F000000001C00C293D6
+:106B800021204000A25C400F000000001800C293CA
+:106B900021204000A25C400F00000000029D023C4A
+:106BA0003400C393B4054424211060004010020057
+:106BB0002110430080100200211044000400428C88
+:106BC0000F00401000000000029D023C3400C393FF
+:106BD000B40544242110600040100200211043003D
+:106BE00080100200211044000400438C01000224A4
+:106BF0000300621000000000100000100000000000
+:106C0000BC5C400F000000001400C2A31000C2973B
+:106C1000FFFF42241000C2A71400C393FF00022408
+:106C20001A006214000000001000C2971700401004
+:106C300000000000F2FF001000000000029D023C76
+:106C40003400C393B40544242110600040100200B6
+:106C50002110430080100200211044000400438CE6
+:106C6000020002240900621400000000BC5C400F16
+:106C700000000000BC5C400F000000001500C2A333
+:106C8000BC5C400F000000001400C2A3029D023C47
+:106C90003400C393B4054424211060004010020066
+:106CA0002110430080100200211044000400438C96
+:106CB000010002241F006214000000001400C0A3A1
+:106CC0001200C0A31200C393FF0002241900621037
+:106CD000000000001400C2931600401400000000E1
+:106CE000FFFF02241000C2A7BC5C400F00000000A0
+:106CF0001400C2A31000C297FFFF42241000C2A7D5
+:106D00001400C29306004014000000001000C29757
+:106D10000300401000000000F3FF0010000000001E
+:106D20001200C293010042241200C2A3E5FF00102A
+:106D300000000000FF000424A25C400F00000000DF
+:106D4000029D043C3400C3932110600040100200F7
+:106D50002110430080180200B40582242110620033
+:106D600008004290050040140000000088BF023C6B
+:106D70005060439002006334506043A01400C28FFF
+:106D80003000C38F000062AC3000C28F21E8C00326
+:106D90002C00BF8F2800BE8F3000BD270800E00305
+:106DA00000000000D0FFBD272C00BFAF2800BEAF01
+:106DB00021F0A0033000C4AF3400C5AF01000224AD
+:106DC0001900C2A33000C28F401202001C00C2AFE3
+:106DD0001400C22721204000070005241C00C68F94
+:106DE000A75A400F000000001400C2930D0040108D
+:106DF000000000001400C2272120400007000524E5
+:106E00001C00C68FA75A400F000000001400C29358
+:106E100004004010000000002000C0AF620000101D
+:106E200000000000FF0202241000C2A7400002245C
+:106E30001200C2A71200C297060040100000000016
+:106E40001200C297FFFF42241200C2A7F9FF0010F0
+:106E500000000000BC5C400F000000001800C2A34E
+:106E60001000C297FFFF42241000C2A74000022476
+:106E70001200C2A71200C2970600401000000000D6
+:106E80001200C297FFFF42241200C2A7F9FF0010B0
+:106E9000000000001800C393FF00022406006214E3
+:106EA000000000001000C297030040100000000026
+:106EB000E8FF0010000000001000C297070040101B
+:106EC000000000001800C393FE00022403006214B7
+:106ED0000000000004000010000000001900C0A322
+:106EE00028000010000000001000C0A71000C2978A
+:106EF0000002422C1D004010000000003400C28F30
+:106F0000130040100000000080BF033CFF0002247B
+:106F1000205A62AC80BF023C105A428C0000427C76
+:106F20000300401400000000FAFF00100000000001
+:106F30001000C3973400C28F2118620080BF023C4A
+:106F4000205A428C000062A00300001000000000E4
+:106F5000BC5C400F000000001000C29701004224FA
+:106F60001000C2A7E1FF001000000000FF00042491
+:106F7000A25C400F00000000FF000424A25C400F50
+:106F800000000000FF000424A25C400F000000008D
+:106F900088BF033C5060629002004234506062A09F
+:106FA0001900C2932000C2AF2000C28F21E8C003A5
+:106FB0002C00BF8F2800BE8F3000BD270800E003E3
+:106FC00000000000D8FFBD272400BFAF2000BEAFE7
+:106FD00021F0A0032800C4AF2C00C5AF2110C000D1
+:106FE0003000C2A3010002241800C2A32800C28FEF
+:106FF00007004014000000003000C2930400401459
+:10700000000000001800C0A3610000100000000094
+:107010001400C3272800C28F401202002120600004
+:107020000900052421304000A75A400F000000004D
+:107030001400C29304004010000000001800C0A318
+:107040004F00001000000000FE000424A25C400F6E
+:10705000000000001000C0A71000C2970002422CE0
+:10706000160040100000000080BF043C1000C397D1
+:107070002C00C28F2110620000004290205A82AC86
+:1070800080BF023C105A428C0000427C0300401436
+:1070900000000000FAFF00100000000080BF023C6A
+:1070A000205A428C1200C2A31000C2970100422451
+:1070B0001000C2A7E8FF001000000000FF00042439
+:1070C000A25C400F00000000FF000424A25C400FFF
+:1070D00000000000BC5C400F000000001200C2A3D2
+:1070E0001200C2930F004330050002240400621016
+:1070F000000000001800C0A31E00001000000000E7
+:107100001000C0A780BF033CFF000224205A62ACDD
+:1071100080BF023C105A428C0000427C03004014A5
+:1071200000000000FAFF00100000000080BF023CD9
+:10713000205A428C1200C2A31000C29701004224C0
+:107140001000C2A71200C293060040140000000005
+:107150001000C2970300401000000000E9FF00107B
+:10716000000000001000C297020040140000000060
+:107170001800C0A3FF000424A25C400F0000000020
+:1071800088BF023C5060439002006334506043A0CB
+:107190001800C29321E8C0032400BF8F2000BE8FD7
+:1071A0002800BD270800E00300000000F8FFBD270D
+:1071B0000000BEAF21F0A00388BF023C1061428CEA
+:1071C000C000427CFF00423021E8C0030000BE8FB7
+:1071D0000800BD270800E00300000000F0FFBD2705
+:1071E0000800BEAF21F0A003211080001000C2A350
+:1071F0001000C2930000C2A30000C293FFFF42240C
+:107200000000C2A3FF004330FF0002240C00621004
+:1072100000000000471D02240400C2AF0400C28F1A
+:10722000FFFF4224211840000400C3AFFFFF0224E7
+:10723000F1FF621000000000F8FF001000000000E5
+:107240000000000021E8C0030800BE8F0800E00332
+:107250001000BD27F8FFBD270000BEAF21F0A0033E
+:1072600080BF033C80BF023C105A428CFF7F4230FB
+:10727000105A62AC21E8C0030000BE8F0800BD2791
+:107280000800E00300000000E0FFBD271C00BFAFC6
+:107290001800BEAF21F0A003211080002000C2A37F
+:1072A00080BF023C105A428CC000427C0300401454
+:1072B00000000000FAFF00100000000080BF033C47
+:1072C0002000C293205A62AC0A7E400F00000000EA
+:1072D0001000C2A32110000021E8C0031C00BF8FD2
+:1072E0001800BE8F2000BD270800E003000000004A
+:1072F000E8FFBD271400BFAF1000BEAF21F0A00310
+:1073000080BF023C105A428CC000427C03004014F3
+:1073100000000000FAFF00100000000080BF033CE6
+:10732000FF000224205A62AC0A7E400F00000000D9
+:10733000FF00423021E8C0031400BF8F1000BE8F51
+:107340001800BD270800E00300000000F8FFBD277B
+:107350000000BEAF21F0A0030800C4AF80BF023C14
+:10736000105A40AC80BF033C005A62904000423447
+:10737000005A62A080BF043C015A8390FEFF0224A1
+:1073800024106200015A82A088BF043C806183906F
+:10739000BFFF022424106200806182A088BF043CE9
+:1073A00081618390FEFF022424106200816182A02B
+:1073B00088BF043C8061839080FF02242510620016
+:1073C000806182A080BF043C015A839080FF022428
+:1073D00025106200015A82A021E8C0030000BE8F80
+:1073E0000800BD270800E00300000000C0FFBD2723
+:1073F0003C00BFAF3800BEAF21F0A0030100022463
+:107400001200C2A3030002241800C2A788BF033CD5
+:107410005060629002004234506062A080BF023C23
+:107420003000C2AF9303023C008742341C00C2AF5D
+:107430000600023C801A42342000C2AF2000C28FF6
+:10744000401802001C00C28F1B004300F4016000C2
+:10745000121000002800C2AF2000C28F40180200A6
+:107460001C00C28F1B004300F401600010100000DC
+:1074700004004010000000002800C28F01004224D8
+:107480002800C2AF2800C28F0101422C0300401423
+:1074900000000000000102242800C2AF2800C28FB3
+:1074A00004004010000000002800C28FFFFF4224AB
+:1074B0002800C2AF2800C28FFF0042302400C2AFB4
+:1074C0002400C28FFF0042303000C38F305A62ACBC
+:1074D00080BF033C005A629020004234005A62A0F0
+:1074E00020000424D35C400F0000000001000424AD
+:1074F000775C400F000000001000C0A71000C2978A
+:107500000A00422C0900401000000000FF00042483
+:10751000A25C400F000000001000C297010042244E
+:107520001000C2A7F5FF00100000000088BF043C57
+:1075300050608390FDFF022424106200506082A0FE
+:1075400001000424775C400F000000001400C227F3
+:10755000212040002128000021300000A75A400FC0
+:10756000000000001400C393FF0002240800621012
+:10757000000000001400C293F70043300100022411
+:1075800003006214000000000A0000100000000068
+:107590001200C0A388BF033C5060629002004234D6
+:1075A000506062A01200C2932C00C2AF7D00001098
+:1075B00000000000FF0F02241000C2A71400C22721
+:1075C000212040000100052421300000A75A400F6F
+:1075D000000000001000C297FFFF42241000C2A765
+:1075E0001400C29306004010000000001000C29773
+:1075F0000300401000000000F0FF00100000000039
+:107600001000C29708004014000000001200C0A340
+:1076100088BF023C5060439002006334506043A036
+:107620005E0000100000000002000424775C400FA0
+:107630000000000080BF023C3400C2AF9303023C54
+:10764000008742342800C2AF3101023C002D423491
+:107650002400C2AF2400C28F401802002800C28F4D
+:107660001B004300F4016000121000001C00C2AFB8
+:107670002400C28F401802002800C28F1B00430064
+:10768000F401600010100000040040100000000031
+:107690001C00C28F010042241C00C2AF1C00C28F1C
+:1076A0000101422C030040140000000000010224EC
+:1076B0001C00C2AF1C00C28F04004010000000007C
+:1076C0001C00C28FFFFF42241C00C2AF1C00C28FEF
+:1076D000FF0042302000C2AF2000C28FFF004230C6
+:1076E0003400C38F305A62AC80BF033C60C00234A8
+:1076F000005A62AC80BF033C005A629020004234C2
+:10770000005A62A01400C227212040001000052466
+:1077100021300000A75A400F000000001400C227CB
+:10772000212040000600052400020624A75A400F2D
+:1077300000000000FF0002241000C2A71000C29742
+:107740000E00401000000000212000002128000051
+:10775000695B400F00000000211840000100022476
+:1077600006006210000000001000C297FFFF4224D4
+:107770001000C2A7F1FF0010000000001000C29727
+:1077800006004014000000001200C0A388BF023CA5
+:107790005060439002006334506043A01200C293D3
+:1077A0002C00C2AF2C00C28F21E8C0033C00BF8F69
+:1077B0003800BE8F4000BD270800E0030000000035
+:1077C00000E85D4100681A4000701B4090FFBD2733
+:1077D0006C00BBAF00601B4082D21A006800BBAFD8
+:1077E000847A5B7F12D000006400BAAF10D0000032
+:1077F0006000BAAF44201B7C00609B405C00BFAFC0
+:107800005800BEAF5400B9AF5000B8AF4C00AFAF96
+:107810004800AEAF4400ADAF4000ACAF3C00ABAFF2
+:107820003800AAAF3400A9AF3000A8AF2C00A7AF32
+:107830002800A6AF2400A5AF2000A4AF1C00A3AF72
+:107840001800A2AF21F0A0031081828F1000C2AFF8
+:10785000010002241000C38F3400621000000000F9
+:107860001000C38F020062280600401000000000D4
+:107870001000C28F09004010000000006F000010CF
+:1078800000000000020002241000C38F2F006210CD
+:107890000000000069000010000000000B0004243C
+:1078A0008660400F00000000E48082AFE480828F99
+:1078B0001B00401800000000EC80838FE480828F62
+:1078C00021106200EC8082AFE880828F01004224A8
+:1078D000E88082AFE880828F0A00422810004014BE
+:1078E00000000000EC80848F6666023C67664234CC
+:1078F000180082001010000083180200C317040053
+:10790000231062007C8282AFE88080AFEC8080AF81
+:1079100001000224108182AF480000100000000026
+:10792000108180AF45000010000000007C82848F31
+:107930001460400F000000005C8282AF020002244D
+:10794000108182AF3D00001000000000555F400F25
+:1079500000000000108180AF88BF023C5061428C63
+:107960000000427C0600401000000000E080828F92
+:1079700001004224E08082AF0200001000000000FD
+:10798000E08080AF898182831500401400000000F0
+:1079900088BF023C5060428CC000427C060040140C
+:1079A0000000000001000224898182A32080828FD0
+:1079B0000A004224208082AF88BF023C5060428C83
+:1079C0008000427C060040140000000001000224F8
+:1079D000898182A32080828FF6FF4224208082AF9B
+:1079E000AC818283150040140000000088BF023C77
+:1079F0005060428CC003427C06004014000000002E
+:107A000001000224AC8182A3FC80828F0100422409
+:107A1000FC8082AF88BF023C5060428C0001427CF7
+:107A2000060040140000000001000224AC8182A383
+:107A3000FC80828FFFFF4224FC8082AF80BF023C2B
+:107A4000100840AC88BF033C00010224341062AC33
+:107A500021E8C0035C00BF8F5800BE8F5400B98F6F
+:107A60005000B88F4C00AF8F4800AE8F4400AD8FF0
+:107A70004000AC8F3C00AB8F3800AA8F3400A98F38
+:107A80003000A88F2C00A78F2800A68F2400A58F78
+:107A90002000A48F1C00A38F1800A28F00606041FB
+:107AA000C00000006400BA8F130040036000BA8F6A
+:107AB000110040036C00BA8F00709A406800BA8FC2
+:107AC0007000BD2700609A401800004200E85D4148
+:107AD000F4FFBD2700601B400800BBAF04201B7CE7
+:107AE000001C7B3700609B4021F0A0030081828F47
+:107AF0000000C2AF010002240000C38F2D006210FD
+:107B0000000000000000C38F020062280600401041
+:107B1000000000000000C28F0900401000000000BB
+:107B20003F00001000000000020002240000C38F8C
+:107B30002E0062100000000039000010000000005C
+:107B40006482828F0F004014000000007082828FD8
+:107B500004004018000000007082828FFFFF422462
+:107B6000708282AF8482828F04004018000000007F
+:107B70008482828FFFFF4224848282AF010002242C
+:107B8000648282AF88BF043C1061828C2880838F1E
+:107B90008410627C106182AC80BF033C050002242B
+:107BA000200A62AC01000224008182AF1C00001098
+:107BB000000000006482828F050040100000000079
+:107BC00088BF023C1061439002006334106143A0FF
+:107BD00080BF023C0A000324200A43AC02000224B6
+:107BE000008182AF0E000010000000006482828FCE
+:107BF000060040100000000088BF043C1061839024
+:107C0000FDFF022424106200106182A080BF033CAB
+:107C10002480828F200A62AC008180AF648280AFB2
+:107C200080BF023C100A40AC88BF033C0010022415
+:107C3000341062AC21E8C0030800BA8F00609A409B
+:107C400018000042E8FFBD271400BFAF1000BEAF10
+:107C500021F0A0032080828F048182AF2080828F58
+:107C60000F00422803004010000000000F00022413
+:107C7000208082AF2080828FD107422803004014E9
+:107C800000000000D0070224208082AF2080848F73
+:107C9000EE78400F000000002130400021386000E5
+:107CA000029D023C0007448C0407458CC177400FBD
+:107CB00000000000029D063C2120400021286000B9
+:107CC0000C07C78C0807C68CEC75400F000000003D
+:107CD00021204000212860008679400F000000002C
+:107CE000248082AFF480828F1000401000000000DA
+:107CF00088BF043C10618390FEFF022424106200C0
+:107D0000106182A02080828F100042280B0040105A
+:107D10000000000088BF023C106143900100633402
+:107D2000106143A0050000100000000088BF023C65
+:107D30001061439001006334106143A021E8C00347
+:107D40001400BF8F1000BE8F1800BD270800E0038D
+:107D500000000000E8FFBD271400BFAF1000BEAF59
+:107D600021F0A003FC80828F02004104000000008B
+:107D7000FC8080AFFC80828F2D01422803004014DC
+:107D8000000000002C010224FC8082AFA0818283CD
+:107D90001900401400000000FC80848FCC7B400F51
+:107DA000000000005C82848F21284000317C400F5D
+:107DB0000000000003004004000000000700001065
+:107DC0000000000088BF023C506143900100633412
+:107DD000506143A00D0000100000000088BF043C6B
+:107DE00050618390FEFF022424106200506182A043
+:107DF000060000100000000088BF043C5061839022
+:107E0000FEFF022424106200506182A088818283D8
+:107E10002600401400000000FC80828FF6FF422400
+:107E200021204000CC7B400F000000005C82848F4A
+:107E300021284000317C400F000000001200400467
+:107E400000000000FC80828F0A00422421204000B4
+:107E5000CC7B400F00000000212040005C82858F19
+:107E6000317C400F000000000700400400000000CB
+:107E7000FC80828F64004228030040140000000050
+:107E80000800001000000000F48080AF88BF023CB2
+:107E90001061439001006334106143A0030000109F
+:107EA0000000000001000224F48082AF88818383F7
+:107EB000010002242C00621400000000FC80828F6C
+:107EC000FFFF422421204000CC7B400F0000000037
+:107ED0005C82848F21284000317C400F000000002C
+:107EE0001800400400000000FC80828F0100422442
+:107EF00021204000CC7B400F0000000021204000EA
+:107F00005C82858F317C400F000000000D00400432
+:107F100000000000FC80828F6400422809004014A9
+:107F2000000000005C82848F21280000317C400F1B
+:107F300000000000030040100000000008000010D6
+:107F400000000000F48080AF88BF023C10614390C5
+:107F500001006334106143A0030000100000000022
+:107F600001000224F48082AF6C818383010002242B
+:107F70001900621400000000FC80828FFBFF422485
+:107F800021204000CC7B400F000000005C82848FE9
+:107F900021284000317C400F000000000300400415
+:107FA00000000000080000100000000088BF043C32
+:107FB00010618390DFFF022424106200106182A010
+:107FC000050000100000000088BF023C10614390D3
+:107FD00020006334106143A0029D023C5C82848FC8
+:107FE0001007458C317C400F00000000030040105A
+:107FF000000000000400001000000000212000002C
+:10800000B060400F00000000029D023C5C82848F43
+:108010001407458C317C400F000000000300401025
+:1080200000000000040000100000000021200000FB
+:10803000B060400F0000000021E8C0031400BF8FB3
+:108040001000BE8F1800BD270800E00300000000EC
+:10805000D0FFBD272800BFAF2400BEAF2000B0AFC7
+:1080600021F0A0033000C4AF3000C28F1C004228B2
+:108070000800401000000000029D023C1807428CDE
+:108080001000C2AF1000C28F1800C2AF5A0000101B
+:10809000000000003000C28FFF0342280C00401493
+:1080A00000000000E080828F330042280800401466
+:1080B00000000000029D023C1C07428C1000C2AF71
+:1080C0001000C28F1800C2AF4B000010000000006B
+:1080D0001400C0AF1400C28F1F0042284600401099
+:1080E00000000000029D043C1400C28F80180200B2
+:1080F00080068224211062000000428C808282AFC0
+:108100003000C38F8082828F2A10430035004010D8
+:10811000000000008082828F548282AF029D043C66
+:108120001400C28F80180200800682242110620091
+:10813000FCFF428C788282AF7882838F5482828F58
+:1081400023106200688282AF3000C38F5482828F16
+:1081500023106200748282AF7482848FCC7B400FC4
+:1081600000000000218040006882848FCC7B400F9B
+:10817000000000002120000221284000417B400F28
+:1081800000000000588282AF029D023C5882848F1A
+:108190002007458CD37A400F00000000588282AF40
+:1081A0001400C38F211060008010020021104300D2
+:1081B0004010020021204000CC7B400F0000000056
+:1081C000212040005882858F367A400F0000000041
+:1081D0001000C2AF1000C28F1800C2AF060000101E
+:1081E000000000001400C28F010042241400C2AF3E
+:1081F000B8FF0010000000001800C28F21E8C00383
+:108200002800BF8F2400BE8F2000B08F3000BD2714
+:108210000800E00300000000F0FFBD270800BEAF2B
+:1082200021F0A0031000C4AF81BF043C4090828CB9
+:108230001000C38F049C627C409082AC81BF033CE1
+:108240000090629002004234009062A00000C0AF33
+:108250000000C28FC8004228060040100000000045
+:108260000000C28F010042240000C2AFF8FF0010DE
+:108270000000000081BF043C00908390FDFF0224B9
+:1082800024106200009082A081BF023C0090428CCA
+:108290000000427C0300401400000000FAFF0010C0
+:1082A0000000000081BF023C7090428C21E8C003B6
+:1082B0000800BE8F1000BD270800E003000000008A
+:1082C000F0FFBD270800BEAF21F0A0031000C4AF2F
+:1082D0001000C28F010042380100422C0000C2AFE2
+:1082E000010002240000C38F100062100000000093
+:1082F0000000C38F0200622806004010000000004A
+:108300000000C28F1D004010000000003900001066
+:1083100000000000020002240000C38F2C00621045
+:1083200000000000330000100000000088BF043C83
+:1083300010618390FEFF022424106200106182A06D
+:1083400088BF033C00010224641062AC88BF033C78
+:1083500000010224681062AC88BF033C00100224B4
+:10836000641062AC88BF033C00100224681062AC49
+:10837000E08080AF1F0000100000000088BF043CB8
+:1083800050618390FEFF022424106200506182A09D
+:1083900088BF033C1061629001004234106162A00A
+:1083A00088BF033C00010224641062AC88BF023C19
+:1083B000681040AC88BF033C00100224641062AC1B
+:1083C00088BF023C681040AC0A00001000000000AA
+:1083D00088BF033C1061629001004234106162A0CA
+:1083E00088BF033C00100224641062AC88BF023CCA
+:1083F000681040AC21E8C0030800BE8F1000BD2704
+:108400000800E00300000000D0FFBD272C00BFAF34
+:108410002800BEAF21F0A00388BF043C0061839018
+:10842000FDFF022424106200006182A088BF043C8A
+:1084300000618390FBFF022424106200006182A08F
+:1084400088BF043C00618390FEFF02242410620078
+:10845000006182A0137E400F000000001000C2AF38
+:1084600088BF023C0030428C0003427C1C00C2AF3B
+:108470000B0040140000000088BF033C00100224E1
+:10848000083062AC88BF023C0030428C0003427C62
+:108490000300401400000000FAFF0010000000007C
+:1084A0001C00C28F1800C2AF1800C28F1400C2AFE8
+:1084B00081BF023C30F240AC81BF033C99AA023C30
+:1084C0005566423430F262AC81BF033C6655023CD3
+:1084D000AA99423430F262AC81BF033C1800023CDE
+:1084E00008F062AC81BF023C04F040AC81BF033CA9
+:1084F0003333023C3333423430F262AC1400C28F67
+:108500001C00C2AF1C00C28F15004010000000000C
+:1085100088BF023C0030428C0003427C2000C2AF86
+:108520000B0040140000000088BF033C0010022430
+:10853000083062AC88BF023C0030428C0003427CB1
+:108540000300401400000000FAFF001000000000CB
+:108550002000C28F1800C2AF04000010000000000D
+:1085600088BF033C00100224043062AC1000C48FAA
+:10857000227E400F0000000080BF023C000840AC9B
+:1085800080BF033C70000224080862AC80BF023C3C
+:10859000100840AC80BF033CF4010224200862AC08
+:1085A00088BF033C1C000224B41062AC88BF033CAB
+:1085B00010000224B81062AC88BF033C0001022402
+:1085C000341062AC80BF033C00800234080862AC07
+:1085D00088BF033C00010224641062AC88BF023CE7
+:1085E000681040AC80BF023C000A40AC80BF033C36
+:1085F00010000224080A62AC80BF023C100A40ACA2
+:1086000080BF033C88130224200A62AC88BF033C6D
+:108610001C000224C41062AC88BF033C1C0002246E
+:10862000C81062AC157E400F0000000088BF033CFC
+:1086300000100224341062AC80BF033C008002347E
+:10864000080A62AC88BF033C00100224641062ACCC
+:1086500088BF023C681040AC88BF033C1061629048
+:1086600001004234106162A06C8180A34C8180A320
+:1086700021E8C0032C00BF8F2800BE8F3000BD272B
+:108680000800E00300000000E0FFBD271C00BFAFB2
+:108690001800BEAF21F0A0031000C0AF21200000E1
+:1086A0003564400F0000000088BF023C5060428CDF
+:1086B000C000427C0300401400000000FAFF0010DC
+:1086C00000000000208080AFFC8080AF2563400F59
+:1086D0000000000001000424B060400F0000000012
+:1086E00088BF023C9061428C4002437C010002241E
+:1086F0002F00621400000000115F400F0000000016
+:108700001000C28F010042241000C2AF1000C28FBF
+:10871000E9034228F2FF4014000000002563400FE7
+:108720000000000088BF023C5060428CC000427CC8
+:1087300004004014000000002080828F0A004224C0
+:10874000208082AF88BF023C5060428C8000427C17
+:1087500004004014000000002080828FF6FF4224B5
+:10876000208082AF88BF023C5060428CC003427CB4
+:108770000400401400000000FC80828F01004224AD
+:10878000FC8082AF88BF023C5060428C0001427C7A
+:108790000400401400000000FC80828FFFFF422490
+:1087A000FC8082AF1000C0AFCDFF001000000000C1
+:1087B00021200000B060400F0000000021E8C0034D
+:1087C0001C00BF8F1800BE8F2000BD270800E003EB
+:1087D00000000000F0FFBD270800BEAF21F0A0039D
+:1087E0001000C4AF0000C0AF1000C28F801802009C
+:1087F0000000C28F2A1043000C004010000000004F
+:108800000000000000000000000000000000000068
+:108810000000000000000000000000000000C28F07
+:1088200001004224F0FF00100000C2AF21E8C003A5
+:108830000800BE8F0800E0031000BD27E8FFBD2739
+:108840001400BFAF1000BEAF21F0A0031800C4AFEA
+:108850001800C28FE8030324021043702120400057
+:10886000F561400F0000000021E8C0031400BF8F35
+:108870001000BE8F1800BD270800E00300000000B4
+:10888000F8FFBD270000BEAF21F0A0038481828FD6
+:108890001C0040100000000088BF023C1061428CA8
+:1088A0000000427C1700401400000000288080AFC8
+:1088B0007082828F0A004014000000006082828F64
+:1088C0000500401400000000E8030224708282AF1B
+:1088D00003000010000000006082828F708282AF6F
+:1088E00090030224248082AF7082828F030040189C
+:1088F00000000000FCFF0010000000000100022446
+:10890000288082AF21E8C0030000BE8F0800BD2789
+:108910000800E00300000000E8FFBD271400BFAF1F
+:108920001000BEAF21F0A0038481828F310040107F
+:108930000000000088BF023C1061428C0000427CB5
+:108940002C0040140000000001000224288082AFA7
+:108950008482828F0A004014000000006C82828FA3
+:108960000500401400000000E8030224848282AF66
+:1089700003000010000000006C82828F848282AFAE
+:1089800090030224248082AF8482828F03004018E7
+:1089900000000000FCFF0010000000002080848F19
+:1089A000EE78400F000000002130400021386000C8
+:1089B000029D023C2807448C2C07458CC177400F50
+:1089C00000000000029D063C21204000212860009C
+:1089D0003407C78C3007C68CEC75400F00000000D0
+:1089E00021204000212860008679400F000000000F
+:1089F000248082AF21E8C0031400BF8F1000BE8F17
+:108A00001800BD270800E00300000000E8FFBD27B4
+:108A10001400BFAF1000BEAF21F0A0032120000062
+:108A200021280000029D023C141546242138000034
+:108A30001965400F00000000010004241C000524FB
+:108A400000A0023CBC044624213800001965400FF8
+:108A5000000000000200042421280000029D023CC6
+:108A600028154624213800001965400F0000000039
+:108A70000300042421280000029D023C38154624EE
+:108A8000213800001965400F000000005480838FDA
+:108A90000200022408006214000000000400042404
+:108AA00021280000029D023C441546242138000084
+:108AB0001965400F0000000021E8C0031400BF8FBB
+:108AC0001000BE8F1800BD270800E0030000000062
+:108AD000D0FFBD272C00BFAF2800BEAF21F0A00300
+:108AE0001000C427029D023C501545243480868F17
+:108AF000666D400F00000000020004245A000524A7
+:108B00001000C627213800001965400F0000000042
+:108B10001C81828F3E004018000000001C81848F61
+:108B2000CC7B400F00000000029D033C2120400050
+:108B30006815658C417B400F000000002000C2AF2B
+:108B40002000C48F1F79400F00000000213040003A
+:108B5000213860001000C427029D023C54154524B2
+:108B6000666D400F00000000030004244B00052444
+:108B70001000C627213800001965400F00000000D2
+:108B80002080848FCC7B400F00000000212040001B
+:108B90001F79400F00000000029D063C212040008C
+:108BA000212860007415C78C7015C68CF776400FAD
+:108BB0000000000021204000212860004879400F7B
+:108BC00000000000888282AF8882848F1F79400F66
+:108BD0000000000021304000213860001000C42750
+:108BE000029D023C54154524666D400F00000000B4
+:108BF000040004244B0005241000C627213800007F
+:108C00001965400F0000000008000010000000007F
+:108C1000030004244B000524029D023C60154624F9
+:108C2000213800001965400F00000000E322400FCA
+:108C3000000000001823400F000000005480838FC4
+:108C4000020002240D006214000000006D63400F5A
+:108C500000000000AC81828303004010000000008F
+:108C60001A64400F000000008981828303004010D5
+:108C700000000000D163400F0000000021E8C003A5
+:108C80002C00BF8F2800BE8F3000BD270800E003F6
+:108C900000000000E8FFBD271400BFAF1000BEAF0A
+:108CA00021F0A0032120000021280000029D023CA9
+:108CB00014154624213800001965400F00000000FB
+:108CC0000100042421280000029D023C781546245E
+:108CD000213800001965400F0000000088BF023CE9
+:108CE0005061428C0000427C0A00401000000000ED
+:108CF0000500042421280000029D023C8C15462416
+:108D0000213800001965400F000000000800001025
+:108D1000000000000500042421280000029D023C00
+:108D200098154624213800001965400F0000000006
+:108D3000029D023C5C82848FB815458C317C400FCB
+:108D40000000000003004004000000000A000010C2
+:108D5000000000000300042421280000029D023CC2
+:108D6000A4154624213800001965400F00000000BA
+:108D70000400001000000000030004249A64400F67
+:108D8000000000001A64400F000000006D63400FF7
+:108D900000000000D163400F0000000021E8C00384
+:108DA0001400BF8F1000BE8F1800BD270800E0031D
+:108DB00000000000D0FFBD272C00BFAF2800BEAFD1
+:108DC00021F0A003029D023C5C82848FF415458C47
+:108DD000317C400F000000000A004010000000003D
+:108DE000029D023C5C82848FF815458C317C400FDB
+:108DF00000000000030040100000000026000010EA
+:108E000000000000070004249A64400F00000000E6
+:108E1000029D023C5C82848FF415458C317C400FAE
+:108E200000000000030040100000000008000010D7
+:108E300000000000070004240A000524029D023CF3
+:108E4000BC154624213800001965400F00000000C1
+:108E5000029D023C5C82848FF815458C317C400F6A
+:108E60000000000003004010000000002F00001070
+:108E700000000000070004240A000524029D023CB3
+:108E8000D0154624213800001965400F000000006D
+:108E900026000010000000005C82848FF67B400FEB
+:108EA000000000002000C2AF1000C427029D023C59
+:108EB000E41545242000C68F666D400F00000000B9
+:108EC000070004242D0005241000C62721380000C7
+:108ED0001965400F0000000088BF023C5061428CC1
+:108EE0000000427C0A00401000000000070004243B
+:108EF00023000524029D023CEC1546242138000085
+:108F00001965400F0000000008000010000000007C
+:108F10000700042423000524029D023CF01546248A
+:108F2000213800001965400F0000000021E8C0034F
+:108F30002C00BF8F2800BE8F3000BD270800E00343
+:108F400000000000D0FFBD272C00BFAF2800BEAF3F
+:108F500021F0A0032080848F6666023C676642345D
+:108F6000180082001010000083180200C3170400CC
+:108F7000231062002000C2AF1000C427029D023CF3
+:108F8000FC1545242000C68F666D400F00000000D0
+:108F900007000424550005241000C62721380000CE
+:108FA0001965400F0000000004000424212800007F
+:108FB000029D023C44154624213800001965400FEB
+:108FC000000000002080848FCC7B400F0000000058
+:108FD000212040001F79400F00000000029D063C48
+:108FE00021204000212860000C16C78C0816C68C72
+:108FF000F776400F0000000021204000212860008B
+:109000004879400F00000000888282AF8882848FF8
+:109010001F79400F0000000021304000213860001F
+:109020001000C427029D023C54154524666D400F74
+:1090300000000000040004244B0005241000C62793
+:10904000213800001965400F00000000898180A3CD
+:1090500021E8C0032C00BF8F2800BE8F3000BD2741
+:109060000800E00300000000D8FFBD272400BFAFC8
+:109070002000BEAF21F0A003FC80828F02004104DB
+:1090800000000000FC8080AF1000C427029D023C5D
+:10909000E4154524FC80868F666D400F00000000BB
+:1090A00007000424212800001000C62721380000F2
+:1090B0001965400F00000000AC8180A321E8C003C7
+:1090C0002400BF8F2000BE8F2800BD270800E003CA
+:1090D00000000000E0FFBD271C00BFAF1800BEAFBE
+:1090E00021F0A003211080002000C2A31000C0A323
+:1090F0001000C2930800422C200040100000000025
+:10910000B0FF03241000C29321106200FF00423020
+:1091100021204000AD68400F000000002120000029
+:10912000AD68400F0000000010000424AD68400F3F
+:10913000000000001100C0A31100C2830A00400417
+:10914000000000002000C29321204000CF68400FA3
+:10915000000000001100C293010042241100C2A3CC
+:10916000F5FF0010000000001000C293010042242F
+:109170001000C2A3DEFF00100000000021E8C003C1
+:109180001C00BF8F1800BE8F2000BD270800E00321
+:1091900000000000E0FFBD271C00BFAF1800BEAFFD
+:1091A00021F0A003211080002400C5AF2000C2A33D
+:1091B000B0FF03242000C29321106200FF00423060
+:1091C00021204000AD68400F000000002120000079
+:1091D000AD68400F0000000010000424AD68400F8F
+:1091E000000000001000C0A31000C2932400C38F31
+:1091F0002A10430009004010000000001800042459
+:10920000CF68400F000000001000C293010042240C
+:109210001000C2A3F4FF0010000000002400C28F61
+:109220001000C2A31000C283090040040000000027
+:1092300021200000CF68400F000000001000C29302
+:10924000010042241000C2A3F6FF0010000000003D
+:1092500021E8C0031C00BF8F1800BE8F2000BD276F
+:109260000800E00300000000E0FFBD271C00BFAFC6
+:109270001800BEAF21F0A003211080002000C2A37F
+:10928000B0FF03242000C29321106200FF0042308F
+:1092900021204000AD68400F0000000021200000A8
+:1092A000AD68400F0000000010000424AD68400FBE
+:1092B000000000001000C0A31000C2830900400499
+:1092C0000000000021200000CF68400F00000000D7
+:1092D0001000C293010042241000C2A3F6FF001048
+:1092E0000000000021E8C0031C00BF8F1800BE8FE3
+:1092F0002000BD270800E00300000000D8FFBD27C4
+:109300002400BFAF2000BEAF21F0A00321108000D9
+:109310002800C2A32800C2931C00C2AF010002248F
+:109320001C00C38F15006210000000001C00C38FDA
+:109330000200622806004010000000001C00C28FDE
+:1093400009004010000000001400001000000000A0
+:10935000020002241C00C38F0D00621000000000F8
+:109360000E00001000000000029D023C380742245D
+:109370001400C2AF0900001000000000029D023C72
+:10938000380B42241400C2AF04000010000000009B
+:10939000029D023C380F42241400C2AF1000C0A34B
+:1093A0001000C2930800422C28004010000000006A
+:1093B0001000C293C01102001800C2AFB0FF032416
+:1093C0001000C29321106200FF00423021204000B3
+:1093D000AD68400F0000000021200000AD68400F84
+:1093E0000000000010000424AD68400F00000000E1
+:1093F0001100C0A31100C2830F0040040000000050
+:109400001100C3931400C28F211862001800C28F8C
+:10941000211062000000429021204000CF68400FE0
+:10942000000000001100C293010042241100C2A3F9
+:10943000F0FF0010000000001000C2930100422461
+:109440001000C2A3D6FF00100000000021E8C003F6
+:109450002400BF8F2000BE8F2800BD270800E00336
+:1094600000000000D0FFBD272C00BFAF2800BEAF1A
+:1094700021F0A0033000C4AF3400C5AF3800C6AF40
+:109480002110E0003C00C2A31C00C0AF3400C28F1A
+:109490001000C2A31000C2930F0042301100C2A3FB
+:1094A0001000C29302110200100042341200C2A345
+:1094B0003000C28FB0FF032421106200FF00423051
+:1094C00021204000AD68400F000000001100C29351
+:1094D00021204000AD68400F000000001200C29340
+:1094E00021204000AD68400F000000001400C0AF14
+:1094F0001400C38F3800C28F211062000000429018
+:1095000097004010000000001400C38F3800C28F85
+:1095100021106200000042905300422C14004010C1
+:10952000000000002000C5271400C38F3800C28F40
+:109530002110620000004490211080008018020079
+:1095400021186400029D023C3813422460FF42242B
+:10955000211062002120A0002128400005000624DF
+:10956000CD69400F000000003C000010000000002A
+:109570001400C38F3800C28F211062000000429097
+:109580007F00422C2E004010000000001400C38F0A
+:109590003800C28F21106200000042905C00422C13
+:1095A00014004014000000002000C5271400C38FE1
+:1095B0003800C28F2110620000004490211080000A
+:1095C0008018020021186400029D023C38144224D5
+:1095D0005CFE4224211062002120A00021284000CE
+:1095E00005000624CD69400F000000001B0000109C
+:1095F000000000002000C5271400C38F3800C28F70
+:1096000021106200000044902110800080180200A8
+:1096100021186400029D023C3814422461FE422459
+:10962000211062002120A00021284000050006240E
+:10963000CD69400F0000000008000010000000008D
+:109640002000C22721204000029D023C38134524FF
+:1096500005000624CD69400F000000001800C0AFCF
+:109660001800C28F050042283200401000000000A0
+:109670001C00C28F800042281B0040100000000028
+:109680003C00C2930A004014000000001800C38F81
+:109690001000C227211043001000429021204000FA
+:1096A000CF68400F000000000A000010000000001A
+:1096B0001800C38F1000C2272110430010004290F1
+:1096C00027100200FF00423021204000CF68400FE9
+:1096D000000000001C00C28F010042241C00C2AF29
+:1096E0000F000010000000003000C28FB1FF032403
+:1096F00021106200FF00423021204000AD68400F81
+:10970000000000001800C38F1000C2272110430082
+:109710001000429021204000CF68400F0000000060
+:109720001800C28F010042241800C2AFCCFF001005
+:109730000000000021200000CF68400F0000000062
+:109740001C00C28F010042241C00C2AF1400C28F53
+:10975000010042241400C2AF65FF001000000000A9
+:1097600021E8C0032C00BF8F2800BE8F3000BD272A
+:109770000800E00300000000E8FFBD271400BFAFB1
+:109780001000BEAF21F0A003212000003564400F7F
+:1097900000000000212000000A000524029D023C78
+:1097A00014154624213800001965400F0000000000
+:1097B0000100042414000524029D023C10164624D6
+:1097C000213800001965400F000000000200042449
+:1097D00014000524029D023C18164624213800007E
+:1097E0001965400F00000000030004241400052444
+:1097F000029D023C24164624213800001965400FC2
+:10980000000000000400042414000524029D023C12
+:1098100030164624213800001965400F0000000072
+:109820000500042414000524029D023C3C16462435
+:10983000213800001965400F0000000021E8C00336
+:109840001400BF8F1000BE8F1800BD270800E00372
+:1098500000000000E8FFBD271400BFAF1000BEAF3E
+:1098600021F0A003212000003564400F000000001B
+:10987000212000000A000524029D023C1415462404
+:10988000213800001965400F000000000100042489
+:1098900020000524029D023C4C164624213800007D
+:1098A0001965400F00000000020004242128000078
+:1098B000029D023C54164624213800001965400FD1
+:1098C000000000000300042421280000029D023C47
+:1098D00060164624213800001965400F0000000082
+:1098E0000400042421280000029D023C6C1646243A
+:1098F000213800001965400F000000000500042415
+:1099000021280000029D023C7816462421380000E0
+:109910001965400F00000000060004242128000003
+:10992000029D023C80164624213800001965400F34
+:10993000000000000700042421280000029D023CD2
+:1099400088164624213800001965400F00000000E9
+:1099500021E8C0031400BF8F1000BE8F1800BD2780
+:109960000800E00300000000E8FFBD271400BFAFBF
+:109970001000BEAF21F0A003212000003564400F8D
+:1099800000000000212000000A000524029D023C86
+:1099900014154624213800001965400F000000000E
+:1099A0000100042414000524029D023C9016462464
+:1099B000213800001965400F0000000021E8C003B5
+:1099C0001400BF8F1000BE8F1800BD270800E003F1
+:1099D00000000000E8FFBD271400BFAF1000BEAFBD
+:1099E00021F0A003010004249A64400F000000004D
+:1099F0000100042414000524029D023C3016462474
+:109A0000213800001965400F0000000021E8C00364
+:109A10001400BF8F1000BE8F1800BD270800E003A0
+:109A200000000000E8FFBD271400BFAF1000BEAF6C
+:109A300021F0A003212000003564400F0000000049
+:109A40000100042421280000029D023CA0164624A7
+:109A5000213800001965400F0000000021E8C00314
+:109A60001400BF8F1000BE8F1800BD270800E00350
+:109A700000000000D8FFBD272400BFAF2000BEAF0C
+:109A800021F0A0032800C4AF2C00C5AF3000C6AF42
+:109A90002110E0003400C2A3212000003564400FF3
+:109AA000000000000100042421280000029D023C67
+:109AB000B4164624213800001965400F000000004C
+:109AC0002800C48F1F79400F0000000021304000A3
+:109AD000213860001000C427029D023CC0164524B6
+:109AE000666D400F000000000300042421280000E0
+:109AF0001000C627213800001965400F0000000043
+:109B00002C00C48F1F79400F00000000213040005E
+:109B1000213860001000C427029D023CC81645246D
+:109B2000666D400F0000000004000424212800009E
+:109B30001000C627213800001965400F0000000002
+:109B40003400C28313004010000000003000C48FB6
+:109B50001F79400F000000002130400021386000D4
+:109B60001000C427029D023CD0164524666D400FAC
+:109B70000000000005000424212800001000C62772
+:109B8000213800001965400F000000000800001097
+:109B9000000000000500042421280000029D023C72
+:109BA000D8164624213800001965400F0000000037
+:109BB00021E8C0032400BF8F2000BE8F2800BD27EE
+:109BC0000800E00300000000E8FFBD271400BFAF5D
+:109BD0001000BEAF21F0A003212000003564400F2B
+:109BE000000000002120000021280000029D023C0E
+:109BF000E4164624213800001965400F00000000DB
+:109C00000200042421280000029D023CF016462494
+:109C1000213800001965400F0000000004000424F2
+:109C200021280000029D023C001746242138000034
+:109C30001965400F0000000021E8C0031400BF8F29
+:109C40001000BE8F1800BD270800E00300000000D0
+:109C5000E8FFBD271400BFAF1000BEAF21F0A00386
+:109C60001800C4AF1C00C5AF2110C0002000C2A363
+:109C70001800C28F0800422C730140100000000041
+:109C80001800C28F80180200029D023C181742245F
+:109C9000211062000000428C08004000000000001B
+:109CA0002000C393010004241C00C58F029D023CC8
+:109CB00010174624213860001965400F000000008D
+:109CC000020004241C00C58F029D023C1417462488
+:109CD000213800001965400F000000000300042433
+:109CE0001C00C58F029D023C141746242138000039
+:109CF0001965400F00000000040004241C00C58FFB
+:109D0000029D023C14174624213800001965400FBB
+:109D100000000000050004241C00C58F029D023CC9
+:109D200014174624213800001965400F0000000078
+:109D3000060004241C00C58F029D023C1417462413
+:109D4000213800001965400F0000000007000424BE
+:109D50001C00C58F029D023C1417462421380000C8
+:109D60001965400F000000003701001000000000DE
+:109D7000010004241C00C58F029D023C14174624D8
+:109D8000213800001965400F000000002000C39337
+:109D9000020004241C00C58F029D023C10174624BB
+:109DA000213860001965400F000000000300042402
+:109DB0001C00C58F029D023C141746242138000068
+:109DC0001965400F00000000040004241C00C58F2A
+:109DD000029D023C14174624213800001965400FEB
+:109DE00000000000050004241C00C58F029D023CF9
+:109DF00014174624213800001965400F00000000A8
+:109E0000060004241C00C58F029D023C1417462442
+:109E1000213800001965400F0000000007000424ED
+:109E20001C00C58F029D023C1417462421380000F7
+:109E30001965400F00000000030100100000000041
+:109E4000010004241C00C58F029D023C1417462407
+:109E5000213800001965400F0000000002000424B2
+:109E60001C00C58F029D023C1417462421380000B7
+:109E70001965400F000000002000C3930300042474
+:109E80001C00C58F029D023C10174624213860003B
+:109E90001965400F00000000040004241C00C58F59
+:109EA000029D023C14174624213800001965400F1A
+:109EB00000000000050004241C00C58F029D023C28
+:109EC00014174624213800001965400F00000000D7
+:109ED000060004241C00C58F029D023C1417462472
+:109EE000213800001965400F00000000070004241D
+:109EF0001C00C58F029D023C141746242138000027
+:109F00001965400F00000000CF00001000000000A5
+:109F1000010004241C00C58F029D023C1417462436
+:109F2000213800001965400F0000000002000424E1
+:109F30001C00C58F029D023C1417462421380000E6
+:109F40001965400F00000000030004241C00C58FA9
+:109F5000029D023C14174624213800001965400F69
+:109F6000000000002000C393040004241C00C58FDF
+:109F7000029D023C10174624213860001965400FED
+:109F800000000000050004241C00C58F029D023C57
+:109F900014174624213800001965400F0000000006
+:109FA000060004241C00C58F029D023C14174624A1
+:109FB000213800001965400F00000000070004244C
+:109FC0001C00C58F029D023C141746242138000056
+:109FD0001965400F000000009B0000100000000009
+:109FE000010004241C00C58F029D023C1417462466
+:109FF000213800001965400F000000000200042411
+:10A000001C00C58F029D023C141746242138000015
+:10A010001965400F00000000030004241C00C58FD8
+:10A02000029D023C14174624213800001965400F98
+:10A0300000000000040004241C00C58F029D023CA7
+:10A0400014174624213800001965400F0000000055
+:10A050002000C393050004241C00C58F029D023C10
+:10A0600010174624213860001965400F00000000D9
+:10A07000060004241C00C58F029D023C14174624D0
+:10A08000213800001965400F00000000070004247B
+:10A090001C00C58F029D023C141746242138000085
+:10A0A0001965400F0000000067000010000000006C
+:10A0B000010004241C00C58F029D023C1417462495
+:10A0C000213800001965400F000000000200042440
+:10A0D0001C00C58F029D023C141746242138000045
+:10A0E0001965400F00000000030004241C00C58F08
+:10A0F000029D023C14174624213800001965400FC8
+:10A1000000000000040004241C00C58F029D023CD6
+:10A1100014174624213800001965400F0000000084
+:10A12000050004241C00C58F029D023C1417462420
+:10A13000213800001965400F000000002000C39383
+:10A14000060004241C00C58F029D023C1017462403
+:10A15000213860001965400F00000000070004244A
+:10A160001C00C58F029D023C1417462421380000B4
+:10A170001965400F000000003300001000000000CF
+:10A18000010004241C00C58F029D023C14174624C4
+:10A19000213800001965400F00000000020004246F
+:10A1A0001C00C58F029D023C141746242138000074
+:10A1B0001965400F00000000030004241C00C58F37
+:10A1C000029D023C14174624213800001965400FF7
+:10A1D00000000000040004241C00C58F029D023C06
+:10A1E00014174624213800001965400F00000000B4
+:10A1F000050004241C00C58F029D023C1417462450
+:10A20000213800001965400F0000000006000424FA
+:10A210001C00C58F029D023C141746242138000003
+:10A220001965400F000000002000C39307000424BC
+:10A230001C00C58F029D023C101746242138600087
+:10A240001965400F0000000021E8C0031400BF8F13
+:10A250001000BE8F1800BD270800E00300000000BA
+:10A26000F8FFBD270000BEAF21F0A0030800C4AF77
+:10A2700080BF033C0800C28F205A62AC80BF023C02
+:10A28000105A428C0000427C030040140000000081
+:10A29000FAFF00100000000080BF023C205A428CF0
+:10A2A00021E8C0030000BE8F0800BD270800E003BE
+:10A2B00000000000E8FFBD271400BFAF1000BEAFD4
+:10A2C00021F0A003211080001800C2A388BF043C25
+:10A2D00010618390BFFF022424106200106182A0ED
+:10A2E00088BF043C50608390DFFF0224241062008A
+:10A2F000506082A01800C293212040009868400F4F
+:10A300000000000088BF033C50606290200042348F
+:10A31000506062A088BF033C1061629040004234EC
+:10A32000106162A021E8C0031400BF8F1000BE8F2F
+:10A330001800BD270800E00300000000E8FFBD276B
+:10A340001400BFAF1000BEAF21F0A00321108000A9
+:10A350001800C2A388BF033C1061629040004234E1
+:10A36000106162A088BF043C50608390DFFF02242C
+:10A3700024106200506082A01800C2932120400087
+:10A380009868400F0000000088BF033C5060629056
+:10A3900020004234506062A088BF033C106162908C
+:10A3A00040004234106162A021E8C0031400BF8F56
+:10A3B0001000BE8F1800BD270800E0030000000059
+:10A3C000E0FFBD271C00BFAF1800BEAF21F0A00307
+:10A3D000211080002000C2A31000C0A31000C2936F
+:10A3E0000800422C2000401000000000B0FF0324B1
+:10A3F0001000C29321106200FF0042302120400073
+:10A40000AD68400F0000000021200000AD68400F43
+:10A410000000000010000424AD68400F00000000A0
+:10A420001100C0A31100C2830A0040040000000014
+:10A430002000C29321204000CF68400F00000000A0
+:10A440001100C293010042241100C2A3F5FF0010C5
+:10A45000000000001000C293010042241000C2A3BB
+:10A46000DEFF00100000000021E8C0031C00BF8FC9
+:10A470001800BE8F2000BD270800E0030000000088
+:10A48000E0FFBD271C00BFAF1800BEAF21F0A00346
+:10A490001000C0AF80BF033C20810234005A62AC80
+:10A4A00088BF043C10618390BFFF02242410620027
+:10A4B000106182A088BF043C50608390DFFF0224BB
+:10A4C00024106200506082A088BF033C106162903B
+:10A4D0007F004230106162A01000C0AF1000C28F38
+:10A4E000D007422C06004010000000001000C28F70
+:10A4F000010042241000C2AFF8FF0010000000006D
+:10A5000088BF043C1061839080FF02242510620004
+:10A51000106182A01000C0AF1000C28FD007422C83
+:10A5200006004010000000001000C28F010042240D
+:10A530001000C2AFF8FF00100000000088BF023C0E
+:10A540005060439020006334506043A0D500042441
+:10A55000AD68400F0000000010000424AD68400FFB
+:10A5600000000000D3000424AD68400F000000008C
+:10A5700021200000AD68400F00000000A800042466
+:10A58000AD68400F000000003F000424AD68400F9C
+:10A5900000000000D8000424AD68400F0000000057
+:10A5A00021200000AD68400F00000000400004249E
+:10A5B000AD68400F00000000A0000424AD68400F0B
+:10A5C00000000000C8000424AD68400F0000000037
+:10A5D000DA000424AD68400F0000000012000424DB
+:10A5E000AD68400F0000000081000424AD68400FFA
+:10A5F00000000000F0000424AD68400F00000000DF
+:10A60000A4000424AD68400F00000000D900042419
+:10A61000AD68400F00000000F2000424AD68400F58
+:10A6200000000000A6000424AD68400F00000000F8
+:10A6300026000424AD68400F00000000010004243F
+:10A64000AD68400F0000000021200000AD68400F01
+:10A650000000000021200000AD68400F0000000055
+:10A6600001000424AD68400F00000000212000001C
+:10A67000F068400F000000001000C0AF1000C28F53
+:10A68000D007422C06004010000000001000C28FCE
+:10A69000010042241000C2AFF8FF001000000000CB
+:10A6A000AF000424AD68400F0000000021E8C003A3
+:10A6B0001C00BF8F1800BE8F2000BD270800E003DC
+:10A6C00000000000E8FFBD271400BFAF1000BEAFC0
+:10A6D00021F0A003212000003564400F000000009D
+:10A6E00001000424BF64400F00000000C8000424DF
+:10A6F000775C400F00000000212000003564400F0F
+:10A700000000000021200000BF64400F0000000096
+:10A71000C8000424775C400F0000000021E8C0035B
+:10A720001400BF8F1000BE8F1800BD270800E00383
+:10A7300000000000211080005600C0100C00CA2C40
+:10A740004D0040152618A400030063302338040090
+:10A75000290060100300E7300600E0102330C70036
+:10A760000000A3980300A3882128A700000083B855
+:10A77000212087000F00C3302338C3001100E010F0
+:10A78000213060002138E5000000A3980300A38871
+:10A790000400A8980700A8880800A9980B00A988B9
+:10A7A0000C00AA980F00AA88000083AC040088ACB3
+:10A7B000080089AC1000A52410008424F2FFA7141F
+:10A7C000FCFF8AAC0300C3302338C3002A00E0102A
+:10A7D000213060002138E5000000A3980300A38821
+:10A7E0000400A52404008424FBFFA714FCFF83AC11
+:10A7F00021000010000000000500E0102330C70019
+:10A800000000A3982128A700000083B8212087001A
+:10A810000F00C3302338C3000D00E010213060006A
+:10A820002138E5000000A38C0400A88C0800A98C46
+:10A830000C00AA8C000083AC040088AC080089AC32
+:10A840001000A52410008424F6FFA714FCFF8AAC96
+:10A850000300C3302338C3000700E010213060003C
+:10A860002138E5000000A38C0400A5240400842402
+:10A87000FCFFA714FCFF83AC0600C0102138C50004
+:10A880000000A3900100A52401008424FCFFA7146C
+:10A89000FFFF83A00800E0030000000021108000FB
+:10A8A0002600C0101000CA2C1F004015FF00A53064
+:10A8B000005205002528AA00005405002528AA00FA
+:10A8C0000300833005006010040007242338E300F0
+:10A8D0002330C700000085B8212087000F00C33057
+:10A8E0002338C3000800E010213060002138E40064
+:10A8F000000085AC040085AC080085AC1000842401
+:10A90000FBFF8714FCFF85AC0300C3302338C30072
+:10A910000500E010213060002138E40004008424A8
+:10A92000FEFF8714FCFF85AC0400C0102138C40072
+:10A9300001008424FEFF8714FFFF85A00800E003C8
+:10A9400000000000254085000300083103000011CD
+:10A9500021108000380000100000AA900000AA8C8E
+:10A960000101093C01012935C07909002340490151
+:10A9700024400F010700001124600A01050088111E
+:10A98000000000000000A5240000AA902A0000108A
+:10A99000000084240400AB8C00008AAC23406901D1
+:10A9A00024400F010700001124600B0105008811ED
+:10A9B000000000000400A5240000AA901E00001062
+:10A9C000040084240800AA8C04008BAC23404901B5
+:10A9D00024400F010700001124600A0105008811BE
+:10A9E000000000000800A5240000AA90120000103A
+:10A9F000080084240C00AB8C08008AAC2340690159
+:10AA000024400F010700001124600B01050088118C
+:10AA1000000000000C00A5240000AA900600001011
+:10AA20000C0084241000AA8C0C008BAC1000842431
+:10AA3000CEFF00101000A5240300401500008AA0DE
+:10AA40000800E003000000000100AB900300601567
+:10AA500001008BA00800E003000000000200AA90A3
+:10AA60000300401502008AA00800E0030000000077
+:10AA70000300AB900300601503008BA00800E00307
+:10AA8000000000000400AA900300401504008AA002
+:10AA90000800E003000000000500AB900300601513
+:10AAA00005008BA00800E003000000000600AA904B
+:10AAB0000300401506008AA00800E0030000000023
+:10AAC0000700AB900300601507008BA00800E003AF
+:10AAD000000000000800AA9008008424D6FF00109F
+:10AAE0000800A52400008A90211080000300401572
+:10AAF000000000000800E0030000022401008A902A
+:10AB000003004015000000000800E00301000224DB
+:10AB100002008A9003004015000000000800E003D6
+:10AB20000200022403008A900300401582200400E2
+:10AB30000800E003030002240100842480200400B4
+:10AB400000008A8C0101093C01012935C079090006
+:10AB50002340490124400F010600001124600A012E
+:10AB6000040088110000000000008A9022000010FC
+:10AB70000000842404008B8C2340690124400F01D1
+:10AB80000600001124600B01040088110000000081
+:10AB900004008A90180000100400842408008A8CA5
+:10ABA0002340490124400F010600001124600A01DE
+:10ABB000040088110000000008008A900E000010B8
+:10ABC000080084240C008B8C2340690124400F0171
+:10ABD0000600001124600B01040088110000000031
+:10ABE0000C008A90040000100C00842410008A8C51
+:10ABF000D7FF00101000842404004015000000005E
+:10AC0000000084240800E0032310820001008A90E1
+:10AC10000400401500000000010084240800E00347
+:10AC20002310820002008A900400401500000000FA
+:10AC3000020084240800E0032310820003008A90AD
+:10AC4000030084240800E00323108200B0FFBD2726
+:10AC50000000A1AF0400A2AF0800A3AF0C00A4AF96
+:10AC60001000A5AF1400A6AF1800A7AF1C00A8AF36
+:10AC70002000A9AF2400AAAF2800ABAF2C00ACAFD6
+:10AC80003000ADAF3400AEAF3800AFAF3C00B8AF6E
+:10AC90004000B9AF4400BFAF124000004800A8AF69
+:10ACA000104000005000A8AF00680440006005405C
+:10ACB000A86D400F000000005000A88F1100000197
+:10ACC0004800A88F130000010000A18F0400A28F8C
+:10ACD0000800A38F0C00A48F1000A58F1400A68F6E
+:10ACE0001800A78F1C00A88F2000A98F2400AA8F0E
+:10ACF0002800AB8F2C00AC8F3000AD8F3400AE8FAE
+:10AD00003800AF8F3C00B88F4000B98F4400BF8F30
+:10AD10005000BD27C0000000180000422518A40004
+:10AD20000300623020004014214080000400C92C40
+:10AD30001C0020152138A0000000AF8CFEFE183C3E
+:10AD4000FFFE053727700F002168E50180800C3C6D
+:10AD50002458AE0180808335245063011200405591
+:10AD60002128E0002148A000212860000000E28C9A
+:10AD7000FCFFC6240400D92C000082AC0400E724A8
+:10AD800008002017040084240000ED8C27600D00CB
+:10AD90002158A90124506C0124184501F4FF60508A
+:10ADA0000000E28C2128E0000E00C010FFFFC2244A
+:10ADB0000000A790FFFFC624000087A00100A52483
+:10ADC000F9FFE014010084240600C010FFFFC22434
+:10ADD000FFFF0324FFFF4224000080A0FDFF431477
+:10ADE000010084240800E0032110000103008230E8
+:10ADF00018004014FF00A530003A05002540A700C8
+:10AE000000340800253806018080033C2130800092
+:10AE1000FEFE043CFFFE8934808068340000CF8C45
+:10AE20002610E7012168E90127700F0027C80200FA
+:10AE300021C049002458AE01246019032450680140
+:10AE40000300401524188801F4FF60500400C62454
+:10AE50002120C00000008390FF0069300300251509
+:10AE6000211080000800E00300000000F9FF6014DA
+:10AE7000010084240800E00321100000E0FFBD274A
+:10AE800000A0053C1000B0AF0000B0241800B2AF25
+:10AE90001400B1AF2190800000A0113C1C00BFAF96
+:10AEA000776D400F212000021C01238E0100042435
+:10AEB000380064AC7B6D400F212000021C01228E03
+:10AEC0001000508C0D0000121C012A8E0400028E0E
+:10AED00008004018FFFF4724804807002140300148
+:10AEE0000800068D09F8C000040007AEF8FF001046
+:10AEF0000400028EF3FF00100000108E3400428D1B
+:10AF0000030040100000000009F8400000000000AD
+:10AF1000CB6D400F21204002029D073C4D17E624D7
+:10AF20002110860000004590200082240100A330FB
+:10AF30000800E0030A108300029D073C4D17E62439
+:10AF40002110860000004590E0FF82240200A3301B
+:10AF50000800E0030A108300029D053C4D17A3245E
+:10AF600021208300000082900800E00307004230A7
+:10AF7000029D053C4D17A3242120830000008290F0
+:10AF80000800E003030042300800E0038000822C48
+:10AF9000029D053C4D17A3242120830000008290D0
+:10AFA0000800E00320004230029D053C4D17A32419
+:10AFB00021208300000082900800E003040042305A
+:10AFC000029D053C4D17A3242120830000008290A0
+:10AFD0000800E00317004230029D053C4D17A324F2
+:10AFE00021208300000082900800E003020042302C
+:10AFF000029D053C4D17A324212083000000828080
+:10B000000800E00397004230029D053C4D17A32441
+:10B0100021208300000082900800E00310004230ED
+:10B02000029D053C4D17A32421208300000082804F
+:10B030000800E00388004230029D053C4D17A32420
+:10B0400021208300000082900800E00301004230CC
+:10B05000029D053C4D17A32421208300000082900F
+:10B060000800E003440042300800E0037F00823023
+:10B070000800E003200082240800E003E0FF8224AF
+:10B08000E8FFBD271000BFAFAA6C400F21280000C9
+:10B090001000BF8F0800E0031800BD27E8FFBD27A0
+:10B0A000212800001000BFAF2F6C400F0A000624BB
+:10B0B0001000BF8F0800E0031800BD270000838048
+:10B0C000213880002150000021700000215800002C
+:10B0D0000E00601021680000029D093C4D172825D4
+:10B0E0002110680000004280880043300800605052
+:10B0F0000000E3800100E7240000EC8003008011E1
+:10B1000021188801F8FF0010000062800000E38031
+:10B110002B000824030068102D000F2404006F1476
+:10B12000000000002D00783801000E2F0100E724F8
+:10B130001100C014100003240000E2803000192424
+:10B140001C0059140A0006240100E7240000E380D3
+:10B1500078000924080006240400691001000D2469
+:10B1600058000C2414006C14FF7F023C0100E724FB
+:10B1700010000010100006240F00C314FF7F023CD3
+:10B180000000EF80300008240C00E815FFFF433476
+:10B190000100E7240000E380780018240400781000
+:10B1A00001000D245800192404007914FFFF4334D2
+:10B1B0000100E724FF7F023CFFFF43341A006600D2
+:10B1C000F401C0002148E0000000E7802400E01006
+:10B1D00012600000029D083C4D1718252178600080
+:10B1E0002110F80000004390040079300700201778
+:10B1F000D0FFE8240300683019000011010063301B
+:10B20000A9FFF924C9FFE8240A4023032A180601EC
+:10B2100001007938C2170800253859001100E054A0
+:10B2200001006F2D2A388A010800E01401000D2466
+:10B2300008006055010029250250467123C8EA0123
+:10B240002A102803020040502150480101000B241D
+:10B250000100292500002781E2FFE0542110F800B9
+:10B2600001006F2D2460CF0123300A000B50CC0069
+:10B27000080060112110400122000B2400A00A3CAC
+:10B2800004024BAD0300C0150080023CFF7F0E3C62
+:10B29000FFFFC2350200A0100A488D000000A9ACD3
+:10B2A0000800E00300000000E8FFBD271000BFAF6A
+:10B2B000717C400F000000001000BF8F0800E00309
+:10B2C0001800BD27E8FFBD271000BFAF0400828C27
+:10B2D00021188000FFFF06240100042421284000DB
+:10B2E00003004610000060AC04000010040066ACCF
+:10B2F000B66D400F00000000212840001000BF8FF5
+:10B300002110A0000800E0031800BD27E8FFBD27BA
+:10B310001000B0AF1400BFAF100083940200623081
+:10B320000E004010218080000000838C0E0060041D
+:10B330001400BF8F0C00848C03006410232883004A
+:10B34000B86D400F0800048E0800058E0C00068EB4
+:10B35000040005AE03000010000006AEFFFF072446
+:10B36000040087AC1400BF8F1000B08F21100000C4
+:10B370000800E0031800BD27D8FFBD271C00B1AFAF
+:10B380001800B0AF2000BFAF0C00A28C2180A0003D
+:10B3900021888000010005240600401421200002BD
+:10B3A0001000A427B86D400F1000B1A323000010B7
+:10B3B000000000AE0000068EFFFF03240100C5243C
+:10B3C0000D00A314000005AE0800078E00A0083C85
+:10B3D000040405250800E0148000062410000A96E5
+:10B3E000040005AE10004935000006AE080005AEA9
+:10B3F0000C0006AE100009A6C36C400F0000000050
+:10B4000000000E8E04000C8EFFFFCD2501008B2561
+:10B410000A00042400000DAE000091A107002416CC
+:10B4200004000BAE1000189608000F330300E01163
+:10B4300021200002C36C400F0000000021102002F8
+:10B440002000BF8F1C00B18F1800B08F0800E003F0
+:10B450002800BD27E0FFBD271000B0AF0280C570F7
+:10B460001800B2AF1400B1AF1C00BFAF2188C000FC
+:10B470002190800011000012212800001000E694A5
+:10B480002120E0000100C230060040104000C3341B
+:10B490001000E3A400A0043C0900032407000010EE
+:10B4A000040283ACC36C400F00000000212800029E
+:10B4B000B86D400F21204002212820021C00BF8FC0
+:10B4C0001800B28F1400B18F1000B08F2110A000AF
+:10B4D0000800E0032000BD2710008794FFFFE33041
+:10B4E000241065004000E6340600401001000324EB
+:10B4F000100086A40900052400A0043C040285ACC9
+:10B50000211800000800E00321106000C8FFBD27DB
+:10B51000FFFFA9242128C0002130E000029D073C44
+:10B5200021408000FFFF0B241000A42782000A2482
+:10B53000AC19E2243000BFAF2200ABA72000AAA7BD
+:10B540001C00A9AF1400A8AF2800A2AF1000A9AF3B
+:10B550008B6E400F1800A8AF1400A38F3000BF8F70
+:10B560003800BD270800E003000060A02110A00003
+:10B57000FF7F053CE8FFBD272138C000FFFFA53451
+:10B580001000BFAF436D400F213040001000BF8F4F
+:10B590000800E0031800BD27E8FFBD272110A00028
+:10B5A000FF7F053C2000A6AF2400A7AFFFFFA53416
+:10B5B0002000A7271000BFAF436D400F213040008F
+:10B5C0001000BF8F0800E0031800BD270800E0034B
+:10B5D000211000000800E003211000000800E00333
+:10B5E000211000000800E003211000000800E00323
+:10B5F000211000000800E003211000000800E00313
+:10B60000211000000800E003211000000800E00302
+:10B61000211000000800E003211000000800E003F2
+:10B62000FFFF02240800E003000000000800E00320
+:10B63000000000000800E003000000000800E00334
+:10B64000000000000800E003000000000800E00324
+:10B65000000000000000828CE8FFBD2704004014B9
+:10B660001000BFAF0200032409F8A000000083AC63
+:10B670001000BF8F211000000800E0031800BD2754
+:10B680000800E003FFFF02240800E003FFFF02249C
+:10B690000800E003211000000800E0032110A000D2
+:10B6A000FFFF001000000000FFFF0010000000007E
+:10B6B0000800E003000000000800E00300000000B4
+:10B6C00000601A40BFFF1B3CFFFF7B3724D05B03A9
+:10B6D00000609A40180000420800E003FFFF0224C7
+:10B6E000E0FFBD271400B1AF1000B0AF1800BFAF2E
+:10B6F00021888000080080102180A000070000122F
+:10B700001800BF8F000024823174400FFFFF102605
+:10B71000FAFF0010010031261800BF8F1400B18F0E
+:10B720001000B08F0800E0032000BD27FFFF0010CD
+:10B7300000000000E0FFBD271800B2AF1400B1AF59
+:10B740001000B0AF1C00BFAF218880002190C00066
+:10B750000C00A010FFFFB02400002482F673400FFD
+:10B7600021284002FFFF0324FFFF1026030043149B
+:10B770000100312604000010FFFF0224F7FF0356EA
+:10B7800000002482211000001C00BF8F1800B28F1F
+:10B790001400B18F1000B08F0800E0032000BD2717
+:10B7A000E0FFBD271800B2AF1400B1AF1000B0AF7A
+:10B7B0001C00BFAF2180A000219080002188C00024
+:10B7C0000D0000122100022E200007240B38020277
+:10B7D0002128E0002120200221304002CD6D400FC1
+:10B7E00023800702FFFF0324F5FF4314FFFF022419
+:10B7F000030000101C00BF8F211000001C00BF8F31
+:10B800001800B28F1400B18F1000B08F0800E00351
+:10B810002000BD27D0FFBD271400B1AF2188E00074
+:10B820004000A78F1800B2AF1000B0AF0100F23097
+:10B830002180C0000100432E1C00B3AF2A981102E2
+:10B84000029D063C241073002800B6AF2400B5AF5B
+:10B850002000B4AF2C00BFAF21A0A0007018C624F8
+:10B86000FFFF16242328300221A880000400401086
+:10B8700021180000E86D400F000000002118400072
+:10B8800021208002212800020E0076102130A00223
+:10B89000CD6D400F000000000B0056102A20300232
+:10B8A0000A0040520A802402029D053C7018A6241A
+:10B8B0002120A0020300601223283002E86D400F0F
+:10B8C000000000002A2030020A8024022110000219
+:10B8D0002C00BF8F2800B68F2400B58F2000B48FB6
+:10B8E0001C00B38F1800B28F1400B18F1000B08FFE
+:10B8F0000800E0033000BD27C8FFBD272C00B5AF0E
+:10B900001C00B1AF21A8C0002188E0002130000058
+:10B91000213800002800B4AF2400B3AF2000B2AF3C
+:10B920001800B0AF3000BFAF219080002198A00078
+:10B930004800B48FC979400F4C00B083110040100B
+:10B94000029D023C6819468C6C19478C21204002EC
+:10B95000F776400F21286002212040002128600056
+:10B960006675400F1000A6270B000010029D063CD4
+:10B97000000025A20000A48E0100832421000010F5
+:10B980000000A3AEEE78400FD0FF04261000A2AF57
+:10B990001400A3AF029D063C7019C48C7419C58CA9
+:10B9A0001400A78FC979400F1000A68F160041041C
+:10B9B000211020022E0006243000052400008D8274
+:10B9C0002660A60101008B2D23208B0200008A90A7
+:10B9D000FFFF942401004825204C087C3A002729C9
+:10B9E0000800E014000088A0F4FF9114000085A076
+:10B9F000DFFFA0563100052431000E24FFFF2EA2E8
+:10BA0000FFFF3126211020023000BF8F2C00B58FA0
+:10BA10002800B48F2400B38F2000B28F1C00B18F98
+:10BA20001800B08F0800E0033800BD2718FBBD27C1
+:10BA3000E404BFAFE004BEAFDC04B7AFD804B6AFD8
+:10BA4000D404B5AFD004B4AFCC04B3AFC804B2AF24
+:10BA5000C404B1AFC004B0AF1800838CEC04A5AF30
+:10BA60001000628CE804A4AF0100052409F840002E
+:10BA7000F004A6AF9404A0AF34054010FFFF0324E8
+:10BA8000EC04A68F0000C4800100C52429058010A5
+:10BA9000EC04A5AF2500072406008710EC04A88F4E
+:10BAA000F673400FE804A58F9404A48F1F050010BF
+:10BAB00001008324000012810B004416FFFF0624BE
+:10BAC000E804A58FF673400F25000424EC04AC8F26
+:10BAD0009404AA8F01008B2501004925EC04ABAF2B
+:10BAE000E7FF00109404A9AF9C04A0AF2D00072429
+:10BAF0002B0005242000042423000324300002240A
+:10BB0000030047169C04AD8F100000100100A835FB
+:10BB1000030045169C04AE8F0C0000100200C835CF
+:10BB2000030044169C04AF8F080000100400E835A1
+:10BB3000030043169C04B08F040000100800083670
+:10BB4000080042169C04B18F10002836EC04B28F16
+:10BB50009C04A8AF01005326EC04B3AFE8FF00102B
+:10BB6000000072822A0014240E005416D0FF4526CD
+:10BB7000F004A28FFCFF1F2403005E2424B0DF0327
+:10BB8000EC04B98F0000D88E01003727EC04B7AF62
+:10BB90009804B8AF0000F2820400D526110000100E
+:10BBA000F004B5AF0A00A32C160060109804A0AFF3
+:10BBB0000A0003249804AC8FEC04AD8F0258837103
+:10BBC0000100AA25EC04AAAF2148720100005281AD
+:10BBD000D0FF2825D0FF44260A00872CF5FFE0146B
+:10BBE0009804A8AF9804A88F070001052E0011241F
+:10BBF0009C04B08F2370080001000F369C04AFAF87
+:10BC00009804AEAF2E0011242600511668000C24B3
+:10BC1000EC04B28F2A00062401005326EC04B3AFD3
+:10BC2000000072820D004616D0FF4226F004BE8F3F
+:10BC3000EC04B78F0300D8270100F626FCFF192477
+:10BC400024A81903EC04B6AF0000D2820000A68E2F
+:10BC50000400B4260F000010F004B4AF0A005F2CFB
+:10BC60000F00E013213000000A000324EC04AA8F27
+:10BC70000220C37001004825EC04A8AF21489200BF
+:10BC800000001281D0FF47260A00E52CF7FFA01420
+:10BC9000D0FF26250000C328FFFF0B240B306301D3
+:10BCA00068000C2412004C166C001524EC04A58FBF
+:10BCB0000100AD800700B2159C04B38F9C04B08FC7
+:10BCC0000100AE2480000F369C04AFAF03000010CB
+:10BCD000EC04AEAF000171369C04B1AFEC04B28F3E
+:10BCE00001005426EC04B4AF27000010000092823B
+:10BCF0001200551671000724EC04A48F01009680F1
+:10BD00000700D2169C04BF8F9C04B98F01009724B2
+:10BD1000000838379C04B8AF03000010EC04B7AF3C
+:10BD20000002FE379C04BEAFEC04A58F0100A224E4
+:10BD3000EC04A2AF14000010000052800900471666
+:10BD40004C000B24EC04AA8F9C04A88F010044250E
+:10BD5000EC04A4AF00009280000809350A0000102E
+:10BD60009C04A9AF09004B16EC04B18FEC04AE8F14
+:10BD70009C04AC8F0100CD25EC04ADAF00048335ED
+:10BD80000000B2819C04A3AFEC04B18F9C04A38F8C
+:10BD90000100302602006F300400E011EC04B0AF67
+:10BDA000FBFF1424249874009C04B3AF9C04A58F5B
+:10BDB0000100B5300400A012BCFF4326EFFF17249A
+:10BDC00024B0B7009C04B6AF3500782C550400139E
+:10BDD00021100000029D053C80F803009018A22469
+:10BDE00021F0E2030000D98F0800200300000000CA
+:10BDF0009C04A78F0002F2349C04B2AF9C04AA8F6B
+:10BE0000F7FF042400104835244804010D000010F9
+:10BE10009C04A9AF9C04A38F00026B349C04ABAFBD
+:10BE200015000010080014249C04AD8F0002AC35EE
+:10BE30009C04ACAF9C04AF8FF7FF10242470F0017A
+:10BE40009C04AEAF0C0000100A0014249C04B38FB5
+:10BE500000407136070000109C04B1AF9C04B58F00
+:10BE60000040B4369C04B4AF9C04B78F0802F63689
+:10BE70009C04B6AF10001424FFFF18240300D8144C
+:10BE80009C04BE8F0400001001000624EFFF1F2455
+:10BE900024C8DF039C04B9AF9C04A58F0010B63002
+:10BEA0000B00C0120008A2300C004014F004AB8F4D
+:10BEB000F004A98FFCFF0224030027252410E200D0
+:10BEC0000000528C2120400210000010C32F1200ED
+:10BED00009004010F004AD8FF004AB8FF8FF0A2486
+:10BEE0000700642524408A000000048D0400058DAD
+:10BEF0000700001008000225FCFF0C240300A32506
+:10BF000024106C000000448C21280000040042240E
+:10BF1000F004A2AF218080002188A0002198C000F9
+:10BF20005F00B2270800C01221B800000700A1047A
+:10BF30002118000023801000238811002B1010000E
+:10BF40002388220201001724211800001B0010166C
+:10BF5000212800021A00711425101102330000126A
+:10BF60009C04AE8F0040C6311B00B400F401800277
+:10BF7000102000000A008F280300E05137009124B0
+:10BF80000400001030008424570090242120200257
+:10BF90000A2006021B00B400F4018002000044A243
+:10BFA000FFFF7326FFFF522612A80000EEFFA01627
+:10BFB000122800001E000010FFFF6226251011024B
+:10BFC0001A004010C3AF1400212820022130800243
+:10BFD0002138A002687F400F212000020A00582863
+:10BFE00006000017300045249C04BF8F57005924D9
+:10BFF0000040FE33370045240A283E03000045A2D6
+:10C00000212000022128200221308002497E400F99
+:10C010002138A002218040002188600025104300C3
+:10C02000FFFF5226E6FF0010FFFF7326FFFF622688
+:10C03000070040049C04A88F30000324FFFF422423
+:10C04000000043A2FDFF4104FFFF52269C04A88F7D
+:10C0500010001331250060129C04AE8F2000A5272C
+:10C060009804A98F233845022128270108000231AE
+:10C070000C004010C1FFA424080008240700881603
+:10C08000FEFF8C2401004B8230000A2404006A5118
+:10C090001000833A03000010C0FFA4241000833A6C
+:10C0A0000A2083010900C052FFFF83240600E056E6
+:10C0B000FFFF84249C04A68F0600CD300300A0114E
+:10C0C000FFFF8324FFFF8424FFFF83240700620413
+:10C0D0009C04AE8F30000224FFFF6324000042A2C4
+:10C0E000FDFF6104FFFF52269C04AE8F0800C4319F
+:10C0F0001600801008000F2408008F56100011242D
+:10C100000100508230000324040003521000112467
+:10C11000000043A20D000010FFFF52260B009116F5
+:10C12000212840029C04B28FFFFFA3240040543218
+:10C1300002008016580004247800042430001524DE
+:10C140000000A4A0FFFF7224000075A01000C01220
+:10C15000010045260B00E0162D0002249C04B78F39
+:10C160000200F6320300C0129C04B98F05000010D3
+:10C170002B0002240400383305000053010045263B
+:10C1800020000224000042A2FFFF522601004526A3
+:10C1900023F0A5031F0300106000C627F004AC8F36
+:10C1A000F8FF0A2407008B2524406A010000098D4E
+:10C1B0000400078D6000A9AF6400A7AF6000B08FD6
+:10C1C0006400B18F080005250055337EFF077F3AD4
+:10C1D000F004A5AF2300E017A004A6AF21200002C1
+:10C1E0002128200221300002C979400F2138200285
+:10C1F0000700405021200002029D033C9804A78FB5
+:10C20000E804A48F90196524040300100300062499
+:10C210002128200221300000C979400F2138000078
+:10C2200009004304029D043C029D063C9C04AD8F22
+:10C230009804A78FE804A48F9C19C5240400062441
+:10C24000F80200101000ADAF941985249C04AE8F45
+:10C250009804A78FE804A48F04000624F1020010BC
+:10C260001000AEAFFFFF0F240400CF14A404A0AF52
+:10C270000600142413000010A004B4AF2800D52831
+:10C280001100A0162140000267005E3A4700593AAB
+:10C290002BB81E002BC0190024B0F8020600C016EF
+:10C2A000D9FFC2249C04B38F08007F320400E0133E
+:10C2B00027000724D9FFC224A404A2AF2700072423
+:10C2C000A004A7AF21400002214820026900A0A3DA
+:10C2D0009004A0AFA004BE8FA804B2AF0A0021064C
+:10C2E000B404A0AF21500001029D083C7C19058DCB
+:10C2F0002D000924268825027002A9A321404001AF
+:10C3000002000010214820027002A0A38004A6278A
+:10C31000212000016675400F212820016900AD270A
+:10C320006902AC2721A86000FFFF8B250100A3252F
+:10C3300021A04000B804A3AFAC04A3AF21986000D3
+:10C3400024000010B004ABAF6819108F6C19118F66
+:10C350002120C0022128E00221382002C177400FAD
+:10C360002130000221204000212860008004A627FF
+:10C370006675400F029D173C8019E68E8419E78E82
+:10C3800021204000212860008804A2AFEE75400FF4
+:10C390008C04A3AF2120400021300002212860003E
+:10C3A000F776400F21382002212040008679400F87
+:10C3B00021286000B004AF8F300056240000F6A1A1
+:10C3C0009004AE8FFFFFE4250100C625B004A4AFA2
+:10C3D0009004A6AF8004B68F8404B78F213000008C
+:10C3E000213800002120C002C979400F2128E00235
+:10C3F000D5FF4014029D183C650019246C005912A9
+:10C4000066005F2A0600E013660007244500022448
+:10C4100067004212470002240300001000000000E1
+:10C420000500471267000224580142126900A683E2
+:10C4300000020010B804B08F9004B28F10004012B8
+:10C44000B804A38FB004A58F6902A9270100A42412
+:10C450002B5089000E004011A004AD8F00008B907E
+:10C460006902AC27010084242B408C0000006BA2E1
+:10C47000FAFF00150100732605000010A004AD8F1F
+:10C4800030001324000073A001007324A004AD8FBA
+:10C490000600A0152E0004249C04AE8F0800C631AF
+:10C4A0000500C010212080022E000424000064A298
+:10C4B00001007326212080022128A00221300000E3
+:10C4C000C979400F213800002F004010A004AF8F21
+:10C4D0001D00E01121208002029D113C6819268E6A
+:10C4E0006C19278E21208002F776400F2128A002A8
+:10C4F00021204000212860006675400F8804A6278F
+:10C500008804A48F8C04A58F21A040008679400F59
+:10C5100021A8600030005624FFFFDE27000076A22D
+:10C520000800C01301007326212080022128A002E8
+:10C5300021300000C979400F21380000E7FF401486
+:10C54000029D113C212080022128A0022130000000
+:10C55000C979400F213800000B004010B804A78FA4
+:10C56000FFFF7726213000007002B02721208002D3
+:10C570002128A0021000B7AF1800B0AF3E6E400FE8
+:10C580001400A0AFAC04A2AFA801C013FFFFC227E4
+:10C5900030000424FFFF0324FFFF4224000064A2B4
+:10C5A000FDFF431401007326A10100106900A6835A
+:10C5B0009004B88F3900001321208002B004A28FAC
+:10C5C000B804B98F01005F900100432400003FA32D
+:10C5D0000500C017010030279C04B28F08004732C5
+:10C5E0001800E01001006D24B804AA8F2E00092461
+:10C5F000010049A11200C01302005025B004A88F09
+:10C600006902A527020003252B1065000A004010CF
+:10C610000000000000006B90FFFFDE2700000BA26F
+:10C620000700C01301001026010063246902AC2733
+:10C63000F6FF00102B106C001500C0179004A48F9B
+:10C6400001006D246902A6272B98A6011000601234
+:10C650009004A48FFFFF0E261000AEAF010075807E
+:10C660007002B4271400B5AF1800B4AFB804A78F98
+:10C6700021A0000021A800009004A627212080020C
+:10C680003E6E400F2128A002AC04A2AF9004A48FFC
+:10C69000FFFF83243D0000109004A3AF2128A002D7
+:10C6A00021300000C979400F213800002B004010D4
+:10C6B000B804A78FFFFF02249004A2AF029D0F3C95
+:10C6C0006819E68D6C19E78D21208002F776400FFE
+:10C6D0002128A00221204000212860006675400F1B
+:10C6E0008804A6278804B08F8C04B18F2130000005
+:10C6F00021380000212000022128200221A0400032
+:10C70000C979400F21A86000030040149004B68F3F
+:10C71000E9FF0010FFFFC226212000028679400FAA
+:10C7200021282002B804B18F30005024000030A22C
+:10C730000500C017010030269C04B88F080017338D
+:10C740001300E01221208002B804B98F2E001F24AC
+:10C75000020030270D00001001003FA3300002242A
+:10C760000000E2A00500C0170100F0249C04AA8F7D
+:10C77000080052310600401221208002B804A98F1F
+:10C780002E000524010025A1020030252120800271
+:10C790002128A00221300000C979400F2138000073
+:10C7A0002F004010000000001D00C0132120800257
+:10C7B000029D0B3C6819668D6C19678D21208002E3
+:10C7C000F776400F2128A002212040002128600098
+:10C7D0006675400F8804A6278804A48F8C04A58F53
+:10C7E00021A040008679400F21A860003000482435
+:10C7F000FFFFDE27000008A20800C013010010267A
+:10C80000212080022128A00221300000C979400F98
+:10C8100021380000E7FF4014029D0B3C21208002DC
+:10C820002128A00221300000C979400F21380000E2
+:10C830000B004010AC04A78F7002AC27FFFF13263B
+:10C840009004A627212080022128A0021000B3AF67
+:10C850001800ACAF3E6E400F1400A0AFAC04A2AF06
+:10C860000700C013FFFFC22730000424FFFF03248A
+:10C87000FFFF4224000004A2FDFF43140100102624
+:10C88000B404BE8F1400C0539004A48F9C04A68FE0
+:10C890000800CD301000A0559004A48F3000032470
+:10C8A000AC04B58F2BA0B0020600805200001682A7
+:10C8B000FFFF102600000E82FBFFC3112BA0B00269
+:10C8C000000016822E00CF3A0100E42D2318040246
+:10C8D000010070249004A48FA804B18F02000526E3
+:10C8E000000011A2060081047804A8272D00172457
+:10C8F000232004002130A00004000010010017A232
+:10C900002B001824010018A22130A0000A00902852
+:10C9100017000016213800010A0005241A008500BE
+:10C92000F401A000FFFFE724101000001220000017
+:10C9300030005F240A009928F8FF20130000FFA0B0
+:10C94000FFFFE52430008A242B18A800FFFFEAA08F
+:10C95000B60060102198C0000000A7900100A52437
+:10C960000000C7A02B18A800F9FF00100100C62482
+:10C9700030008924300008240000A8A00100A9A0EC
+:10C980000200A624A90000102198C000A004AB8FCB
+:10C99000010010249004A38F0B80CB032A280302EC
+:10C9A0001300A014FEFF4D2616006014B004AE8FD5
+:10C9B000212080022128A00221300000C979400FE7
+:10C9C000213800001E004010B804A48F029D0C3CCA
+:10C9D0008819868D8C19878D21208002C979400F96
+:10C9E0002128A00216004104B804A48FFEFF4D26A2
+:10C9F00001001324FFFF1E26A804ADAFECFE0010BB
+:10CA0000B404B3AF6902A6270100C4252BF0860049
+:10CA10000E00C0130000000000008F906902B627CE
+:10CA2000010084242B18960000006FA2FFFF10263F
+:10CA3000F9FF6014010073260400001000000000DC
+:10CA400030001124000091A001009324060000167C
+:10CA50002E0019249C04B88F080017330500E0123B
+:10CA6000219000002E001924000079A20100122458
+:10CA700001007326212080022128A002213000001D
+:10CA8000C979400F213800004C0040509C04B58FFC
+:10CA90003800001221208002029D113C6C19278E63
+:10CAA0006819268E21208002F776400F2128A002E7
+:10CAB000212040008804A6276675400F21286000C9
+:10CAC0008804A48F8C04A58F21A040008679400F94
+:10CAD00021A8600030005F2400007FA28804A48F9A
+:10CAE0008C04A58F2130000021380000C979400F47
+:10CAF00001007326150040149004A28FE7FF4050F8
+:10CB0000029D113C12000010FFFF10266C19278EA9
+:10CB100021208002F776400F2128A002212040002A
+:10CB2000212860006675400F8804A6278804A48F1A
+:10CB30008C04A58F21A040008679400F21A86000B9
+:10CB400030004A2400006AA201007326FFFF10266D
+:10CB500007000012212080022128A00221300000BD
+:10CB6000C979400F21380000E8FF40146819268E6B
+:10CB7000212080022128A00221300000C979400F25
+:10CB8000213800000D0040509C04B58FB804A78FD9
+:10CB9000FFFF68267002A9272130000021208002B3
+:10CBA0002128A0021000A8AF1800A9AF3E6E400FC8
+:10CBB0001400A0AFAC04A2AF9C04B58F0800B4323F
+:10CBC0000B0080120000000018000012FFFF022678
+:10CBD00030000424FFFF0324FFFF4224000064A26E
+:10CBE000FDFF431401007326110000106900A683A5
+:10CBF0000F0040126900A68330000324AC04B28FFA
+:10CC00002B8053020600005200006C82FFFF732647
+:10CC100000006782FBFFE3102B80530200006C8250
+:10CC20002E008B392B280B00219865026900A68302
+:10CC3000B804B08FAC04AD8F7002A3936900BE2717
+:10CC40000B80C6030500601023886D02FFFF1026CD
+:10CC50000100312611000010000003A29C04AE8FD9
+:10CC60000200D331060060129C04B68FFFFF10262D
+:10CC70002B0003240100312608000010000003A24D
+:10CC80000400CF320600E0119C04BF8FFFFF102686
+:10CC900020000424000004A2010031269C04BF8F60
+:10CCA000A404B98F9804A88F0100F43321903902AD
+:10CCB0000100982E2A98480224B813030700E012B6
+:10CCC00021200000029D023CE804A48F7018462435
+:10CCD000E86D400F2328120121204000FFFF15249A
+:10CCE00005009510E804A68F21200002CD6D400FAD
+:10CCF0002128200221204000A404A58F2740040001
+:10CD00002B5008002B4805002488490106002012FA
+:10CD100000000000E804A48F029D103CE86D400F65
+:10CD200050180626212040000C0095109804A78F6B
+:10CD30000B0080122A28F2000A0060120B3845020C
+:10CD40009804B48F029D153CE804A48F7018A626A1
+:10CD5000E86D400F232892029804A78F2A28F2003A
+:10CD60000B3845026F0000102110E000F004B38F73
+:10CD7000FCFF062403007E262458C60300006D8DA8
+:10CD80009C04AC8F9804A78FE804A48F040072253C
+:10CD90007804A527010006247804ADA31000ACAFE9
+:10CDA00020000010F004B2AFF004A48FFCFF0324B5
+:10CDB000030096242478C3020000F18D0400EE25C0
+:10CDC000F004AEAF0400201621802002029D173C23
+:10CDD000A419F12621802002FFFF18240900D8148D
+:10CDE000FFFFC324B96A400F212020020700001072
+:10CDF000218002020600201321282002FFFF632465
+:10CE000001001026FBFF6304000019822128200284
+:10CE1000233011029804A78FE804A48F9C04BF8FCD
+:10CE20001000BFAF056E400F000000003E00001074
+:10CE30009404AD8F9C04B18F000822320D00401085
+:10CE40009C04AB8FF004A58FFCFF07240300B524DE
+:10CE500024A0A7029404A88F00008A8EC34F080064
+:10CE600004009026F004B0AF000048AD2C00001084
+:10CE7000040049AD000272310B0040529C04A38FA4
+:10CE8000F004AF8FFCFF0E240300F32524306E0264
+:10CE90000000CC8C9404AD8F0400DE24F004BEAFFF
+:10CEA0001F00001000008DADF004A48F000176304B
+:10CEB0000900C01203008324FCFF022424F862004E
+:10CEC0000000F78F9404B88F0400F927F004B9AF7D
+:10CED000130000100000F8A69C04AA8F80005131B6
+:10CEE00009002012FCFF0C24FCFF152424A075006F
+:10CEF0000000898E9404A88F04009026F004B0AF3F
+:10CF000007000010000028A124586C000000678D65
+:10CF10009404A58F04007225F004B2AF0000E5ACC4
+:10CF2000211000009404AD8F2118A201D4FA001042
+:10CF30009404A3AFE804AE8F9404BE8F1000D39581
+:10CF4000FFFF0324400066320A18C603E404BF8FC3
+:10CF5000E004BE8FDC04B78FD804B68FD404B58F3D
+:10CF6000D004B48FCC04B38FC804B28FC404B18F83
+:10CF7000C004B08F211060000800E003E804BD2762
+:10CF800000A0063CE8FFBD271C01C28C1000BFAF0B
+:10CF9000211880000400448C2130A0008B6E400FCB
+:10CFA000212860001000BF8F0800E0031800BD2793
+:10CFB0000800E003FFFF02240800E00321108000C6
+:10CFC0000800E003211000000800E0032110000029
+:10CFD0000800E00301000224E0FFBD271400B1AF08
+:10CFE0001000B0AF1800BFAF1800A38C2180A000C4
+:10CFF0001000628C218880002120A00009F84000E8
+:10D000000100052419004010FFFF03240000078ED3
+:10D010000A00283AFFFFE6242120200221280002EE
+:10D020000100032D0600C004000006AE10000B96A0
+:10D03000C0006A7D244843010700201121302002EE
+:10D0400018000C8E0400908D09F80002000000000A
+:10D0500005000010213040000400058E0100A424CA
+:10D060000000B1A0040004AE2118C0001800BF8F5A
+:10D070001400B18F1000B08F211060000800E00391
+:10D080002000BD27E8FFBD271000BFAFF673400F9B
+:10D09000000000001000BF8F0800E0031800BD274B
+:10D0A00000A0033CE8FFBD271C01628C1000BFAF4D
+:10D0B000F673400F0400458C1000BF8F0800E0039A
+:10D0C0001800BD272024047C80BF033C1062658CBF
+:10D0D0000002A27CFDFF40100000000080BF033C66
+:10D0E000206264AC0800E00300000000405005002E
+:10D0F00042550A00C04A0500427D040025482F0120
+:10D10000C042040000800E3C25482E014068070004
+:10D11000426D0D00C0620700427D060025608F0150
+:10D12000C05A060025608E012470C501FFFF4F25FF
+:10D13000FE07E12D5600201000000000FFFFAF2584
+:10D14000FE07E12D6E0020100000000023384D0185
+:10D150004B00E0040000000042400800C07F0900CE
+:10D1600025400F014248090042580B00C07F0C00C7
+:10D1700025586F0142600C002B780B0123400B01F6
+:10D180002B102F0123482F012B782C012578E20149
+:10D190000500E01123482C0121400B012B780B01E5
+:10D1A00021482C0121482F012A7800012140080143
+:10D1B0002148290121482F01FFFFE724EEFFE10468
+:10D1C000000000000800201525500D000300001588
+:10D1D000000000000D00001000000A242548000196
+:10D1E00000000824E0FF4A25203827710700E010DE
+:10D1F0000000000023504701223007000630C8001D
+:10D200000440E8000448E900254826011400401DB8
+:10D2100000000000010007242338EA002000E12C70
+:10D22000050020140000000025400900000009242A
+:10D23000FAFF0015E0FFE7240800E01000000000FE
+:10D24000253009000640E8000648E90020000F24C8
+:10D250002338E7010430E6002540060100000A24D7
+:10D26000C2220800407D090025208F0040280900C7
+:10D27000022B0500007D0A002528AF002528AE00FE
+:10D2800025100400251805000800E0030000000038
+:10D290003B004015000000002A78000121400801F1
+:10D2A0002148290121482F0125782801A3FFE011F9
+:10D2B0000000000008002015000000000300001519
+:10D2C000000000009DFF001000000A242548000116
+:10D2D00000000824E0FF4A252038277197FFE0105E
+:10D2E0000000000023504701223007000630C8002C
+:10D2F0000440E8000448E90090FF0010254826019A
+:10D300001B00A015000000002A78600121586B0165
+:10D3100021608C0121608F0125788B011800E011BC
+:10D3200000000000080080150000000003006015E8
+:10D330000000000085FF001000000D242560600142
+:10D3400000000B24E0FFAD25203887717FFFE0103F
+:10D35000000000002368A701223007000630CB0040
+:10D360000458EB000460EC0078FF00102560860193
+:10D3700040780C002578EB01C1FFE01100000000AF
+:10D38000F8FF053CBEFF00100000042440380500F3
+:10D39000423D0700FFFFE924FE07212D0C0020106D
+:10D3A0000000000002FCE7240F80013CFFFF213455
+:10D3B0002428A100E03F013C2528A1000000C7ACC3
+:10D3C00025100400251805000800E00300000000F7
+:10D3D0001300E01400000000404805002548240127
+:10D3E000F6FF2011000000000080013C2440A10055
+:10D3F0000100E724FFFFE7242A4880002120840061
+:10D400002128A5002128A9001000013C2B08A1001B
+:10D41000F8FF201400000000E2FF00102528A800FB
+:10D42000F8FF053C00000724E4FF0010252007005A
+:10D4300040480500424D0900FFFF2C25FE07812DC5
+:10D440000F0020100000000021482601FFFF2C25BE
+:10D45000FE07812D21002010000000000F80013CFC
+:10D46000FFFF21342428A100006509002528AC0015
+:10D4700025100400251805000800E0030000000046
+:10D480000063050025608401F9FF801100000000A1
+:10D490000400201100000000F8FF053CF4FF00101C
+:10D4A00000000424010029250080013C2450A10033
+:10D4B000FFFF29252A608000212084002128A50063
+:10D4C0002128AC001000013C2B08A100F8FF20141B
+:10D4D00000000000DCFF00102528AA00C042050063
+:10D4E0004265040025400C01C03A04000080013C64
+:10D4F000254001010080013C050020192428A100DD
+:10D50000F07F013C2528A100D9FF00100000042471
+:10D5100001000A24235049012000412D0700201456
+:10D5200000000000E0FF4A212B2007000D0008103A
+:10D5300025380401F8FF00100000083409004011EC
+:10D540000000000022580A00042067010458680106
+:10D55000063847010640480102008010253867015F
+:10D560000200E7340004E7240004EC2C21400C0105
+:10D57000C262070001008C312338EC00C222070090
+:10D580004065080025208C004060080002630C0004
+:10D59000B7FF00102528AC00253804002540050001
+:10D5A0000080013C2458A10040480500424D09007C
+:10D5B000FFFF2C25FE07812D370020100000000002
+:10D5C00033040A2423504901350041292F0020103B
+:10D5D0000000000020004129060020140000000087
+:10D5E000E0FF4A250000042406284501050000103C
+:10D5F00004284501030040190000000006204401F2
+:10D6000004204401234005012338E4000000C4AC99
+:10D610000400C5AC080000150B0029250300E01428
+:10D62000000000000D000010000009242540E0006B
+:10D6300000000724E0FF2925202004710700801046
+:10D640000000000023482401225004000650470136
+:10D65000043887000440880025400A01C2220700E0
+:10D660004065080025208C0040280800022B05009A
+:10D67000006509002528AC002528AB002510040012
+:10D68000251805000800E003000000000400CBACF2
+:10D69000FAFF00100000C0ACFCFF201100000000E9
+:10D6A000F8FF053C000004240000C4ACF3FF0010A8
+:10D6B0000400C5AC0080013C2440A10040380500B6
+:10D6C000423D0700FF0701242A00E110000000008E
+:10D6D00033040A24233847012200E0180000000028
+:10D6E0003500E12808002014000000002A00001581
+:10D6F000000000002550A400240040150000000098
+:10D7000025000010000000000500001500000000CA
+:10D710002B50040023200400232805002328AA00FE
+:10D720001F00EA3001000924044849012348090088
+:10D730002000E12804002014000000000000042460
+:10D74000020000102428A9002420890005000015EB
+:10D75000000000002B5004002320040023280500B3
+:10D760002328AA0025100400251805000800E0035E
+:10D770000000000000530500255044010900401539
+:10D7800000000000F7FF001000000000F03F053C23
+:10D79000F4FF00100000042425280800F1FF001009
+:10D7A00000000424F8FF053CEEFF001000000424F4
+:10D7B0000080013C2638E10040580500425D0B0026
+:10D7C000C0520500427D040025504F01C04A0400AC
+:10D7D0000080083C255048014070070042750E004B
+:10D7E000C06A0700427D06002568AF01C0620600DE
+:10D7F0002568A801FFFF6F25FE07E12D8D00201091
+:10D8000000000000FFFFCF25FE07E12DBB00201028
+:10D81000000000000080013C2428A10023406E018C
+:10D820002C0000110000000015000019000000008D
+:10D830002000012D0700201400000000E0FF082157
+:10D840002B300C0023000D102560A601F8FF0010FE
+:10D8500000000D341F00001100000000222008000D
+:10D8600004308C0004208D0006600C0106680D0158
+:10D870001800C01025608C001600001002008C35C6
+:10D8800025580E00234008002000012D0700201419
+:10D8900000000000E0FF08212B3009000D000A10F5
+:10D8A00025484601F8FF001000000A340900001165
+:10D8B00000000000222008000430890004208A00B3
+:10D8C0000648090106500A010200C01025488900D7
+:10D8D000020029352678A7001C00E00500000000A2
+:10D8E00021482C012B782C0121504D0121504F0152
+:10D8F00002004D11000000002B784D013700E011AF
+:10D900000000000001002F310200E01100000000C3
+:10D910000200293542480900C07F0A0025482F012E
+:10D9200042500A000080013C2550410101006B2556
+:10D93000FF0701242900611500000000F07F013C71
+:10D940002528A10037000010000004242B782C01AA
+:10D9500023482C012B104F0123504F012B784D01F0
+:10D960002578E2010700E01123504D010080013CC1
+:10D970002628A1002B7809002348090023500A001B
+:10D9800023504F010800401500000000030020153F
+:10D99000000000000D00001000000B2425502001A5
+:10D9A00000000924E0FF6B252040487107000011AA
+:10D9B000000000002358680122200800062089008A
+:10D9C0000448090104500A01255044012578490101
+:10D9D0000200E01500000000000005246800601946
+:10D9E000000000000004292500042F2D21504F01C4
+:10D9F0002B784F0121586F01C27A09000100EF31E5
+:10DA000023482F01C2220900407D0A0025208F00F3
+:10DA100040780A00027B0F002528AF00007D0B0034
+:10DA20002528AF0025100400251805000800E00394
+:10DA3000000000002A7820012148290121504A01D4
+:10DA40002300601521504F01257849011400E01191
+:10DA50000000000008004015000000000300201531
+:10DA60000000000067FF001000000B24255020017B
+:10DA700000000924E0FF6B252040487161FF001180
+:10DA800000000000235868012220080006208900B9
+:10DA90000448090104500A015AFF001025504401AE
+:10DAA000FF0701241500C111000000002140E7001C
+:10DAB000257806010300E01500000000D9FFE0040E
+:10DAC0000000000025100600D8FF001025180700F0
+:10DAD000257849012700E01500000000FF07012418
+:10DAE000D0FFC115000000002678A7002100E00546
+:10DAF00000000000F3FF0010000000002A78800101
+:10DB000021608C012168AD011700C0152168AF01AB
+:10DB10002578AC01C3FFE011000000000800A0154B
+:10DB200000000000030080150000000039FF001015
+:10DB300000000E242568800100000C24E0FFCE25A3
+:10DB40002040A87133FF0011000000002370C801BD
+:10DB50002220080006208C0004600C0104680D01DE
+:10DB60002CFF00102568A4012578AC01D5FFE01139
+:10DB700000000000F8FF053CAAFF0010000004248C
+:10DB80000100082423400B012000012D0700201470
+:10DB900000000000E0FF08212B3009000D000A10F2
+:10DBA00025484601F8FF001000000A340900001162
+:10DBB00000000000222008000430890004208A00B0
+:10DBC0000648090106500A010200C01025488900D4
+:10DBD0000200293583FF001000000B24405005008F
+:10DBE00042550A00C04A0500427D040025482F0125
+:10DBF000C042040000800E3C25482E01406807000A
+:10DC0000426D0D00C0620700427D060025608F0155
+:10DC1000C05A060025608E012628A7002428AE00E1
+:10DC2000FFFF4F25FE07E12D4700201000000000F8
+:10DC3000FFFFAF25FE07E12D6F0020100000000060
+:10DC400002FCAF2521504F0119002C0112380000B1
+:10DC50001070000019000B011220000010300000AD
+:10DC600019002B0112580000106800002130CB0071
+:10DC70002B78CB002138ED002138EF000200ED10A9
+:10DC8000000000002B78ED002170CF0119000C017D
+:10DC900012400000104800002130C8002B78C80056
+:10DCA0002138E9002138EF000200E91000000000EF
+:10DCB0002B78E9002170CF01257886000200E01161
+:10DCC000000000000100E73425480E000600200592
+:10DCD000254007002A780001214008012148290138
+:10DCE00021482F01FFFF4A25FFFF4F25FE07E12DA9
+:10DCF00068002010000000000004082500040F2D1B
+:10DD000021482F012B782F0121504F01C27A0800A2
+:10DD10000100EF3123400F01C2220800407D0900BD
+:10DD200025208F0040780900027B0F002528AF00D6
+:10DD3000007D0A002528AF002510040025180500E5
+:10DD40000800E003000000002A78000121400801DB
+:10DD5000214829011C00401521482F012578280160
+:10DD60001400E01100000000080020150000000071
+:10DD70000300001500000000ADFF001000000A24A1
+:10DD80002548000100000824E0FF4A2520702E717C
+:10DD9000A7FFC0110000000023504E0122380E00E2
+:10DDA0000638E8000440C8010448C901A0FF00107B
+:10DDB00025482701FF0701243300A11100000000BE
+:10DDC000DDFF001000000000257828012E00E0157E
+:10DDD000000000000500A0150000000040780C00C5
+:10DDE0002578EB012800E01100000000FF07012466
+:10DDF0002100A115000000002A78600121586B0164
+:10DE000021608C011900A01521608F0125788B01FC
+:10DE10001400E01100000000080080150000000060
+:10DE2000030060150000000085FF001000000D24B5
+:10DE30002560600100000B24E0FFAD2520308671D5
+:10DE40007FFFC010000000002368A60122700600BA
+:10DE50000670CB010458CB000460CC0078FF0010A2
+:10DE600025608E01B4FF00100000042425788B018A
+:10DE70000500E01500000000F07F013C2528A1000E
+:10DE8000ADFF001000000424F8FF053CAAFF0010BD
+:10DE900000000424F8FF401D0000000001000E24D3
+:10DEA0002370CA012000C12D0700201400000000CB
+:10DEB000E0FFCE212B3008000D000910254026017F
+:10DEC000F8FF0010000009340900C0110000000034
+:10DED00022380E000430E8000438E9000640C8018A
+:10DEE0000648C9010200C0102540E80002000835BC
+:10DEF0000004082500040F2D21482F0183FF001086
+:10DF0000C25709004050050042550A00C04A0500AA
+:10DF1000427D040025482F01C042040000800E3CD1
+:10DF200025482E0140680700426D0D00C0620700C1
+:10DF3000427D060025608F01C05A060025608E01D3
+:10DF40002628A7002428AE00FFFF4F25FE07E12D5D
+:10DF5000CB00201000000000FFFFAF25FE07E12DE1
+:10DF6000F40020100000000023504D01FF034A255B
+:10DF700042400800C07F090025400F0142480900C7
+:10DF8000023C0C00F401E0001B00270112700000AD
+:10DF900010480000FFFF86311900CE00122000005B
+:10DFA000004C0900027C080025482F012B78240131
+:10DFB0000600E01123482401FFFFCE2521482C0153
+:10DFC0002B082C01FCFF201000000000F401E000F1
+:10DFD0001B00270112380000104800001900C7007C
+:10DFE00012200000004C0900FFFF0F3125482F01CF
+:10DFF0002B7824010600E01123482401FFFFE724C9
+:10E0000021482C012B082C01FCFF201000000000EF
+:10E0100000740E002170C7011900CB0112380000F6
+:10E0200010200000000008242B780701234007017E
+:10E030002B102F0123482F012B7824012578E20192
+:10E040000B00E01123482401FFFFCE2521400B01E6
+:10E050002B780B0121482C0121482F0102002C11A3
+:10E06000000000002B782C01F7FFE01100000000F9
+:10E0700006002C150000000025200B002548080094
+:10E0800000000D242A00001025380D00023C0C0071
+:10E09000F401E0001B002701126800001048000096
+:10E0A000FFFF86311900CD0012200000004C09004E
+:10E0B000027C080025482F012B7824010600E0117E
+:10E0C00023482401FFFFAD2521482C012B082C01FA
+:10E0D000FCFF201000000000F401E0001B002701FD
+:10E0E00012380000104800001900C700122000007C
+:10E0F000004C0900FFFF0F3125482F012B78240128
+:10E100000600E01123482401FFFFE72421482C01E9
+:10E110002B082C01FCFF201000000000006C0D00FB
+:10E120002168A7011900AB0112380000102000007F
+:10E13000000008242B780701234007012B102F0132
+:10E1400023482F012B7824012578E2010B00E011F0
+:10E1500023482401FFFFAD2521400B012B780B0143
+:10E1600021482C0121482F0102002C110000000041
+:10E170002B782C01F7FFE011000000000600C0051D
+:10E18000000000002A78A0012168AD012170CE01B5
+:10E190002170CF01FFFF4A25257828010200E011F8
+:10E1A000000000000100AD3525480E0025400D009F
+:10E1B000FFFF4F25FE07E12D150020100000000095
+:10E1C0000004082500040F2D21482F012B782F0172
+:10E1D00021504F01C27A08000100EF3123400F01A6
+:10E1E000C2220800407D090025208F0040780900E8
+:10E1F000027B0F002528AF00007D0A002528AF0014
+:10E2000025100400251805000800E00300000000A8
+:10E210004400401D0000000001000E242370CA01CC
+:10E220002000C12D0700201400000000E0FFCE21D7
+:10E230002B2008000D00091025402401F8FF0010D4
+:10E24000000009340900C0110000000022300E0057
+:10E250000420C8000430C9000640C8010648C901AE
+:10E26000020080102540C80002000835000408257F
+:10E2700000040F2D21482F01D6FF0010C2570900BE
+:10E280002A78000121400801214829011700401582
+:10E2900021482F01257828011400E011000000001A
+:10E2A0000800201500000000030000150000000019
+:10E2B00029FF001000000A2425480001000008245E
+:10E2C000E0FF4A2520702E7123FFC01100000000DE
+:10E2D00023504E0122300E000630C8000440C80111
+:10E2E0000448C9011CFF00102548260105004D15F2
+:10E2F0000000000040780C002578EB012B00E011B5
+:10E3000000000000FF0701240A00A1110000000026
+:10E31000BBFF401100000000257828012300E01514
+:10E3200000000000F07F013C2528A100B4FF001090
+:10E33000000004242A78600121586B0121608C01BF
+:10E340001700A01521608F0125788B01F5FFE011E2
+:10E3500000000000080080150000000003006015A8
+:10E360000000000000FF001000000D242560600187
+:10E3700000000B24E0FFAD2520708E71FAFEC01165
+:10E38000000000002368AE0122300E000630CB00F2
+:10E390000458CB010460CC01F3FE00102560860117
+:10E3A00025788B010200E01100000000F8FF053C19
+:10E3B00093FF0010000004240000052425480500F8
+:10E3C00025380500253004000C00C01000000000B6
+:10E3D0000600C104000000000080093C2B5005002D
+:10E3E00023280500233006002330CA001E0407241A
+:10E3F0002040C8702338E80004300601C2420500FE
+:10E400004055060025400A014050060002530A000C
+:10E4100025482A010055070025482A012510080033
+:10E42000251809000800E003000000000000052492
+:10E4300025380500253004000500C010000000004C
+:10E440001E0407242048C9702338E900043026013F
+:10E45000C24205004055060025400A01404806001A
+:10E46000024B09000055070025482A012510080025
+:10E47000251809000800E00300000000C23D040068
+:10E48000FF00E7300080013C24308100FFFFE924D9
+:10E49000FE00212D0C002010000000008003E72466
+:10E4A000404A0400024B09002530C900402F0400F7
+:10E4B000004D07002530C90025100500251806006D
+:10E4C0000800E00300000000000005242120840073
+:10E4D000F7FF8010000000000900E01400000000B9
+:10E4E000FFFFE724212084008000013C2B088100ED
+:10E4F000FBFF201400000000E8FF001000000000F7
+:10E50000FF07072400FF013C010021342B08810094
+:10E51000E7FF201400000000E5FF0010F8FF063CB4
+:10E52000C03A0500425D04002538EB00C03204000B
+:10E530000080013C2538E1000080013C2448A10016
+:10E54000404005004245080080FC0825FFFF0B25E0
+:10E55000FE00612D11002010000000000200C0101C
+:10E56000000000000100E7348000E7248000EB2C6D
+:10E5700021400B01025A070001006B312338EB00E8
+:10E5800040380700423A0700C05D08002538EB001C
+:10E590002510E9000800E003000000007F040124CA
+:10E5A00007000115000000004058070025586601CB
+:10E5B0000300601100000000F6FF0010C0FF023CE5
+:10E5C000FF0001290400201400000000807F013CAE
+:10E5D000F0FF00102510210101000A2423504801FA
+:10E5E0002000412D0300201400000000E9FF00106E
+:10E5F0002510090020000C2423608A01045887019B
+:10E600002530CB0006384701000008240080013C7B
+:10E61000D2FF00102538E100C03A05004255040041
+:10E620002538EA000080013C2538E1004050050013
+:10E6300042550A001E0406242330CA000B00C018ED
+:10E64000000000002000C12C020020140000000087
+:10E65000000007340200A1040638C7002338070071
+:10E66000251007000800E0030000000002008010F1
+:10E67000000000000100A534F07F013C01002134BE
+:10E680002B08A1000300201400000000F5FF00107B
+:10E690000080023CFF7F023CF2FF0010FFFF42348B
+:10E6A000C03A0500425504002538EA000080013CCC
+:10E6B0002538E1004050050042550A001E0406249A
+:10E6C0002330CA000B00C004000000002000C12C51
+:10E6D0000200201400000000000007340200A10422
+:10E6E0000638C70023380700251007000800E0039C
+:10E6F0000000000002008010000000000100A534AE
+:10E70000F07F013C010021342B08A10003002014FC
+:10E7100000000000F5FF00100080023CF3FF001035
+:10E72000FFFF0224FEFF0924405005004058070067
+:10E73000255864012558660125504B0103004015FA
+:10E74000000000003C0000100000022402008010C5
+:10E750004040050001000825E0FF013C0100213494
+:10E760002B08010136002010000000000200C0103C
+:10E770004040070001000825E0FF013C0100213472
+:10E780002B0801012E002010000000001600A1043B
+:10E79000000000000300E00400000000260000105C
+:10E7A000FFFF02242B508600232086002B58AA004E
+:10E7B0002328AA002B50A70025504B01030040112D
+:10E7C0002328A7001C000010010002242550A400EB
+:10E7D000030040110000000017000010FFFF02249A
+:10E7E00015000010000002240300E10400000000F6
+:10E7F00011000010010002242B5086002320860007
+:10E800002B58AA002328AA002B50A70025504B0103
+:10E81000030040112328A70007000010FFFF022477
+:10E820002550A40003004011000000000200001069
+:10E8300001000224000002240800E00300000000A0
+:10E84000FDFF0010251009000080013C2628A100D2
+:10E8500025100400251805000800E0030000000052
+:10E86000FF7F013CFFFF21342428A1002510040074
+:10E87000251805000800E0030000000002008010D9
+:10E880004040050001000825E0FF013C0100213463
+:10E890002B08010103002014000000000C000010F0
+:10E8A000010002240200C0104040070001000825BA
+:10E8B000E0FF013C010021342B080101030020147A
+:10E8C00000000000020000100100022400000224E9
+:10E8D0000800E003000000000080013C2628A100A1
+:10E8E000C24D0400FF002931C25D0500FF006B31FD
+:10E8F0000080073C0042040025400701005205004B
+:10E9000025504701FFFF2D25FE00A12D610020109D
+:10E9100000000000FFFF6D25FE00A12D77002010F4
+:10E920000000000023602B010D00800500000000A6
+:10E9300020008129030020140000000015000010B1
+:10E9400002000A2425300A0006508A0104688A0160
+:10E950001000A611000000000E00001002004A3551
+:10E9600025480B0023600C0020008129030020149F
+:10E9700000000000070000100200082425300800F5
+:10E9800006408801046888010200A611000000000A
+:10E990000200083524608700266885011000A00564
+:10E9A0000000000021400A012B680A011700A01195
+:10E9B0000000000001000D310200A0110000000065
+:10E9C000020008354240080001002925FF0001240B
+:10E9D0000E002115000000000C00001000000824AB
+:10E9E0002B680A010400A01123400A0123400800FB
+:10E9F0000300001026608701500000110000000095
+:10EA000020300671234826010440C8000E0020195A
+:10EA1000000000008000082580000D2D21482D01F8
+:10EA2000026A08000100AD3123400D01404008009A
+:10EA300042420800C06D090025400D0125100C015F
+:10EA40000800E00300000000010006242330C90094
+:10EA50002000C12C39002010000000000080013C83
+:10EA60002540010120000D242368A6010448A801C7
+:10EA7000020020110640C8000100083500000924EA
+:10EA800080000D25E3FFA10500000000E1FF00105C
+:10EA9000010009240E00201500000000214008019B
+:10EAA000050000110000000020600C7123482C01BB
+:10EAB00098FF001004408801FF0001240F0061113D
+:10EAC000000000000080013C1800A11400000000BC
+:10EAD000216808011B00A01500000000FF000124B0
+:10EAE0001400611500000000266885001500A005CF
+:10EAF000000000000D00001000000000080060157C
+:10EB00000000000021504A010A00401100000000EE
+:10EB100020604C7123586C0182FF001004508A0160
+:10EB200021684A010700A01500000000C4FF001082
+:10EB300025100500C2FF001025100400C0FF0010C2
+:10EB400000000224BEFF0010C0FF023CC23D0400D2
+:10EB5000FF00E730C24D0500FF00293100800A3C6C
+:10EB6000003204002530CA000042050025400A0199
+:10EB70002660850024504C01FFFFEC24FE00812D0F
+:10EB80002100201000000000FFFF2C25FE00812D39
+:10EB900036002010000000001900C80012580000C4
+:10EBA00002006011103000000100C6340300C004F0
+:10EBB0000000000040300600FFFFE72482FF2C2504
+:10EBC0002138EC00FFFFEC24FE00812D3A002010DC
+:10EBD000000000008000C6248000CC2C2138EC000E
+:10EBE0000262060001008C312330CC004030060068
+:10EBF00042320600C06507002530CC002510CA004F
+:10EC00000800E003000000000D00E0140000000018
+:10EC10002130C6000500C010000000002058CB7055
+:10EC20002338EB00D8FF001004306601FF000124F8
+:10EC30001F0021110000000015000010000000005E
+:10EC40002160C6001A008015000000000400201595
+:10EC50000000000021600801150080110000000084
+:10EC6000FF0001240F002115000000000A002015FC
+:10EC70000000000021400801050000110000000014
+:10EC800020580B7123482B01C3FF0010044068017A
+:10EC9000DBFF001025100A00216008010400801528
+:10ECA00000000000807F013CD5FF001025104101CD
+:10ECB000D3FF0010C0FF023CFAFFE01C0000000080
+:10ECC00001000B24235867012000612DF0FF201064
+:10ECD0000000000020000C2423608B010438860112
+:10ECE0000200E010063066010200C634000007246E
+:10ECF0008000CC24B7FF810500000000B5FF0010A4
+:10ED00000100072400800B3CC2450400FF000831CD
+:10ED1000C2550500FF004A31003A04002538EB00D7
+:10ED2000004A050025482B012670850024586E01F5
+:10ED3000FFFF0E25FE00C12D3F0020100000000047
+:10ED4000FFFF4E25FE00C12D5300201000000000E3
+:10ED50002B08E900030020140000000042380700DF
+:10ED60000100082582630900F40180011B00EC000A
+:10ED70001220000010300000FF3F2D311900A401C7
+:10ED800012280000803306002B70C5000400C0115B
+:10ED90002330C500FFFF84242130C9002B70C90037
+:10EDA000F40180011B00CC0012380000103000007C
+:10EDB0001900A70112280000803306002B70C5003F
+:10EDC0000400C0112330C500FFFFE7242130C90033
+:10EDD0002B70C900807304002138EE000200C010BF
+:10EDE000003907000100E7347E000E242370CA01B9
+:10EDF00021400E01FFFF0E25FE00C12D3400201022
+:10EE0000000000008000E7248000EE2C21400E016D
+:10EE1000027207000100CE312338EE0040380700AF
+:10EE2000423A0700C07508002538EE002510EB00B7
+:10EE30000800E003000000000800001500000000CA
+:10EE40002138E7000500E010000000002060EC70B1
+:10EE500023400C01BAFF0010043887010400481554
+:10EE600000000000217029012F00C01100000000E7
+:10EE7000FF000124080041110000000012000011F1
+:10EE8000000000002170E7002700C015000000000E
+:10EE900022000010000000000800401500000000E3
+:10EEA000214829011D0020110000000020602C7164
+:10EEB00023504C01A6FF001004488901217029014C
+:10EEC0001900C01500000000D9FF001025100B002C
+:10EED0001200001D0000000001000C2423608801C6
+:10EEE0002000812DF8FF20100000000020000E24DB
+:10EEF0002370CC010440C7010200001106388701CD
+:10EF00000200E734000008248000EE24BDFFC105A4
+:10EF100000000000BBFF001001000824807F013CBE
+:10EF2000C3FF001025106101C1FF0010C0FF023CAB
+:10EF30000080013C12008010243081000200810416
+:10EF400000000000232004009E0005242038877064
+:10EF50002328A7000420E400800084248000882C5B
+:10EF60002128A80003420400010008312320880062
+:10EF70004020040042220400C045050025208800EE
+:10EF8000251086000800E003000000000F0080103C
+:10EF9000000000009E000624202885702330C50054
+:10EFA0000420A400800084248000872C2130C70026
+:10EFB000023A04000100E7302320870040200400CB
+:10EFC00042220400C03D06002520870025100400D1
+:10EFD0000800E00300000000002A04000080013C5B
+:10EFE0002528A100C23D0400FF00E7309E00062452
+:10EFF0002330C7000C00C018000000002000C1280A
+:10F00000030020140000000005000010000002248E
+:10F01000020081040628C5002328050025100500EC
+:10F020000800E00300000000807F013C0100213463
+:10F030002B0881000300201400000000F8FF0010DE
+:10F040000080023CFF7F023CF5FF0010FFFF4234CE
+:10F05000002A04000080013C2528A100C23D0400D4
+:10F06000FF00E7309E0006242330C7000C00C004D8
+:10F07000000000002000C128030020140000000050
+:10F080000500001000000224020081040628C500CB
+:10F0900023280500251005000800E00300000000FB
+:10F0A000807F013C010021342B08810003002014E3
+:10F0B00000000000F8FF00100080023CF6FF001086
+:10F0C000FFFF0224FEFF0824403004004038050002
+:10F0D0002548C7001B0020110000000000FF013C74
+:10F0E000010021342B08C10019002010000000008D
+:10F0F00000FF013C010021342B08E1001400201026
+:10F1000000000000020081044230060023300600A7
+:10F110000200A10442380700233807002A08C7006C
+:10F12000030020100000000007000010FFFF022471
+:10F130002A08E60003002010000000000200001072
+:10F1400001000224000002240800E0030000000087
+:10F15000FDFF0010251008004010040042100200BE
+:10F160000800E003000000000080013C2610810040
+:10F170000800E003000000004030040000FF013CF4
+:10F18000010021342B08C1000300201400000000FE
+:10F190000A000010010002244030050000FF013C7D
+:10F1A000010021342B08C1000300201400000000DE
+:10F1B0000200001001000224000002240800E00305
+:10F1C00000000000B8FFBD274800A4AF4000BEAF5C
+:10F1D0003400B5AF3000B4AF2C00B3AF4400BFAFC4
+:10F1E0003C00B7AF3800B6AF2800B2AF2400B1AFD3
+:10F1F0002000B0AF00008880029D063C4D17C4245B
+:10F2000021100401000047804800B38F8800E330DC
+:10F210004C00A5AF1000A0AF1400A0AF21F000007B
+:10F220001800A0AF21A000000800601021A8000075
+:10F23000010073260000688221500401000049810A
+:10F2400088002531FBFFA054010073262D00042403
+:10F25000D40004112B000C24D7000C51010073269C
+:10F260004D17D724217017010000CD910400A6315D
+:10F270001B00C01001000F24029D163C1800AFAF08
+:10F280006819C68E6C19C78ED0FF12252128A002DE
+:10F29000F776400F212080022120400221A8400063
+:10F2A000EE78400F21A06000213040002120A00214
+:10F2B0002128800221386000EE75400F010073267E
+:10F2C0000000688225F0D2032190170100005192BE
+:10F2D00021A0400004003032E9FF001621A86000A0
+:10F2E0002E0016248A001651010073261800A48FE0
+:10F2F000280080104C00A48F4500063965000D39A8
+:10F300000100AB2D0100CC2C25406C012100001127
+:10F310004C00A48F01007326000064822D000E248F
+:10F3200021280000AF008E10213800002B000F2490
+:10F33000A3008F500100732621C097000000169390
+:10F340000400D7320D00E012029D193C4D1726270C
+:10F35000809005002150450240280A0001007326D4
+:10F360002148A400000064822118860000006290F9
+:10F3700004005F30F6FFE017D0FF25251400B18FA1
+:10F38000238005000B280702213825021400A7AFAF
+:10F390004C00A48F050080104800AB8F1800AC8F84
+:10F3A0004C00A88F0A986C01000013AD1400A28FC6
+:10F3B00028004010029D1F3CC39F0200029D0F3C8D
+:10F3C00026705300029D0D3C081AE68D0C1AE78D3D
+:10F3D0002390D30121B04000B819B32503000010D9
+:10F3E000090003241000001221180002FFFF7024FE
+:10F3F00007C01202C0C803000100173321403303C5
+:10F400002120C000F7FFE0122128E0000000068D57
+:10F41000F776400F0400078D21386000213040004E
+:10F42000F2FF0016211800026A00C00621208002A7
+:10F43000F776400F2128A0022120400021286000FB
+:10F44000827D400F2130C00221A0400021A8600031
+:10F45000029D1F3C141AF68F040080162438B60251
+:10F46000F07F023C5800E210220003242590950210
+:10F470000100452E2B501E002448AA005D00205597
+:10F48000220015241000A78F0E00E0142110800226
+:10F490002118A0024400BF8F4000BE8F3C00B78FF0
+:10F4A0003800B68F3400B58F3000B48F2C00B38F86
+:10F4B0002800B28F2400B18F2000B08F0800E00335
+:10F4C0004800BD2721208002127A400F2128A00287
+:10F4D00021A0400021A86000211080022118A00274
+:10F4E0004400BF8F4000BE8F3C00B78F3800B68FFE
+:10F4F0003400B58F3000B48F2C00B38F2800B28F4A
+:10F500002400B18F2000B08F0800E0034800BD2721
+:10F510000000688221F817010000F99304003833D5
+:10F5200072FF0013029D163C010003241800A3AFD4
+:10F530006819C68E6C19C78ED0FF12252128A0022B
+:10F54000F776400F212080022120400221804000D8
+:10F55000EE78400F218860002138600021282002C9
+:10F560002120000221304000EE75400F010073267B
+:10F57000000068821400A98F2150170121A04000CB
+:10F5800000004291FFFF25250400473021A86000BC
+:10F5900025F0D203E6FFE0141400A5AF57FF0010DA
+:10F5A00045000639010073260000688201000B2423
+:10F5B0002BFF00101000ABAF29FF00100000688285
+:10F5C0005DFF00100000648200A01E3CADFF001033
+:10F5D0000402C3AFC177400F2128A00297FF00109B
+:10F5E00021204000010073260000648252FF0010B9
+:10F5F0000100072400A0143C040295AE21A00000E5
+:10F60000A0FF001021A800000055A77CFFFFE32405
+:10F61000FE07622C214080002150C000C007AB7C57
+:10F620003F0040100098A97C029D043C1C1A858C68
+:10F6300001FCE424253025012148C00021788A00FE
+:10F64000C048090042570800FF03E72525482A0162
+:10F650004100E018C0400800070006311D00C0143A
+:10F66000C000057D40670900C2300800FF07E4289C
+:10F670002540CC0031008010C2480900029D033CA7
+:10F680001C1A798C2178000024C039012550F8011A
+:10F69000070040512138000021100001029D083C64
+:10F6A0002C1A058D21404000247025012148C001FD
+:10F6B000C06A0B002520A70100350400216000006E
+:10F6C000252088012528C900211080000800E003BA
+:10F6D0002118A0000300A2242118000021400201EB
+:10F6E000029D183C2BC8020121482301241A0F8FC8
+:10F6F000214839012168000024502F012560AA010A
+:10F70000D9FF801140670900C07709004240080016
+:10F7100025400E0142480900D2FF00100100E724F5
+:10F720000400E01421108000253889002900E0142D
+:10F73000026809000800E0032118A000C06A0B005D
+:10F74000FF07A735002D07002120000021108000B1
+:10F750000800E0032118A00001001924233027032A
+:10F760003800D82818000053010008242328060078
+:10F770002000A2302718C0000660C80004186900E5
+:10F780000668C90040180300256083012000C330CB
+:10F790000B60A3010B68030021500001040040141A
+:10F7A0000418A800021809000440A3002518480105
+:10F7B0002B20030021280000254084012548A501B5
+:10F7C000A5FF00102138E60021480000A2FF00102C
+:10F7D0002138E60002FC04240300A0152018A371C0
+:10F7E00020700E712000C325F5FF632494FF601084
+:10F7F00021788A002710600004386900061048004C
+:10F8000004306800421002002538E2002000623017
+:10F810000B38C2000B300200232083002140C000BF
+:10F8200086FF00102148E00080BF033C105A648C22
+:10F830000000827CFDFF40100000000080BF033C00
+:10F84000205A628C0800E003000000000800E0037A
+:10F8500000606241E8FFBD271000BFAF00680540AF
+:10F860008000063C2520A600006884400010032488
+:10F8700088BF023C477E400F081043AC1000BF8F8A
+:10F880000800E0031800BD27010084300300801049
+:10F89000000000000800E003206060410800E00371
+:10F8A00000606041E8FFBD271000BFAF137E400F2E
+:10F8B0000000000088BF043C0030838C0003627CA1
+:10F8C0000800401499AA0F3C0010062488BF053C8C
+:10F8D0000830A6AC0030888C0003077DFDFFE010E7
+:10F8E00099AA0F3C66550D3C81BF0B3C5566EE3521
+:10F8F000AA99AC3501000A2481BF093C30F260AD01
+:10F9000081BF043C30F26EAD30F26CAD18F62AAD1A
+:10F9100010F6828CFFFF0010000000000800E003DA
+:10F92000206062412118E0002140A0002138C00081
+:10F930003A006014216080002B10A6008C0040105B
+:10F94000000000002030C670C200C014232806004A
+:10F95000023407001B000601F401C000FFFFEB307A
+:10F9600002740C001248000010C000001250000089
+:10F9700002482B71007C18002528EE012B68A90095
+:10F980001B000601F401C0000900A0512320A900BA
+:10F990002128A7002B40A70004000015FFFF4A25DF
+:10F9A0002BC8A900FC002057FFFF4A252320A900EF
+:10F9B0001B008600F401C000FFFF833112680000C5
+:10F9C00010280000124800000258AB710014050016
+:10F9D000254043002B600B011B008600F401C00092
+:10F9E00009008051005C0A00214007012B3007010B
+:10F9F0000400C014FFFFA9252B700B012B380E004B
+:10FA000023482701005C0A002520690121300000FD
+:10FA1000211080000800E0032118C0002B58A3002B
+:10FA200021200000FAFF6015213000002048697095
+:10FA30008E0020112B10870120000D242370A901B6
+:10FA4000045023010678C70125684F0106C8C50187
+:10FA500002540D001B002A03F401400106C0CC0132
+:10FA600004282501FFFFAF312570B80004C02C0128
+:10FA7000021C0E000438270112200000105800005C
+:10FA80001260000002408F70004C0B0025582301CB
+:10FA90002B3068011B002A03F40140010B00C05009
+:10FAA0002318680121586D012B106D0106004014C8
+:10FAB000FFFF8C242B3068010400C010231868015C
+:10FAC000FFFF8C2521586D01231868011B006A0077
+:10FAD000F4014001FFFFCB3112480000104000004C
+:10FAE0001230000002482F710024080025408B00CE
+:10FAF0002BC809011B006A00F40140010B002053D0
+:10FB0000007C0C0021400D012B280D010600A014E3
+:10FB1000FFFFC6242B7009010400C011007C0C00FB
+:10FB200021400D01FFFFC624007C0C002520E601CA
+:10FB30001900870010280000231809012B606500B8
+:10FB400009008055FFFF8424121000002668A300DE
+:10FB50002B5002030100B82D24380A03ACFFE050FB
+:10FB600021300000FFFF8424A9FF00102130000095
+:10FB70004500C01001000A242050EA7049004015D9
+:10FB8000200009242328070101000624024C070055
+:10FB9000FFFFED301B00A900F401200102CC0C0096
+:10FBA00012500000101800001258000002504D7151
+:10FBB00000240300254099002B700A011B00A900B6
+:10FBC000F40120010900C01123780A012140070136
+:10FBD0002B2807010400A014FFFF6B252B100A013E
+:10FBE0006B004054FFFF6B2523780A011B00E901DD
+:10FBF000F4012001FFFF983112C8000010400000FE
+:10FC00001250000002602D73007408002540D801D6
+:10FC10002B680C011B00E901F40120010900A0116F
+:10FC2000001C0B00214007012B480701050020158F
+:10FC3000FFFF2A272B380C012B60070023504C01B3
+:10FC4000001C0B0025206A00211080000800E00342
+:10FC50002118C0000620A4000418C8002540640034
+:10FC60000460CC003AFF00100438C7002B20650068
+:10FC700001004538255085002B200A002110800006
+:10FC80000800E0032118C0001B004601F401C00079
+:10FC9000123800002050EA70BBFF401123280701F2
+:10FCA0002000092423782A010438470106C8E80106
+:10FCB000024C07001B002903F40120010670EC012F
+:10FCC00004104801FFFFED3025784E0002240F009C
+:10FCD0001230000010280000127000000240CD70A9
+:10FCE000001C0500255864002BC068011B00290377
+:10FCF000F40120010A00001304604C01215867013F
+:10FD00002B50670106004015FFFFCE242BC0680171
+:10FD10000400001323C86801FFFFCE2521586701A6
+:10FD200023C868011B002903F4012001FFFFE4310F
+:10FD30001228000010400000123000000250AD7088
+:10FD4000001C0800254064002B580A011B002903F1
+:10FD5000F40120010B00601100C40E0021400701D6
+:10FD60002B10070107004014FFFFA6242B780A017F
+:10FD70000500E05125300603FFFFC624214007019E
+:10FD800000C40E002530060382FF001023280A015C
+:10FD900095FF00102140070104FF00102128A70053
+:10FDA000E8FFBD272140E0001000B2AF0C00B1AF6A
+:10FDB0000800B0AF2190A0032150C000215880005E
+:10FDC000400000152138A0002B10A6005C00401058
+:10FDD0002070CE707900C01523280E00024C0A0056
+:10FDE0001B00E900F4012001FFFF4F3102640B000A
+:10FDF000128000001030000002280F72006C060014
+:10FE00002530AC012B40C5001B00E900F4012001A6
+:10FE10000A0000112318C5002130CA002B38CA007F
+:10FE20000600E0142318C5002BC8C5000000383BAD
+:10FE30002188CA000B3038022318C5001B00690056
+:10FE4000F4012001FFFF713112C8000010C0000052
+:10FE500002582F73007C18002540F1012B380B014C
+:10FE60001B006900F40120010A00E01023180B01B7
+:10FE700021400A012B480A010600201523180B0116
+:10FE80002B100B0121200A0100004A380B408A0088
+:10FE900023180B010660C301030040122168000013
+:10FEA00000004CAE04004DAE0000A28F0400A38FF2
+:10FEB0001000B28F0C00B18F0800B08F0800E00373
+:10FEC0001800BD272B70A8000A00C05120700E71C9
+:10FED0001000B28F0C00B18F0800B08F211080008D
+:10FEE0002118A0000000A4AF0400A5AF0800E003A3
+:10FEF0001800BD273700C01520000F242B6886008E
+:10FF00000100AC392B3005012528CC000700A010DA
+:10FF10002160600123808A002388E8002B40900044
+:10FF2000233828022158000221606001DEFF4012C0
+:10FF30002168E00000004CAEDBFF001004004DAE75
+:10FF40007E00C0100100092420704E718200C0158F
+:10FF500020000F242330EA00024C0A00FFFF4F313B
+:10FF60001B00C900F401200102240B001240000014
+:10FF70001028000002380F71001C050025286400BD
+:10FF80002B10A7001B00C900F4012001ABFF40109B
+:10FF90002318A7002128AA002B30AA00A7FFC054CD
+:10FFA0002318A7002B80A70000000D3A2160AA00AB
+:10FFB0000B288D01A1FF00102318A7000620A40024
+:10FFC0000418C701253864000450C60183FF0010DF
+:10FFD0000458CB0123C0EE010448C80106C806033B
+:10FFE0002578390106200503024C0F001B0089000B
+:10FFF000F401200106380B030468C501FFFFF1314D
+:020000041D02DB
+:1000000025C8A7010480CB010438CA01021C1900CD
+:100010001230000010600000125800000250D17031
+:10002000002C0C002540A3002B100A011B008900A6
+:10003000F40120010B00405023180A0121400F0158
+:100040002B100F0106004014FFFFCB242B200A01C8
+:100050000400801023180A01FFFF6B2521400F01C7
+:1000600023180A011B006900F4012001FFFF25335A
+:100070001250000010400000123000000250517178
+:1000800000640800254085012B880A011B006900D7
+:10009000F40120010B00201200140B0021400F017D
+:1000A0002B680F010700A015FFFFC6242BC80A010B
+:1000B0000500201325484600FFFFC62421400F01FC
+:1000C00000140B00254846001900270110300000DD
+:1000D00023400A012B580601070060151228000072
+:1000E0002660C8000100912D2B1805022420230250
+:1000F00006008010000000002350A7002B38AA0043
+:100100002368CF002330A7012128400166FF401259
+:1001100023780502232806012B400F022380A80024
+:100120000430100306C0CF012560D8000668D00156
+:1001300000004CAE5CFF001004004DAE1B00260119
+:10014000F401C0001250000020704E7182FFC011F7
+:100150002330EA0020000F242380EE010450CA015E
+:1001600006200702024C0A001B008900F40120014E
+:1001700006680B020430C701FFFF4F312538CD0060
+:10018000021C0700126000001040000002308F7156
+:10019000002C08002540A3002B1006011B0089003D
+:1001A000F4012001050040100458CB0121400A0150
+:1001B0002B880A01190020122B10060123180601B2
+:1001C0001B006900F4012001FFFFE5301268000008
+:1001D000106000000238AF7100440C0025300501AA
+:1001E0002B20C7001B006900F40120015CFF805038
+:1001F0002330C7002130CA002B80CA0058FF0056A8
+:100200002330C7002BC8C7000000383B2188CA0034
+:100210000B30380252FF00102330C700000059385D
+:1002200021C00A01E5FF00100B401903FFFFFFFF8B
+:100230005261704D616E205665723A312E302E3902
+:1002400000000000496E736572742053442D4361B1
+:100250007264206F720000003C3C45534320544FB1
+:1002600020524553554D4500496E76616C696420B6
+:1002700046696C652054797065000000506C6561BA
+:100280007365206F6E6C7920757365002A2E424667
+:1002900042206F72202A2E47434F2046696C6573B7
+:1002A0000000000050415553450000004572726F38
+:1002B0007220544553540000457874727564657219
+:1002C000204F46460000000046696C65204572726A
+:1002D0006F72203A7365656B20707400556E6B6E9B
+:1002E0006F776E204572726F72000000203C45539C
+:1002F0004320544F20524553455400003C00000019
+:10030000000002430000C8C2546F6F6C3A20506571
+:100310006E000000546F6F6C3A20457874727564FB
+:1003200065720000546F6F6C3A2045787472756482
+:1003300065723200546F6F6C3A204E6F74204465C2
+:1003400066696E6564000000546F6F6C3A20526FEE
+:100350007574657200000000546F6F6C3A204E6F28
+:100360006E6500007200000046696C65204572727F
+:100370006F7220202020000046696C65204E6F744B
+:1003800020466F756E6400004F70656E00000000BF
+:100390002A2E2A0046696E642046697273742045CD
+:1003A00072726F72000000004E6F2066696C657398
+:1003B000206F6E20636172640000000046696C6506
+:1003C00000000000253375006F6600000000004447
+:1003D0000000FE420000FE42204F4B2000000000C3
+:1003E000544553540000000025362E3266000000AC
+:1003F000CDCCCCCCCCE45540000020455A20444F15
+:10040000574E2020202020005920464F525741525D
+:1004100044202000484F4D45205820202020000037
+:10042000484F4D452059202020200000484F4D4581
+:10043000205A202020200000484F4D452041424FA7
+:100440005254454400000000484F4D4520434F4D55
+:10045000504C455445000000CDCCCCCCCCE45540AC
+:1004600039B4C876BE9FF63F0000C84200000000C5
+:10047000CDCCCCCCCCE455400000204500000000A1
+:10048000CDCCCCCCCCE4554000808443000048C3A4
+:10049000000002430000C8C2000000000000E03F6E
+:1004A000000000000000E03F000000000000E0BF8E
+:1004B00054454D5045524154555245204348414EB4
+:1004C00047450000440B019D6C0D019D6C0D019D85
+:1004D0006C0D019D6C0D019D6C0D019D6C0D019DC0
+:1004E0006C0D019D6C0D019D6C0D019D6C0D019DB0
+:1004F0006C0D019D6C0D019D6C0D019D6C0D019DA0
+:100500006C0D019D6C0D019D040D019D6C0D019DF7
+:100510006C0D019D6C0D019D6C0D019D580A019D96
+:100520006C0D019D6C0D019D6C0D019D6C0D019D6F
+:100530006C0D019D6C0D019D6C0D019D6C0D019D5F
+:100540006C0D019D440B019D6C0D019D6C0D019D79
+:100550006C0D019D6C0D019D6C0D019D6C0D019D3F
+:100560006C0D019D6C0D019D6C0D019D6C0D019D2F
+:100570006C0D019D6C0D019D6C0D019D6C0D019D1F
+:100580006C0D019D6C0D019D040D019D6C0D019D77
+:100590006C0D019D6C0D019D6C0D019D580A019D16
+:1005A0002E2E00002020202020202020202020008F
+:1005B00000000000009500000000000000000000A6
+:1005C00001F90000000000000000000009AF000079
+:1005D00000000000010000000A1B000000000000F5
+:1005E000010000000CC3000000000000000000003B
+:1005F0000DAF0000020000000000000010FF00002E
+:10060000000000000000000011FF000000000000DA
+:100610000100000012FF00000000000001000000C7
+:1006200018FF0000000000000100000019FF00009A
+:10063000000000000100000020FF0000000000009A
+:100640000000000021FF000000000000000000008A
+:1006500026DF0000010000000000000037730000EA
+:1006600000000000000000003A2500000300000028
+:10067000000000003B25000000000000000000001A
+:1006800000040000FF030000FE030000FC03000064
+:10069000FA030000F7030000F2030000EC0300007F
+:1006A000E3030000D8030000C9030000B603000004
+:1006B0009F03000083030000610300003B03000070
+:1006C00010030000E1020000AF0200007B02000006
+:1006D0004702000013020000E0010000B101000029
+:1006E000840100005A0100003501000013010000E0
+:1006F000F4000000D9000000C1000000000000006C
+:1007000000000000389C2C4100000000000039402F
+:10071000000080BF00C0794400C07944000080BF61
+:10072000000020410000000000000000389C2C4127
+:100730000000000000003940000000000000000040
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:10077000E0E0606060FFFF6363E3E3030303FFFF08
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F000FFFFC0C0C0C7C7C6C6FFFF060606070783
+:1008000000000000000000000000000000000000E8
+:1008100000000000000000000000000000000000D8
+:1008200000000000000000000000000000000000C8
+:1008300000000000000000000000000000000000B8
+:1008400000000000000000000000000000000000A8
+:100850000000000000000000000000000000000098
+:100860000000000000000000000000000000000088
+:100870000000000000000000000000000000000078
+:100880000000000000000000000000000000000068
+:100890000000000000000000000000000000000058
+:1008A0000000000000000000000000000000000048
+:1008B000000000000000000000000040C0C0C0C0F8
+:1008C000C0C0C0C0C0C0C0C0C0C0C0C08080000028
+:1008D0000000000000000000000000000000000018
+:1008E0000000000000000000000000000000000008
+:1008F00000000000000040C0C0C0C0C0C0C0C08038
+:10090000000000000080C0C0C0C0C0C0C0C0400027
+:1009100000000000000000000000000000000000D7
+:1009200000000000000000000000000000000000C7
+:10093000000000000000000000000000FFFFFFFFBB
+:10094000FFFFFF7171F1F1FFFFFFFFFF7F3F00002D
+:10095000009C9C9C9C9C9C9C9C9CFCFCFCFCFCF837
+:10096000F0000004FCFCFCFCFCFCF81C1C1CFCFC67
+:10097000FCFCFCF8F00000FFFFFF0F7FFFFFFFFF14
+:10098000FCE000E0FC3F07FFFFFFFFFFFFFF000070
+:1009900000009C9C9C9C9C9C9C9C9CFCFCFCFCFCEF
+:1009A000F8F0000000FCFCFCFCFCFCF81C1C1CFC2F
+:1009B000FCFCFCFCF8F00000000000407F7F7F7F23
+:1009C0007F7F7F400000073F7F7F7F7F7C704000FC
+:1009D0003F7F7F7F7F7F7F7171717F7F7F7F7F7F91
+:1009E0007F400000FFFFFFFFFFFFFF7070707F7F01
+:1009F0007F7F7F7F3F00407F7F7F0000031F7F7FDF
+:100A00007F7F7F0F0100407F7F7F7F7F7F7F400060
+:100A1000003F7F7F7F7F7F7F7171717F7F7F7F7FCF
+:100A20007F7F4000407F7F7F7F7F7F7F4000407FD0
+:100A30007F7F7F7F7F7F400000000000000000007C
+:100A400000000000000000000000000000000000A6
+:100A50000000000000000000000000000000000096
+:100A60000000000007070707070707040000000051
+:100A70000000000000000000000000000000000076
+:100A80000000000000000000000000000000000066
+:100A90000000000000000000000000000000000056
+:100AA0000000000000000000000000000000000046
+:100AB0000000000000000000000000000000000036
+:100AC0000000000000000000000000000000000026
+:100AD0000000000000000000000000000000000016
+:100AE0000000000000000000000000000000000006
+:100AF00000000000000000000000000000000000F6
+:100B000000000000000000000000000000000000E5
+:100B100000000000000000000000000000000000D5
+:100B200000000000000000000000000000000000C5
+:100B300000000000000000000000000000000000B5
+:100B400000000000000000000000000000000000A5
+:100B50000000000000000000000000000000000095
+:100B6000000000000000000000C060301088E45465
+:100B70006E6E26F32F272323272FF3266E5664CC81
+:100B8000983020E08000000000000000000000001D
+:100B90000000000000000000000000000000000055
+:100BA0000000000000000000000000000000000045
+:100BB0000000000000000000000000000000000035
+:100BC0000000000000000000000000000000000025
+:100BD0000000000000000000000000000000000015
+:100BE000000000000000C0FC472632F93F10080852
+:100BF00008F80F0908080808080809FF080808107D
+:100C0000173DF326655FFCC00000000000000000F7
+:100C100000000000000000000000000000000000D4
+:100C200000000000000000000000000000000000C4
+:100C300000000000000000000000000000000000B4
+:100C400000000000000000000000000000000000A4
+:100C50000000000000000000000000000000000094
+:100C60000000000000000F74C888107FD0302060A2
+:100C7000607FC04040404040404040FF60602030C6
+:100C800010F01F90D8E87C0F00000000000000006A
+:100C90000000000000000000000000000000000054
+:100CA0000000000000000000000000000000000044
+:100CB0000000000000000000000000000000000034
+:100CC0000000000000000000000000000000000024
+:100CD0000000000000000000000000000000000014
+:100CE000000000000000000003070D3B276E5CA819
+:100CF000C888977CD090101090D03C97D8E8B8CC9A
+:100D000067371B0D07010000000000000000000015
+:100D100000000000000000000000000000000000D3
+:100D200000000000000000000000000000000000C3
+:100D300000000000000000000000000000C0C040F3
+:100D40004040C0C08000C000C0C0C0C08080C000A3
+:100D500080C0C0C0C0000000000000C0C0C0C0C053
+:100D600000000000C0C0C0C0C0C0C080000080C083
+:100D7000C0C1C1C1810303C383030101010000801D
+:100D8000C00000000000C0C0404040C0C080000063
+:100D9000C0C000000080C00000C0C0C0C08080C0D3
+:100DA0000080C0C0C0C00000000080C0C0C0C00043
+:100DB000000000000000000000000000003F3F268F
+:100DC0002226361F0F003F0000003F3F00000000BA
+:100DD00033333434343C18000000003F3D04040435
+:100DE000040404003F3F060E1E1E362700061F3077
+:100DF000303030301F06003F030F1C38381C0F0303
+:100E00003F00000000003F3F262226361F0F000053
+:100E10000001033E03010000000000003F0000004D
+:100E2000001F1F3434343434340033333434343C0E
+:100E3000180000000000000000000000000000009A
+:100E400000000000000000000000000000000000A2
+:100E50000000000000000000000000000000000092
+:100E60000000000080808000E0F0F81818B0A000BA
+:100E7000E0F0F818F8F0E000F8F8F810F8F8F018DA
+:100E8000F8F8F00000000000000000000000000082
+:100E90000000000000000000000000000000000052
+:100EA0000000000000000000000000000000000042
+:100EB0000000000000000000000000000000000032
+:100EC0000000000000000000000000000000000022
+:100ED0000000000000000000000000000000000012
+:100EE00000000000030303000001030303010000EE
+:100EF00000010303030100000303030003030300D5
+:100F000003030300000000000000000000000000D8
+:100F100000000000000000000000000000000000D1
+:100F200000000000000000000000000000000000C1
+:100F300000000000000000000000000000000000B1
+:100F400000000000000000000000000000000000A1
+:100F50000000000000000000000000000000000091
+:100F60000000000000000000000000000000000081
+:100F70000000000000000000000000000000000071
+:100F80000000000000000000000000000000000061
+:100F90000000000000000000000000000000000051
+:100FA0000000000000000000000000000000000041
+:100FB0000000000000000000000000000000000031
+:100FC0000000000000000000000000000000000021
+:100FD0000000000000000000000000000000000011
+:100FE0000000000000000000000000000000000001
+:100FF00000000000000000000000000000000000F1
+:1010000000000000000000000000000000000000E0
+:1010100000000000000000000000000000000000D0
+:1010200000000000000000000000000000000000C0
+:1010300000000000000000000000000080402020B0
+:1010400040800000000000000000000000000000E0
+:101050000000000000000000000000000000000090
+:101060000000000000000000000000000000000080
+:101070000000000000000000000000000000000070
+:101080000000000000000000000000000000000060
+:101090000000000000000000000000000000000050
+:1010A0000000000000000000000000000000000040
+:1010B00000000000000000000000FC0300C0C0C0F1
+:1010C000C00003FC00000000000000000000000061
+:1010D00000000000000000000000020502003C4289
+:1010E0008181816600000000000000000000000017
+:1010F00000000000000000000000000000000000F0
+:1011000000000000000000000000000000000000DF
+:10111000000080402010100808080404040404089B
+:1011200008081010204080000000000000000000AF
+:1011300000000000000000000000FF0000FFFFFFB3
+:10114000FF0000FF000000000000000000000000A1
+:10115000000000000000000000000000000080808F
+:10116000808000000000000000000000000000007F
+:10117000000000000000000000000000000000006F
+:10118000800000008000000000000000000000005F
+:10119000F00E010000000000000080E0E0E0000030
+:1011A000000000000000010EF00000000000000040
+:1011B00000000000000000000000FF0000FFFFFF33
+:1011C000FF0000FF00000000000000000000000021
+:1011D00000000000000000000000000000007F048C
+:1011E000040000324A4A7C007E04027C00000000B9
+:1011F00000000000000000000000000000000003EC
+:1012000004631C3348300000000000F00808F000C0
+:10121000010E3040880404020101000000000000BB
+:10122000000000008040300E01E010902000E0102F
+:1012300010E000000000000080C0FFF0F8FFFFFF9A
+:10124000FFF8F0FFC0800000000000000000000078
+:10125000000000000000000000000000000000008E
+:10126000000000000000000000000000000000007E
+:10127000000000000000000000000000000000006E
+:101280000000000000000000000000030404030050
+:101290000000000000010102020204040404040230
+:1012A000020201010000000000070908070007080A
+:1012B0000807000000000000FFFFFFFFFFFFFFFF27
+:1012C000FFFF7F3F1F0F0000000000000000000034
+:1012D000000000000000000000020502003C428106
+:1012E0008181660000000000000000000000000096
+:1012F00000000000000000000000000000000000EE
+:1013000000000000000000000000000000FF0919BC
+:10131000294680FF1111110E00FF0678807806FF24
+:1013200000000000000000000000000000000000BD
+:101330000000000000000000000000000000005F4E
+:1013400000000003000300143E143E14242A7F2AE8
+:1013500012433308666136495522500005030000E8
+:10136000001C2241000041221C0014083E08140801
+:10137000083E08080050300000080808080800600F
+:1013800060000020100804023E5149453E04027FDF
+:101390000000426151494622414949361814127FE2
+:1013A0001027454545393E49494932010171090730
+:1013B0003649494936264949493E0036360000003B
+:1013C000563600000814224100141414141400416D
+:1013D00022140802015109063E4159555E7E090951
+:1013E000097E7F494949363E414141227F41414181
+:1013F0003E7F494949417F090909013E4141493A36
+:101400007F0808087F00417F4100304040403F7F17
+:10141000081422417F404040407F020C027F7F023F
+:1014200004087F3E4141413E7F090909061E2121F2
+:10143000215E7F0909097600264949493201017F69
+:1014400001013F4040403F1F2040201F7F201020CF
+:101450007F41221C2241070870080761514945431A
+:10146000007F410000020408102004020102044031
+:1014700040404040000102040020545454787F440E
+:101480004444383844444444384444447F385454F1
+:10149000541804047E0505085454543C7F08040481
+:1014A0007800447D40002040443D007F10284400E7
+:1014B00000417F40007C047804787C08040478387C
+:1014C000444444387C14141408081414147C007C1C
+:1014D000080404485454542004043F44443C40400D
+:1014E000207C1C2040201C3C4030403C44281028DC
+:1014F000440C5050503C4464544C44000836414124
+:1015000000007F0000414136080002010204020091
+:10151000000000005261704D616E205665723A31D4
+:101520002E302E3900000000472D436F6465204C9B
+:10153000696E653A0000000048656164205370657B
+:1015400065643A004578742E20526174653A000053
+:101550002531750025352E31666D6D2F7300000025
+:101560004E6F74205365740000007042000000004C
+:1015700079E9263108ACAC3F4578747275646572C0
+:1015800020436F6E74726F6C0000000048656174D8
+:101590006572204F6E200000486561746572204FAF
+:1015A00066660000203C31303043204D6F746F720E
+:1015B000204F4646000000000000C84254454D50F0
+:1015C00045524154555245204552524F5200000059
+:1015D000544845524D4953544F52204552524F5250
+:1015E0000000000025337543000000002A000000C1
+:1015F0002000000000C07944000080BF25337552F0
+:10160000504D00000000000084471B47ACC5A73FB9
+:101610004D454E550000000052554E2046494C4560
+:10162000000000004D414E55414C204D4F564500A5
+:10163000544F4F4C2053455455500000484F4D4592
+:1016400020544F4F4C204845414400004D414E55D9
+:10165000414C000058204C696D69743A000000004C
+:1016600059204C696D69743A000000005A204C6999
+:101670006D69743A000000005820537465703A0098
+:101680005920537465703A005A20537465703A00BB
+:101690004155544F3A204C6F6164696E672E2E009D
+:1016A000484F4D494E4720504C45415345205741E6
+:1016B000495400004D4F564520544F3A0000000059
+:1016C000583D25362E326600593D25362E326600AD
+:1016D0005A3D25362E3266004E4F205A204D4F5629
+:1016E0004500000050726F672E456E6400000000D8
+:1016F00052657475726E20746F204D656E750000B2
+:101700003C3C3C205072657373204573632E00008F
+:101710003E0000002020000048A2019DA09C019DE9
+:10172000709D019D409E019D109F019DE09F019D28
+:10173000B0A0019D80A1019DC4B2019D78B3019D1F
+:101740000CB3019D54B4019DD8B4019D002020200C
+:101750002020202020202828282828202020202061
+:101760002020202020202020202020202080101039
+:10177000101010101010101010101010100404048D
+:10178000040404040404041010101010101041414B
+:101790004141414101010101010101010101010139
+:1017A000010101010101010110101010101042424D
+:1017B0004242424202020202020202020202020209
+:1017C00002020202020202021010101020000000A9
+:1017D0000000000000000000000000000000000009
+:1017E00000000000000000000000000000000000F9
+:1017F00000000000000000000000000000000000E9
+:1018000000000000000000000000000000000000D8
+:1018100000000000000000000000000000000000C8
+:1018200000000000000000000000000000000000B8
+:1018300000000000000000000000000000000000A8
+:101840000000000000000000000000000000000098
+:101850003030303030303030303030303030303088
+:101860003030303030303030303030303030303078
+:101870002020202020202020202020202020202068
+:101880002020202020202020202020202020202058
+:10189000F0BD019D9CC1019D20CF019D9CC1019D7A
+:1018A00020CF019D20CF019D20CF019D20CF019D04
+:1018B00020CF019D20CF019D20CF019D14BE019D11
+:1018C0005CBE019D20CF019D20CF019D20CF019DB9
+:1018D00020CF019D28BE019D20CF019D20CF019DDD
+:1018E0004CBE019D20CF019D20CF019D20CF019DA9
+:1018F00020CF019D20CF019D20CF019D20CF019DB4
+:1019000020CF019D20CF019D20CF019D6CCD019D59
+:10191000FCBD019D9CC1019D9CC1019D9CC1019D7F
+:1019200020CF019DFCBD019D20CF019D20CF019DB9
+:1019300020CF019D20CF019D34CE019D20BE019D71
+:1019400068BE019D20CF019D20CF019DA8CD019DA6
+:1019500020CF019D34BE019D20CF019D20CF019D50
+:1019600074BE019D00000000000000000000244043
+:101970000000000000001040000000000000008097
+:101980007B14AE47E17A843F2D431CEBE2361A3FCD
+:101990004E614E002B496E66000000002D496E66B8
+:1019A00000000000286E756C6C290000B0CF019D0E
+:1019B000B8CF019DC0CF019DC8CF019DD0CF019D63
+:1019C000000000000000144000000000000039404A
+:1019D00000000000008883400000000084D7174109
+:1019E0000080E03779C34142176E05B5B5B893441E
+:1019F000F5F93FE9034F3849321D30F948778252F3
+:101A00003CBF737FDD4F1565000000000000F03F14
+:101A1000FFFFFFFFFFFFFF7F00000000000010003E
+:101A20000000000000000001FFFFFFFFFFFF0F00AC
+:101A30000C00000000000000010001041F0C1D004C
+:101A40000C0000001400000024F9019D7C0400003B
+:101A50000C00000000000000010001041F0C1D002C
+:101A60001C00000014000000A0FD019D8C0400007B
+:101A7000440E185011107C11117D11127E000000CF
+:101A800000000000FFFFFFFF00000000000000005A
+:101A90000000000000000000000000000000000046
+:101AA000840000A0A00000A0BC0000A0800000A056
+:101AB0007C0300A001000000000000000000000006
+:101AC0000000000000000000000000000000000016
+:101AD0000000000000000000000000000000000006
+:101AE00000000000000000000000000000000000F6
+:101AF00000000000000000000000000000000000E6
+:101B000000000000FFFFFFFFFFFFFFFF00000000DD
+:101B10000004000009100000000000003817029DBA
+:101B2000FFFFFFFF000000000000000000040000B5
+:101B30000A100100000000003817029DFFFFFFFFA0
+:101B40000000000000000000000000000200020091
+:101B5000000000003817029DFDFFFFFF000000009D
+:101B60000000000000000000000000000000000075
+:101B700000000000010000001E000000FFFF000048
+:101B800001000000FFFF0000FFFFFFFFC80E00A0E4
+:101B900090010000F5FF000001000000200000A0FF
+:101BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:101BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:101BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:101BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:101BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:101BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:101C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:101C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:101C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:101C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:101C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:101C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:101C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:101C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:101C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:101C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:101CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:101CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:101CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:101CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:101CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:101CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:101D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:101D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:101D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:101D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:101D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:101D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:101D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:101D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:101D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:101D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:101DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:101DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:101DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:101DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:101DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:101DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:101E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:101E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:101E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:101E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:101E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:101E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:101E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:101E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:101E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:101E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:101EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:101EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:101EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:101ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:101EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:101EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:101F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:101F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:101F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:101F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:101F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:101F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:101F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:101F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:101F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:101F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:101FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:101FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:101FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:101FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:101FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:101FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10200000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10201000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10202000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10203000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10204000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10205000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10206000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10207000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10208000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10209000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:1020A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1020B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1020C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1020D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1020E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1020F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10210000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10211000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10212000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10213000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10214000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10215000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10216000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10217000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10218000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10219000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:1021A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1021B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1021C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1021D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1021E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1021F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10220000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10221000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10222000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10223000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10224000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10225000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10226000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10227000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10228000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10229000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:1022A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1022B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1022C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1022D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1022E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1022F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10230000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10231000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10232000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10233000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10234000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10235000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10236000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10237000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10238000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10239000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:1023A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1023B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1023C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1023D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1023E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1023F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10240000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10241000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10242000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10243000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10244000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10245000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10246000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10247000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10248000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10249000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:1024A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1024B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1024C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1024D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1024E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1024F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10250000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10251000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10252000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10253000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10254000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10255000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10256000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10257000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10258000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10259000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:1025A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1025B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1025C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1025D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1025E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1025F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10260000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10261000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10263000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10264000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10265000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10266000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10267000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10268000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10269000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:1026A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1026B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1026C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1026D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1026E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1026F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10270000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10271000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10272000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10273000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10274000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10275000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10276000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10277000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10278000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10279000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:1027A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1027B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1027C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1027D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1027E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1027F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10280000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10281000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10282000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10283000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10284000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10285000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10286000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10287000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10288000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10289000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:1028A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1028B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1028C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1028D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1028E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1028F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10290000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10291000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10292000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10293000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10294000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10295000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10296000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10297000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10298000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10299000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:1029A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1029B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1029C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1029D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1029E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1029F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:102A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:102A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:102A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:102A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:102A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:102A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:102A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:102A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:102A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:102A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:102AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:102AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:102AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:102AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:102AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:102AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:102B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:102B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:102B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:102B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:102B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:102B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:102B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:102B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:102B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:102B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:102BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:102BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:102BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:102BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:102BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:102BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:102C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:102C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:102C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:102C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:102C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:102C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:102C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:102C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:102C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:102C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:102CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:102CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:102CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:102CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:102CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:102CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:102D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:102D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:102D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:102D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:102D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:102D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:102D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:102D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:102D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:102D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:102DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:102DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:102DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:102DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:102DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:102DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:102E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:102E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:102E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:102E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:102E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:102E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:102E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:102E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:102E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:102E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:102EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:102EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:102EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:102ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:102EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:102EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:102F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:102F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:102F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:102F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:102F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:102F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:102F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:102F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:102F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:102F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:102FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:102FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:102FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:102FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:102FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:102FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10300000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10301000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10302000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10303000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10304000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10305000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10306000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10307000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10308000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10309000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1030A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1030B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1030C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1030D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1030E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1030F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10310000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10311000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10312000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10313000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10314000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10315000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10316000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10317000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10318000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10319000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1031A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1031B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1031C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1031D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1031E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1031F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10320000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10321000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10322000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10323000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10324000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10325000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10326000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10327000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10328000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10329000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1032A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1032B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1032C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1032D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1032E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1032F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10330000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10331000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10332000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10333000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10334000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10335000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10336000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10337000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10338000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10339000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1033A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1033B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1033C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1033D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1033E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1033F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10340000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10341000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10342000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10343000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10344000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10345000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10346000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10347000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10348000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10349000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1034A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1034B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1034C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1034D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1034E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1034F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10350000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10351000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10352000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10353000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10354000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10355000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10356000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10357000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10358000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10359000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1035A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1035B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1035C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1035D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1035E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1035F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10360000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10361000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10362000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10363000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10364000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10365000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10366000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10367000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10368000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10369000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1036A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1036B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1036C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1036D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1036E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1036F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10370000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10371000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10372000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10373000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10374000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10375000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10376000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10377000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10378000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10379000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1037A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1037B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1037D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1037E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1037F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10380000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10381000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10382000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10383000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10384000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10385000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10388000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10389000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1038A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1038B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1038C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1038D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1038E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1038F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10390000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10391000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10392000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10393000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10394000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10395000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10396000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10397000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10398000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10399000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1039A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1039B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1039D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1039E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1039F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:103A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:103A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:103A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:103A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:103A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:103A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:103A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:103A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:103A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:103AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:103AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:103AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:103AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:103AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:103AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:103B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:103B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:103B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:103B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:103B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:103B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:103B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:103B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:103B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:103B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:103BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:103BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:103BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:103BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:103BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:103BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:103C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:103C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:103C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:103C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:103C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:103C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:103C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:103C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:103C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:103C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:103CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:103CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:103CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:103CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:103CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:103CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:103D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:103D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:103D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:103D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:103D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:103D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:103D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:103D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:103D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:103D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:103DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:103DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:103DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:103DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:103DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:103DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:103E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:103E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:103E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:103E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:103E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:103E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:103E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:103E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:103E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:103E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:103EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:103EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:103EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:103ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:103EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:103EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:103F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:103F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:103F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:103F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:103F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:103F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:103F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:103F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:103F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:103F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:103FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:103FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:103FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:103FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:103FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:103FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10400000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10401000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10402000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10403000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10404000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10405000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10406000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10407000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10408000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10409000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1040A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1040B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1040C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1040D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1040E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1040F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10410000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10411000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10412000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10413000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10414000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10415000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10416000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10417000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10418000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10419000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1041A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1041B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1041C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1041D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1041E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1041F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10420000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10421000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10422000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10423000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10424000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10425000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10426000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10427000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10428000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10429000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1042A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1042B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1042C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1042D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1042E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1042F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10430000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10431000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10432000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10433000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10434000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10435000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10436000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10437000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10438000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10439000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1043A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1043B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1043C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1043D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1043E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1043F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10440000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10441000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10442000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10443000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10444000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10445000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10446000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10447000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10448000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10449000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1044A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1044B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1044C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1044D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1044E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1044F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10450000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10451000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10452000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10453000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10454000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10455000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10456000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10457000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10458000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10459000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1045A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1045B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1045C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1045D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1045E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1045F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10460000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10461000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10462000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10463000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10464000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10465000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10466000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10467000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10468000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10469000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1046A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1046B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1046C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1046D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1046E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1046F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10470000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10471000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10472000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10473000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10474000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10475000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10476000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10477000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10478000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10479000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1047A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1047B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1047C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1047D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1047E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1047F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10480000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10481000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10482000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10483000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10484000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10485000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10486000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10487000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10488000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10489000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1048A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1048B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1048C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1048D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1048E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1048F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10490000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10491000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10493000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10495000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10497000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10499000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1049A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1049B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1049C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1049D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1049E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1049F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:104A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:104A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:104A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:104A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:104A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:104A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:104A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:104A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:104A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:104A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:104AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:104AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:104AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:104AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:104AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:104AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:104B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:104B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:104B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:104B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:104B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:104B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:104B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:104B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:104B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:104BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:104BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:104BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:104C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:104C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:104C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:104C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:104C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:104C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:104C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:104C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:104C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:104C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:104CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:104CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:104CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:104CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:104CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:104CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:104D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:104D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:104D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:104D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:104D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:104D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:104D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:104D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:104D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:104D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:104DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:104DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:104DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:104DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:104DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:104DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:104E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:104E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:104E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:104E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:104E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:104E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:104E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:104E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:104E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:104ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:104EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:104F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:104F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:104F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:104F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:104F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:104F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:104F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:104F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:104F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:104F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:104FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:104FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:104FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:104FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:104FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:104FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10501000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10502000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10503000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10504000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10505000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10506000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10507000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10508000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10509000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1050A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1050B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1050C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1050D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1050E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1050F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10510000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10511000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10512000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10513000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10514000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10515000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10516000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10517000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10518000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10519000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1051A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1051B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1051C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1051D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1051E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1051F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10520000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10521000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10522000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10523000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10524000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10525000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10526000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10527000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10528000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10529000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1052A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1052B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1052C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1052D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1052E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1052F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10530000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10531000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10532000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10533000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10534000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10535000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10536000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10537000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10538000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10539000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1053A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1053B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1053C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1053D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10540000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10541000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10542000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10543000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10544000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10545000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10546000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10547000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10548000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10549000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1054A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1054B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1054C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1054D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1054E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1054F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10550000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10551000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10552000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10553000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10554000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10555000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10556000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10557000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10558000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10559000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1055A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1055B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1055C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1055D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1055E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1055F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10560000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10561000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10562000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10563000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10564000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10565000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10566000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10567000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10568000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10569000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1056A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1056B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1056C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1056D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1056E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1056F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10570000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10571000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10572000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10573000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10574000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10575000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10576000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10577000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10578000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10579000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1057A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1057B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1057C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1057D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1057E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1057F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10580000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10581000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10582000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10583000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10584000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10585000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10586000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10587000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10588000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10589000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1058A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1058B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1058C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1058D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1058E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1058F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10590000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10591000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10592000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10593000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10594000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10595000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10596000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10597000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10598000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10599000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1059A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1059B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1059C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1059D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1059E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1059F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:105A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:105A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:105A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:105A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:105A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:105A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:105A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:105A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:105A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:105A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:105AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:105AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:105AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:105AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:105AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:105AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:105B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:105B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:105B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:105B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:105B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:105B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:105B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:105B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:105B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:105B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:105BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:105BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:105BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:105BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:105BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:105BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:105C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:105C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:105C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:105C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:105C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:105C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:105C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:105C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:105C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:105C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:105CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:105CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:105CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:105CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:105CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:105CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:105D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:105D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:105D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:105D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:105D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:105D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:105D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:105D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:105D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:105D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:105DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:105DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:105DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:105DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:105DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:105DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:105E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:105E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:105E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:105E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:105E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:105E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:105E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:105E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:105E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:105E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:105EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:105EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:105EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:105ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:105EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:105EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:105F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:105F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:105F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:105F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:105F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:105F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:105F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:105F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:105F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:105F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:105FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:105FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:105FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:105FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:105FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:105FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10600000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10601000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10602000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10603000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10604000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10605000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10606000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10607000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10608000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10609000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1060A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1060B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1060C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1060D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1060E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1060F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10610000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10611000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10612000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10613000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10614000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10615000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10616000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10617000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10618000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10619000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1061A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1061B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1061C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1061D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1061E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10620000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10621000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10622000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10624000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10625000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10626000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10627000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10628000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10629000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1062A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1062B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1062C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1062D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1062E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1062F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10630000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10631000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10632000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10633000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10634000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10635000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10636000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10637000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10638000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10639000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1063A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1063B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1063C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10644000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10645000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10646000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10647000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10648000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10649000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1064A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1064B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1064C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1064D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1064E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1064F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10650000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10651000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10652000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10653000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10654000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10655000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10656000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10657000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10658000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10659000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1065A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1065B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1065C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1065D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1065E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1065F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10660000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10661000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10662000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10663000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10664000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10665000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10666000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10667000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10668000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10669000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1066A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1066B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1066C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1066D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1066E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1066F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10670000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10671000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10672000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10673000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10674000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10675000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10676000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10677000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10678000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10679000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1067A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1067B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1067C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1067D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1067E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1067F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10680000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10681000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10682000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10683000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10684000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10685000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10686000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10687000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10688000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10689000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1068A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1068B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1068C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1068D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1068E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10697000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:106A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:106A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:106A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:106A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:106A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:106A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:106A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:106A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:106A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:106A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:106AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:106AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:106AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:106AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:106AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:106AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:106B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:106B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:106B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:106B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:106B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:106B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:106B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:106B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:106B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:106B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:106BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:106BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:106BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:106BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:106BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:106BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:106C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:106C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:106C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:106C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:106C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:106C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:106C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:106C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:106C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:106C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:106CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:106CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:106CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:106CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:106CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:106CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:106D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:106D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:106D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:106D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:106D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:106D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:106D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:106D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:106D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:106D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:106DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:106DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:106DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:106DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:106DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:106DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:106E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:106E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:106E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:106E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:106E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:106E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:106E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:106E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:106E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:106E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:106EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:106EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:106EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:106ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:106EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:106EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:106F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:106F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:106F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:106F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:106F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:106F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:106F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:106F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:106F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:106F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:106FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:106FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:106FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:106FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:106FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:106FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10701000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10702000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10703000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10707000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10709000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1070B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1070C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1070D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1070E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1070F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10710000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10711000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10712000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10713000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10714000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10715000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10716000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10717000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10718000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10719000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1071A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1071B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1071C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1071D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1071E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1071F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10720000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10721000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10722000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10723000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10724000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10725000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10726000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10727000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10728000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10729000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1072A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1072B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1072C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1072D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1072E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1072F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10730000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10731000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10732000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10733000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10734000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10735000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10736000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10737000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10738000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10739000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1073A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1073B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1073C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1073D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1073E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1073F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10740000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10741000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10742000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10743000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10744000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10745000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10746000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10747000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10748000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10749000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1074A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1074B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1074C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1074D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1074E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1074F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10750000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10751000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10752000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10753000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10754000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10755000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10756000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10757000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10758000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10759000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1075A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1075B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1075C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1075D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1075E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1075F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10760000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10761000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10762000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10763000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10764000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10765000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10766000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10767000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10768000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10769000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1076A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1076B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1076C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1076D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1076E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1076F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10770000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10771000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10772000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10773000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10774000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10775000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10776000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10777000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10778000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10779000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1077A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1077B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1077C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1077D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1077E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1077F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10780000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10781000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10782000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10783000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10784000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10785000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10786000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10787000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10788000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10789000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1078A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1078B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1078C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1078D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1078E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1078F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10790000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10791000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10792000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10793000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10794000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10795000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10796000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10797000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10798000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10799000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1079A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1079B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1079C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1079D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1079E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1079F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:107A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:107A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:107A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:107A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:107A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:107A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:107A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:107A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:107A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:107A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:107AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:107AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:107AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:107AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:107AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:107AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:107B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:107B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:107B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:107B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:107B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:107B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:107B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:107B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:107B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:107B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:107BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:107BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:107BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:107BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:107BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:107BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:107C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:107C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:107C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:107C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:107C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:107C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:107C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:107C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:107C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:107C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:107CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:107CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:107CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:107CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:107CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:107CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:107D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:107D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:107D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:107D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:107D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:107D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:107D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:107D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:107D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:107D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:107DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:107DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:107DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:107DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:107DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:107DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:107E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:107E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:107E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:107E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:107E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:107E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:107E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:107E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:107E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:107E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:107EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:107EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:107EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:107ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:107EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:107EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:107F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:107F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:107F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:107F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:107F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:107F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:107F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:107F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:107F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:107F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:107FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:107FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:107FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:107FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:107FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:107FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10801000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10802000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10803000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10804000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10805000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10806000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10807000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10808000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10809000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1080A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1080B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1080C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1080D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1080E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:1080F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10810000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10811000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10812000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10813000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10814000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10815000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10816000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10817000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10818000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10819000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1081A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1081B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1081C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1081D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1081E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:1081F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10820000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10821000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10822000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10823000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10824000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10825000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10826000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10827000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10828000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10829000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1082A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1082B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1082C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1082D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1082E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:1082F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10830000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10831000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10832000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10833000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10834000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10835000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10836000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10837000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10838000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10839000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1083A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1083B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1083C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1083D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1083E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:1083F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10840000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10841000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10842000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10843000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10844000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10845000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10846000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10847000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10848000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10849000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1084A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1084B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1084C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1084D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1084E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:1084F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10850000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10851000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10852000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10853000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10854000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10855000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10856000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10857000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10858000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10859000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1085A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1085B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1085C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1085D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1085E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:1085F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10860000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10861000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10862000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10863000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10864000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10865000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10866000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10867000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10868000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10869000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1086A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1086B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1086C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1086D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1086E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:1086F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10870000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10871000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10872000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10873000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10874000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10875000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10876000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10877000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10878000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10879000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1087A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1087B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1087C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1087D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1087E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:1087F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10880000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10881000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10882000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10883000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10884000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10885000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10886000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10887000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10888000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10889000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1088A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1088B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1088C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1088D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1088E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:1088F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10890000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10891000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10892000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10893000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10894000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10895000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10896000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10897000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10898000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10899000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1089A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1089B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1089C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1089D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1089E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:1089F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:108A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:108A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:108A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:108A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:108A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:108A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:108A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:108A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:108A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:108A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:108AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:108AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:108AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:108AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:108AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:108AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:108B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:108B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:108B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:108B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:108B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:108B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:108B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:108B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:108B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:108B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:108BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:108BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:108BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:108BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:108BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:108BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:108C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:108C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:108C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:108C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:108C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:108C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:108C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:108C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:108C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:108C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:108CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:108CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:108CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:108CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:108CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:108CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:108D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:108D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:108D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:108D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:108D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:108D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:108D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:108D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:108D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:108D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:108DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:108DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:108DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:108DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:108DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:108DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:108E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:108E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:108E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:108E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:108E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:108E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:108E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:108E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:108E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:108E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:108EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:108EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:108EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:108ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:108EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:108EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:108F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:108F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:108F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:108F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:108F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:108F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:108F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:108F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:108F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:108F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:108FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:108FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:108FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:108FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:108FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:108FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10900000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10901000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10902000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10903000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10904000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10905000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10906000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10907000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10908000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10909000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1090A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1090B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1090C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1090D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:1090E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:1090F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10910000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10911000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10912000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10913000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10914000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10915000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10916000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10917000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10918000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10919000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1091A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1091B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1091C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1091D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:1091E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:1091F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10920000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10921000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10922000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10923000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10924000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10925000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10926000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10927000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10928000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10929000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1092A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1092B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1092C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1092D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:1092E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:1092F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10930000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10931000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10932000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10933000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10934000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10935000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10936000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10937000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10938000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10939000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1093A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1093B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1093C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1093D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:1093E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:1093F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10940000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10941000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10942000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10943000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10944000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10945000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10946000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10947000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10948000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10949000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1094A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1094B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1094C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1094D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:1094E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:1094F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10950000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10951000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10952000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10953000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10954000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10955000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10956000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10957000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10958000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10959000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1095A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1095B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1095C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1095D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:1095E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:1095F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10960000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10961000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10962000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10963000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10964000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10965000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10966000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10967000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10968000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10969000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1096A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1096B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1096C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1096D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:1096E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:1096F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10970000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10971000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10972000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10973000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10974000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10975000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10976000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10977000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10978000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10979000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1097A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1097B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1097C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1097D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:1097E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:1097F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10980000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10981000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10982000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10983000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10984000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10985000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10986000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10987000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10988000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10989000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1098A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1098B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1098C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1098D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:1098E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:1098F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10990000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10991000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10992000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10993000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10994000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10995000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10996000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10997000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10998000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10999000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1099A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1099B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1099C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1099D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:1099E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:1099F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:109A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:109A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:109A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:109A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:109A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:109A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:109A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:109A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:109A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:109A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:109AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:109AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:109AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:109AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:109AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:109AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:109B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:109B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:109B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:109B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:109B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:109B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:109B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:109B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:109B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:109B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:109BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:109BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:109BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:109BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:109BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:109BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:109C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:109C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:109C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:109C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:109C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:109C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:109C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:109C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:109C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:109C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:109CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:109CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:109CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:109CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:109CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:109CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:109D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:109D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:109D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:109D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:109D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:109D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:109D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:109D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:109D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:109D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:109DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:109DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:109DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:109DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:109DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:109DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:109E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:109E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:109E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:109E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:109E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:109E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:109E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:109E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:109E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:109E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:109EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:109EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:109EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:109ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:109EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:109EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:109F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:109F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:109F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:109F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:109F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:109F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:109F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:109F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:109F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:109F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:109FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:109FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:109FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:109FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:109FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:109FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10A00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10A01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10A02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10A03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10A04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10A05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10A06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10A07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10A08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10A09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10A0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10A0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10A0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10A0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10A0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10A0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10A10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10A11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10A12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10A13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10A14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10A15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10A16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10A17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10A18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10A19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10A1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10A1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10A1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10A1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10A1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10A1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10A20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10A21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10A22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10A23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10A24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10A25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10A26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10A27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10A28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10A29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10A2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10A2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10A2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10A2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10A2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10A2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10A30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10A31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10A32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10A33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10A34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10A35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10A36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10A37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10A38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10A39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10A3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10A3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10A3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10A3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10A3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10A3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10A40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10A41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10A42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10A43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10A44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10A45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10A46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10A47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10A48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10A49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10A4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10A4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10A4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10A4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10A4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10A4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10A50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10A51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10A52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10A53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10A54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10A55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10A56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10A57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10A58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10A59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10A5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10A5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10A5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10A5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10A5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10A5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10A60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10A61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10A62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10A63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10A64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10A65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10A66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10A67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10A68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10A69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10A6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10A6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10A6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10A6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10A6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10A6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10A70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10A71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10A72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10A73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10A74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10A75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10A76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10A77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10A78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10A79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10A7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10A7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10A7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10A7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10A7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10A7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10A80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10A81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10A82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10A83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10A84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10A85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10A86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10A87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10A88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10A89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10A8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10A8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10A8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10A8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10A8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10A8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10A90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10A91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10A92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10A93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10A94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10A95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10A96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10A97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10A98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10A99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10A9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10A9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10A9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10A9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10A9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10A9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10AA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10AA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10AA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10AA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10AA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10AA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10AA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10AA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10AA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10AA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10AAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10AAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10AAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10AAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10AAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10AAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10AB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10AB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10AB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10AB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10AB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10AB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10AB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10AB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10AB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10AB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10ABA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10ABB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10ABC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10ABD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10ABE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10ABF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10AC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10AC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10AC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10AC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10AC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10AC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10AC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10AC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10AC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10AC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10ACA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10ACB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10ACC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10ACD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10ACE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10ACF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10AD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10AD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10AD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10AD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10AD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10AD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10AD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10AD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10AD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10AD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10ADA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10ADB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10ADC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10ADD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10ADE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10ADF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10AE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10AE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10AE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10AE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10AE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10AE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10AE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10AE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10AE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10AE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10AEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10AEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10AEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10AED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10AEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10AEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10AF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10AF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10AF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10AF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10AF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10AF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10AF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10AF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10AF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10AF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10AFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10AFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10AFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10AFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10AFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10AFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10B00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10B01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10B02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10B03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10B04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10B05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10B06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10B07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10B08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10B09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10B0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10B0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10B0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10B0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10B0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10B0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10B10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10B11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10B12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10B13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10B14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10B15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10B16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10B17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10B18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10B19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10B1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10B1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10B1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10B1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10B1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10B1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10B20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10B21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10B22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10B23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10B24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10B25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10B26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10B27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10B28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10B29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10B2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10B2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10B2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10B2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10B2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10B2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10B30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10B31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10B32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10B33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10B34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10B35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10B36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10B37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10B38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10B39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10B3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10B3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10B3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10B3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10B3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10B3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10B40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10B41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10B42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10B43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10B44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10B45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10B46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10B47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10B48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10B49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10B4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10B4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10B4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10B4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10B4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10B4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10B50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10B51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10B52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10B53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10B54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10B55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10B56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10B57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10B58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10B59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10B5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10B5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10B5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10B5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10B5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10B5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10B60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10B61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10B62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10B63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10B64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10B65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10B66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10B67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10B68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10B69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10B6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10B6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10B6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10B6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10B6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10B6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10B70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10B71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10B72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10B73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10B74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10B75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10B76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10B77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10B78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10B79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10B7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10B7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10B7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10B7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10B7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10B7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10B80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10B81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10B82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10B83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10B84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10B85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10B86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10B87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10B88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10B89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10B8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10B8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10B8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10B8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10B8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10B8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10B90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10B91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10B92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10B93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10B94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10B95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10B96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10B97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10B98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10B99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10B9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10B9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10B9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10B9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10B9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10B9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10BA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10BA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10BA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10BA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10BA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10BA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10BA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10BA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10BA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10BA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10BAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10BAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10BAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10BAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10BAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10BAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10BB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10BB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10BB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10BB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10BB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10BB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10BB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10BB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10BB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10BB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10BBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10BBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10BBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10BBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10BBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10BBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10BC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10BC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10BC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10BC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10BC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10BC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10BC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10BC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10BC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10BC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10BCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10BCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10BCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10BCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10BCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10BCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10BD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10BD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10BD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10BD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10BD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10BD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10BD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10BD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10BD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10BD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10BDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10BDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10BDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10BDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10BDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10BDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10BE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10BE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10BE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10BE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10BE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10BE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10BE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10BE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10BE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10BE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10BEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10BEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10BEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10BED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10BEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10BEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10BF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10BF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10BF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10BF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10BF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10BF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10BF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10BF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10BF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10BF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10BFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10BFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10BFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10BFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10BFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10BFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10C00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10C01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10C02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10C03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10C04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10C05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10C06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10C07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10C08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10C09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10C0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10C0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10C0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10C0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10C0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10C0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10C10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10C11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10C12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10C13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10C14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10C15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10C16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10C17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10C18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10C19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10C1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10C1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10C1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10C1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10C1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10C1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10C20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10C21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10C22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10C23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10C24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10C25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10C26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10C27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10C28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10C29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10C2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10C2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10C2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10C2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10C2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10C2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10C30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10C31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10C32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10C33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10C34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10C35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10C36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10C37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10C38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10C39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10C3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10C3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10C3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10C3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10C3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10C3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10C40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10C41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10C42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10C43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10C44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10C45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10C46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10C47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10C48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10C49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10C4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10C4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10C4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10C4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10C4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10C4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10C50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10C51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10C52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10C53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10C54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10C55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10C56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10C57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10C58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10C59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10C5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10C5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10C5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10C5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10C5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10C5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10C60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10C61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10C62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10C63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10C64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10C65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10C66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10C67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10C68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10C69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10C6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10C6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10C6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10C6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10C6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10C6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10C70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10C71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10C72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10C73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10C74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10C75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10C76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10C77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10C78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10C79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10C7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10C7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10C7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10C7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10C7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10C7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10C80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10C81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10C82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10C83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10C84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10C85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10C86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10C87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10C88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10C89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10C8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10C8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10C8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10C8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10C8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10C8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10C90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10C91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10C92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10C93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10C94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10C95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10C96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10C97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10C98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10C99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10C9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10C9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10C9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10C9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10C9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10C9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10CA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10CA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10CA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10CA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10CA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10CA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10CA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10CA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10CA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10CA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10CAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10CAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10CAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10CAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10CAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10CAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10CB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10CB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10CB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10CB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10CB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10CB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10CB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10CB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10CB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10CB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10CBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10CBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10CBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10CBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10CBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10CBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10CC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10CC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10CC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10CC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10CC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10CC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10CC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10CC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10CC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10CC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10CCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10CCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10CCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10CCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10CCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10CCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10CD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10CD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10CD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10CD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10CD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10CD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10CD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10CD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10CD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10CD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10CDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10CDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10CDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10CDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10CDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10CDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10CE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10CE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10CE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10CE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10CE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10CE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10CE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10CE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10CE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10CE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10CEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10CEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10CEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10CED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10CEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10CEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10CF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10CF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10CF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10CF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10CF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10CF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10CF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10CF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10CF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10CF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10CFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10CFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10CFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10CFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10CFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10CFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10D00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10D01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10D02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10D03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10D04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10D05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10D06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10D07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10D08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10D09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10D0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10D0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10D0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10D0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10D0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10D0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10D10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10D11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10D12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10D13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10D14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10D15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10D16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10D17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10D18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10D19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10D1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10D1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10D1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10D1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10D1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10D1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10D20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10D21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10D22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10D23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10D24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10D25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10D26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10D27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10D28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10D29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10D2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10D2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10D2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10D2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10D2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10D2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10D30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10D31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10D32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10D33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10D34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10D35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10D36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10D37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10D38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10D39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10D3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10D3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10D3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10D3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10D3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10D3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10D40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10D41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10D42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10D43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10D44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10D45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10D46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10D47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10D48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10D49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10D4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10D4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10D4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10D4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10D4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10D4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10D50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10D51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10D52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10D53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10D54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10D55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10D56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10D57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10D58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10D59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10D5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10D5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10D5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10D5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10D5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10D5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10D60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10D61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10D62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10D63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10D64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10D65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10D66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10D67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10D68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10D69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10D6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10D6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10D6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10D6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10D6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10D6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10D70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10D71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10D72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10D73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10D74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10D75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10D76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10D77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10D78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10D79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10D7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10D7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10D7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10D7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10D7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10D7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10D80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10D81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10D82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10D83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10D84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10D85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10D86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10D87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10D88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10D89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10D8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10D8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10D8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10D8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10D8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10D8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10D90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10D91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10D92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10D93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10D94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10D95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10D96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10D97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10D98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10D99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10D9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10D9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10D9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10D9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10D9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10D9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10DA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10DA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10DA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10DA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10DA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10DA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10DA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10DA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10DA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10DA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10DAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10DAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10DAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10DAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10DAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10DAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10DB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10DB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10DB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10DB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10DB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10DB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10DB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10DB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10DB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10DB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10DBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10DBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10DBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10DBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10DBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10DBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10DC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10DC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10DC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10DC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10DC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10DC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10DC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10DC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10DC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10DC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10DCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10DCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10DCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10DCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10DCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10DCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10DD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10DD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10DD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10DD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10DD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10DD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10DD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10DD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10DD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10DD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10DDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10DDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10DDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10DDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10DDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10DDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10DE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10DE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10DE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10DE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10DE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10DE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10DE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10DE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10DE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10DE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10DEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10DEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10DEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10DED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10DEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10DEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10DF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10DF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10DF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10DF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10DF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10DF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10DF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10DF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10DF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10DF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10DFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10DFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10DFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10DFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10DFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10DFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10E00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10E01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10E02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10E03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10E04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10E05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10E06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10E07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10E08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10E09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10E0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10E0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10E0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10E0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10E0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10E0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10E10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10E11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10E12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10E13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10E14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10E15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10E16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10E17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10E18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10E19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10E1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10E1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10E1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10E1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10E1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10E1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10E20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10E21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10E22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10E23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10E24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10E25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10E26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10E27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10E28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10E29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10E2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10E2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10E2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10E2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10E2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10E2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10E30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10E31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10E32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10E33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10E34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10E35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10E36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10E37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10E38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10E39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10E3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10E3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10E3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10E3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10E3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10E3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10E40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10E41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10E42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10E43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10E44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10E45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10E46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10E47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10E48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10E49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10E4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10E4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10E4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10E4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10E4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10E4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10E50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10E51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10E52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10E53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10E54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10E55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10E56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10E57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10E58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10E59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10E5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10E5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10E5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10E5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10E5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10E5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10E60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10E61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10E62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10E63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10E64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10E65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10E66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10E67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10E68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10E69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10E6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10E6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10E6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10E6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10E6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10E6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10E70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10E71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10E72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10E73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10E74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10E75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10E76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10E77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10E78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10E79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10E7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10E7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10E7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10E7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10E7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10E7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10E80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10E81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10E82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10E83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10E84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10E85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10E86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10E87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10E88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10E89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10E8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10E8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10E8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10E8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10E8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10E8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10E90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10E91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10E92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10E93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10E94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10E95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10E96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10E97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10E98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10E99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10E9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10E9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10E9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10E9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10E9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10E9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10EA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10EA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10EA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10EA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10EA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10EA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10EA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10EA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10EA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10EA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10EAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10EAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10EAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10EAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10EAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10EAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10EB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10EB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10EB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10EB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10EB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10EB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10EB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10EB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10EB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10EB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10EBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10EBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10EBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10EBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10EBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10EBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10EC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10EC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10EC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10EC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10EC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10EC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10EC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10EC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10EC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10EC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10ECA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10ECB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10ECC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10ECD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10ECE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10ECF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10ED0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10ED1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10ED2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10ED3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10ED4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10ED5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10ED6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10ED7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10ED8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10ED9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10EDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10EDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10EDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10EDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10EDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10EDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10EE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10EE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10EE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10EE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10EE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10EE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10EE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10EE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10EE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10EE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10EEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10EEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10EEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10EED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10EEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10EEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10EF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10EF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10EF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10EF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10EF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10EF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10EF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10EF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10EF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10EF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10EFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10EFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10EFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10EFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10EFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10EFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10F00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10F01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10F02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10F03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10F04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10F05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10F06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10F07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10F08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10F09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10F0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10F0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10F0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10F0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10F0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10F0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10F10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10F11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10F12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10F13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10F14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10F15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10F16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10F17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10F18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10F19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10F1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10F1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10F1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10F1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10F1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10F1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10F20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10F21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10F22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10F23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10F24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10F25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10F26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10F27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10F28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10F29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10F2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10F2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10F2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10F2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10F2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10F2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10F30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10F31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10F32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10F33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10F34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10F35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10F36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10F37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10F38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10F39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10F3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10F3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10F3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10F3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10F3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10F3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10F40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10F41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10F42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10F43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10F44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10F45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10F46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10F47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10F48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10F49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10F4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10F4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10F4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10F4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10F4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10F4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10F50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10F51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10F52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10F53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10F54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10F55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10F56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10F57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10F58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10F59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10F5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10F5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10F5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10F5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10F5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10F5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10F60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10F61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10F62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10F63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10F64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10F65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10F66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10F67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10F68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10F69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10F6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10F6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10F6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10F6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10F6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10F6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10F70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10F71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10F72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10F73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10F74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10F75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10F76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10F77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10F78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10F79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10F7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10F7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10F7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10F7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10F7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10F7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10F80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10F81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10F82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10F83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10F84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10F85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10F86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10F87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10F88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10F89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10F8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10F8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10F8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10F8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10F8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10F8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10F90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10F91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10F92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10F93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10F94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10F95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10F96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10F97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10F98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10F99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10F9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10F9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10F9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10F9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10F9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10F9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10FA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10FA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10FA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10FA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10FA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10FA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10FA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10FA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10FA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10FA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10FAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10FAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10FAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10FAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10FAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10FAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10FB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10FB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10FB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10FB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10FB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10FB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10FB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10FB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10FB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10FB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10FBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10FBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10FBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10FBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10FBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10FBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10FC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10FC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10FC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10FC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10FC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10FC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10FC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10FC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10FC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10FC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10FCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10FCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10FCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10FCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10FCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10FCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10FD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10FD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10FD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10FD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10FD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10FD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10FD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10FD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10FD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10FD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10FDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10FDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10FDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10FDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10FDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10FDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10FE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10FE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10FE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10FE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10FE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10FE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10FE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10FE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10FE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10FE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10FEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10FEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10FEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10FED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10FEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10FEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10FF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10FF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10FF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10FF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10FF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10FF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10FF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10FF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10FF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10FFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10FFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10FFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10FFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10FFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10FFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:020000041D03DA
+:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10011000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10013000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10016000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10017000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10019000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:1001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:1001B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:1001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1001D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1001E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1001F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10021000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10023000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10025000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10027000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10029000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:1002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:1002B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:1002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1002D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1002E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1002F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10031000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10033000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10035000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10037000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10039000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:1003B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:1003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1003D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1003F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10040000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10041000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10042000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10043000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10044000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10045000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10046000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10047000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10048000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10049000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:1004A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:1004B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:1004C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1004D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1004E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1004F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10050000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10051000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10052000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10053000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10054000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10055000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10056000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10057000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10058000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10059000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:1005A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:1005B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:1005C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1005D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1005E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1005F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10060000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10061000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10062000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10063000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10064000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10065000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10066000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10067000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10068000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10069000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:1006A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:1006B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:1006C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1006D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1006E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1006F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10070000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10071000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10072000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10073000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10074000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10075000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10076000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10077000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10078000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10079000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:1007A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:1007B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:1007C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1007D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1007E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1007F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10080000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10081000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10082000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10083000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10084000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10085000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10086000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10087000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10088000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10089000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:1008A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:1008B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:1008C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1008D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1008E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1008F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10090000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10091000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10092000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10093000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10094000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10095000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10096000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10097000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10098000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10099000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:1009A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:1009B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:1009C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1009D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1009E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1009F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:100A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:100A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:100A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:100A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:100A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:100A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:100A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:100A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:100A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:100A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:100AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:100AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:100AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:100AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:100AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:100AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:100B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:100B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:100B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:100B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:100B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:100B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:100B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:100B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:100B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:100B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:100BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:100BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:100BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:100BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:100BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:100BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:100C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:100C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:100C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:100C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:100C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:100C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:100C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:100C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:100C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:100C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:100CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:100CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:100CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:100CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:100CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:100CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:100D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:100D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:100D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:100D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:100D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:100D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:100D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:100D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:100D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:100D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:100DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:100DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:100DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:100DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:100DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:100DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:100E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:100E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:100E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:100E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:100E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:100E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:100E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:100E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:100E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:100E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:100EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:100EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:100EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:100ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:100EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:100EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:100F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:100F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:100F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:100F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:100F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:100F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:100F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:100F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:100F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:100F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:100FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:100FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:100FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:100FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:100FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:100FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10100000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10101000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10102000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10103000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10104000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10105000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10106000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10107000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10108000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10109000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:1010A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:1010B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1010C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1010D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1010E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1010F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10110000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10111000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10112000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10113000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10114000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10115000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10116000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10117000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10118000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10119000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:1011A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:1011B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1011C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1011D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1011E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1011F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10120000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10121000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10122000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10123000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10124000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10125000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10126000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10127000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10128000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10129000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:1012A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:1012B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1012C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1012D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1012E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1012F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10130000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10131000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10133000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10134000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10135000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10136000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10137000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10138000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10139000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:1013A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:1013B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1013C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1013D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1013E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1013F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10140000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10141000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10142000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10143000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10144000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10145000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10146000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10147000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10148000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10149000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:1014A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:1014B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1014C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1014D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1014E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1014F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10150000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10151000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10152000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10153000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10154000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10155000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10156000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10157000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10158000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10159000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:1015A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:1015B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1015C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1015D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1015E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1015F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10160000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10161000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10162000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10163000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10164000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10165000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10166000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10167000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10168000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10169000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:1016A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:1016B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1016C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1016D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1016E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1016F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10170000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10171000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10172000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10173000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10174000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10175000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10176000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10177000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10178000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10179000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:1017A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:1017B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1017C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1017D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1017E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1017F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10180000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10181000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10182000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10183000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10184000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10185000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10186000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10187000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10188000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10189000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:1018A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:1018B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1018C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1018D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1018E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1018F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10190000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10191000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10192000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10193000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10194000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10195000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10196000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10197000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10198000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10199000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:1019A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:1019B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1019C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1019D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1019E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1019F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:101A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:101A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:101A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:101A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:101A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:101A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:101A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:101A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:101A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:101A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:101AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:101AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:101AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:101AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:101AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:101AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:101B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:101B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:101B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:101B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:101B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:101B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:101B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:101B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:101B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:101B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:101BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:101BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:101BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:101BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:101BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:101BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:101C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:101C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:101C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:101C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:101C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:101C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:101C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:101C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:101C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:101C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:101CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:101CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:101CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:101CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:101CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:101CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:101D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:101D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:101D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:101D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:101D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:101D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:101D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:101D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:101D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:101D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:101DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:101DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:101DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:101DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:101DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:101DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:101E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:101E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:101E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:101E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:101E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:101E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:101E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:101E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:101E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:101E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:101EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:101EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:101EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:101ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:101EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:101EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:101F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:101F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:101F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:101F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:101F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:101F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:101F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:101F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:101F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:101F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:101FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:101FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:101FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:101FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:101FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:101FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10200000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10201000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10202000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10203000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10204000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10205000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10206000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10207000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10208000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10209000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:1020A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1020B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1020C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1020D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1020E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1020F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10210000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10211000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10212000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10213000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10214000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10215000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10216000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10217000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10218000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10219000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:1021A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1021B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1021C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1021D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1021E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1021F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10220000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10221000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10222000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10223000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10224000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10225000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10226000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10227000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10228000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10229000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:1022A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1022B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1022C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1022D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1022E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1022F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10230000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10231000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10232000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10233000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10234000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10235000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10236000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10237000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10238000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10239000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:1023A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1023B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1023C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1023D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1023E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1023F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10240000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10241000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10242000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10243000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10244000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10245000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10246000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10247000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10248000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10249000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:1024A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1024B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1024C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1024D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1024E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1024F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10250000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10251000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10252000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10253000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10254000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10255000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10256000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10257000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10258000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10259000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:1025A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1025B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1025C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1025D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1025E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1025F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10260000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10261000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10263000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10264000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10265000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10266000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10267000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10268000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10269000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:1026A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1026B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1026C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1026D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1026E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1026F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10270000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10271000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10272000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10273000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10274000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10275000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10276000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10277000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10278000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10279000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:1027A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1027B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1027C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1027D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1027E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1027F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10280000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10281000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10282000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10283000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10284000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10285000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10286000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10287000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10288000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10289000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:1028A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1028B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1028C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1028D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1028E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1028F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10290000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10291000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10292000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10293000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10294000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10295000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10296000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10297000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10298000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10299000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:1029A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1029B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1029C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1029D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1029E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1029F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:102A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:102A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:102A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:102A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:102A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:102A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:102A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:102A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:102A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:102A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:102AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:102AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:102AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:102AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:102AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:102AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:102B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:102B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:102B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:102B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:102B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:102B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:102B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:102B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:102B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:102B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:102BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:102BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:102BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:102BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:102BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:102BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:102C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:102C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:102C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:102C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:102C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:102C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:102C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:102C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:102C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:102C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:102CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:102CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:102CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:102CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:102CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:102CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:102D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:102D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:102D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:102D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:102D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:102D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:102D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:102D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:102D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:102D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:102DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:102DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:102DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:102DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:102DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:102DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:102E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:102E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:102E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:102E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:102E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:102E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:102E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:102E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:102E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:102E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:102EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:102EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:102EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:102ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:102EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:102EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:102F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:102F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:102F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:102F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:102F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:102F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:102F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:102F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:102F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:102F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:102FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:102FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:102FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:102FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:102FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:102FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10300000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10301000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10302000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10303000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10304000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10305000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10306000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10307000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10308000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10309000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:1030A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1030B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1030C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1030D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1030E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1030F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10310000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10311000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10312000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10313000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10314000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10315000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10316000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10317000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10318000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10319000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:1031A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1031B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1031C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1031D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1031E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1031F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10320000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10321000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10322000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10323000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10324000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10325000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10326000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10327000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10328000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10329000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:1032A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1032B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1032C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1032D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1032E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1032F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10330000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10331000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10332000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10333000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10334000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10335000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10336000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10337000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10338000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10339000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:1033A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1033B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1033C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1033D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1033E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1033F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10340000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10341000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10342000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10343000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10344000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10345000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10346000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10347000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10348000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10349000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:1034A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1034B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1034C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1034D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1034E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1034F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10350000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10351000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10352000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10353000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10354000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10355000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10356000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10357000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10358000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10359000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:1035A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1035B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1035C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1035D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1035E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1035F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10360000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10361000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10362000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10363000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10364000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10365000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10366000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10367000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10368000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10369000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:1036A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1036B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1036C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1036D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1036E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1036F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10370000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10371000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10372000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10373000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10374000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10375000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10376000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10377000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10378000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10379000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:1037A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1037B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1037D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1037E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1037F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10380000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10381000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10382000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10383000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10384000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10385000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10388000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10389000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:1038A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1038B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1038C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1038D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1038E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1038F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10390000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10391000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10392000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10393000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10394000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10395000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10396000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10397000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10398000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10399000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:1039A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1039B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1039D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1039E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1039F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:103A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:103A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:103A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:103A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:103A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:103A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:103A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:103A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:103A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:103AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:103AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:103AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:103AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:103AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:103AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:103B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:103B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:103B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:103B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:103B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:103B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:103B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:103B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:103B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:103B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:103BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:103BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:103BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:103BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:103BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:103BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:103C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:103C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:103C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:103C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:103C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:103C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:103C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:103C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:103C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:103C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:103CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:103CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:103CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:103CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:103CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:103CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:103D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:103D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:103D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:103D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:103D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:103D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:103D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:103D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:103D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:103D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:103DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:103DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:103DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:103DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:103DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:103DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:103E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:103E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:103E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:103E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:103E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:103E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:103E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:103E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:103E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:103E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:103EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:103EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:103EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:103ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:103EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:103EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:103F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:103F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:103F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:103F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:103F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:103F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:103F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:103F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:103F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:103F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:103FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:103FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:103FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:103FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:103FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:103FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10400000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10401000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10402000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10403000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10404000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10405000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10406000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10407000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10408000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10409000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:1040A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1040B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1040C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1040D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1040E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1040F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10410000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10411000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10412000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10413000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10414000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10415000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10416000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10417000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10418000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10419000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:1041A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1041B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1041C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1041D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1041E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1041F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10420000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10421000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10422000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10423000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10424000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10425000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10426000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10427000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10428000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10429000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:1042A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1042B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1042C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1042D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1042E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1042F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10430000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10431000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10432000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10433000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10434000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10435000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10436000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10437000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10438000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10439000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:1043A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1043B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1043C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1043D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1043E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1043F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10440000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10441000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10442000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10443000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10444000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10445000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10446000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10447000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10448000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10449000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:1044A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1044B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1044C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1044D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1044E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1044F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10450000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10451000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10452000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10453000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10454000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10455000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10456000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10457000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10458000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10459000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:1045A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1045B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1045C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1045D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1045E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1045F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10460000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10461000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10462000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10463000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10464000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10465000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10466000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10467000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10468000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10469000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:1046A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1046B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1046C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1046D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1046E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1046F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10470000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10471000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10472000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10473000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10474000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10475000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10476000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10477000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10478000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10479000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:1047A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1047B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1047C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1047D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1047E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1047F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10480000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10481000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10482000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10483000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10484000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10485000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10486000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10487000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10488000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10489000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:1048A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1048B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1048C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1048D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1048E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1048F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10490000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10491000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10493000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10495000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10497000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10499000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:1049A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1049B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1049C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1049D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1049E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1049F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:104A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:104A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:104A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:104A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:104A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:104A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:104A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:104A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:104A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:104A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:104AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:104AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:104AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:104AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:104AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:104AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:104B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:104B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:104B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:104B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:104B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:104B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:104B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:104B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:104B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:104BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:104BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:104BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:104C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:104C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:104C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:104C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:104C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:104C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:104C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:104C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:104C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:104C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:104CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:104CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:104CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:104CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:104CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:104CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:104D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:104D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:104D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:104D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:104D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:104D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:104D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:104D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:104D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:104D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:104DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:104DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:104DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:104DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:104DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:104DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:104E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:104E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:104E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:104E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:104E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:104E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:104E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:104E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:104E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:104ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:104EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:104F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:104F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:104F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:104F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:104F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:104F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:104F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:104F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:104F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:104F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:104FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:104FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:104FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:104FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:104FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:104FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10501000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10502000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10503000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10504000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10505000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10506000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10507000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10508000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10509000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:1050A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1050B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1050C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1050D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1050E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1050F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10510000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10511000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10512000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10513000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10514000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10515000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10516000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10517000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10518000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10519000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:1051A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1051B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1051C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1051D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1051E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1051F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10520000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10521000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10522000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10523000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10524000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10525000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10526000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10527000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10528000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10529000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:1052A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1052B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1052C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1052D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1052E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1052F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10530000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10531000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10532000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10533000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10534000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10535000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10536000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10537000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10538000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10539000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:1053A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1053B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1053C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1053D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10540000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10541000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10542000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10543000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10544000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10545000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10546000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10547000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10548000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10549000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:1054A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1054B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1054C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1054D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1054E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1054F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10550000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10551000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10552000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10553000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10554000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10555000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10556000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10557000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10558000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10559000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:1055A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1055B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1055C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1055D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1055E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1055F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10560000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10561000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10562000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10563000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10564000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10565000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10566000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10567000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10568000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10569000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:1056A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1056B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1056C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1056D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1056E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1056F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10570000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10571000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10572000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10573000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10574000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10575000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10576000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10577000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10578000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10579000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1057A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1057B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1057C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1057D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1057E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1057F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10580000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10581000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10582000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10583000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10584000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10585000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10586000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10587000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10588000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10589000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:1058A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1058B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1058C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1058D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1058E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1058F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10590000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10591000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10592000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10593000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10594000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10595000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10596000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10597000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10598000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10599000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1059A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1059B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1059C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1059D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1059E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1059F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:105A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:105A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:105A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:105A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:105A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:105A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:105A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:105A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:105A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:105A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:105AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:105AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:105AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:105AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:105AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:105AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:105B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:105B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:105B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:105B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:105B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:105B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:105B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:105B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:105B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:105B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:105BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:105BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:105BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:105BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:105BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:105BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:105C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:105C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:105C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:105C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:105C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:105C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:105C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:105C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:105C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:105C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:105CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:105CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:105CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:105CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:105CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:105CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:105D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:105D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:105D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:105D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:105D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:105D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:105D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:105D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:105D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:105D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:105DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:105DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:105DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:105DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:105DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:105DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:105E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:105E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:105E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:105E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:105E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:105E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:105E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:105E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:105E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:105E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:105EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:105EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:105EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:105ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:105EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:105EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:105F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:105F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:105F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:105F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:105F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:105F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:105F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:105F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:105F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:105F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:105FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:105FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:105FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:105FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:105FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:105FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10600000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10601000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10602000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10603000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10604000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10605000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10606000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10607000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10608000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10609000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:1060A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1060B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1060C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1060D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1060E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1060F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10610000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10611000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10612000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10613000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10614000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10615000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10616000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10617000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10618000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10619000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:1061A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1061B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1061C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1061D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1061E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1061F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10620000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10621000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10622000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10623000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10624000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10625000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10626000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10627000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10628000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10629000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:1062A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1062B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1062C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1062D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1062E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1062F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10630000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10631000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10632000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10633000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10634000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10635000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10636000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10637000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10638000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10639000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:1063A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1063B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1063C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10644000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10645000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10646000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10647000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10648000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10649000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:1064A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1064B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1064C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1064D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1064E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1064F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10650000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10651000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10652000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10653000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10654000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10655000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10656000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10657000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10658000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10659000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:1065A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1065B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1065C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1065D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1065E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1065F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10660000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10661000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10662000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10663000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10664000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10665000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10666000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10667000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10668000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10669000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:1066A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1066B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1066C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1066D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1066E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1066F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10670000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10671000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10672000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10673000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10674000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10675000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10676000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10677000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10678000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10679000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1067A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1067B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1067C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1067D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1067E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1067F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10680000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10681000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10682000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10683000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10684000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10685000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10686000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10687000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10688000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10689000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:1068A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1068B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1068C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1068D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1068E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10697000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:106A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:106A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:106A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:106A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:106A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:106A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:106A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:106A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:106A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:106A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:106AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:106AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:106AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:106AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:106AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:106AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:106B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:106B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:106B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:106B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:106B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:106B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:106B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:106B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:106B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:106B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:106BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:106BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:106BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:106BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:106BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:106BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:106C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:106C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:106C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:106C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:106C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:106C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:106C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:106C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:106C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:106C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:106CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:106CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:106CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:106CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:106CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:106CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:106D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:106D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:106D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:106D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:106D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:106D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:106D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:106D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:106D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:106D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:106DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:106DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:106DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:106DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:106DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:106DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:106E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:106E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:106E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:106E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:106E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:106E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:106E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:106E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:106E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:106E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:106EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:106EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:106EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:106ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:106EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:106EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:106F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:106F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:106F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:106F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:106F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:106F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:106F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:106F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:106F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:106F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:106FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:106FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:106FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:106FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:106FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:106FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10701000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10702000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10703000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10707000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10709000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:1070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1070B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1070C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1070D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1070E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1070F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10710000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10711000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10712000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10713000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10714000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10715000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10716000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10717000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10718000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10719000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:1071A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1071B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1071C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1071D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1071E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1071F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10720000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10721000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10722000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10723000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10724000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10725000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10726000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10727000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10728000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10729000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:1072A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1072B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1072C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1072D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1072E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1072F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10730000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10731000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10732000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10733000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10734000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10735000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10736000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10737000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10738000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10739000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:1073A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1073B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1073C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1073D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1073E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1073F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10740000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10741000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10742000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10743000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10744000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10745000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10746000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10747000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10748000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10749000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:1074A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1074B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1074C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1074D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1074E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1074F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10750000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10751000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10752000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10753000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10754000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10755000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10756000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10757000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10758000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10759000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:1075A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1075B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1075C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1075D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1075E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1075F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10760000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10761000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10762000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10763000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10764000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10765000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10766000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10767000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10768000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10769000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:1076A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1076B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1076C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1076D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1076E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1076F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10770000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10771000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10772000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10773000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10774000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10775000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10776000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10777000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10778000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10779000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:1077A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1077B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1077C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1077D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1077E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1077F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10780000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10781000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10782000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10783000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10784000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10785000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10786000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10787000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10788000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10789000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:1078A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1078B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1078C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1078D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1078E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1078F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10790000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10791000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10792000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10793000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10794000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10795000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10796000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10797000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10798000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10799000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1079A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1079B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1079C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1079D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1079E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1079F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:107A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:107A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:107A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:107A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:107A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:107A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:107A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:107A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:107A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:107A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:107AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:107AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:107AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:107AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:107AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:107AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:107B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:107B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:107B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:107B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:107B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:107B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:107B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:107B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:107B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:107B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:107BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:107BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:107BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:107BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:107BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:107BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:107C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:107C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:107C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:107C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:107C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:107C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:107C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:107C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:107C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:107C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:107CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:107CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:107CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:107CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:107CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:107CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:107D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:107D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:107D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:107D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:107D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:107D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:107D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:107D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:107D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:107D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:107DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:107DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:107DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:107DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:107DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:107DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:107E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:107E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:107E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:107E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:107E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:107E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:107E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:107E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:107E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:107E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:107EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:107EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:107EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:107ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:107EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:107EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:107F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:107F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:107F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:107F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:107F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:107F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:107F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:107F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:107F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:107F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:107FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:107FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:107FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:107FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:107FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:107FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10800000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10801000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10802000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10803000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10804000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10805000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10806000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10807000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10808000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10809000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:1080A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1080B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1080C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1080D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1080E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:1080F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10810000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10811000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10812000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10813000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10814000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10815000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10816000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10817000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10818000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10819000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:1081A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1081B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1081C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1081D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1081E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:1081F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10820000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10821000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10822000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10823000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10824000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10825000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10826000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10827000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10828000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10829000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:1082A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1082B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1082C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1082D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1082E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:1082F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10830000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10831000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10832000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10833000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10834000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10835000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10836000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10837000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10838000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10839000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:1083A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1083B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1083C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1083D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1083E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:1083F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10840000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10841000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10842000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10843000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10844000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10845000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10846000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10847000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10848000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10849000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:1084A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1084B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1084C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1084D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1084E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:1084F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10850000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10851000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10852000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10853000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10854000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10855000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10856000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10857000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10858000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10859000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:1085A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1085B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1085C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1085D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1085E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:1085F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10860000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10861000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10862000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10863000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10864000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10865000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10866000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10867000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10868000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10869000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:1086A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1086B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1086C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1086D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1086E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:1086F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10870000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10871000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10872000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10873000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10874000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10875000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10876000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10877000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10878000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10879000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:1087A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1087B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1087C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1087D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1087E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:1087F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10880000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10881000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10882000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10883000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10884000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10885000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10886000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10887000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10888000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10889000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:1088A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1088B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1088C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1088D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1088E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:1088F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10890000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10891000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10892000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10893000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10894000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10895000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10896000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10897000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10898000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10899000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1089A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1089B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1089C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1089D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1089E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:1089F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:108A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:108A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:108A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:108A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:108A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:108A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:108A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:108A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:108A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:108A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:108AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:108AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:108AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:108AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:108AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:108AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:108B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:108B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:108B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:108B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:108B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:108B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:108B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:108B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:108B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:108B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:108BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:108BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:108BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:108BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:108BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:108BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:108C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:108C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:108C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:108C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:108C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:108C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:108C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:108C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:108C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:108C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:108CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:108CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:108CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:108CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:108CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:108CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:108D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:108D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:108D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:108D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:108D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:108D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:108D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:108D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:108D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:108D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:108DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:108DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:108DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:108DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:108DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:108DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:108E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:108E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:108E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:108E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:108E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:108E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:108E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:108E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:108E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:108E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:108EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:108EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:108EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:108ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:108EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:108EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:108F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:108F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:108F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:108F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:108F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:108F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:108F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:108F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:108F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:108F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:108FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:108FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:108FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:108FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:108FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:108FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10900000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10901000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10902000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10903000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10904000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10905000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10906000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10907000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10908000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10909000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:1090A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:1090B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:1090C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:1090D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:1090E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:1090F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10910000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10911000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10912000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10913000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10914000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10915000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10916000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10917000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10918000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10919000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:1091A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:1091B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:1091C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:1091D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:1091E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:1091F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10920000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10921000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10922000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10923000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10924000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10925000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10926000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10927000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10928000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10929000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:1092A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:1092B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:1092C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:1092D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:1092E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:1092F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10930000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10931000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10932000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10933000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10934000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10935000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10936000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10937000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10938000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10939000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:1093A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:1093B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:1093C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:1093D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:1093E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:1093F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10940000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10941000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10942000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10943000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10944000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10945000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10946000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10947000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10948000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10949000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:1094A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:1094B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:1094C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:1094D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:1094E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:1094F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10950000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10951000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10952000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10953000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10954000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10955000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10956000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10957000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10958000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10959000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:1095A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:1095B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:1095C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:1095D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:1095E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:1095F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10960000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10961000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10962000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10963000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10964000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10965000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10966000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10967000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10968000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10969000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:1096A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:1096B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:1096C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:1096D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:1096E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:1096F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10970000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10971000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10972000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10973000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10974000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10975000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10976000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10977000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10978000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10979000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:1097A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:1097B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:1097C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:1097D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:1097E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:1097F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10980000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10981000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10982000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10983000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10984000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10985000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10986000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10987000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10988000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10989000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:1098A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:1098B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:1098C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:1098D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:1098E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:1098F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10990000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10991000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10992000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10993000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10994000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10995000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10996000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10997000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10998000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10999000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1099A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:1099B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:1099C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:1099D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:1099E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:1099F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:109A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:109A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:109A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:109A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:109A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:109A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:109A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:109A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:109A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:109A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:109AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:109AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:109AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:109AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:109AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:109AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:109B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:109B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:109B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:109B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:109B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:109B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:109B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:109B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:109B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:109B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:109BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:109BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:109BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:109BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:109BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:109BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:109C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:109C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:109C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:109C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:109C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:109C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:109C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:109C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:109C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:109C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:109CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:109CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:109CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:109CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:109CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:109CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:109D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:109D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:109D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:109D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:109D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:109D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:109D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:109D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:109D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:109D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:109DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:109DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:109DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:109DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:109DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:109DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:109E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:109E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:109E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:109E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:109E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:109E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:109E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:109E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:109E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:109E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:109EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:109EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:109EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:109ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:109EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:109EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:109F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:109F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:109F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:109F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:109F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:109F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:109F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:109F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:109F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:109F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:109FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:109FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:109FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:109FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:109FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:109FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10A00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10A01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10A02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10A03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10A04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10A05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10A06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10A07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10A08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10A09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10A0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10A0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10A0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10A0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10A0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10A0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10A10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10A11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10A12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10A13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10A14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10A15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10A16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10A17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10A18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10A19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10A1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10A1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10A1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10A1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10A1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10A1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10A20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10A21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10A22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10A23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10A24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10A25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10A26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10A27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10A28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10A29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10A2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10A2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10A2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10A2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10A2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10A2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10A30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10A31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10A32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10A33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10A34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10A35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10A36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10A37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10A38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10A39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10A3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10A3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10A3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10A3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10A3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10A3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10A40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10A41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10A42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10A43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10A44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10A45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10A46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10A47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10A48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10A49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10A4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10A4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10A4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10A4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10A4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10A4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10A50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10A51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10A52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10A53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10A54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10A55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10A56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10A57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10A58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10A59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10A5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10A5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10A5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10A5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10A5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10A5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10A60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10A61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10A62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10A63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10A64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10A65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10A66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10A67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10A68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10A69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10A6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10A6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10A6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10A6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10A6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10A6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10A70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10A71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10A72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10A73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10A74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10A75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10A76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10A77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10A78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10A79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10A7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10A7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10A7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10A7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10A7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10A7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10A80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10A81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10A82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10A83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10A84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10A85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10A86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10A87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10A88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10A89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10A8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10A8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10A8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10A8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10A8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10A8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10A90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10A91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10A92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10A93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10A94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10A95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10A96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10A97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10A98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10A99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10A9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10A9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10A9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10A9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10A9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10A9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10AA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10AA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10AA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10AA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10AA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10AA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10AA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10AA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10AA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10AA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10AAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10AAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10AAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10AAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10AAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10AAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10AB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10AB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10AB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10AB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10AB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10AB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10AB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10AB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10AB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10AB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10ABA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10ABB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10ABC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10ABD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10ABE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10ABF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10AC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10AC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10AC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10AC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10AC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10AC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10AC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10AC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10AC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10AC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10ACA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10ACB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10ACC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10ACD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10ACE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10ACF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10AD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10AD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10AD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10AD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10AD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10AD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10AD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10AD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10AD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10AD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10ADA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10ADB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10ADC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10ADD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10ADE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10ADF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10AE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10AE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10AE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10AE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10AE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10AE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10AE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10AE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10AE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10AE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10AEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10AEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10AEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10AED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10AEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10AEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10AF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10AF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10AF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10AF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10AF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10AF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10AF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10AF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10AF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10AF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10AFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10AFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10AFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10AFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10AFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10AFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10B00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10B01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10B02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10B03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10B04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10B05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10B06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10B07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10B08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10B09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10B0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10B0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10B0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10B0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10B0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10B0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10B10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10B11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10B12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10B13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10B14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10B15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10B16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10B17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10B18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10B19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10B1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10B1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10B1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10B1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10B1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10B1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10B20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10B21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10B22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10B23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10B24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10B25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10B26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10B27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10B28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10B29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10B2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10B2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10B2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10B2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10B2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10B2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10B30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10B31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10B32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10B33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10B34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10B35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10B36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10B37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10B38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10B39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10B3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10B3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10B3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10B3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10B3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10B3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10B40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10B41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10B42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10B43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10B44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10B45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10B46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10B47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10B48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10B49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10B4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10B4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10B4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10B4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10B4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10B4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10B50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10B51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10B52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10B53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10B54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10B55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10B56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10B57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10B58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10B59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10B5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10B5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10B5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10B5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10B5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10B5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10B60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10B61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10B62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10B63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10B64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10B65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10B66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10B67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10B68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10B69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10B6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10B6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10B6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10B6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10B6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10B6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10B70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10B71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10B72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10B73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10B74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10B75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10B76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10B77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10B78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10B79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10B7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10B7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10B7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10B7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10B7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10B7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10B80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10B81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10B82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10B83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10B84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10B85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10B86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10B87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10B88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10B89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10B8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10B8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10B8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10B8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10B8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10B8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10B90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10B91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10B92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10B93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10B94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10B95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10B96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10B97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10B98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10B99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10B9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10B9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10B9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10B9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10B9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10B9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10BA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10BA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10BA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10BA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10BA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10BA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10BA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10BA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10BA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10BA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10BAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10BAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10BAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10BAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10BAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10BAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10BB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10BB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10BB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10BB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10BB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10BB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10BB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10BB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10BB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10BB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10BBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10BBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10BBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10BBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10BBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10BBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10BC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10BC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10BC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10BC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10BC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10BC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10BC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10BC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10BC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10BC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10BCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10BCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10BCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10BCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10BCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10BCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10BD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10BD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10BD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10BD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10BD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10BD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10BD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10BD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10BD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10BD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10BDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10BDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10BDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10BDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10BDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10BDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10BE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10BE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10BE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10BE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10BE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10BE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10BE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10BE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10BE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10BE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10BEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10BEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10BEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10BED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10BEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10BEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10BF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10BF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10BF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10BF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10BF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10BF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10BF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10BF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10BF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10BF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10BFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10BFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10BFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10BFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10BFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10BFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10C00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10C01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10C02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10C03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10C04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10C05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10C06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10C07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10C08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10C09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10C0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10C0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10C0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10C0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10C0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10C0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10C10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10C11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10C12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10C13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10C14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10C15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10C16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10C17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10C18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10C19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10C1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10C1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10C1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10C1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10C1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10C1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10C20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10C21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10C22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10C23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10C24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10C25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10C26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10C27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10C28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10C29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10C2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10C2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10C2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10C2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10C2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10C2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10C30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10C31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10C32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10C33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10C34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10C35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10C36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10C37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10C38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10C39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10C3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10C3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10C3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10C3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10C3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10C3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10C40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10C41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10C42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10C43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10C44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10C45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10C46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10C47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10C48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10C49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10C4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10C4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10C4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10C4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10C4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10C4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10C50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10C51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10C52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10C53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10C54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10C55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10C56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10C57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10C58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10C59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10C5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10C5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10C5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10C5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10C5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10C5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10C60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10C61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10C62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10C63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10C64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10C65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10C66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10C67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10C68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10C69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10C6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10C6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10C6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10C6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10C6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10C6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10C70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10C71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10C72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10C73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10C74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10C75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10C76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10C77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10C78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10C79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10C7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10C7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10C7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10C7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10C7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10C7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10C80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10C81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10C82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10C83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10C84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10C85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10C86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10C87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10C88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10C89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10C8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10C8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10C8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10C8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10C8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10C8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10C90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10C91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10C92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10C93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10C94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10C95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10C96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10C97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10C98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10C99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10C9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10C9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10C9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10C9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10C9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10C9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10CA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10CA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10CA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10CA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10CA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10CA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10CA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10CA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10CA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10CA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10CAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10CAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10CAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10CAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10CAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10CAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10CB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10CB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10CB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10CB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10CB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10CB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10CB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10CB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10CB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10CB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10CBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10CBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10CBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10CBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10CBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10CBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10CC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10CC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10CC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10CC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10CC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10CC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10CC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10CC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10CC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10CC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10CCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10CCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10CCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10CCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10CCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10CCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10CD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10CD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10CD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10CD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10CD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10CD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10CD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10CD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10CD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10CD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10CDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10CDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10CDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10CDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10CDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10CDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10CE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10CE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10CE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10CE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10CE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10CE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10CE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10CE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10CE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10CE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10CEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10CEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10CEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10CED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10CEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10CEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10CF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10CF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10CF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10CF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10CF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10CF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10CF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10CF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10CF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10CF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10CFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10CFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10CFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10CFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10CFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10CFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10D00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10D01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10D02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10D03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10D04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10D05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10D06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10D07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10D08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10D09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10D0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10D0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10D0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10D0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10D0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10D0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10D10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10D11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10D12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10D13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10D14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10D15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10D16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10D17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10D18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10D19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10D1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10D1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10D1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10D1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10D1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10D1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10D20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10D21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10D22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10D23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10D24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10D25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10D26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10D27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10D28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10D29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10D2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10D2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10D2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10D2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10D2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10D2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10D30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10D31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10D32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10D33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10D34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10D35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10D36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10D37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10D38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10D39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10D3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10D3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10D3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10D3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10D3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10D3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10D40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10D41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10D42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10D43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10D44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10D45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10D46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10D47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10D48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10D49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10D4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10D4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10D4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10D4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10D4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10D4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10D50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10D51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10D52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10D53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10D54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10D55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10D56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10D57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10D58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10D59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10D5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10D5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10D5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10D5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10D5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10D5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10D60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10D61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10D62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10D63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10D64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10D65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10D66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10D67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10D68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10D69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10D6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10D6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10D6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10D6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10D6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10D6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10D70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10D71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10D72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10D73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10D74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10D75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10D76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10D77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10D78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10D79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10D7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10D7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10D7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10D7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10D7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10D7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10D80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10D81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10D82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10D83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10D84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10D85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10D86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10D87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10D88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10D89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10D8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10D8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10D8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10D8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10D8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10D8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10D90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10D91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10D92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10D93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10D94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10D95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10D96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10D97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10D98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10D99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10D9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10D9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10D9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10D9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10D9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10D9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10DA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10DA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10DA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10DA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10DA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10DA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10DA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10DA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10DA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10DA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10DAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10DAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10DAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10DAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10DAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10DAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10DB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10DB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10DB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10DB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10DB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10DB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10DB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10DB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10DB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10DB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10DBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10DBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10DBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10DBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10DBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10DBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10DC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10DC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10DC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10DC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10DC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10DC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10DC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10DC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10DC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10DC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10DCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10DCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10DCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10DCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10DCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10DCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10DD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10DD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10DD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10DD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10DD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10DD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10DD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10DD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10DD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10DD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10DDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10DDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10DDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10DDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10DDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10DDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10DE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10DE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10DE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10DE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10DE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10DE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10DE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10DE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10DE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10DE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10DEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10DEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10DEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10DED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10DEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10DEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10DF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10DF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10DF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10DF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10DF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10DF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10DF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10DF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10DF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10DF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10DFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10DFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10DFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10DFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10DFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10DFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10E00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10E01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10E02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10E03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10E04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10E05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10E06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10E07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10E08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10E09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10E0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10E0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10E0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10E0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10E0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10E0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10E10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10E11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10E12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10E13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10E14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10E15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10E16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10E17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10E18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10E19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10E1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10E1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10E1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10E1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10E1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10E1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10E20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10E21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10E22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10E23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10E24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10E25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10E26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10E27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10E28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10E29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10E2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10E2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10E2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10E2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10E2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10E2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10E30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10E31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10E32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10E33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10E34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10E35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10E36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10E37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10E38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10E39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10E3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10E3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10E3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10E3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10E3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10E3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10E40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10E41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10E42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10E43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10E44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10E45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10E46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10E47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10E48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10E49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10E4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10E4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10E4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10E4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10E4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10E4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10E50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10E51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10E52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10E53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10E54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10E55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10E56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10E57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10E58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10E59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10E5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10E5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10E5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10E5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10E5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10E5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10E60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10E61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10E62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10E63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10E64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10E65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10E66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10E67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10E68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10E69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10E6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10E6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10E6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10E6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10E6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10E6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10E70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10E71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10E72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10E73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10E74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10E75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10E76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10E77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10E78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10E79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10E7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10E7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10E7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10E7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10E7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10E7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10E80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10E81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10E82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10E83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10E84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10E85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10E86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10E87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10E88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10E89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10E8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10E8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10E8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10E8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10E8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10E8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10E90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10E91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10E92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10E93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10E94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10E95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10E96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10E97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10E98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10E99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10E9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10E9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10E9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10E9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10E9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10E9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10EA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10EA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10EA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10EA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10EA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10EA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10EA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10EA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10EA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10EA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10EAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10EAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10EAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10EAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10EAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10EAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10EB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10EB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10EB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10EB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10EB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10EB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10EB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10EB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10EB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10EB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10EBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10EBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10EBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10EBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10EBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10EBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10EC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10EC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10EC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10EC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10EC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10EC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10EC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10EC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10EC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10EC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10ECA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10ECB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10ECC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10ECD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10ECE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10ECF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10ED0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10ED1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10ED2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10ED3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10ED4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10ED5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10ED6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10ED7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10ED8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10ED9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10EDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10EDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10EDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10EDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10EDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10EDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10EE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10EE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10EE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10EE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10EE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10EE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10EE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10EE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10EE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10EE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10EEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10EEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10EEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10EED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10EEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10EEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10EF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:10EF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10EF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10EF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10EF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10EF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10EF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10EF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10EF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10EF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10EFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10EFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10EFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10EFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10EFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10EFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10F00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:10F01000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10F02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10F03000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10F04000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10F05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10F06000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10F07000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10F08000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10F09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10F0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10F0B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10F0C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10F0D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10F0E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10F0F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:10F10000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:10F11000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:10F12000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:10F13000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:10F14000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:10F15000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:10F16000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:10F17000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:10F18000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:10F19000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:10F1A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:10F1B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:10F1C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:10F1D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:10F1E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:10F1F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:10F20000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:10F21000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:10F22000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:10F23000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:10F24000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:10F25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:10F26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:10F27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:10F28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:10F29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:10F2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:10F2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:10F2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:10F2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:10F2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:10F2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:10F30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:10F31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:10F32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:10F33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:10F34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:10F35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:10F36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:10F37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:10F38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:10F39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:10F3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:10F3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:10F3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:10F3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:10F3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:10F3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:10F40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:10F41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:10F42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:10F43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:10F44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:10F45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:10F46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:10F47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:10F48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:10F49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:10F4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:10F4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:10F4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:10F4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:10F4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:10F4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:10F50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:10F51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:10F52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:10F53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:10F54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:10F55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:10F56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:10F57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:10F58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:10F59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:10F5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:10F5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:10F5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:10F5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:10F5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:10F5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:10F60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:10F61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:10F62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:10F63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:10F64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:10F65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10F66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:10F67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:10F68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:10F69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:10F6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:10F6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:10F6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:10F6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:10F6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:10F6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:10F70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:10F71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:10F72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:10F73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:10F74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:10F75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:10F76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:10F77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:10F78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:10F79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:10F7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:10F7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:10F7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:10F7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:10F7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:10F7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:10F80000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:10F81000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:10F82000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:10F83000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:10F84000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:10F85000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:10F86000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:10F87000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:10F88000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:10F89000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:10F8A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10F8B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:10F8C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:10F8D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:10F8E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:10F8F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:10F90000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:10F91000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:10F92000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:10F93000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:10F94000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:10F95000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:10F96000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:10F97000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10F98000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10F99000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10F9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10F9B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10F9C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10F9D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10F9E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10F9F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10FA0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:10FA1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:10FA2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:10FA3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:10FA4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:10FA5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:10FA6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:10FA7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:10FA8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:10FA9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:10FAA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:10FAB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:10FAC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:10FAD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:10FAE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:10FAF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:10FB0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:10FB1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:10FB2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:10FB3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:10FB4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:10FB5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:10FB6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:10FB7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:10FB8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:10FB9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:10FBA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:10FBB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:10FBC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:10FBD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:10FBE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:10FBF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:10FC0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:10FC1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:10FC2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:10FC3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:10FC4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:10FC5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10FC6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:10FC7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:10FC8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:10FC9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:10FCA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:10FCB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:10FCC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:10FCD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:10FCE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:10FCF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:10FD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:10FD1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:10FD2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:10FD3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:10FD4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:10FD5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:10FD6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:10FD7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:10FD8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:10FD9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:10FDA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:10FDB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:10FDC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:10FDD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:10FDE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:10FDF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:10FE0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:10FE1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:10FE2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:10FE3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:10FE4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:10FE5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:10FE6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:10FE7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:10FE8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:10FE9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:10FEA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:10FEB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:10FEC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:10FED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:10FEE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:10FEF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:10FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:10FF1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:10FF2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:10FF3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:10FF4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:10FF5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:10FF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:10FF7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:10FF8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:10FF9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:10FFA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:10FFB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:10FFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:10FFD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:10FFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:10FFF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:00000001FF
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/SD-SPI.c b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/SD-SPI.c new file mode 100644 index 00000000..fa57e704 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/SD-SPI.c @@ -0,0 +1,1493 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: SD-SPI.c
+ * Dependencies: SD-SPI.h
+ * string.h
+ * FSIO.h
+ * FSDefs.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#include "FSIO.h"
+#include "FSDefs.h"
+#include "SD-SPI.h"
+#include "string.h"
+#include "FSConfig.h"
+#include "HardwareProfile.h"
+
+/******************************************************************************
+ * Global Variables
+ *****************************************************************************/
+
+// Description: Used for the mass-storage library to determine capacity
+DWORD MDD_SDSPI_finalLBA;
+
+
+#ifdef __18CXX
+ // Summary: Table of SD card commands and parameters
+ // Description: The sdmmc_cmdtable contains an array of SD card commands, the corresponding CRC code, the
+ // response type that the card will return, and a parameter indicating whether to expect
+ // additional data from the card.
+ const rom typMMC_CMD sdmmc_cmdtable[] =
+#else
+ const typMMC_CMD sdmmc_cmdtable[] =
+#endif
+{
+ // cmd crc response
+ {cmdGO_IDLE_STATE, 0x95, R1, NODATA},
+ {cmdSEND_OP_COND, 0xF9, R1, NODATA},
+ {cmdSEND_CSD, 0xAF, R1, MOREDATA},
+ {cmdSEND_CID, 0x1B, R1, MOREDATA},
+ {cmdSTOP_TRANSMISSION, 0xC3, R1, NODATA},
+ {cmdSEND_STATUS, 0xAF, R2, NODATA},
+ {cmdSET_BLOCKLEN, 0xFF, R1, NODATA},
+ {cmdREAD_SINGLE_BLOCK, 0xFF, R1, MOREDATA},
+ {cmdREAD_MULTI_BLOCK, 0xFF, R1, MOREDATA},
+ {cmdWRITE_SINGLE_BLOCK, 0xFF, R1, MOREDATA},
+ {cmdWRITE_MULTI_BLOCK, 0xFF, R1, MOREDATA},
+ {cmdTAG_SECTOR_START, 0xFF, R1, NODATA},
+ {cmdTAG_SECTOR_END, 0xFF, R1, NODATA},
+ {cmdERASE, 0xDF, R1b, NODATA},
+ {cmdAPP_CMD, 0x73, R1, NODATA},
+ {cmdREAD_OCR, 0x25, R3, NODATA},
+ {cmdCRC_ON_OFF, 0x25, R1, NODATA}
+};
+
+
+
+
+/******************************************************************************
+ * Prototypes
+ *****************************************************************************/
+
+extern void Delayms(BYTE milliseconds);
+BYTE MDD_SDSPI_ReadMedia(void);
+BYTE MDD_SDSPI_MediaInitialize(void);
+MMC_RESPONSE SendMMCCmd(BYTE cmd, DWORD address);
+
+#if defined __C30__ || defined __C32__
+ void OpenSPIM ( unsigned int sync_mode);
+ void CloseSPIM( void );
+ unsigned char WriteSPIM( unsigned char data_out );
+#elif defined __18CXX
+ void OpenSPIM ( unsigned char sync_mode);
+ void CloseSPIM( void );
+ unsigned char WriteSPIM( unsigned char data_out );
+
+ unsigned char WriteSPIManual(unsigned char data_out);
+ BYTE ReadMediaManual (void);
+ MMC_RESPONSE SendMMCCmdManual(BYTE cmd, DWORD address);
+#endif
+
+#ifdef __PIC32MX__
+
+/*********************************************************
+ Function:
+ static inline __attribute__((always_inline)) unsigned char SPICacutateBRG (unsigned int pb_clk, unsigned int spi_clk)
+ Summary:
+ Calculate the PIC32 SPI BRG value
+ Conditions:
+ None
+ Input:
+ pb_clk - The value of the PIC32 peripheral clock
+ spi_clk - The desired baud rate
+ Return:
+ The corresponding BRG register value.
+ Side Effects:
+ None.
+ Description:
+ The SPICalutateBRG function is used to determine an appropriate BRG register value for the PIC32 SPI module.
+ Remarks:
+ None
+ *********************************************************/
+
+static inline __attribute__((always_inline)) unsigned char SPICalutateBRG(unsigned int pb_clk, unsigned int spi_clk)
+{
+ unsigned int brg;
+
+ brg = pb_clk / (2 * spi_clk);
+
+ if(pb_clk % (2 * spi_clk))
+ brg++;
+
+ if(brg > 0x100)
+ brg = 0x100;
+
+ if(brg)
+ brg--;
+
+ return (unsigned char) brg;
+}
+#endif
+
+
+/*********************************************************
+ Function:
+ BYTE MDD_SDSPI_MediaDetect
+ Summary:
+ Determines whether an SD card is present
+ Conditions:
+ The MDD_MediaDetect function pointer must be configured
+ to point to this function in FSconfig.h
+ Input:
+ None
+ Return Values:
+ TRUE - Card detected
+ FALSE - No card detected
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_MediaDetect function will determine if an
+ SD card is connected to the microcontroller by polling
+ the SD card detect pin.
+ Remarks:
+ None
+ *********************************************************/
+
+BYTE MDD_SDSPI_MediaDetect (void)
+{
+ return(!SD_CD);
+}//end MediaDetect
+
+
+/*********************************************************
+ Function:
+ WORD MDD_SDSPI_ReadSectorSize (void)
+ Summary:
+ Determines the current sector size on the SD card
+ Conditions:
+ MDD_MediaInitialize() is complete
+ Input:
+ None
+ Return:
+ The size of the sectors for the physical media
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_ReadSectorSize function is used by the
+ USB mass storage class to return the card's sector
+ size to the PC on request.
+ Remarks:
+ None
+ *********************************************************/
+
+WORD MDD_SDSPI_ReadSectorSize(void)
+{
+ return MEDIA_SECTOR_SIZE;
+}
+
+
+/*********************************************************
+ Function:
+ DWORD MDD_SDSPI_ReadCapacity (void)
+ Summary:
+ Determines the current capacity of the SD card
+ Conditions:
+ MDD_MediaInitialize() is complete
+ Input:
+ None
+ Return:
+ The capacity of the device
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_ReadCapacity function is used by the
+ USB mass storage class to return the total number
+ of sectors on the card.
+ Remarks:
+ None
+ *********************************************************/
+DWORD MDD_SDSPI_ReadCapacity(void)
+{
+ return (MDD_SDSPI_finalLBA);
+}
+
+
+/*********************************************************
+ Function:
+ WORD MDD_SDSPI_InitIO (void)
+ Summary:
+ Initializes the I/O lines connected to the card
+ Conditions:
+ MDD_MediaInitialize() is complete. The MDD_InitIO
+ function pointer is pointing to this function.
+ Input:
+ None
+ Return:
+ None
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_InitIO function initializes the I/O
+ pins connected to the SD card.
+ Remarks:
+ None
+ *********************************************************/
+
+void MDD_SDSPI_InitIO (void)
+{
+ // Turn off the card
+ SD_CD_TRIS = INPUT; //Card Detect - input
+ SD_CS = 1; //Initialize Chip Select line
+ SD_CS_TRIS = OUTPUT; //Card Select - output
+ SD_WE_TRIS = INPUT; //Write Protect - input
+}
+
+
+
+/*********************************************************
+ Function:
+ BYTE MDD_SDSPI_ShutdownMedia (void)
+ Summary:
+ Disables the SD card
+ Conditions:
+ The MDD_ShutdownMedia function pointer is pointing
+ towards this function.
+ Input:
+ None
+ Return:
+ None
+ Side Effects:
+ None.
+ Description:
+ This function will disable the SPI port and deselect
+ the SD card.
+ Remarks:
+ None
+ *********************************************************/
+
+BYTE MDD_SDSPI_ShutdownMedia(void)
+{
+ // close the spi bus
+ CloseSPIM();
+
+ // deselect the device
+ SD_CS = 1;
+
+ return 0;
+}
+
+
+/*****************************************************************************
+ Function:
+ MMC_RESPONSE SendMMCCmd (BYTE cmd, DWORD address)
+ Summary:
+ Sends a command packet to the SD card.
+ Conditions:
+ None.
+ Input:
+ None.
+ Return Values:
+ MMC_RESPONSE - The response from the card
+ - Bit 0 - Idle state
+ - Bit 1 - Erase Reset
+ - Bit 2 - Illegal Command
+ - Bit 3 - Command CRC Error
+ - Bit 4 - Erase Sequence Error
+ - Bit 5 - Address Error
+ - Bit 6 - Parameter Error
+ - Bit 7 - Unused. Always 0.
+ Side Effects:
+ None.
+ Description:
+ SendMMCCmd prepares a command packet and sends it out over the SPI interface.
+ Response data of type 'R1' (as indicated by the SD/MMC product manual is returned.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+MMC_RESPONSE SendMMCCmd(BYTE cmd, DWORD address)
+{
+ WORD timeout = 0x8;
+ BYTE index;
+ MMC_RESPONSE response;
+ CMD_PACKET CmdPacket;
+
+ SD_CS = 0; //Card Select
+
+ // Copy over data
+ CmdPacket.cmd = sdmmc_cmdtable[cmd].CmdCode;
+ CmdPacket.address = address;
+ CmdPacket.crc = sdmmc_cmdtable[cmd].CRC; // Calc CRC here
+
+ CmdPacket.TRANSMIT_BIT = 1; //Set Tranmission bit
+
+ WriteSPIM(CmdPacket.cmd); //Send Command
+ WriteSPIM(CmdPacket.addr3); //Most Significant Byte
+ WriteSPIM(CmdPacket.addr2);
+ WriteSPIM(CmdPacket.addr1);
+ WriteSPIM(CmdPacket.addr0); //Least Significant Byte
+ WriteSPIM(CmdPacket.crc); //Send CRC
+
+ // see if we are going to get a response
+ if(sdmmc_cmdtable[cmd].responsetype == R1 || sdmmc_cmdtable[cmd].responsetype == R1b)
+ {
+ do
+ {
+ response.r1._byte = MDD_SDSPI_ReadMedia();
+ timeout--;
+ }while(response.r1._byte == MMC_FLOATING_BUS && timeout != 0);
+ }
+ else if(sdmmc_cmdtable[cmd].responsetype == R2)
+ {
+ MDD_SDSPI_ReadMedia();
+
+ response.r2._byte1 = MDD_SDSPI_ReadMedia();
+ response.r2._byte0 = MDD_SDSPI_ReadMedia();
+ }
+
+ if(sdmmc_cmdtable[cmd].responsetype == R1b)
+ {
+ response.r1._byte = 0x00;
+
+ for(index =0; index < 0xFF && response.r1._byte == 0x00; index++)
+ {
+ timeout = 0xFFFF;
+
+ do
+ {
+ response.r1._byte = MDD_SDSPI_ReadMedia();
+ timeout--;
+ }while(response.r1._byte == 0x00 && timeout != 0);
+ }
+ }
+
+ mSend8ClkCycles(); //Required clocking (see spec)
+
+ // see if we are expecting data or not
+ if(!(sdmmc_cmdtable[cmd].moredataexpected))
+ SD_CS = 1;
+
+ return(response);
+}
+
+#ifdef __18CXX
+#if (GetSystemClock() >= 25600000)
+
+/*****************************************************************************
+ Function:
+ MMC_RESPONSE SendMMCCmdManual (BYTE cmd, DWORD address)
+ Summary:
+ Sends a command packet to the SD card with bit-bang SPI.
+ Conditions:
+ None.
+ Input:
+ None.
+ Return Values:
+ MMC_RESPONSE - The response from the card
+ - Bit 0 - Idle state
+ - Bit 1 - Erase Reset
+ - Bit 2 - Illegal Command
+ - Bit 3 - Command CRC Error
+ - Bit 4 - Erase Sequence Error
+ - Bit 5 - Address Error
+ - Bit 6 - Parameter Error
+ - Bit 7 - Unused. Always 0.
+ Side Effects:
+ None.
+ Description:
+ SendMMCCmd prepares a command packet and sends it out over the SPI interface.
+ Response data of type 'R1' (as indicated by the SD/MMC product manual is returned.
+ This function is intended to be used when the clock speed of a PIC18 device is
+ so high that the maximum SPI divider can't reduce the clock below the maximum
+ SD card initialization sequence speed.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+MMC_RESPONSE SendMMCCmdManual(BYTE cmd, DWORD address)
+{
+ WORD timeout = 0x8;
+ BYTE index;
+ MMC_RESPONSE response;
+ CMD_PACKET CmdPacket;
+
+ SD_CS = 0; //Card Select
+
+ // Copy over data
+ CmdPacket.cmd = sdmmc_cmdtable[cmd].CmdCode;
+ CmdPacket.address = address;
+ CmdPacket.crc = sdmmc_cmdtable[cmd].CRC; // Calc CRC here
+
+ CmdPacket.TRANSMIT_BIT = 1; //Set Tranmission bit
+
+ WriteSPIManual(CmdPacket.cmd); //Send Command
+ WriteSPIManual(CmdPacket.addr3); //Most Significant Byte
+ WriteSPIManual(CmdPacket.addr2);
+ WriteSPIManual(CmdPacket.addr1);
+ WriteSPIManual(CmdPacket.addr0); //Least Significant Byte
+ WriteSPIManual(CmdPacket.crc); //Send CRC
+
+ // see if we are going to get a response
+ if(sdmmc_cmdtable[cmd].responsetype == R1 || sdmmc_cmdtable[cmd].responsetype == R1b)
+ {
+ do
+ {
+ response.r1._byte = ReadMediaManual();
+ timeout--;
+ }while(response.r1._byte == MMC_FLOATING_BUS && timeout != 0);
+ }
+ else if(sdmmc_cmdtable[cmd].responsetype == R2)
+ {
+ ReadMediaManual();
+
+ response.r2._byte1 = ReadMediaManual();
+ response.r2._byte0 = ReadMediaManual();
+ }
+
+ if(sdmmc_cmdtable[cmd].responsetype == R1b)
+ {
+ response.r1._byte = 0x00;
+
+ for(index =0; index < 0xFF && response.r1._byte == 0x00; index++)
+ {
+ timeout = 0xFFFF;
+
+ do
+ {
+ response.r1._byte = ReadMediaManual();
+ timeout--;
+ }while(response.r1._byte == 0x00 && timeout != 0);
+ }
+ }
+
+ WriteSPIManual(0xFF); //Required clocking (see spec)
+
+ // see if we are expecting data or not
+ if(!(sdmmc_cmdtable[cmd].moredataexpected))
+ SD_CS = 1;
+
+ return(response);
+}
+#endif
+#endif
+
+
+
+/*****************************************************************************
+ Function:
+ BYTE MDD_SDSPI_SectorRead (DWORD sector_addr, BYTE * buffer)
+ Summary:
+ Reads a sector of data from an SD card.
+ Conditions:
+ The MDD_SectorRead function pointer must be pointing towards this function.
+ Input:
+ sector_addr - The address of the sector on the card.
+ byffer - The buffer where the retrieved data will be stored. If
+ buffer is NULL, do not store the data anywhere.
+ Return Values:
+ TRUE - The sector was read successfully
+ FALSE - The sector could not be read
+ Side Effects:
+ None
+ Description:
+ The MDD_SDSPI_SectorRead function reads 512 bytes of data from the SD card
+ starting at the sector address and stores them in the location pointed to
+ by 'buffer.'
+ Remarks:
+ The card expects the address field in the command packet to be a byte address.
+ The sector_addr value is converted to a byte address by shifting it left nine
+ times (multiplying by 512).
+ ***************************************************************************************/
+
+BYTE MDD_SDSPI_SectorRead(DWORD sector_addr, BYTE* buffer)
+{
+ WORD index;
+ WORD delay;
+ MMC_RESPONSE response;
+ BYTE data_token;
+ BYTE status = TRUE;
+ DWORD new_addr;
+
+#ifdef USB_USE_MSD
+ DWORD firstSector;
+ DWORD numSectors;
+#endif
+
+ // send the cmd
+ new_addr = sector_addr << 9;
+ response = SendMMCCmd(READ_SINGLE_BLOCK,new_addr);
+
+ // Make sure the command was accepted
+ if(response.r1._byte != 0x00)
+ {
+ response = SendMMCCmd (READ_SINGLE_BLOCK,new_addr);
+ if(response.r1._byte != 0x00)
+ {
+ return FALSE;
+ }
+ }
+
+ index = 0x2FF;
+
+ // Timing delay- at least 8 clock cycles
+ delay = 0x40;
+ while (delay)
+ delay--;
+
+ //Now, must wait for the start token of data block
+ do
+ {
+ data_token = MDD_SDSPI_ReadMedia();
+ index--;
+
+ delay = 0x40;
+ while (delay)
+ delay--;
+
+ }while((data_token == MMC_FLOATING_BUS) && (index != 0));
+
+ // Hopefully that zero is the datatoken
+ if((index == 0) || (data_token != DATA_START_TOKEN))
+ {
+ status = FALSE;
+ }
+ else
+ {
+#ifdef USB_USE_MSD
+ if ((sector_addr == 0) && (buffer == NULL))
+ MDD_SDSPI_finalLBA = 0x00000000;
+#endif
+
+ for(index = 0; index < MEDIA_SECTOR_SIZE; index++) //Reads in 512-byte of data
+ {
+ if(buffer != NULL)
+ {
+#ifdef __18CXX
+ data_token = SPIBUF;
+ SPI_INTERRUPT_FLAG = 0;
+ SPIBUF = 0xFF;
+ while(!SPI_INTERRUPT_FLAG);
+ buffer[index] = SPIBUF;
+#else
+ SPIBUF = 0xFF;
+ while (!SPISTAT_RBF);
+ buffer[index] = SPIBUF;
+#endif
+ }
+ else
+ {
+#ifdef USB_USE_MSD
+ if (sector_addr == 0)
+ {
+ if ((index == 0x1C6) || (index == 0x1D6) || (index == 0x1E6) || (index == 0x1F6))
+ {
+ firstSector = MDD_SDSPI_ReadMedia();
+ firstSector |= (DWORD)MDD_SDSPI_ReadMedia() << 8;
+ firstSector |= (DWORD)MDD_SDSPI_ReadMedia() << 16;
+ firstSector |= (DWORD)MDD_SDSPI_ReadMedia() << 24;
+ numSectors = MDD_SDSPI_ReadMedia();
+ numSectors |= (DWORD)MDD_SDSPI_ReadMedia() << 8;
+ numSectors |= (DWORD)MDD_SDSPI_ReadMedia() << 16;
+ numSectors |= (DWORD)MDD_SDSPI_ReadMedia() << 24;
+ index += 8;
+ if ((firstSector + numSectors) > MDD_SDSPI_finalLBA)
+ {
+ MDD_SDSPI_finalLBA = firstSector + numSectors - 1;
+ }
+ }
+ else
+ {
+ MDD_SDSPI_ReadMedia();
+ }
+ }
+ else
+ MDD_SDSPI_ReadMedia();
+#else
+ MDD_SDSPI_ReadMedia();
+#endif
+ }
+ }
+ // Now ensure CRC
+ mReadCRC(); //Read 2 bytes of CRC
+ //status = mmcCardCRCError;
+ }
+
+ mSend8ClkCycles(); //Required clocking (see spec)
+
+ SD_CS = 1;
+
+ return(status);
+}//end SectorRead
+
+
+/*****************************************************************************
+ Function:
+ BYTE MDD_SDSPI_SectorWrite (DWORD sector_addr, BYTE * buffer, BYTE allowWriteToZero)
+ Summary:
+ Writes a sector of data to an SD card.
+ Conditions:
+ The MDD_SectorWrite function pointer must be pointing to this function.
+ Input:
+ sector_addr - The address of the sector on the card.
+ buffer - The buffer with the data to write.
+ allowWriteToZero -
+ - TRUE - Writes to the 0 sector (MBR) are allowed
+ - FALSE - Any write to the 0 sector will fail.
+ Return Values:
+ TRUE - The sector was written successfully.
+ FALSE - The sector could not be written.
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_SectorWrite function writes 512 bytes of data from the location
+ pointed to by 'buffer' to the specified sector of the SD card.
+ Remarks:
+ The card expects the address field in the command packet to be a byte address.
+ The sector_addr value is ocnverted to a byte address by shifting it left nine
+ times (multiplying by 512).
+ ***************************************************************************************/
+
+BYTE MDD_SDSPI_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero)
+{
+ WORD index;
+ BYTE data_response;
+#ifdef __18CXX
+ BYTE clear;
+#endif
+ MMC_RESPONSE response;
+ BYTE status = TRUE;
+
+ if (sector_addr == 0 && allowWriteToZero == FALSE)
+ status = FALSE;
+ else
+ {
+ // send the cmd
+ response = SendMMCCmd(WRITE_SINGLE_BLOCK,(sector_addr << 9));
+
+ // see if it was accepted
+ if(response.r1._byte != 0x00)
+ status = FALSE;
+ else
+ {
+ WriteSPIM(DATA_START_TOKEN); //Send data start token
+
+ for(index = 0; index < MEDIA_SECTOR_SIZE; index++) //Send 512 bytes of data
+ {
+#ifdef __18CXX
+ clear = SPIBUF;
+ SPI_INTERRUPT_FLAG = 0;
+ SPIBUF = buffer[index]; // write byte to SSP1BUF register
+ while( !SPI_INTERRUPT_FLAG ); // wait until bus cycle complete
+ data_response = SPIBUF; // Clear the SPIBUF
+#else
+ SPIBUF = buffer[index];
+ while (!SPISTAT_RBF);
+ data_response = SPIBUF;
+#endif
+ }
+
+ // calc crc
+ mSendCRC(); //Send 2 bytes of CRC
+
+ data_response = MDD_SDSPI_ReadMedia(); //Read response
+
+ if((data_response & 0x0F) != DATA_ACCEPTED)
+ {
+ status = FALSE;
+ }
+ else
+ {
+ index = 0; //using i as a timeout counter
+
+ do //Wait for write completion
+ {
+#ifdef __18CXX
+ clear = SPIBUF;
+ SPI_INTERRUPT_FLAG = 0;
+ SPIBUF = 0xFF;
+ while(!SPI_INTERRUPT_FLAG);
+ data_response = SPIBUF;
+#else
+ SPIBUF = 0xFF;
+ while(!SPISTAT_RBF);
+ data_response = SPIBUF;
+#endif
+ index++;
+ }while((data_response == 0x00) && (index != 0));
+
+ if(index == 0) //if timeout first
+ status = FALSE;
+ }
+
+ mSend8ClkCycles();
+ }
+
+ SD_CS = 1;
+
+ } // Not writing to 0 sector
+
+ return(status);
+} //end SectorWrite
+
+
+/*****************************************************************************
+ Function:
+ BYTE MDD_SDSPI_WriteProtectState
+ Summary:
+ Indicates whether the card is write-protected.
+ Conditions:
+ The MDD_WriteProtectState function pointer must be pointing to this function.
+ Input:
+ None.
+ Return Values:
+ TRUE - The card is write-protected
+ FALSE - The card is not write-protected
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_WriteProtectState function will determine if the SD card is
+ write protected by checking the electrical signal that corresponds to the
+ physical write-protect switch.
+ Remarks:
+ None
+ ***************************************************************************************/
+
+BYTE MDD_SDSPI_WriteProtectState(void)
+{
+ return(SD_WE);
+}
+
+
+/*****************************************************************************
+ Function:
+ void Delayms (BYTE milliseconds)
+ Summary:
+ Delay.
+ Conditions:
+ None.
+ Input:
+ BYTE milliseconds - Number of ms to delay
+ Return:
+ None.
+ Side Effects:
+ None.
+ Description:
+ The Delayms function will delay a specified number of milliseconds. Used for SPI
+ timing.
+ Remarks:
+ Depending on compiler revisions, this function may delay for the exact time
+ specified. This shouldn't create a significant problem.
+ ***************************************************************************************/
+
+void Delayms(BYTE milliseconds)
+{
+ BYTE ms;
+ DWORD count;
+
+ ms = milliseconds;
+ while (ms--)
+ {
+ count = MILLISECDELAY;
+ while (count--);
+ }
+ Nop();
+ return;
+}
+
+
+/*****************************************************************************
+ Function:
+ void CloseSPIM (void)
+ Summary:
+ Disables the SPI module.
+ Conditions:
+ None.
+ Input:
+ None.
+ Return:
+ None.
+ Side Effects:
+ None.
+ Description:
+ Disables the SPI module.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+void CloseSPIM (void)
+{
+#if defined __C30__ || defined __C32__
+
+ SPISTAT &= 0x7FFF;
+
+#elif defined __18CXX
+
+ SPICON1 &= 0xDF;
+
+#endif
+}
+
+
+
+/*****************************************************************************
+ Function:
+ unsigned char WriteSPIM (unsigned char data_out)
+ Summary:
+ Writes data to the SD card.
+ Conditions:
+ None.
+ Input:
+ data_out - The data to write.
+ Return:
+ 0.
+ Side Effects:
+ None.
+ Description:
+ The WriteSPIM function will write a byte of data from the microcontroller to the
+ SD card.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+unsigned char WriteSPIM( unsigned char data_out )
+{
+#ifdef __PIC32MX__
+ BYTE clear;
+ putcSPI((BYTE)data_out);
+ clear = getcSPI();
+ return ( 0 ); // return non-negative#
+#elif defined __18CXX
+ BYTE clear;
+ clear = SPIBUF;
+ SPI_INTERRUPT_FLAG = 0;
+ SPIBUF = data_out;
+ if (SPICON1 & 0x80)
+ return -1;
+ else
+ while (!SPI_INTERRUPT_FLAG);
+ return 0;
+#else
+ BYTE clear;
+ SPIBUF = data_out; // write byte to SSP1BUF register
+ while( !SPISTAT_RBF ); // wait until bus cycle complete
+ clear = SPIBUF;
+ return ( 0 ); // return non-negative#
+#endif
+}
+
+
+
+/*****************************************************************************
+ Function:
+ BYTE MDD_SDSPI_ReadMedia (void)
+ Summary:
+ Reads a byte of data from the SD card.
+ Conditions:
+ None.
+ Input:
+ None.
+ Return:
+ The byte read.
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_ReadMedia function will read one byte from the SPI port.
+ Remarks:
+ This function replaces ReadSPI, since some implementations of that function
+ will initialize SSPBUF/SPIBUF to 0x00 when reading. The card expects 0xFF.
+ ***************************************************************************************/
+BYTE MDD_SDSPI_ReadMedia(void)
+{
+
+#ifdef __C32__
+
+ putcSPI((BYTE)0xFF);
+ return (BYTE)getcSPI();
+
+#elif defined __18CXX
+
+ BYTE clear;
+ clear = SPIBUF;
+ SPI_INTERRUPT_FLAG = 0;
+ SPIBUF = 0xFF;
+ while (!SPI_INTERRUPT_FLAG);
+ return SPIBUF;
+
+#else
+ SPIBUF = 0xFF; //Data Out - Logic ones
+ while(!SPISTAT_RBF); //Wait until cycle complete
+ return(SPIBUF); //Return with byte read
+#endif
+}
+
+/*****************************************************************************
+ Function:
+ void OpenSPIM (unsigned int sync_mode)
+ Summary:
+ Initializes the SPI module
+ Conditions:
+ None.
+ Input:
+ sync_mode - Sets synchronization
+ Return:
+ None.
+ Side Effects:
+ None.
+ Description:
+ The OpenSPIM function will enable and configure the SPI module.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+#ifdef __18CXX
+void OpenSPIM (unsigned char sync_mode)
+#else
+void OpenSPIM( unsigned int sync_mode)
+#endif
+{
+ SPISTAT = 0x0000; // power on state
+
+#ifndef __PIC32MX__
+ SPICON1 = 0x0000; // power on state
+ SPICON1 |= sync_mode; // select serial mode
+#endif
+
+#ifdef __18CXX
+ SPICON1 |= 0x80;
+ SPISTATbits.CKE = 1;
+#else
+ SPICON1bits.CKP = 1;
+ SPICON1bits.CKE = 0;
+#endif
+
+ SPICLOCK = 0;
+ SPIOUT = 0; // define SDO1 as output (master or slave)
+ SPIIN = 1; // define SDI1 as input (master or slave)
+ SPIENABLE = 1; // enable synchronous serial port
+}
+
+
+
+
+
+#ifdef __18CXX
+#if (GetSystemClock() >= 25600000)
+
+// Description: Delay value for the manual SPI clock
+#define MANUAL_SPI_CLOCK_VALUE 1
+
+/*****************************************************************************
+ Function:
+ unsigned char WriteSPIManual (unsigned char data_out)
+ Summary:
+ Write a character to the SD card with bit-bang SPI.
+ Conditions:
+ None.
+ Input:
+ data_out - Data to send.
+ Return:
+ 0.
+ Side Effects:
+ None.
+ Description:
+ Writes a character to the SD card.
+ Remarks:
+ The WriteSPIManual function is for use on a PIC18 when the clock speed is so
+ high that the maximum SPI clock divider cannot reduce the SPI clock speed below
+ the maximum SD card initialization speed.
+ ***************************************************************************************/
+unsigned char WriteSPIManual(unsigned char data_out)
+{
+ char i = data_out;
+ unsigned char clock;
+
+ ADCON1 = 0xFF;
+ SPICLOCKLAT = 0;
+ SPIOUTLAT = 1;
+ SPICLOCK = OUTPUT;
+ SPIOUT = OUTPUT;
+
+ if ((SPIOUTPORT != SPIOUTLAT) || (SPICLOCKPORT != SPICLOCKLAT))
+ return (-1);
+
+ // Perform loop operation iteratively to reduce discrepancy
+ // Bit 7
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x80)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 6
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x40)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 5
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x20)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 4
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x10)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 3
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x08)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 2
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x04)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 1
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x02)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ // Bit 0
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ if (i & 0x01)
+ SPIOUTLAT = 1;
+ else
+ SPIOUTLAT = 0;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+
+ SPICLOCKLAT = 0;
+
+ return 0;
+}
+
+
+/*****************************************************************************
+ Function:
+ BYTE ReadMediaManual (void)
+ Summary:
+ Reads a byte of data from the SD card.
+ Conditions:
+ None.
+ Input:
+ None.
+ Return:
+ The byte read.
+ Side Effects:
+ None.
+ Description:
+ The MDD_SDSPI_ReadMedia function will read one byte from the SPI port.
+ Remarks:
+ This function replaces ReadSPI, since some implementations of that function
+ will initialize SSPBUF/SPIBUF to 0x00 when reading. The card expects 0xFF.
+ This function is for use on a PIC18 when the clock speed is so high that the
+ maximum SPI clock prescaler cannot reduce the SPI clock below the maximum SD card
+ initialization speed.
+ ***************************************************************************************/
+BYTE ReadMediaManual (void)
+{
+ char i, result = 0x00;
+ unsigned char clock;
+
+ SPICLOCKLAT = 0;
+ SPIOUTLAT = 1;
+ SPICLOCK = OUTPUT;
+ SPIOUT = OUTPUT;
+ SPIIN = INPUT;
+
+ if ((SPIOUTPORT != SPIOUTLAT) || (SPICLOCKPORT != SPICLOCKLAT))
+ return (-1);
+
+ // Perform loop operation iteratively to reduce discrepancy
+ // Bit 7
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x80;
+
+ // Bit 6
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x40;
+
+ // Bit 5
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x20;
+
+ // Bit 4
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x10;
+
+ // Bit 3
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x08;
+
+ // Bit 2
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x04;
+
+ // Bit 1
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x02;
+
+ // Bit 0
+ SPICLOCKLAT = 0;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ SPICLOCKLAT = 1;
+ clock = MANUAL_SPI_CLOCK_VALUE;
+ while (clock--);
+ if (SPIINPORT)
+ result |= 0x01;
+
+ SPICLOCKLAT = 0;
+
+ return result;
+}//end ReadMedia
+
+#endif // End >25600000
+#endif // End __18CXX
+
+
+/*****************************************************************************
+ Function:
+ BYTE MDD_SDSPI_MediaInitialize (void)
+ Summary:
+ Initializes the SD card.
+ Conditions:
+ The MDD_MediaInitialize function pointer must be pointing to this function.
+ Input:
+ None.
+ Return Values:
+ TRUE - The card was successfully initialized
+ FALSE - Communication could not be established.
+ Side Effects:
+ None.
+ Description:
+ This function will send initialization commands to and SD card.
+ Remarks:
+ None.
+ ***************************************************************************************/
+
+BYTE MDD_SDSPI_MediaInitialize(void)
+{
+ WORD timeout;
+ BYTE status = TRUE;
+ MMC_RESPONSE response;
+#if defined __C30__ || defined __C32__
+ WORD spiconvalue = 0x0003;
+#endif
+
+ SD_CS = 1; //Initialize Chip Select line
+
+ //Media powers up in the open-drain mode and cannot handle a clock faster
+ //than 400kHz. Initialize SPI port to slower than 400kHz
+#if defined __C30__ || defined __C32__
+#ifdef __PIC32MX__
+ OpenSPI(SPI_START_CFG_1, SPI_START_CFG_2);
+ SPIBRG = SPICalutateBRG(GetPeripheralClock(), 400000);
+#else
+ // Calculate the prescaler needed for the clock
+ timeout = GetSystemClock() / 400000;
+ // if timeout is less than 400k and greater than 100k use a 1:1 prescaler
+ if (timeout == 0)
+ {
+ OpenSPIM (MASTER_ENABLE_ON | PRI_PRESCAL_1_1 | SEC_PRESCAL_1_1);
+ }
+ else
+ {
+ while (timeout != 0)
+ {
+ if (timeout > 8)
+ {
+ spiconvalue--;
+ // round up
+ if ((timeout % 4) != 0)
+ timeout += 4;
+ timeout /= 4;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ timeout--;
+
+ OpenSPIM (MASTER_ENABLE_ON | spiconvalue | ((~(timeout << 2)) & 0x1C));
+ }
+#endif
+
+
+ // let the card power on and initialize
+ Delayms(1);
+
+ //Media requires 80 clock cycles to startup [8 clocks/BYTE * 10 us]
+ for(timeout=0; timeout<10; timeout++)
+ mSend8ClkCycles();
+
+ SD_CS = 0;
+
+ Delayms(1);
+
+ // Send CMD0 to reset the media
+ response = SendMMCCmd(GO_IDLE_STATE,0x0);
+
+ if((response.r1._byte == MMC_BAD_RESPONSE) || ((response.r1._byte & 0xF7) != 0x01))
+ {
+ status = FALSE; // we have not got anything back from the card
+ SD_CS = 1; // deselect the devices
+
+ return status;
+ }
+
+ // According to spec cmd1 must be repeated until the card is fully initialized
+ timeout = 0xFFF;
+
+ do
+ {
+ response = SendMMCCmd(SEND_OP_COND,0x0);
+ timeout--;
+ }while(response.r1._byte != 0x00 && timeout != 0);
+
+ // see if it failed
+ if(timeout == 0)
+ {
+ status = FALSE; // we have not got anything back from the card
+
+ SD_CS = 1; // deselect the devices
+ }
+ else
+ {
+
+#else
+
+ // let the card power on and initialize
+ Delayms(1);
+
+ #if (GetSystemClock() < 25600000)
+
+ #if (GetSystemClock() < 1600000)
+ OpenSPIM (SYNC_MODE_FAST, BUS_MODE, SMP_PHASE);
+ #elif (GetSystemClock() < 6400000)
+ OpenSPIM (SYNC_MODE_MED, BUS_MODE, SMP_PHASE);
+ #else
+ OpenSPIM (SYNC_MODE_SLOW, BUS_MODE, SMP_PHASE);
+ #endif
+
+ // let the card power on and initialize
+ Delayms(1);
+
+ //Media requires 80 clock cycles to startup [8 clocks/BYTE * 10 us]
+ for(timeout=0; timeout<10; timeout++)
+ mSend8ClkCycles();
+
+ SD_CS = 0;
+
+ Delayms(1);
+
+ // Send CMD0 to reset the media
+ response = SendMMCCmd(GO_IDLE_STATE,0x0);
+
+ if((response.r1._byte == MMC_BAD_RESPONSE) || ((response.r1._byte & 0xF7) != 0x01))
+ {
+ status = FALSE; // we have not got anything back from the card
+ SD_CS = 1; // deselect the devices
+
+ return status;
+ }
+
+ // According to spec cmd1 must be repeated until the card is fully initialized
+ timeout = 0xFFF;
+
+ do
+ {
+ response = SendMMCCmd(SEND_OP_COND,0x0);
+ timeout--;
+ }while(response.r1._byte != 0x00 && timeout != 0);
+
+ #else
+
+ // Make sure the SPI module doesn't control the bus
+ SPICON1 = 0x00;
+
+ //Media requires 80 clock cycles to startup [8 clocks/BYTE * 10 us]
+ for(timeout=0; timeout<10; timeout++)
+ WriteSPIManual(0xFF);
+
+ SD_CS = 0;
+
+ Delayms(1);
+
+ // Send CMD0 to reset the media
+ response = SendMMCCmdManual (GO_IDLE_STATE, 0x0);
+
+ if ((response.r1._byte == MMC_BAD_RESPONSE) || ((response.r1._byte & 0xF7) != 0x01))
+ {
+ status = FALSE; // we have not got anything back from the card
+ SD_CS = 1; // deselect the devices
+
+ return status;
+ }
+
+ // According to the spec cmd1 must be repeated until the card is fully initialized
+ timeout = 0xFFF;
+
+ do
+ {
+ response = SendMMCCmdManual (SEND_OP_COND, 0x0);
+ timeout--;
+ }while(response.r1._byte != 0x00 && timeout != 0);
+ #endif
+
+ // see if it failed
+ if (timeout == 0)
+ {
+ status = FALSE; // we have not got anything back from the card
+ SD_CS = 1; // deselect the devices
+ }
+ else
+ {
+#endif
+
+ Delayms (2);
+
+ #ifdef __PIC32MX__
+ #if (GetSystemClock() <= 20000000)
+ SPIBRG = SPICalutateBRG(GetPeripheralClock(), 10000);
+ #else
+ SPIBRG = SPICalutateBRG(GetPeripheralClock(), SPI_FREQUENCY);
+ #endif
+ #else
+ OpenSPIM(SYNC_MODE_FAST);
+ #endif
+
+ // Turn off CRC7 if we can, might be an invalid cmd on some cards (CMD59)
+ response = SendMMCCmd(CRC_ON_OFF,0x0);
+
+ // Now set the block length to media sector size. It should be already
+ response = SendMMCCmd(SET_BLOCKLEN,MEDIA_SECTOR_SIZE);
+
+ for(timeout = 0xFF; timeout > 0 && MDD_SDSPI_SectorRead(0x0,NULL) != TRUE; timeout--)
+ {;}
+
+ // see if we had an issue
+ if(timeout == 0)
+ {
+ status = FALSE;
+ SD_CS = 1; // deselect the devices
+ }
+ }
+
+ return(status);
+}//end MediaInitialize
+
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/SD-SPI.d b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/SD-SPI.d new file mode 100644 index 00000000..b22968c6 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/SD-SPI.d @@ -0,0 +1,58 @@ +SD-SPI.o: SD-SPI.c FSIO.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h FSconfig.h \
+ C:/Microchip\ Solutions/Microchip/Include/Compiler.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/string.h \
+ HardwareProfile.h FSDefs.h SD-SPI.h FSConfig.h
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/SD-SPI.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/SD-SPI.h new file mode 100644 index 00000000..0b4c7c4b --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/SD-SPI.h @@ -0,0 +1,443 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: SD-SPI.h
+ * Dependencies: GenericTypeDefs.h
+ * FSconfig.h
+ * FSDefs.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#ifndef SDMMC_H
+#define SDMMC_H
+
+#include "GenericTypeDefs.h"
+#include "FSconfig.h"
+#include "FSDefs.h"
+
+
+#ifdef __18CXX
+ // Description: This macro is used to initialize a PIC18 SPI module with a 4x prescale divider
+ #define SYNC_MODE_FAST 0x00
+ // Description: This macro is used to initialize a PIC18 SPI module with a 16x prescale divider
+ #define SYNC_MODE_MED 0x01
+ // Description: This macro is used to initialize a PIC18 SPI module with a 64x prescale divider
+ #define SYNC_MODE_SLOW 0x02
+#elif defined __PIC32MX__
+ // Description: This macro is used to initialize a PIC32 SPI module
+ #define SYNC_MODE_FAST 0x3E
+ // Description: This macro is used to initialize a PIC32 SPI module
+ #define SYNC_MODE_SLOW 0x3C
+#else
+ // Description: This macro indicates the SPI enable bit for 16-bit PICs
+ #ifndef MASTER_ENABLE_ON
+ #define MASTER_ENABLE_ON 0x0020
+ #endif
+
+ // Description: This macro is used to initialize a 16-bit PIC SPI module
+ #ifndef SYNC_MODE_FAST
+ #define SYNC_MODE_FAST 0x3E
+ #endif
+ // Description: This macro is used to initialize a 16-bit PIC SPI module
+ #ifndef SYNC_MODE_SLOW
+ #define SYNC_MODE_SLOW 0x3C
+ #endif
+
+ // Description: This macro is used to initialize a 16-bit PIC SPI module secondary prescaler
+ #ifndef SEC_PRESCAL_1_1
+ #define SEC_PRESCAL_1_1 0x001c
+ #endif
+ // Description: This macro is used to initialize a 16-bit PIC SPI module primary prescaler
+ #ifndef PRI_PRESCAL_1_1
+ #define PRI_PRESCAL_1_1 0x0003
+ #endif
+#endif
+
+
+
+/*****************************************************************/
+/* Strcutures and defines */
+/*****************************************************************/
+
+
+// Description: This macro represents an SD card start token
+#define DATA_START_TOKEN 0xFE
+
+// Description: This macro represents an SD card data accepted token
+#define DATA_ACCEPTED 0x05
+
+// Description: This macro indicates that the SD card expects to transmit or receive more data
+#define MOREDATA !0
+
+// Description: This macro indicates that the SD card does not expect to transmit or receive more data
+#define NODATA 0
+
+// Description: This macro represents a floating SPI bus condition
+#define MMC_FLOATING_BUS 0xFF
+
+// Description: This macro represents a bad SD card response byte
+#define MMC_BAD_RESPONSE MMC_FLOATING_BUS
+
+// The SDMMC Commands
+
+// Description: This macro defines the command code to reset the SD card
+#define cmdGO_IDLE_STATE 0
+// Description: This macro defines the command code to initialize the SD card
+#define cmdSEND_OP_COND 1
+// Description: This macro defines the command code to get the Card Specific Data
+#define cmdSEND_CSD 9
+// Description: This macro defines the command code to get the Card Information
+#define cmdSEND_CID 10
+// Description: This macro defines the command code to stop transmission during a multi-block read
+#define cmdSTOP_TRANSMISSION 12
+// Description: This macro defines the command code to get the card status information
+#define cmdSEND_STATUS 13
+// Description: This macro defines the command code to set the block length of the card
+#define cmdSET_BLOCKLEN 16
+// Description: This macro defines the command code to read one block from the card
+#define cmdREAD_SINGLE_BLOCK 17
+// Description: This macro defines the command code to read multiple blocks from the card
+#define cmdREAD_MULTI_BLOCK 18
+// Description: This macro defines the command code to write one block to the card
+#define cmdWRITE_SINGLE_BLOCK 24
+// Description: This macro defines the command code to write multiple blocks to the card
+#define cmdWRITE_MULTI_BLOCK 25
+// Description: This macro defines the command code to set the address of the start of an erase operation
+#define cmdTAG_SECTOR_START 32
+// Description: This macro defines the command code to set the address of the end of an erase operation
+#define cmdTAG_SECTOR_END 33
+// Description: This macro defines the command code to erase all previously selected blocks
+#define cmdERASE 38
+// Description: This macro defines the command code to begin application specific command inputs
+#define cmdAPP_CMD 55
+// Description: This macro defines the command code to get the OCR register information from the card
+#define cmdREAD_OCR 58
+// Description: This macro defines the command code to disable CRC checking
+#define cmdCRC_ON_OFF 59
+
+
+// Description: Enumeration of different SD response types
+typedef enum
+{
+ R1, // R1 type response
+ R1b, // R1b type response
+ R2, // R2 type response
+ R3 // R3 type response
+}RESP;
+
+// Summary: SD card command data structure
+// Description: The typMMC_CMD structure is used to create a command table of information needed for each relevant SD command
+typedef struct
+{
+ BYTE CmdCode; // The command code
+ BYTE CRC; // The CRC value for that command
+ RESP responsetype; // The response type
+ BYTE moredataexpected; // Set to MOREDATA or NODATA, depending on whether more data is expected or not
+} typMMC_CMD;
+
+
+// Summary: An SD command packet
+// Description: This union represents different ways to access an SD card command packet
+typedef union
+{
+ // This structure allows array-style access of command bytes
+ struct
+ {
+ #ifdef __18CXX
+ BYTE field[6]; // BYTE array
+ #else
+ BYTE field[7];
+ #endif
+ };
+ // This structure allows byte-wise access of packet command bytes
+ struct
+ {
+ BYTE crc; // The CRC byte
+ #if defined __C30__
+ BYTE c30filler; // Filler space (since bitwise declarations can't cross a WORD boundary)
+ #elif defined __C32__
+ BYTE c32filler[3]; // Filler space (since bitwise declarations can't cross a DWORD boundary)
+ #endif
+
+ BYTE addr0; // Address byte 0
+ BYTE addr1; // Address byte 1
+ BYTE addr2; // Address byte 2
+ BYTE addr3; // Address byte 3
+ BYTE cmd; // Command code byte
+ };
+ // This structure allows bitwise access to elements of the command bytes
+ struct
+ {
+ BYTE END_BIT:1; // Packet end bit
+ BYTE CRC7:7; // CRC value
+ DWORD address; // Address
+ BYTE CMD_INDEX:6; // Command code
+ BYTE TRANSMIT_BIT:1; // Transmit bit
+ BYTE START_BIT:1; // Packet start bit
+ };
+} CMD_PACKET;
+
+
+// Summary: The format of an R1 type response
+// Description: This union represents different ways to access an SD card R1 type response packet.
+typedef union
+{
+ BYTE _byte; // Byte-wise access
+ // This structure allows bitwise access of the response
+ struct
+ {
+ unsigned IN_IDLE_STATE:1; // Card is in idle state
+ unsigned ERASE_RESET:1; // Erase reset flag
+ unsigned ILLEGAL_CMD:1; // Illegal command flag
+ unsigned CRC_ERR:1; // CRC error flag
+ unsigned ERASE_SEQ_ERR:1; // Erase sequence error flag
+ unsigned ADDRESS_ERR:1; // Address error flag
+ unsigned PARAM_ERR:1; // Parameter flag
+ unsigned B7:1; // Unused bit 7
+ };
+} RESPONSE_1;
+
+// Summary: The format of an R2 type response
+// Description: This union represents different ways to access an SD card R2 type response packet
+typedef union
+{
+ WORD _word;
+ struct
+ {
+ BYTE _byte0;
+ BYTE _byte1;
+ };
+ struct
+ {
+ unsigned IN_IDLE_STATE:1;
+ unsigned ERASE_RESET:1;
+ unsigned ILLEGAL_CMD:1;
+ unsigned CRC_ERR:1;
+ unsigned ERASE_SEQ_ERR:1;
+ unsigned ADDRESS_ERR:1;
+ unsigned PARAM_ERR:1;
+ unsigned B7:1;
+ unsigned CARD_IS_LOCKED:1;
+ unsigned WP_ERASE_SKIP_LK_FAIL:1;
+ unsigned ERROR:1;
+ unsigned CC_ERROR:1;
+ unsigned CARD_ECC_FAIL:1;
+ unsigned WP_VIOLATION:1;
+ unsigned ERASE_PARAM:1;
+ unsigned OUTRANGE_CSD_OVERWRITE:1;
+ };
+} RESPONSE_2;
+
+// Summary: A union of responses from an SD card
+// Description: The MMC_RESPONSE union represents any of the possible responses that an SD card can return after
+// being issued a command.
+typedef union
+{
+ RESPONSE_1 r1;
+ RESPONSE_2 r2;
+}MMC_RESPONSE;
+
+
+// Summary: A description of the card specific data register
+// Description: This union represents different ways to access information in a packet with SD card CSD informaiton. For more
+// information on the CSD register, consult an SD card user's manual.
+typedef union
+{
+ struct
+ {
+ DWORD _u320;
+ DWORD _u321;
+ DWORD _u322;
+ DWORD _u323;
+ };
+ struct
+ {
+ BYTE _byte[16];
+ };
+ struct
+ {
+ unsigned NOT_USED :1;
+ unsigned CRC :7;
+ unsigned ECC :2;
+ unsigned FILE_FORMAT :2;
+ unsigned TMP_WRITE_PROTECT :1;
+ unsigned PERM_WRITE_PROTECT :1;
+ unsigned COPY :1;
+ unsigned FILE_FORMAT_GRP :1;
+ unsigned RESERVED_1 :5;
+ unsigned WRITE_BL_PARTIAL :1;
+ unsigned WRITE_BL_LEN_L :2;
+ unsigned WRITE_BL_LEN_H :2;
+ unsigned R2W_FACTOR :3;
+ unsigned DEFAULT_ECC :2;
+ unsigned WP_GRP_ENABLE :1;
+ unsigned WP_GRP_SIZE :5;
+ unsigned ERASE_GRP_SIZE_L :3;
+ unsigned ERASE_GRP_SIZE_H :2;
+ unsigned SECTOR_SIZE :5;
+ unsigned C_SIZE_MULT_L :1;
+ unsigned C_SIZE_MULT_H :2;
+ unsigned VDD_W_CURR_MAX :3;
+ unsigned VDD_W_CUR_MIN :3;
+ unsigned VDD_R_CURR_MAX :3;
+ unsigned VDD_R_CURR_MIN :3;
+ unsigned C_SIZE_L :2;
+ unsigned C_SIZE_H :8;
+ unsigned C_SIZE_U :2;
+ unsigned RESERVED_2 :2;
+ unsigned DSR_IMP :1;
+ unsigned READ_BLK_MISALIGN :1;
+ unsigned WRITE_BLK_MISALIGN :1;
+ unsigned READ_BL_PARTIAL :1;
+ unsigned READ_BL_LEN :4;
+ unsigned CCC_L :4;
+ unsigned CCC_H :8;
+ unsigned TRAN_SPEED :8;
+ unsigned NSAC :8;
+ unsigned TAAC :8;
+ unsigned RESERVED_3 :2;
+ unsigned SPEC_VERS :4;
+ unsigned CSD_STRUCTURE :2;
+ };
+} CSD;
+
+
+// Summary: A description of the card information register
+// Description: This union represents different ways to access information in a packet with SD card CID register informaiton. For more
+// information on the CID register, consult an SD card user's manual.
+typedef union
+{
+ struct
+ {
+ DWORD _u320;
+ DWORD _u321;
+ DWORD _u322;
+ DWORD _u323;
+ };
+ struct
+ {
+ BYTE _byte[16];
+ };
+ struct
+ {
+ unsigned NOT_USED :1;
+ unsigned CRC :7;
+ unsigned MDT :8;
+ DWORD PSN;
+ unsigned PRV :8;
+ char PNM[6];
+ WORD OID;
+ unsigned MID :8;
+ };
+} CID;
+
+#ifndef FALSE
+ #define FALSE 0
+#endif
+#ifndef TRUE
+ #define TRUE !FALSE
+#endif
+
+#define INPUT 1
+#define OUTPUT 0
+
+
+// Description: A delay prescaler
+#define DELAY_PRESCALER (BYTE) 8
+
+// Description: An approximation of the number of cycles per delay loop of overhead
+#define DELAY_OVERHEAD (BYTE) 5
+
+// Description: An approximate calculation of how many times to loop to delay 1 ms in the Delayms function
+#define MILLISECDELAY (WORD) ((GetInstructionClock()/DELAY_PRESCALER/(WORD)1000) - DELAY_OVERHEAD)
+
+
+// Summary: An enumeration of SD commands
+// Description: This enumeration corresponds to the position of each command in the sdmmc_cmdtable array
+// These macros indicate to the SendMMCCmd function which element of the sdmmc_cmdtable array
+// to retrieve command code information from.
+typedef enum
+{
+ GO_IDLE_STATE,
+ SEND_OP_COND,
+ SEND_CSD,
+ SEND_CID,
+ STOP_TRANSMISSION,
+ SEND_STATUS,
+ SET_BLOCKLEN,
+ READ_SINGLE_BLOCK,
+ READ_MULTI_BLOCK,
+ WRITE_SINGLE_BLOCK,
+ WRITE_MULTI_BLOCK,
+ TAG_SECTOR_START,
+ TAG_SECTOR_END,
+ ERASE,
+ APP_CMD,
+ READ_OCR,
+ CRC_ON_OFF
+}sdmmc_cmd;
+
+
+
+/***************************************************************************/
+/* Macros */
+/***************************************************************************/
+
+// Description: A macro to send clock cycles to dummy-read the CRC
+#define mReadCRC() WriteSPIM(0xFF);WriteSPIM(0xFF);
+
+// Description: A macro to send clock cycles to dummy-write the CRC
+#define mSendCRC() WriteSPIM(0xFF);WriteSPIM(0xFF);
+
+// Description: A macro to send 8 clock cycles for SD timing requirements
+#define mSend8ClkCycles() WriteSPIM(0xFF);
+
+/*****************************************************************************/
+/* Prototypes */
+/*****************************************************************************/
+
+DWORD MDD_SDSPI_ReadCapacity(void);
+WORD MDD_SDSPI_ReadSectorSize(void);
+void MDD_SDSPI_InitIO(void);
+
+BYTE MDD_SDSPI_MediaDetect(void);
+BYTE MDD_SDSPI_MediaInitialize(void);
+BYTE MDD_SDSPI_SectorRead(DWORD sector_addr, BYTE* buffer);
+BYTE MDD_SDSPI_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero);
+
+BYTE MDD_SDSPI_WriteProtectState(void);
+BYTE MDD_SDSPI_ShutdownMedia(void);
+
+#if defined __C30__ || defined __C32__
+ extern BYTE ReadByte( BYTE* pBuffer, WORD index );
+ extern WORD ReadWord( BYTE* pBuffer, WORD index );
+ extern DWORD ReadDWord( BYTE* pBuffer, WORD index );
+#endif
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Screens.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Screens.h new file mode 100644 index 00000000..a5322eed --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Screens.h @@ -0,0 +1,183 @@ +/**********************************************************************
+ *************************** Screens.h ******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+/***********************************************************/
+// Variable Declaration
+/***********************************************************/
+
+//RapMan logo
+const unsigned char RAPMAN_LOGO[1024] = {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0xFF,0xFF,0x63,0x63,0xE3,0xE3,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC7,0xC7,0xC6,0xC6,0xFF,0xFF,0x06,0x06,0x06,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x40,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x71,0x71,0xF1,0xF1,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x00,0x00,0x00,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF0,0x00,0x00,0x04,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0x1C,0x1C,0x1C,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF0,0x00,0x00,0xFF,0xFF,0xFF,0x0F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,0xE0,0x00,0xE0,0xFC,0x3F,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0x9C,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF0,0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0x1C,0x1C,0x1C,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF0,0x00,0x00,
+0x00,0x00,0x00,0x40,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,0x00,0x07,0x3F,0x7F,0x7F,0x7F,0x7F,0x7C,0x70,0x40,0x00,0x3F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x71,0x71,0x71,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x70,0x70,0x70,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F,0x00,0x40,0x7F,0x7F,0x7F,0x00,0x00,0x03,0x1F,0x7F,0x7F,0x7F,0x7F,0x7F,0x0F,0x01,0x00,0x40,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,0x00,0x3F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x71,0x71,0x71,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,0x40,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,0x40,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x40,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+//Bits From Bytes logo with globe
+const unsigned char BfB_LOGO[1024] = {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x60,0x30,0x10,0x88,0xE4,0x54,0x6E,0x6E,0x26,0xF3,0x2F,0x27,0x23,0x23,0x27,0x2F,0xF3,0x26,0x6E,0x56,0x64,0xCC,0x98,0x30,0x20,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFC,0x47,0x26,0x32,0xF9,0x3F,0x10,0x08,0x08,0x08,0xF8,0x0F,0x09,0x08,0x08,0x08,0x08,0x08,0x08,0x09,0xFF,0x08,0x08,0x08,0x10,0x17,0x3D,0xF3,0x26,0x65,0x5F,0xFC,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x74,0xC8,0x88,0x10,0x7F,0xD0,0x30,0x20,0x60,0x60,0x7F,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x60,0x60,0x20,0x30,0x10,0xF0,0x1F,0x90,0xD8,0xE8,0x7C,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0D,0x3B,0x27,0x6E,0x5C,0xA8,0xC8,0x88,0x97,0x7C,0xD0,0x90,0x10,0x10,0x90,0xD0,0x3C,0x97,0xD8,0xE8,0xB8,0xCC,0x67,0x37,0x1B,0x0D,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x40,0x40,0x40,0xC0,0xC0,0x80,0x00,0xC0,0x00,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0xC0,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x80,0xC0,0xC0,0xC1,0xC1,0xC1,0x81,0x03,0x03,0xC3,0x83,0x03,0x01,0x01,0x01,0x00,0x00,0x80,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x40,0x40,0x40,0xC0,0xC0,0x80,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x80,0xC0,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0xC0,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x26,0x22,0x26,0x36,0x1F,0x0F,0x00,0x3F,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x33,0x33,0x34,0x34,0x34,0x3C,0x18,0x00,0x00,0x00,0x00,0x3F,0x3D,0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x3F,0x3F,0x06,0x0E,0x1E,0x1E,0x36,0x27,0x00,0x06,0x1F,0x30,0x30,0x30,0x30,0x30,0x1F,0x06,0x00,0x3F,0x03,0x0F,0x1C,0x38,0x38,0x1C,0x0F,0x03,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x26,0x22,0x26,0x36,0x1F,0x0F,0x00,0x00,0x00,0x01,0x03,0x3E,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x1F,0x1F,0x34,0x34,0x34,0x34,0x34,0x34,0x00,0x33,0x33,0x34,0x34,0x34,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0xE0,0xF0,0xF8,0x18,0x18,0xB0,0xA0,0x00,0xE0,0xF0,0xF8,0x18,0xF8,0xF0,0xE0,0x00,0xF8,0xF8,0xF8,0x10,0xF8,0xF8,0xF0,0x18,0xF8,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x00,0x00,0x01,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x01,0x00,0x00,0x03,0x03,0x03,0x00,0x03,0x03,0x03,0x00,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+//Extruder Screen
+const unsigned char EXTRUDER_SCREEN[1024] = {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xFC,0x03,0x00,0xC0,0xC0,0xC0,0xC0,0x00,0x03,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x05,0x02,0x00,0x3C,0x42,0x81,0x81,0x81,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x0E,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x04,0x04,0x00,0x00,0x32,0x4A,0x4A,0x7C,0x00,0x7E,0x04,0x02,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x63,0x1C,0x33,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0x08,0xF0,0x00,0x01,0x0E,0x30,0x40,0x88,0x04,0x04,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x30,0x0E,0x01,0xE0,0x10,0x90,0x20,0x00,0xE0,0x10,0x10,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,
+0x80,0xC0,0xFF,0xF0,0xF8,0xFF,0xFF,0xFF,0xFF,0xF8,0xF0,0xFF,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x04,0x04,0x04,0x04,0x04,0x02,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x07,0x09,0x08,0x07,0x00,0x07,0x08,0x08,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x05,0x02,0x00,0x3C,0x42,0x81,0x81,0x81,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x09,0x19,0x29,0x46,0x80,0xFF,0x11,0x11,0x11,0x0E,0x00,0xFF,0x06,0x78,0x80,0x78,0x06,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+//TextFont5x7
+//Font def for characters 5x7
+const unsigned char TEXT[51][5] ={0x00, 0x00, 0x00, 0x00, 0x00, // SPACE
+ 0x00, 0x00, 0x5F, 0x00, 0x00, // !
+ 0x00, 0x03, 0x00, 0x03, 0x00, // "
+ 0x14, 0x3E, 0x14, 0x3E, 0x14, // #
+ 0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
+ 0x43, 0x33, 0x08, 0x66, 0x61, // %
+ 0x36, 0x49, 0x55, 0x22, 0x50, // &
+ 0x00, 0x05, 0x03, 0x00, 0x00, // '
+ 0x00, 0x1C, 0x22, 0x41, 0x00, // (
+ 0x00, 0x41, 0x22, 0x1C, 0x00, // )
+ 0x14, 0x08, 0x3E, 0x08, 0x14, // *
+ 0x08, 0x08, 0x3E, 0x08, 0x08, // +
+ 0x00, 0x50, 0x30, 0x00, 0x00, // ,
+ 0x08, 0x08, 0x08, 0x08, 0x08, // -
+ 0x00, 0x60, 0x60, 0x00, 0x00, // .
+ 0x20, 0x10, 0x08, 0x04, 0x02, // /
+ 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
+ 0x04, 0x02, 0x7F, 0x00, 0x00, // 1
+ 0x42, 0x61, 0x51, 0x49, 0x46, // 2
+ 0x22, 0x41, 0x49, 0x49, 0x36, // 3
+ 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
+ 0x27, 0x45, 0x45, 0x45, 0x39, // 5
+ 0x3E, 0x49, 0x49, 0x49, 0x32, // 6
+ 0x01, 0x01, 0x71, 0x09, 0x07, // 7
+ 0x36, 0x49, 0x49, 0x49, 0x36, // 8
+ 0x26, 0x49, 0x49, 0x49, 0x3E, // 9
+ 0x00, 0x36, 0x36, 0x00, 0x00, // :
+ 0x00, 0x56, 0x36, 0x00, 0x00, // ;
+ 0x08, 0x14, 0x22, 0x41, 0x00, // <
+ 0x14, 0x14, 0x14, 0x14, 0x14, // =
+ 0x00, 0x41, 0x22, 0x14, 0x08, // >
+ 0x02, 0x01, 0x51, 0x09, 0x06, // ?
+ 0x3E, 0x41, 0x59, 0x55, 0x5E, // @
+ 0x7E, 0x09, 0x09, 0x09, 0x7E, // A
+ 0x7F, 0x49, 0x49, 0x49, 0x36, // B
+ 0x3E, 0x41, 0x41, 0x41, 0x22, // C
+ 0x7F, 0x41, 0x41, 0x41, 0x3E, // D
+ 0x7F, 0x49, 0x49, 0x49, 0x41, // E
+ 0x7F, 0x09, 0x09, 0x09, 0x01, // F
+ 0x3E, 0x41, 0x41, 0x49, 0x3A, // G
+ 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
+ 0x00, 0x41, 0x7F, 0x41, 0x00, // I
+ 0x30, 0x40, 0x40, 0x40, 0x3F, // J
+ 0x7F, 0x08, 0x14, 0x22, 0x41, // K
+ 0x7F, 0x40, 0x40, 0x40, 0x40, // L
+ 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
+ 0x7F, 0x02, 0x04, 0x08, 0x7F, // N
+ 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
+ 0x7F, 0x09, 0x09, 0x09, 0x06, // P
+ 0x1E, 0x21, 0x21, 0x21, 0x5E, // Q
+ 0x7F, 0x09, 0x09, 0x09, 0x76};// R
+
+const unsigned char TEXT2[44][5]={ 0x26, 0x49, 0x49, 0x49, 0x32, // S
+ 0x01, 0x01, 0x7F, 0x01, 0x01, // T
+ 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
+ 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
+ 0x7F, 0x20, 0x10, 0x20, 0x7F, // W
+ 0x41, 0x22, 0x1C, 0x22, 0x41, // X
+ 0x07, 0x08, 0x70, 0x08, 0x07, // Y
+ 0x61, 0x51, 0x49, 0x45, 0x43, // Z
+ 0x00, 0x7F, 0x41, 0x00, 0x00, // [
+ 0x02, 0x04, 0x08, 0x10, 0x20, // \
+ 0x00, 0x00, 0x41, 0x7F, 0x00, // ]
+ 0x04, 0x02, 0x01, 0x02, 0x04, // ^
+ 0x40, 0x40, 0x40, 0x40, 0x40, // _
+ 0x00, 0x01, 0x02, 0x04, 0x00, // `
+ 0x20, 0x54, 0x54, 0x54, 0x78, // a
+ 0x7F, 0x44, 0x44, 0x44, 0x38, // b
+ 0x38, 0x44, 0x44, 0x44, 0x44, // c
+ 0x38, 0x44, 0x44, 0x44, 0x7F, // d
+ 0x38, 0x54, 0x54, 0x54, 0x18, // e
+ 0x04, 0x04, 0x7E, 0x05, 0x05, // f
+ 0x08, 0x54, 0x54, 0x54, 0x3C, // g
+ 0x7F, 0x08, 0x04, 0x04, 0x78, // h
+ 0x00, 0x44, 0x7D, 0x40, 0x00, // i
+ 0x20, 0x40, 0x44, 0x3D, 0x00, // j
+ 0x7F, 0x10, 0x28, 0x44, 0x00, // k
+ 0x00, 0x41, 0x7F, 0x40, 0x00, // l
+ 0x7C, 0x04, 0x78, 0x04, 0x78, // m
+ 0x7C, 0x08, 0x04, 0x04, 0x78, // n
+ 0x38, 0x44, 0x44, 0x44, 0x38, // o
+ 0x7C, 0x14, 0x14, 0x14, 0x08, // p
+ 0x08, 0x14, 0x14, 0x14, 0x7C, // q
+ 0x00, 0x7C, 0x08, 0x04, 0x04, // r
+ 0x48, 0x54, 0x54, 0x54, 0x20, // s
+ 0x04, 0x04, 0x3F, 0x44, 0x44, // t
+ 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
+ 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
+ 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
+ 0x44, 0x28, 0x10, 0x28, 0x44, // x
+ 0x0C, 0x50, 0x50, 0x50, 0x3C, // y
+ 0x44, 0x64, 0x54, 0x4C, 0x44, // z
+ 0x00, 0x08, 0x36, 0x41, 0x41, // {
+ 0x00, 0x00, 0x7F, 0x00, 0x00, // |
+ 0x41, 0x41, 0x36, 0x08, 0x00, // }
+ 0x02, 0x01, 0x02, 0x04, 0x02 // ~
+ };
+
+
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Stepper.c b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Stepper.c new file mode 100644 index 00000000..7e1f5d74 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Stepper.c @@ -0,0 +1,1033 @@ +/**********************************************************************
+ *************************** Stepper.c ******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+#include <plib.h> //required for interrupt handlers
+#include <stdio.h>
+#include <stdlib.h>
+#include <p32xxxx.h>
+#include <math.h>
+#include <inttypes.h>
+#include "Stepper.h"
+#include "Enviroment.h" //to import button defs
+#include "Extruder.h"
+#include "OLED.h"
+
+#define X_LEFT 1
+#define X_RIGHT 0
+#define Z_DOWN 1
+#define Z_UP 0
+#define Y_FORWARD 1
+#define Y_BACK 0
+
+#define VERY_SLOW_MOVE 60000 //Sets the speed of the start speed in manual move mode
+#define HOME_SPEED_X_Y 1000
+#define HOME_SPEED_X_Y_SET 60000
+#define HOME_SPEED_Z 500
+#define HOME_SPEED_Z_SET 5000
+
+#define PRESSED 0
+#define NOT_PRESSED 1
+
+#define X_HOME_MM -135
+#define Y_HOME_MM 100
+#define Z_HOME_MM 0
+
+//Internal Functions
+int f_to_ul(float fNumber); //float to unsigned long
+signed int f_to_sl(float fNumber); //float to signed long
+void Bresenham_3D_Line(signed int x1, signed int y1, signed int z1,signed int x2, signed int y2, signed int z2);
+void AddToStepBuffer(unsigned char SData, char xs, char ys);
+void Stepper_SaveValues(void);
+
+//Module Globals
+
+int S_M_Code; //Stepper M code
+
+int xyrate = 0; //Used when x and y steps occur together
+int ZFeed_Rate = 0; //always do rapid z move
+
+float Delta_X; //Used to hold movement data
+float Delta_Y;
+float Delta_Z;
+
+float Save_X = 0; //Last used coordinate saved here.
+float Save_Y = 0;
+float Save_Z = 0;
+float Save2_X = 0; //2nd to Last used coordinate saved here.
+float Save2_Y = 0;
+float Save2_Z = 0;
+float Save3_X = 0; //3nd to Last used coordinate saved here.
+float Save3_Y = 0;
+float Save3_Z = 0;
+
+//Step value coordinates
+float X_Steps,Y_Steps,Z_Steps; //Float value of steps
+signed long lX_Steps,lY_Steps,lZ_Steps; //Long integer values of steps
+signed long lSaveSteps_X, lSaveSteps_Y, lSaveSteps_Z;
+signed long lHomeStepsX, lHomeStepsY, lHomeStepsZ; //Stores the machine home coordinates
+PRIVATE signed int OffsetSteps_X;//Stores the number of steps offset from absolute coordinate
+PRIVATE signed int OffsetSteps_Y;
+PRIVATE signed int OffsetSteps_Z;
+
+//Globals for the step circular buffer
+unsigned char SBuf; //Step buffer Flag
+int SBR, SBW; //Buffer pointers
+// circular buffer
+int SCB[ SB_SIZE]; //Step circular buffer
+// Buffer status
+volatile int SBReady;
+int SBCode; //Byte from buffer Only used in stepper Interrupt
+unsigned char BufferEmpty = 1; //Flags Buffer empty = 1
+
+int StepRPM_Setting = 30, PR4_Setting = 65535, StepperInt_Cycle = 0, ManualStepperInt_Cycle = 0;//, Direction = CCW;
+
+int Set_X_Dir, Set_Y_Dir, Set_Z_Dir;
+char moveX = 0, moveY = 0, moveZ = 0;
+int Manual_Mode_Set = !TRUE;
+int FirstPass = TRUE;
+
+//Functions
+/******************************************************************/
+void Manual_Mode(char ShowPos)
+{
+//ShowPos show position on OLED = 1 or not = 0
+unsigned char AsciiString[9];
+float Xmm=0,Ymm=0,Zmm=0;
+
+ while (SBR!=SBW); //wait for step buffer to empty
+ mT4IntEnable(!TRUE); //Disable T4 step buffer interrput
+ Feed_Rate = VERY_SLOW_MOVE; //Set speed to slow
+ moveX = !TRUE; //Turn off all steppers
+ moveY = !TRUE;
+ moveZ = !TRUE;
+ Axis_Stepper_Motors(On);
+ OLED_Manual_Screen();
+
+ while(!XPlusRight_Btn); //Wait for menu selection key to be released
+ while(Manual_Select == NOT_PRESSED){
+ Manual_Mode_Set = TRUE;
+
+ if(Feed_Rate>1000)Feed_Rate -=75; //Ramping of the move speed
+ if(Feed_Rate>100)Feed_Rate -=5; //the longer the button is
+ if(Feed_Rate<400) Feed_Rate = 400; //pressed
+
+ //Set direction & move
+ if (!XPlusRight_Btn) { Set_X_Dir = X_RIGHT; moveX =TRUE;}
+ if (!XMinusLeft_Btn) { Set_X_Dir = X_LEFT; moveX =TRUE;}
+ if (XPlusRight_Btn && XMinusLeft_Btn) moveX = !TRUE;
+ if (!YPlusTop_Btn) { Set_Y_Dir = Y_BACK; moveY =TRUE;}
+ if (!YMinusBot_Btn) { Set_Y_Dir = Y_FORWARD; moveY =TRUE;}
+ if (YPlusTop_Btn && YMinusBot_Btn) moveY = !TRUE;
+ if (!ZPlus_up_Btn) { Set_Z_Dir = Z_UP; moveZ =TRUE;}
+ if (!ZMinus_down_Btn){ Set_Z_Dir = Z_DOWN; moveZ =TRUE;}
+ if (ZPlus_up_Btn && ZMinus_down_Btn) moveZ = !TRUE;
+ if (!moveX && !moveY && !moveZ) Feed_Rate = VERY_SLOW_MOVE; //Re-set move speed
+
+ //Report current position to OLED.
+ if(ShowPos){
+ Xmm = (float)lSaveSteps_X / StepsPer_mm;
+ sprintf(AsciiString, "%6.2f",Xmm); // Converts number to text
+ OLED_FastText57(4, 64, AsciiString,0); // Write the new number
+ Ymm = (float)lSaveSteps_Y / StepsPer_mm;
+ sprintf(AsciiString, "%6.2f",Ymm); // Converts number to text
+ OLED_FastText57(5, 64, AsciiString,0); // Write the new number
+ Zmm = (float)lSaveSteps_Z / ZStepsPer_mm;
+ sprintf(AsciiString, "%6.2f",Zmm); // Converts number to text
+ OLED_FastText57(6, 64, AsciiString,0); // Write the new number
+ }
+ }
+ Manual_Mode_Set = !TRUE;
+ mT4IntEnable(!TRUE); //Disable T4 step buffer interrput
+}//ManualMode
+
+/******************************************************************/
+void Axis_Stepper_Motors(int on_off)
+{
+ if(on_off == On){
+ X_Disable = !TRUE; //to enable X axis
+ Y_Disable = !TRUE; //to enable Y axis
+ Z_Disable = !TRUE; //to enable Z axis
+ mT4IntEnable(TRUE); //Turn on interrupts
+ }
+ else{
+ X_Disable = TRUE; //to disable X axis
+ Y_Disable = TRUE; //to disable Y axis
+ Z_Disable = TRUE; //to disable Z axis
+ mT4IntEnable(!TRUE); //Turn off interrupts
+ }
+}
+/******************************************************************/
+int RapMan_Home(void)
+{
+int i;
+ OLED_Home_Screen();
+
+ moveX = !TRUE; //Turn off all steppers
+ moveY = !TRUE;
+ moveZ = !TRUE;
+ Stepper_InitIO();
+ Axis_Stepper_Motors(On);
+ Manual_Mode_Set = TRUE;
+
+ Feed_Rate = HOME_SPEED_Z; //Move tool down to prevent crash
+ OLED_FastText57(3, 0, "Z DOWN ",0);
+ Set_Z_Dir = Z_DOWN;
+ moveZ = TRUE;
+ for(i=0;i<200000;i++);
+ moveZ = !TRUE;
+
+ OLED_FastText57(3, 0, "Y FORWARD ",0);
+ Feed_Rate = HOME_SPEED_X_Y; //Move tool forward to prevent crash
+ Set_Y_Dir = Y_FORWARD;
+ moveY = TRUE;
+ for(i=0;i<60000;i++);
+ moveY = !TRUE;
+
+ OLED_FastText57(3, 0, "HOME X ",0); //Display operation
+ Feed_Rate = HOME_SPEED_X_Y; //Set homing speed
+ while(!X_HomeSwitch && Manual_Select){ //Keep homing until the switch is pressed
+ Set_X_Dir = X_LEFT; //Direction of home
+ while(!X_HomeSwitch && Manual_Select)moveX = TRUE;
+ moveX = !TRUE;
+ for(i=0;i<20000;i++); //Wait to allow de-bounce of switch/ noise
+ }
+ moveX=TRUE; //Move a little more to ensure full switch
+ for(i=0;i<10000;i++);
+ moveX = !TRUE;
+
+ Feed_Rate = HOME_SPEED_X_Y_SET; //At slow speed pull away from switch
+ while(X_HomeSwitch && Manual_Select){ //to get accurate switch point
+ Set_X_Dir = X_RIGHT;
+ while(X_HomeSwitch && Manual_Select)moveX = TRUE;
+ moveX = !TRUE;
+ for(i=0;i<2000;i++); //Wait to allow de-bounce of switch/ noise
+ lSaveSteps_X = X_HOME_MM * StepsPer_mm; //*************HOME X
+ lHomeStepsX = lSaveSteps_X;
+ }
+
+ OLED_FastText57(3, 0, "HOME Y ",0);
+ Feed_Rate = HOME_SPEED_X_Y;
+ while(!Y_HomeSwitch && Manual_Select){
+ Set_Y_Dir = Y_BACK;
+ while(!Y_HomeSwitch && Manual_Select)moveY = TRUE;
+ moveY = !TRUE;
+ for(i=0;i<20000;i++);
+ }
+ moveY=TRUE;
+ for(i=0;i<10000;i++);
+ moveY = !TRUE;
+
+ Feed_Rate = HOME_SPEED_X_Y_SET;
+ while(Y_HomeSwitch && Manual_Select){
+ Set_Y_Dir = Y_FORWARD;
+ while(Y_HomeSwitch && Manual_Select)moveY = TRUE;
+ moveY = !TRUE;
+ for(i=0;i<2000;i++);
+ lSaveSteps_Y = Y_HOME_MM * StepsPer_mm;//*************HOME Y
+ lHomeStepsY = lSaveSteps_Y;
+ }
+
+ OLED_FastText57(3, 0, "HOME Z ",0);
+ Feed_Rate = HOME_SPEED_Z;
+ while(!Z_HomeSwitch && Manual_Select){
+ Set_Z_Dir = Z_UP;
+ while(!Z_HomeSwitch && Manual_Select)moveZ = TRUE;
+ moveZ = !TRUE;
+ for(i=0;i<2000;i++);
+ }
+ moveZ=TRUE;
+ for(i=0;i<10000;i++);
+ moveZ = !TRUE;
+
+ Feed_Rate = HOME_SPEED_Z_SET;
+ while(Z_HomeSwitch && Manual_Select){
+ Set_Z_Dir = Z_DOWN;
+ while(Z_HomeSwitch && Manual_Select)moveZ = TRUE;
+ moveZ = !TRUE;
+ for(i=0;i<2000;i++);
+ lSaveSteps_Z = Z_HOME_MM;//*************HOME Z
+ lHomeStepsZ = lSaveSteps_Z;
+ }
+ Manual_Mode_Set = !TRUE;
+ mT4IntEnable(!TRUE);
+ if(!Manual_Select)
+ {
+ OLED_FastText57(3, 0, "HOME ABORTED",0);
+ for(i=0;i<2000000;i++);
+ return !TRUE;
+ }
+ else
+ {
+ OLED_FastText57(3, 0, "HOME COMPLETE",0);
+ for(i=0;i<2000000;i++);
+ return TRUE;
+ }
+}//Home
+
+//******************************************************************
+void GoToRest(void)
+{
+//Variables required for Run3DLine
+//Values set from last move: lSaveSteps_X,lSaveSteps_Y,lSaveSteps_Z
+//Values set here: lX_Steps,lY_Steps,lZ_Steps
+
+extern float X_Rest_mm,Y_Rest_mm,Z_Rest_mm;
+
+ GX_On=1; //Enable axis for move
+ GY_On=1;
+ GZ_On=0; //To stop any Z move
+ Feed_Rate = GO_TO_REST_RATE; //set speed
+
+ X_Steps = X_Rest_mm * StepsPer_mm;//Convert mm coordinate to steps
+ Y_Steps = Y_Rest_mm * StepsPer_mm;
+ //Z_Steps = Z_Rest_mm * ZStepsPer_mm;//Uncomment for Z move
+
+ lX_Steps= f_to_sl(X_Steps); //Convert to integer steps
+ lY_Steps= f_to_sl(Y_Steps); //float to signed long.
+ //lZ_Steps= f_to_sl(Z_Steps);//Uncomment for Z move
+
+ mT4IntEnable(TRUE);
+
+ Stepper_Run3DLine();//Run line and reset all values
+
+ GX_On=0;
+ GY_On=0;
+ //GZ_On=0;//Uncomment for Z move
+ Delayms(250);
+
+}//GoToRest
+
+//******************************************************************
+// STEPPER INTERRUPT
+//******************************************************************
+void __ISR( _TIMER_4_VECTOR, ipl2) T4Interrupt( void)
+{
+//XYZ-Axis step timer
+//SBCode is 32bit containing step and direction for xyz and speed data
+//SBCode Bits 7 XDir, 6 X, 5 YDir, 4 Y, 3 ZDir, 2 Z, 1 & 0 Not used
+int mask;
+unsigned char bit_pos = 0;
+unsigned char xs,ys;
+
+if(Manual_Mode_Set){
+ switch(ManualStepperInt_Cycle)
+ {
+ case 0: //set Direction
+ {
+ X_Dir = Set_X_Dir;
+ Y_Dir = Set_Y_Dir;
+ Z_Dir = Set_Z_Dir;
+ PR4 = 5;
+ ManualStepperInt_Cycle = 1;
+ break;
+ }
+
+ case 1:
+ {
+ if(moveX){
+ X_Step = 1;
+ if(!Set_X_Dir) lSaveSteps_X += 1;
+ else lSaveSteps_X -= 1;
+ }
+ else X_Step = 0;
+ if(moveY){
+ Y_Step = 1;
+ if(!Set_Y_Dir) lSaveSteps_Y += 1;
+ else lSaveSteps_Y -= 1;
+ }
+ else Y_Step = 0;
+ if(moveZ){
+ Z_Step = 1;
+ if(! Set_Z_Dir) lSaveSteps_Z += 1;
+ else lSaveSteps_Z -= 1;
+ }
+ else Z_Step = 0;
+
+ PR4 = 10; //Set the on Time
+ ManualStepperInt_Cycle = 2;
+ break;
+ }
+
+ case 2:
+ {
+ PR4 = Feed_Rate;
+ X_Step = 0; Y_Step = 0; Z_Step = 0;
+ ManualStepperInt_Cycle = 0;
+ break;
+ }
+ }
+ TMR4 = 0;
+ mT4ClearIntFlag();
+}
+else
+{
+ switch(StepperInt_Cycle)
+ {
+ case 0: //Read in new code and set Direction
+ if(!SBReady&&(SBR!=SBW))
+ { //ready and the buffer is not empty
+ SBCode = SCB[ SBR]; //Read buffer
+ SCB[ SBR] = 0x00; //once read, set to zero
+ SBR++;
+ SBR %= SB_SIZE;
+ SBReady = 1; //Step byte consumed - ready to take another byte
+
+ mask = 0x08000000;
+ bit_pos = 3;
+ do // Unpack the code into axis Step and Dir
+ {
+ if ( SBCode & mask )
+ {
+ switch(bit_pos)
+ {
+ //set 1's in code
+ case 3: Z_Dir = 1; break;
+ case 5: Y_Dir = 1; break;
+ case 7: X_Dir = 1; break;
+ }
+ }
+ else
+ {
+ switch(bit_pos)
+ {
+ //set 0's in code
+ case 3: Z_Dir = 0; break;
+ case 5: Y_Dir = 0; break;
+ case 7: X_Dir = 0; break;
+ }
+ }
+ bit_pos += 2;
+ mask <<= 2;
+ }
+ while (mask !=0);
+ }
+ PR4 = 5;
+ StepperInt_Cycle = 1;
+ break;
+
+ case 1:
+ if (SBReady)
+ {
+ mask = 0x04000000;
+ bit_pos = 2;
+ do // Unpack the code into axis Step and Dir
+ {
+ if ( SBCode & mask )
+ {
+ switch(bit_pos)
+ {
+ //set 1's in code
+ case 2: Z_Step = 1; break;
+ case 4: Y_Step = 1; ys = 1; break;
+ case 6: X_Step = 1; xs = 1; break;
+ }
+ }
+ else
+ {
+ switch(bit_pos)
+ {
+ //set 0's in code
+ case 2: Z_Step = 0; break;
+ case 4: Y_Step = 0; ys=0; break;
+ case 6: X_Step = 0; xs=0; break;
+ }
+ }
+ bit_pos += 2;
+ mask <<= 2;
+ }
+ while (mask !=0);
+ }
+ PR4 = 10; //Set the on Time
+ StepperInt_Cycle = 2;
+ break;
+
+ case 2:
+ if (SBReady)
+ {
+ mask = 0xFFFF; //to return the bottom two bytes
+ PR4_Setting = SBCode & mask;
+ PR4 = PR4_Setting; //Set the off time
+ }
+ else
+ PR4 = 5000;
+
+ X_Step = 0; Y_Step = 0; Z_Step = 0; //turn off step pulse
+ StepperInt_Cycle = 0;
+ SBReady = 0;//code taken from buffer
+ SBCode = 0;
+ break;
+ }
+
+ TMR4 = 0;
+ mT4ClearIntFlag();
+ }
+}//T4Interrupt
+//******************************************************************
+void Stepper_InitIO (void)
+{
+ // Setup timers
+ //Timer 1
+ T1CON = 0x8030; //Set up timer 1 Fosc/2, prescaled 1:256
+
+ DDPCONbits.JTAGEN = 0; //To release port A pins from use by JTAG port
+
+ //Set Tris for Stepper
+ //X
+ AD1PCFGbits.PCFG8 = 1; //AtoD port cfg AN8/B8
+ TRISBbits.TRISB8 = OUTPUT; //Step
+ AD1PCFGbits.PCFG9 = 1; //AtoD port cfg AN9/B9
+ TRISBbits.TRISB9 = OUTPUT; //Dir
+ AD1PCFGbits.PCFG13 = 1; //AtoD port cfg AN13/B13
+ TRISBbits.TRISB13 = OUTPUT; //Enable
+ TRISDbits.TRISD4 = INPUT; //X_HomeSwitch
+ //Y
+ TRISDbits.TRISD8 = OUTPUT; //Step
+ TRISDbits.TRISD9 = OUTPUT; //Dir
+ TRISDbits.TRISD10 = OUTPUT; //Enable
+ TRISCbits.TRISC13 = INPUT; //Y_HomeSwitch
+
+ //Z
+ TRISDbits.TRISD2 = OUTPUT; //Step
+ TRISDbits.TRISD7 = OUTPUT; //Dir
+ TRISDbits.TRISD3 = OUTPUT; //Enable
+ TRISCbits.TRISC14 = INPUT; //Z_HomeSwitch
+
+ X_Disable = TRUE;
+ Y_Disable = TRUE;
+ Z_Disable = TRUE;
+
+ //Timer 4 is used to time the stepper motor steps
+ //PB clk = 8MHz Post scaler = 2 to 1 tick every 25nS
+ T4CON = 0x0; //Clear timer setting register
+ T4CONSET = 0x0010; //Set PS to 2
+ TMR4 = 0; //Reset clock
+ PR4 = 500; //Initialise PR4 value (when T4 matches PR4 it interrupts)
+ mT4SetIntPriority(7); //Set T4 interrupt to top priority
+ INTEnableSystemMultiVectoredInt();//Set T4 to vectored i.e. Fast
+ mT4ClearIntFlag(); //Clear interrupt flag
+ T4CONSET = 0x8000; //Turn on T4
+ mT4IntEnable(!TRUE); //Disable T4 interrputs
+
+ // init the circular buffer pointers
+ SBR = 0;
+ SBW = 0;
+ // Init Rapid moves
+ G_CodeRapidXYMove=0;
+ G_CodeRapidZMove=0;
+
+}//InitStepper
+//****************************************************************
+void Stepper_LoadNewValues(int Feed_Code, int Machine_Code)
+{
+int PBspeed;
+extern int GoToRestSpeed;
+extern char FastMoveMotorEnable;//Flag to switch motor on/off during fast move
+
+ S_F_Code = Feed_Code;
+ S_M_Code = Machine_Code;
+
+ //Set the feed Rate
+ //From Enrique's code Feed rate comes in as mm/s
+ //Old code may come in as mm/min
+ //if (Feed_Code > 50)
+ //{ //assume its mm/min
+ Feed_Code /= 60; //to give mm/sec
+ //}
+
+ //PB clk = 80/8 = 10MHz PS is 2:1
+ //Timer is 5MHz
+ //defined above FeedFactor 57094 = 5000000 / 87.575 StepsPer_mm
+
+ if (Feed_Code !=0)
+ {
+ Feed_Rate = (int)FeedFactor / Feed_Code;
+ }
+ else Feed_Rate = SAFE_FEED_RATE;
+
+ if (G_CodeRapidZMove > 0) ZFeed_Rate = G_CodeRapidZMove; // if it gets a value from G_Code use it
+ else ZFeed_Rate = Z_FEED_RATE; //always do rapid z move
+
+ xyrate = Feed_Rate * 1.414; //Multiply by root2 for 45Degree step
+
+
+ //Extruder OFF Feed Rate
+ //Realistic range for Extruder off 250(Very fast) - 7136{Slow)
+ if (ExtruderStatus == 0)
+ {
+ if (G_CodeRapidXYMove > 0) Feed_Rate = G_CodeRapidXYMove;
+ else Feed_Rate = RAPID_MOVE_FEED_RATE; //extruder off fast speed
+
+ if (FastMoveMotorEnable == FALSE) //flag set by G-Code
+ //default is motor On ie TRUE
+ {
+ if (FirstPass == TRUE)Extruder_Reverse();
+
+ EXTRUDER_DISABLE = TRUE; //Turn off motor
+ FirstPass = FALSE;
+ }
+ }
+ else
+ {
+ if (FirstPass == FALSE)Extruder_Prime();
+ FirstPass = TRUE;
+ }
+
+ if (GoToRestSpeed)//Flag set and reset in the RapMan_Rest function
+ {
+ if (G_CodeRapidXYMove > 0)
+ {//if it gets a value from the G_Code
+ Feed_Rate = G_CodeRapidXYMove;
+ xyrate = G_CodeRapidXYMove;
+ }
+ else
+ {// Use default
+ Feed_Rate = RAPID_MOVE_FEED_RATE;
+ xyrate = RAPID_MOVE_FEED_RATE;
+ }
+ EXTRUDER_DISABLE = TRUE; //Turn off motor
+ }
+
+}//Stepper_LoadNewValues
+//****************************************************************
+void Stepper_CalcSteps(int Units, char G2_G3)
+{
+//Number of steps on each Axis
+ switch (Units)
+ {
+ case 20: //Inches
+ X_Steps = GX * StepsPer_Inch;//numbers here are not rounded
+ Y_Steps = GY * StepsPer_Inch;//up or down!
+ Z_Steps = GZ * StepsPer_Inch;
+
+ lX_Steps= f_to_sl(X_Steps); //Float to long function at bottom of this
+ lY_Steps= f_to_sl(Y_Steps); //section.
+ lZ_Steps= f_to_sl(Z_Steps);
+ break;
+
+ case 21: //Metric
+ default: //Default metric
+ X_Steps = GX * StepsPer_mm;
+ Y_Steps = GY * StepsPer_mm;
+ Z_Steps = GZ * ZStepsPer_mm;
+
+ lX_Steps= f_to_sl(X_Steps); //Float to long function at bottom of this
+ lY_Steps= f_to_sl(Y_Steps); //section.
+ lZ_Steps= f_to_sl(Z_Steps);
+ break;
+ }//switch
+}
+//****************************************************************
+void OriginOffset(void)
+{
+extern float X_Rest_mm,Y_Rest_mm,Z_Rest_mm;
+float OffsetX_mm,OffsetY_mm,OffsetZ_mm;
+
+ OffsetSteps_X = lHomeStepsX - lSaveSteps_X;
+ OffsetSteps_Y = lHomeStepsY - lSaveSteps_Y;
+ OffsetSteps_Z = lHomeStepsZ - lSaveSteps_Z;
+
+ //SAVE offset to EEPROM here?
+
+ //reset saved values to new origin
+ lSaveSteps_X = 0; //zero only if the machine is at new 0,0
+ lSaveSteps_Y = 0;
+ lSaveSteps_Z = 0;
+
+ OffsetX_mm = OffsetSteps_X / StepsPer_mm;
+ OffsetY_mm = OffsetSteps_Y / StepsPer_mm;
+ OffsetZ_mm = OffsetSteps_Z / ZStepsPer_mm;
+
+ X_Rest_mm = X_REST_ABS_MM - X_HOME_MM + OffsetX_mm;
+ Y_Rest_mm = Y_REST_ABS_MM - Y_HOME_MM + OffsetY_mm;
+ Z_Rest_mm = Z_REST_ABS_MM - Z_HOME_MM + OffsetZ_mm;
+
+}//OriginOffset
+//****************************************************************
+void ResetOrigin(void)
+{
+extern float X_Rest_mm,Y_Rest_mm,Z_Rest_mm;
+
+ //restore offset from EEPROM?
+
+ if (lSaveSteps_X != lHomeStepsX) lSaveSteps_X = lHomeStepsX - OffsetSteps_X + lSaveSteps_X;
+ if (lSaveSteps_Y != lHomeStepsY) lSaveSteps_Y = lHomeStepsY - OffsetSteps_Y + lSaveSteps_Y;
+ if (lSaveSteps_Z != lHomeStepsZ) lSaveSteps_Z = lHomeStepsZ - OffsetSteps_Z + lSaveSteps_Z;
+
+ X_Rest_mm = X_REST_ABS_MM;
+ Y_Rest_mm = Y_REST_ABS_MM;
+ Z_Rest_mm = Z_REST_ABS_MM;
+
+}//ResetOrigin
+
+//****************************************************************
+void Stepper_Run3DLine()
+{
+//all the variables in the following are available a global or local
+ Bresenham_3D_Line(lX_Steps,lY_Steps,lZ_Steps,lSaveSteps_X,lSaveSteps_Y,lSaveSteps_Z);
+ Stepper_SaveValues();
+
+}//Stepper_Run3DLine
+
+//****************************************************************
+void Bresenham_3D_Line(signed int x1, signed int y1, signed int z1,
+ signed int x2, signed int y2, signed int z2)
+{
+
+int MajorAxis = 0;
+signed int incX = 1, incY = 1, incZ = 1;
+signed long DeltaX = x2-x1;
+signed long DeltaY = y2-y1;
+signed long DeltaZ = z2-z1;
+signed long TwoDeltaX = DeltaX + DeltaX;
+signed long TwoDeltaY = DeltaY + DeltaY;
+signed long TwoDeltaZ = DeltaZ + DeltaZ;
+int currentX = x1;
+int currentY = y1;
+int currentZ = z1;
+int ErrorX = 0, ErrorY = 0, ErrorZ = 0;
+int moveX = 0, moveY = 0, moveZ = 0;
+
+//StepData Bits 7 XDir, 6 X, 5 YDir, 4 Y, 3 ZDir, 2 Z, 1 & 0 Not used
+unsigned char StepData = 0;
+
+ if (!GX_On)
+ { //checks to see if the code mentions X
+ DeltaX = 0; //if not mentioned then no change
+ TwoDeltaX=0;
+ }
+ if (!GY_On)
+ {
+ DeltaY = 0;
+ TwoDeltaY=0;
+ }
+ if (!GZ_On)
+ {
+ DeltaZ = 0;
+ TwoDeltaZ=0;
+ }
+
+ //if there is no delta, current step coord is same as saved value
+ if (DeltaX == 0)
+ {
+ x1=x2;
+ lX_Steps=lSaveSteps_X;
+ GX = Save_X;
+ }
+ if (DeltaY == 0)
+ {
+ y1=y2;
+ lY_Steps=lSaveSteps_Y;
+ GY = Save_Y;
+ }
+ if (DeltaZ == 0)
+ {
+ z1=z2;
+ lZ_Steps=lSaveSteps_Z;
+ GZ = Save_Z;
+ }
+
+ if (DeltaX < 0)
+ {
+ X_Dir = 0; //Set X Direction based on sign of Delta value
+ StepData = StepData & ~0x80; //set bit 7 off
+ incX = -1;
+ DeltaX = -DeltaX;
+ TwoDeltaX = -TwoDeltaX;
+ }
+ else
+ {
+ X_Dir = 1;
+ StepData |= 0x80; //set bit 7 on
+ }
+
+ if (DeltaY < 0)
+ {
+ Y_Dir = 0; //Set Y Direction based on sign of Delta value
+ StepData = StepData & ~0x20; //set bit 5 off
+ incY = -1;
+ DeltaY = -DeltaY;
+ TwoDeltaY = -TwoDeltaY;
+ }
+ else
+ {
+ Y_Dir = 1;
+ StepData |= 0x20; //set bit 5 on
+ }
+
+ if (DeltaZ < 0)
+ {
+ Z_Dir = 1; //Set Z Direction based on sign of Delta value
+ StepData |= 0x08; //set bit 3 on
+ incZ = -1;
+ DeltaZ = -DeltaZ;
+ TwoDeltaZ = -TwoDeltaZ;
+ }
+ else
+ {
+ Z_Dir = 0;
+ StepData = StepData & ~0x08; //set bit 3 off
+ }
+
+ if ((DeltaX == 0)&(DeltaY == 0))
+ {
+ // if its only a z change then go fast
+ if (DeltaZ != 0) Feed_Rate = ZFeed_Rate;
+ }
+
+ if ((DeltaZ >= DeltaX)&(DeltaZ >= DeltaY))(MajorAxis = 1);
+ if ((DeltaX >= DeltaZ)&(DeltaX >= DeltaY))(MajorAxis = 2);
+ if ((DeltaY >= DeltaX)&(DeltaY >= DeltaZ))(MajorAxis = 3);
+
+ if ((DeltaX ==0)&(DeltaY==0)&(DeltaZ==0)) MajorAxis = 0;
+
+ //if (MajorAxis == 0)
+ //{
+ //error trap if required
+ //if MajorAxis is 0 then it drops out of this code with no action
+ //}
+
+//case 1
+ if (MajorAxis == 1)// = Z
+ {
+ do
+ {
+ currentZ += incZ;
+ ErrorX += TwoDeltaX;
+ ErrorY += TwoDeltaY;
+
+ if (ErrorX > DeltaZ)
+ {
+ currentX += incX;
+ ErrorX -= TwoDeltaZ;
+ moveX = 1;
+ StepData |= 0x40; //x set bit 6 on
+ }
+ if (ErrorY > DeltaZ)
+ {
+ currentY += incY;
+ ErrorY -= TwoDeltaZ;
+ moveY = 1;
+ StepData |= 0x10; //y set bit 5 on
+ }
+
+ StepData |= 0x04; //z set bit 2 on
+ AddToStepBuffer(StepData,moveX,moveY); //add step data to cuircular buffer
+ moveX = 0, moveY = 0, moveZ = 0;
+ StepData = StepData & ~0x54; //set bit 6,4,2 (x,y,z) off
+
+ }
+ while(currentZ != z2);
+
+ }//if
+
+//case 2
+ if (MajorAxis == 2)// = X
+ {
+ do
+ {
+ currentX += incX;
+ ErrorZ += TwoDeltaZ;
+ ErrorY += TwoDeltaY;
+
+ if (ErrorZ > DeltaX)
+ {
+ currentZ += incZ;
+ ErrorZ -= TwoDeltaX;
+ moveZ = 1;
+ StepData |= 0x04; //z set bit 2 on
+ }
+ if (ErrorY > DeltaX)
+ {
+ currentY += incY;
+ ErrorY -= TwoDeltaX;
+ moveY = 1;
+ StepData |= 0x10; //y set bit 5 on
+ }
+
+ StepData |= 0x40; //x set bit 6 on
+ AddToStepBuffer(StepData,moveX,moveY); //add step data to cuircular buffer
+ moveX = 0, moveY = 0, moveZ = 0;
+ StepData = StepData & ~0x54; //set bit 6,4,2 (x,y,z) off
+
+ }
+ while(currentX != x2);
+ }//if
+
+//case 3
+ if (MajorAxis == 3)// = Y
+ {
+ if (currentY != y2)
+ {
+ do
+ {
+ currentY += incY;
+ ErrorX += TwoDeltaX;
+ ErrorZ += TwoDeltaZ;
+
+ if (ErrorX > DeltaY)
+ {
+ currentX += incX;
+ ErrorX -= TwoDeltaY;
+ moveX = 1;
+ StepData |= 0x40; //x set bit 6 on
+ }
+ if (ErrorZ > DeltaY)
+ {
+ currentZ += incZ;
+ ErrorZ -= TwoDeltaY;
+ moveZ = 1;
+ StepData |= 0x04; //z set bit 2 on
+ }
+
+ StepData |= 0x10; //y set bit 5 on
+ AddToStepBuffer(StepData,moveX,moveY); //add step data to circular buffer
+ moveX = 0, moveY = 0; moveZ = 0;
+ StepData = StepData & ~0x54; //set bit 6,4,2 (x,y,z) off
+
+ }
+ while(currentY != y2);
+ }//if
+ }//if
+}//Bresenham_3D_Line
+
+//*************************************************************
+void Stepper_SaveValues()
+{
+//Tidy up after Gcode instruction.
+//Save current dimension and step coordinates
+
+ lSaveSteps_X = lX_Steps;
+ lSaveSteps_Y = lY_Steps;
+ lSaveSteps_Z = lZ_Steps;
+
+ Save3_X = Save2_X;
+ Save3_Y = Save2_Y;
+ Save3_Z = Save2_Z;
+
+ Save2_X = Save_X;
+ Save2_Y = Save_Y;
+ Save2_Z = Save_Z;
+
+ Save_X = GX;
+ Save_Y = GY;
+ Save_Z = GZ;
+
+//Reset globals
+ Delta_X=0; Delta_Y=0; Delta_Z=0;
+ X_Steps=0; Y_Steps=0; Z_Steps=0;
+ lX_Steps=0;lY_Steps=0;lZ_Steps=0;
+
+}//Stepper_SaveValues
+
+//*************************************************************
+int f_to_ul(float fNumber)
+{
+//Function returns a rounded unsigned long value for fNumber
+
+double IntNumber, Fraction;
+int TempNum;
+
+ Fraction = modf(fNumber, &IntNumber);//split float into Int and fraction
+ TempNum = (int)IntNumber;
+
+ if (Fraction >= 0.5)
+ {
+ TempNum += 1;
+ return TempNum;
+ }
+ else
+ return TempNum;
+
+}//f_to_ul
+
+//****************************************************************
+signed int f_to_sl(float fNumber)
+{
+//Function returns a rounded signed long value for fNumber
+
+double IntNumber, Fraction;
+signed int TempNum;
+
+ Fraction=modf(fNumber,&IntNumber);//split float into Int and fraction
+ TempNum = (signed int)IntNumber;
+
+ if (Fraction >= 0.5)
+ {
+ TempNum += 1;
+ }
+ if (Fraction <= -0.5)
+ {
+ TempNum -= 1;
+ }
+
+ return TempNum;
+
+}//f_to_sl
+
+//****************************************************************
+void AddToStepBuffer(unsigned char SData, char xs, char ys)
+{
+int BufferCode = 0;
+int addmask;
+
+ BufferCode = SData; //shift in 8Bit step data
+ BufferCode <<= 24;
+
+ if (xs && ys) //if we have a step in x and y
+ { //at the same time, the move is at 45deg
+ addmask = xyrate; //therefore swap in the slower feed rate
+ }
+ else
+ {
+ addmask = Feed_Rate;
+ }
+ BufferCode |= addmask; //add in the feed rate
+
+ //ready to add new data so now wait if buffer is full
+ while ( (SBW+1)%SB_SIZE == SBR);
+
+ SCB[ SBW] = BufferCode; //write in the buffer
+ SBW++; //increment ptr
+ SBW %= SB_SIZE; //wrap around if required
+
+}//AddToStepBuffer
+/*****************************************************************/
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Stepper.d b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Stepper.d new file mode 100644 index 00000000..7fd16a94 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Stepper.d @@ -0,0 +1,63 @@ +Stepper.o: Stepper.c \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/math.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/inttypes.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdint.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_mwgwtypes.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_const.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_fmtio.h \
+ Stepper.h Enviroment.h Extruder.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h OLED.h
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Stepper.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Stepper.h new file mode 100644 index 00000000..f867cc38 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/Stepper.h @@ -0,0 +1,122 @@ +/**********************************************************************
+ *************************** Stepper.h ******************************
+ **********************************************************************
+ *
+ * Company: Bits From Bytes Ltd
+ *
+ * Software License Agreement
+ *
+ * Copyright (C) 2009 Bits From Bytes Ltd. All rights reserved.
+ *
+ * Bits From Bytes Ltd licenses to you the right to use, modify,
+ * copy, and distribute this software under the
+ * Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported
+ * licence (see
+ * CreativeCommons-by-nc-sa-3.0-summary.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/ for a
+ * summary and CreativeCommons-by-nc-sa-3.0.pdf which is a copy of the
+ * text at http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
+ * for the full legal text).
+ *
+ * You should refer to the license agreement (Bits From Bytes Ltd Software
+ * Licence.pdf) accompanying this Software for additional information
+ * regarding your rights and obligations.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BITS FROM BYTES LTD BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
+ *
+ *
+ * Author(s) Date Comment
+ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Tony Fletcher (& Ian Adkins) 16/11/2009 Initial Release
+ ***********************************************************************/
+
+#define SHOW_POSITIONS 1
+#define HIDE_POSITIONS 0
+
+//General Defines
+
+extern int GX_On;
+extern int GY_On;
+extern int GZ_On;
+extern int GI_On;
+extern int GJ_On;
+
+extern float GX;
+extern float GY;
+extern float GZ;
+extern float GI_Val;
+extern float GJ_Val;
+extern int F_Code;
+extern int M_Code;
+
+extern char ExtruderStatus;
+int Feed_Rate;
+
+#define INPUT 1
+#define OUTPUT 0
+
+//18T MXL Pulley 1/16 Stepping for X & Y Axis
+#define StepsPer_mm 87.575 // 1/16 Stepping
+#define StepsPer_Inch 100 // 1/16 Stepping
+#define FeedFactor 57094
+
+//M8 x 1.25 thread
+//200 steps per rev 3200 at 1/16 stepping x 1/1.25 = 2560
+#define ZStepsPer_mm 2560
+
+// Axis definitions
+#define X_Step PORTDbits.RD2 //Digital
+#define X_Dir PORTDbits.RD7 //Digital
+#define X_Disable PORTDbits.RD3 //Digital
+
+#define Y_Step PORTDbits.RD8 //Digital
+#define Y_Dir PORTDbits.RD9 //Digital
+#define Y_Disable PORTDbits.RD10 //Digital
+
+#define Z_Step PORTBbits.RB8 //Analog
+#define Z_Dir PORTBbits.RB9 //Analog
+#define Z_Disable PORTBbits.RB13 //Analog
+
+#define SB_SIZE 512 // Step buffer size
+
+//Flag setup for interrupts
+#define _T4IE IEC0bits.T4IE
+#define _T4IF IFS0bits.T4IF
+
+#define SAFE_FEED_RATE 2000
+#define RAPID_MOVE_FEED_RATE 750 //was500
+#define Z_FEED_RATE 750
+#define GO_TO_REST_RATE 500
+
+#define X_REST_ABS_MM 130
+#define Y_REST_ABS_MM -100
+#define Z_REST_ABS_MM 0
+
+int G_CodeRapidXYMove;
+int G_CodeRapidZMove;
+int S_F_Code; //Stepper F code
+
+/****************************************************************/
+/* Functions */
+/****************************************************************/
+//External Functions
+extern void Stepper_InitIO(void);
+extern void Stepper_LoadNewValues(int Feed_Code, int Machine_Code);
+extern void Stepper_CalcSteps(int Units, char G2_G3);
+extern void OriginOffset(void);
+extern void ResetOrigin(void);
+extern void Manual_Mode(char ShowPos);
+extern int RapMan_Home(void);
+extern void GoToRest();
+extern void Stepper_Run3DLine(void);
+extern void Axis_Stepper_Motors(int on_off);
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.elf b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.elf Binary files differnew file mode 100644 index 00000000..65e4c4f0 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.elf diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.hex b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.hex new file mode 100644 index 00000000..b42e56a0 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.hex @@ -0,0 +1,7073 @@ +:020000040000fa
+:020000041fc01b
+:042ff400d9fff8ff0a
+:020000040000fa
+:020000041fc01b
+:042ff800dbfd7fff7f
+:020000040000fa
+:020000041fc01b
+:042ffc00ffffff7f55
+:020000040000fa
+:020000041d00dd
+:10600000009d1a3c90645a270800400300000000dd
+:020000040000fa
+:020000041d00dd
+:10638000029d1a3c30ba5a27080040030000000062
+:020000040000fa
+:020000041d00dd
+:10518000029d1a3cd4af5a270800400300000000db
+:020000040000fa
+:020000041d00dd
+:08530000861a400b00000000ba
+:020000040000fa
+:020000041d00dd
+:085380004b1b400b0000000074
+:020000040000fa
+:020000041d00dd
+:08540000ea63400b000000000c
+:020000040000fa
+:020000041d00dd
+:1064900000601a40c0045a7f05004013000000004d
+:1064a000029d1a3c48ba5a27080040030000000029
+:1064b00001a01d3c0080bd2701a01c3cf0809c2752
+:1064c0000260094020582001801e2a7d8449497db0
+:1064d0000260894000e0dc4102608b40029d083c84
+:1064e00038ba082509f800010000000000a0083ca7
+:1064f0002001082500a0093c801229250600001073
+:1065000000000000000000ad040000ad080000ad78
+:106510000c0000ad100008252b080901f9ff20141c
+:1065200000000000029d083c601e082500a0093cf8
+:106530000000292500a00a3c20014a250500001082
+:106540000000000000000b8d00002bad04000825aa
+:10655000040029252b082a01faff2014000000005e
+:106560000000093c000029251d002011000000004a
+:10657000029d083c801f082500a0093c0018292521
+:1065800000a00a3c00184a2500000b8d00002bad2e
+:1065900004000825040029252b082a01faff2014ed
+:1065a000000000000000093c0018292588bf0a3cb3
+:1065b00010204a25000049ad0100093c0080292532
+:1065c00088bf0a3c20204a25000049ad0100093c53
+:1065d0000080292588bf0a3c30204a25000049adab
+:1065e00000488040ffff0a2400588a40009d093c73
+:1065f00000502925017889400000093c0100292527
+:1066000000000a2444492a7d01608a408000093c38
+:1066100000688940008008408005097d404c0900e1
+:10662000006008405800013c244001012540280139
+:1066300000608840029d083c40ba082509f8000126
+:106640000000000000600840bfff013cffff213454
+:106650002440010100608840000084300000a53023
+:10666000009d083c006a08250800000100000000a9
+:020000040000fa
+:020000041d00dd
+:106a0000e257400f00000000816c400f00000000c2
+:106a1000ffff00100000000000e85d4100681a4020
+:106a200000701b4088ffbd277400bbaf00601b4097
+:106a300082d21a007000bbaf847a5b7f12d0000054
+:106a40006c00baaf10d000006800baaf44201b7cc5
+:106a500000609b406000bfaf5c00beaf5800b9afa4
+:106a60005400b8af5000afaf4c00aeaf4800adaf70
+:106a70004400acaf4000abaf3c00aaaf3800a9afb8
+:106a80003400a8af3000a7af2c00a6af2800a5aff8
+:106a90002400a4af2000a3af1c00a2af1800a1af38
+:106aa00021f0a0036080828f1000c2af0100022499
+:106ab0001000c38f34006210000000001000c38f6c
+:106ac0000200622806004010000000001000c28f83
+:106ad00009004010000000006f00001000000000de
+:106ae000020002241000c38f2f006210000000007b
+:106af00069000010000000000b0004241e1d400f60
+:106b000000000000348082af3480828f1b00401868
+:106b1000000000003c80838f3480828f211062004f
+:106b20003c8082af3880828f01004224388082af5f
+:106b30003880828f0a0042281000401400000000b4
+:106b40003c80848f6666023c67664234180082008f
+:106b50001010000083180200c31704002310620005
+:106b6000648182af388080af3c8080af0100022416
+:106b7000608082af4800001000000000608080af9d
+:106b800045000010000000006481848fac1c400fa1
+:106b900000000000248182af02000224608082afe6
+:106ba0003d00001000000000ed1b400f0000000041
+:106bb000608080af88bf023c5061428c0000427c04
+:106bc00006004010000000003080828f0100422447
+:106bd000308082af0200001000000000308080afe3
+:106be00049818283150040140000000088bf023ce8
+:106bf0005060428cc000427c06004014000000003f
+:106c000001000224498182a30480828f0a00422469
+:106c1000048082af88bf023c5060428c8000427c7e
+:106c2000060040140000000001000224498182a3f4
+:106c30000480828ff6ff4224048082af6c818283bd
+:106c4000150040140000000088bf023c5060428cd8
+:106c5000c003427c06004014000000000100022432
+:106c60006c8182a34c80828f010042244c8082afd1
+:106c700088bf023c5060428c0001427c06004014f8
+:106c800000000000010002246c8182a34c80828fee
+:106c9000ffff42244c8082af80bf023c100840ac12
+:106ca00088bf033c00010224341062ac21e8c00319
+:106cb0006000bf8f5c00be8f5800b98f5400b88f42
+:106cc0005000af8f4c00ae8f4800ad8f4400ac8faa
+:106cd0004000ab8f3c00aa8f3800a98f3400a88fea
+:106ce0003000a78f2c00a68f2800a58f2400a48f2a
+:106cf0002000a38f1c00a28f1800a18f00606041ac
+:106d0000c00000006c00ba8f130040036800ba8f07
+:106d1000110040037400ba8f00709a407000ba8f5f
+:106d20007800bd2700609a401800004200e85d41ed
+:106d3000f4ffbd2700601b400800bbaf04201b7c94
+:106d4000001c7b3700609b4021f0a0035080828fa5
+:106d50000000c2af010002240000c38f2d006210aa
+:106d6000000000000000c38f0200622806004010ef
+:106d7000000000000000c28f090040100000000069
+:106d80003f00001000000000020002240000c38f3a
+:106d90002e0062100000000039000010000000000a
+:106da0003081828f0f004014000000005881828fd4
+:106db00004004018000000005881828fffff422429
+:106dc000588182af7081828f04004018000000005b
+:106dd0007081828fffff4224708182af0100022404
+:106de000308182af88bf043c1061828c0c80838f1d
+:106df0008410627c106182ac80bf033c05000224d9
+:106e0000200a62ac01000224508082af1c000010f6
+:106e1000000000003081828f05004010000000005b
+:106e200088bf023c1061439002006334106143a0ac
+:106e300080bf023c0a000324200a43ac0200022463
+:106e4000508082af0e000010000000003081828f61
+:106e5000060040100000000088bf043c10618390d1
+:106e6000fdff022424106200106182a080bf033c59
+:106e70000880828f200a62ac508080af308180af62
+:106e800080bf023c100a40ac88bf033c00100224c3
+:106e9000341062ac21e8c0030800ba8f00609a4049
+:106ea00018000042e8ffbd271400bfaf1000beafbe
+:106eb00021f0a0030480828f548082af0480828fef
+:106ec0000f00422803004010000000000f000224c1
+:106ed000048082af0480828fd107422803004014cf
+:106ee00000000000d0070224048082af0480848f59
+:106ef000d079400f000000002130400021386000b0
+:106f0000029d023c2006448c2406458ca378400f49
+:106f100000000000029d063c212040002128600066
+:106f20002c06c78c2806c68cce76400f00000000c9
+:106f30002120400021286000687a400f00000000f6
+:106f4000088082af4480828f100040100000000053
+:106f500088bf043c10618390feff0224241062006d
+:106f6000106182a00480828f100042280b00401024
+:106f70000000000088bf023c1061439001006334b0
+:106f8000106143a0050000100000000088bf023c13
+:106f90001061439001006334106143a021e8c003f5
+:106fa0001400bf8f1000be8f1800bd270800e0033b
+:106fb00000000000e8ffbd271400bfaf1000beaf07
+:106fc00021f0a0034c80828f0200410400000000e9
+:106fd0004c8080af4c80828f2d01422803004014ea
+:106fe000000000002c0102244c8082af20828283aa
+:106ff00019004014000000004c80848fae7c400fcc
+:10700000000000002481848f21284000137d400f60
+:107010000000000003004004000000000700001012
+:107020000000000088bf023c5061439001006334bf
+:10703000506143a00d0000100000000088bf043c18
+:1070400050618390feff022424106200506182a0f0
+:10705000060000100000000088bf043c50618390cf
+:10706000feff022424106200506182a048818283c6
+:1070700026004014000000004c80828ff6ff42245e
+:1070800021204000ae7c400f000000002481848f4e
+:1070900021284000137d400f000000001200400432
+:1070a000000000004c80828f0a0042242120400012
+:1070b000ae7c400f00000000212040002481858f1d
+:1070c000137d400f00000000070040040000000096
+:1070d0004c80828f640042280300401400000000ae
+:1070e0000800001000000000448080af88bf023c10
+:1070f0001061439001006334106143a0030000104d
+:107100000000000001000224448082af4881838394
+:10711000010002242c006214000000004c80828fc9
+:10712000ffff422421204000ae7c400f0000000001
+:107130002481848f21284000137d400f000000002f
+:1071400018004004000000004c80828f010042249f
+:1071500021204000ae7c400f0000000021204000b4
+:107160002481858f137d400f000000000d00400436
+:10717000000000004c80828f640042280900401407
+:10718000000000002481848f21280000137d400f1f
+:107190000000000003004010000000000800001084
+:1071a00000000000448080af88bf023c1061439023
+:1071b00001006334106143a00300001000000000d0
+:1071c00001000224448082af3c81838301000224b9
+:1071d00019006214000000004c80828ffbff4224e3
+:1071e00021204000ae7c400f000000002481848fed
+:1071f00021284000137d400f0000000003004004e0
+:1072000000000000080000100000000088bf043cdf
+:1072100010618390dfff022424106200106182a0bd
+:10722000050000100000000088bf023c1061439080
+:1072300020006334106143a0029d023c2481848fae
+:107240003006458c137d400f000000000300401005
+:1072500000000000040000100000000021200000d9
+:10726000481d400f00000000029d023c2481848fd5
+:107270003406458c137d400f0000000003004010d1
+:1072800000000000040000100000000021200000a9
+:10729000481d400f0000000021e8c0031400bf8f0c
+:1072a0001000be8f1800bd270800e003000000009a
+:1072b000d0ffbd272800bfaf2400beaf2000b0af75
+:1072c00021f0a0033000c4af3000c28f1c00422860
+:1072d0000800401000000000029d023c3806428c6d
+:1072e0001000c2af1000c28f1800c2af5a000010c9
+:1072f000000000003000c28fff0342280c00401441
+:10730000000000003080828f3300422808004014c3
+:1073100000000000029d023c3c06428c1000c2afff
+:107320001000c28f1800c2af4b0000100000000018
+:107330001400c0af1400c28f1f0042284600401046
+:1073400000000000029d043c1400c28f801802005f
+:10735000a0058224211062000000428c688182af67
+:107360003000c38f6881828f2a104300350040109f
+:10737000000000006881828f1c8182af029d043c66
+:107380001400c28f80180200a00582242110620020
+:10739000fcff428c608182af6081838f1c81828f71
+:1073a00023106200508182af3000c38f1c81828f16
+:1073b000231062005c8182af5c81848fae7c400fc1
+:1073c00000000000218040005081848fae7c400f7f
+:1073d000000000002120000221284000237c400ff3
+:1073e00000000000208182af029d023c2081848f3a
+:1073f0004006458cb57b400f00000000208182af25
+:107400001400c38f2110600080100200211043007f
+:107410004010020021204000ae7c400f0000000020
+:10742000212040002081858f187b400f0000000044
+:107430001000c2af1000c28f1800c2af06000010cb
+:10744000000000001400c28f010042241400c2afeb
+:10745000b8ff0010000000001800c28f21e8c00330
+:107460002800bf8f2400be8f2000b08f3000bd27c2
+:107470000800e00300000000f0ffbd270800beafd9
+:1074800021f0a0031000c4af81bf043c4090828c67
+:107490001000c38f049c627c409082ac81bf033c8f
+:1074a0000090629002004234009062a00000c0afe1
+:1074b0000000c28fc80042280600401000000000f3
+:1074c0000000c28f010042240000c2aff8ff00108c
+:1074d0000000000081bf043c00908390fdff022467
+:1074e00024106200009082a081bf023c0090428c78
+:1074f0000000427c0300401400000000faff00106e
+:107500000000000081bf023c7090428c21e8c00363
+:107510000800be8f1000bd270800e0030000000037
+:10752000f0ffbd270800beaf21f0a0031000c4afdc
+:107530001000c28f010042380100422c0000c2af8f
+:10754000010002240000c38f100062100000000040
+:107550000000c38f020062280600401000000000f7
+:107560000000c28f1d004010000000003900001014
+:1075700000000000020002240000c38f2c006210f3
+:1075800000000000330000100000000088bf043c31
+:1075900010618390feff022424106200106182a01b
+:1075a00088bf033c00010224641062ac88bf033c26
+:1075b00000010224681062ac88bf033c0010022462
+:1075c000641062ac88bf033c00100224681062acf7
+:1075d000308080af1f0000100000000088bf043c16
+:1075e00050618390feff022424106200506182a04b
+:1075f00088bf033c1061629001004234106162a0b8
+:1076000088bf033c00010224641062ac88bf023cc6
+:10761000681040ac88bf033c00100224641062acc8
+:1076200088bf023c681040ac0a0000100000000057
+:1076300088bf033c1061629001004234106162a077
+:1076400088bf033c00100224641062ac88bf023c77
+:10765000681040ac21e8c0030800be8f1000bd27b1
+:107660000800e00300000000d0ffbd272c00bfafe2
+:107670002800beaf21f0a00388bf043c00618390c6
+:10768000fdff022424106200006182a088bf043c38
+:1076900000618390fbff022424106200006182a03d
+:1076a00088bf043c00618390feff02242410620026
+:1076b000006182a00e7f400f000000001000c2afea
+:1076c00088bf023c0030428c0003427c1c00c2afe9
+:1076d0000b0040140000000088bf033c001002248f
+:1076e000083062ac88bf023c0030428c0003427c10
+:1076f0000300401400000000faff0010000000002a
+:107700001c00c28f1800c2af1800c28f1400c2af95
+:1077100081bf023c30f240ac81bf033c99aa023cdd
+:107720005566423430f262ac81bf033c6655023c80
+:10773000aa99423430f262ac81bf033c1800023c8b
+:1077400008f062ac81bf023c04f040ac81bf033c56
+:107750003333023c3333423430f262ac1400c28f14
+:107760001c00c2af1c00c28f1500401000000000ba
+:1077700088bf023c0030428c0003427c2000c2af34
+:107780000b0040140000000088bf033c00100224de
+:10779000083062ac88bf023c0030428c0003427c5f
+:1077a0000300401400000000faff00100000000079
+:1077b0002000c28f1800c2af0400001000000000bb
+:1077c00088bf033c00100224043062ac1000c48f58
+:1077d0001d7f400f0000000080bf023c000840ac4d
+:1077e00080bf033c70000224080862ac80bf023cea
+:1077f000100840ac80bf033cf4010224200862acb6
+:1078000088bf033c1c000224b41062ac88bf033c58
+:1078100010000224b81062ac88bf033c00010224af
+:10782000341062ac80bf033c00800234080862acb4
+:1078300088bf033c00010224641062ac88bf023c94
+:10784000681040ac80bf023c000a40ac80bf033ce3
+:1078500010000224080a62ac80bf023c100a40ac4f
+:1078600080bf033c88130224200a62ac88bf033c1b
+:107870001c000224c41062ac88bf033c1c0002241c
+:10788000c81062ac107f400f0000000088bf033cae
+:1078900000100224341062ac80bf033c008002342c
+:1078a000080a62ac88bf033c00100224641062ac7a
+:1078b00088bf023c681040ac88bf033c10616290f6
+:1078c00001004234106162a03c8180a3348180a316
+:1078d00021e8c0032c00bf8f2800be8f3000bd27d9
+:1078e0000800e00300000000e0ffbd271c00bfaf60
+:1078f0001800beaf21f0a0031000c0af212000008f
+:107900005f52400f0000000088bf023c5060428c74
+:10791000c000427c0300401400000000faff001089
+:1079200000000000048080af4c8080af4f51400fba
+:107930000000000001000424481d400f000000006a
+:1079400088bf023c9061428c4002437c01000224cb
+:107950002f00621400000000a91b400f000000006f
+:107960001000c28f010042241000c2af1000c28f6d
+:10797000e9034228f2ff4014000000004f51400f7d
+:107980000000000088bf023c5060428cc000427c76
+:1079900004004014000000000480828f0a0042248a
+:1079a000048082af88bf023c5060428c8000427ce1
+:1079b00004004014000000000480828ff6ff42247f
+:1079c000048082af88bf023c5060428cc003427c7e
+:1079d00004004014000000004c80828f010042240b
+:1079e0004c8082af88bf023c5060428c0001427cd8
+:1079f00004004014000000004c80828fffff4224ee
+:107a00004c8082af1000c0afcdff0010000000001e
+:107a100021200000481d400f0000000021e8c003a5
+:107a20001c00bf8f1800be8f2000bd270800e00398
+:107a300000000000f0ffbd270800beaf21f0a0034a
+:107a40001000c4af0000c0af1000c28f8018020049
+:107a50000000c28f2a1043000c00401000000000fc
+:107a60000000000000000000000000000000000016
+:107a70000000000000000000000000000000c28fb5
+:107a800001004224f0ff00100000c2af21e8c00353
+:107a90000800be8f0800e0031000bd27e8ffbd27e7
+:107aa0001400bfaf1000beaf21f0a0031800c4af98
+:107ab0001800c28fe8030324021043702120400005
+:107ac0008d1e400f0000000021e8c0031400bf8f8e
+:107ad0001000be8f1800bd270800e0030000000062
+:107ae000f8ffbd270000beaf21f0a0034481828fc4
+:107af0001c0040100000000088bf023c1061428c56
+:107b00000000427c17004014000000000c8080af91
+:107b10005881828f0a004014000000002881828f63
+:107b20000500401400000000e8030224588182afe1
+:107b300003000010000000002881828f588182af6e
+:107b400090030224088082af5881828f030040187e
+:107b500000000000fcff00100000000001000224f3
+:107b60000c8082af21e8c0030000be8f0800bd2753
+:107b70000800e00300000000e8ffbd271400bfafcd
+:107b80001000beaf21f0a0034481828f310040106d
+:107b90000000000088bf023c1061428c0000427c63
+:107ba0002c00401400000000010002240c8082af71
+:107bb0007081828f0a004014000000005481828f7f
+:107bc0000500401400000000e8030224708182af29
+:107bd00003000010000000005481828f708182af8a
+:107be00090030224088082af7081828f03004018c6
+:107bf00000000000fcff0010000000000480848fe3
+:107c0000d079400f00000000213040002138600092
+:107c1000029d023c4806448c4c06458ca378400fdc
+:107c200000000000029d063c212040002128600049
+:107c30005406c78c5006c68cce76400f000000005c
+:107c40002120400021286000687a400f00000000d9
+:107c5000088082af21e8c0031400bf8f1000be8fe0
+:107c60001800bd270800e00300000000e0ffbd276a
+:107c70001c00bfaf1800beaf21f0a0031000c0afc2
+:107c80001000c28f030042280b00401000000000cb
+:107c90001000c38f74818227211862000100022422
+:107ca000000062a01000c28f010042241000c2af89
+:107cb000f3ff0010000000006e8080a3e748400f33
+:107cc0000000000000a0023cd80944247c21400fa1
+:107cd0000000000030004014000000001880838f76
+:107ce00000a0023cd8094224000062ac1880828fb8
+:107cf0000c0040a41880828f0e0040a41880828f50
+:107d0000100040ac1880828f140040ac1880838f24
+:107d10005c000224200062a0010002241000c2af17
+:107d20001000c28f0b0042280b0040100000000022
+:107d30001880838f1000c28f211862002000022457
+:107d4000200062a01000c28f010042241000c2afc8
+:107d5000f3ff0010000000001880828f2c0040a468
+:107d60001880838f10000224300062a41880838f53
+:107d70007c81828f340062ac1880838f7c81828ffb
+:107d8000380062ac8c8180a3010002241400c2afd1
+:107d900002000010000000001400c0af1400c28fe9
+:107da00021e8c0031c00bf8f1800be8f2000bd2734
+:107db0000800e00300000000c8ffbd273000bfaf8f
+:107dc0002c00beaf2800b0af21f0a0033800c4af34
+:107dd0003c00c5af2110c0002118e0004000c2a344
+:107de0004400c3a33800c28f2c0042941400c2a7e1
+:107df0000b0002241800c2af3800c38f3800c28fb6
+:107e00003400428c380062ac3c00c28f3000429497
+:107e1000271002001200c2a71400c2970d004014e0
+:107e2000000000001400c2273800c48f2128400041
+:107e300001000624182a400f00000000130040141f
+:107e4000000000001b0002241800c2af0f00001049
+:107e5000000000001400c2970f0042300b004010d9
+:107e6000000000001400c2273800c48f2128400001
+:107e700001000624182a400f0000000003004014ef
+:107e8000000000001b0002241800c2af1800c38fbe
+:107e90001b000224cc006210000000001800c28ffa
+:107ea000c9004010000000001400c2273800c48f31
+:107eb00021284000012e400f000000001600c2a340
+:107ec0001600c393020002240300621400000000a5
+:107ed000bd000010000000001600c293b100401465
+:107ee000000000003800c28f300042941000c2a78a
+:107ef0001000c2973f0042301000c2a74400c29356
+:107f00002000c2af2000c38f0700601000000000f7
+:107f1000010002242000c38f2d0062100000000029
+:107f2000a4000010000000001000c3970800022405
+:107f3000a0006210000000001800c0af6d00022415
+:107f40001c00c2a31700c0a31700c2930b00422c51
+:107f500098004010000000003800c38f1700c29343
+:107f600021106200200042901c00c2a33c00c38f7d
+:107f70001700c29321106200200042901d00c2a38e
+:107f80001c00c29321204000a86c400f000000009c
+:107f9000218040001d00c29321204000a86c400faa
+:107fa0000000000005000212000000000b00022487
+:107fb0001800c2af7f000010000000001700c2933d
+:107fc000010042241700c2a3dfff001000000000e0
+:107fd0001000c3971200c29724106200ffff4230c6
+:107fe00074004014000000001000c3970f0002242a
+:107ff00070006210000000001800c0af6d00022485
+:108000001c00c2a33c00c28f200043802a0002242f
+:108010002e006210000000001700c0a31700c293da
+:108020000800422c29004010000000003800c38fd7
+:108030001700c29321106200200042901c00c2a3ce
+:108040003c00c38f1700c2932110620020004290b1
+:108050001d00c2a31d00c3932a0002240300621462
+:108060000000000019000010000000001d00c39374
+:108070003f00022410006210000000001c00c293a8
+:1080800021204000a86c400f00000000218040002b
+:108090001d00c29321204000a86c400f000000008a
+:1080a00005000212000000000b0002241800c2affd
+:1080b00006000010000000001700c29301004224d7
+:1080c0001700c2a3d5ff0010000000003c00c28fc3
+:1080d000280043802a0002243600621000000000bd
+:1080e0001800c28f33004014000000000800022472
+:1080f0001700c2a31700c2930b00422c2d004010a2
+:10810000000000003800c38f1700c29321106200e6
+:10811000200042901c00c2a33c00c38f1700c293f2
+:1081200021106200200042901d00c2a31d00c393d5
+:108130002a00022403006214000000001d00001049
+:10814000000000001d00c3933f00022410006210d5
+:10815000000000001c00c29321204000a86c400fca
+:1081600000000000218040001d00c293212040003b
+:10817000a86c400f00000000050002120000000083
+:108180000b0002241800c2af0a000010000000001b
+:108190001700c293010042241700c2a3d5ff0010ac
+:1081a000000000004000c2930200401400000000e4
+:1081b0001800c0af1400c297010042241400c2a7e7
+:1081c00036ff0010000000001800c28f21e8c00335
+:1081d0003000bf8f2c00be8f2800b08f3800bd2725
+:1081e0000800e00300000000d0ffbd272c00bfaf57
+:1081f0002800beaf21f0a0033000c4af3400c5afeb
+:108200002110c0003800c2a31c00c0af3000c28fd4
+:108210000000428c1000c2af1000c28f1f004290bd
+:108220000500401400000000070002241c00c2af3b
+:1082300089000010000000003000c38f3000c28fa2
+:108240003400428c380062ac3400c28f000042948b
+:108250000c004014000000003000c48f3400c58fb3
+:1082600001000624182a400f0000000013004014eb
+:10827000000000001b0002241c00c2af0f00001011
+:10828000000000003400c28f000042940f00423012
+:108290000a004010000000003000c48f3400c58f79
+:1082a00001000624182a400f0000000003004014bb
+:1082b000000000001b0002241c00c2af3000c48f6d
+:1082c0003400c58f012e400f000000001400c2a32f
+:1082d0001400c29305004010000000000b000224af
+:1082e0001c00c2af5c000010000000003000c28f14
+:1082f000100040ac3000c38f3000c28f0400428cad
+:10830000080062ac3000c28f0c0040a43000c28f65
+:108310000e0040a41400c39301000224050062145f
+:10832000000000000b0002241c00c2af2700001058
+:10833000000000003000c28f1000c48f0800458c80
+:10834000cd33400f000000001800c2af6c80829354
+:1083500009004010000000009235400f00000000ae
+:108360000500401000000000090002242000c2aff8
+:108370003b000010000000003000c28f688082af18
+:108380001480838f1800c28f10006210000000005c
+:108390006e8080a31000c28f0300438800004398c2
+:1083a000211060001800c48f21284000d349400fdd
+:1083b0000000000003004014000000000800022438
+:1083c0001c00c2af1800c28f148082af3000c48f6f
+:1083d0001800838cfbff022424106200180082ac7a
+:1083e0003800c383770002240700621000000000f9
+:1083f0003800c38361000224030062100000000003
+:108400000c000010000000003000c38f1800628cc8
+:1084100001004234180062ac3000c48f1800838c15
+:10842000fdff022424106200180082ac0a00001034
+:10843000000000003000c48f1800838cfeff02246f
+:1084400024106200180082ac3000c38f1800628cc8
+:1084500002004234180062ac1c00c28f2000c2af80
+:108460002000c28f21e8c0032c00bf8f2800be8fe0
+:108470003000bd270800e00300000000c8ffbd2752
+:108480003400bfaf3000beaf21f0a0033800c4af4e
+:108490003c00c5af2000c0a33800c28f0000428c52
+:1084a0002400c2af2400c28f1e0042902800c2af39
+:1084b000010002242800c38f0f006210000000009a
+:1084c000030002242800c38f030062100000000094
+:1084d0000f00001000000000ff0f023cf8ff4234c4
+:1084e0001c00c2afff0f023cffff42341800c2afb6
+:1084f0000b00001000000000f80f02241c00c2afa7
+:10850000ffff02341800c2af050000100000000099
+:10851000f8ff02341c00c2afffff02341800c2afe4
+:108520003800c28f0800428c1400c2af2400c48ff0
+:108530001400c58f8c39400f000000001000c2af3e
+:108540001000c38f1800c28f0500621400000000e5
+:10855000080002242000c2a3110000100000000047
+:108560002400c28f19004388160043981000c28f60
+:108570002b10430003004014000000000a000224f6
+:108580002000c2a31000c28f1c00c38f2b10430019
+:1085900003004014000000003c0002242000c2a39d
+:1085a0003800c38f1000c28f080062ac3c00c28f3d
+:1085b000ffff42243c00c2af060040100000000054
+:1085c0002000c2930300401400000000d4ff0010fc
+:1085d000000000002000c29321e8c0033400bf8fd8
+:1085e0003000be8f3800bd270800e0030000000007
+:1085f000e0ffbd271c00bfaf1800beaf21f0a003f5
+:108600002000c4af1000c0a32000c28f1f0040a0f4
+:108610002000c28f00a0033c9c046324030043a8f5
+:10862000000043b8654b400f0000000021184000d7
+:10863000010002240700621000000000060002246e
+:108640001000c2a3060002248c8182a31200001035
+:10865000000000002000c48fad21400f000000008a
+:108660001000c2a31000c2930b00401400000000d1
+:108670002000c48fb322400f000000001000c2a3ee
+:108680001000c29304004014000000002000c38fbb
+:10869000010002241f0062a01000c29321e8c00361
+:1086a0001c00bf8f1800be8f2000bd270800e0030c
+:1086b00000000000d0ffbd272c00bfaf2800beafd8
+:1086c00021f0a0033000c4af1400c0a33000c28f5b
+:1086d000030043880000439821106000212000001f
+:1086e00021284000d349400f00000000211840001d
+:1086f00001000224070062100000000008000224ac
+:108700001400c2a3080002248c8182a3e60000109a
+:10871000000000003000c28f03004388000043982f
+:10872000211060001800c2af1800c28ffe014390f4
+:108730005500022490006214000000001800c28f4f
+:10874000ff014390aa0002248b0062140000000085
+:108750003000c28f0300438800004398211060005e
+:1087600021204000360005247a33400f000000002d
+:1087700021184000460002243a0062140000000064
+:108780003000c28f0300438800004398211060002e
+:1087900021204000370005247a33400f00000000fc
+:1087a00021184000410002242e0062140000000045
+:1087b0003000c28f030043880000439821106000fe
+:1087c00021204000380005247a33400f00000000cb
+:1087d000211840005400022422006214000000000e
+:1087e0003000c28f030043880000439821106000ce
+:1087f00021204000390005247a33400f000000009a
+:10880000211840003100022416006214000000000c
+:108810003000c28f0300438800004398211060009d
+:1088200021204000260005247a33400f000000007c
+:1088300021184000290002240a00621400000000f0
+:108840003000c28f070040a8040040b83000c38f3a
+:10885000020002241e0062a01c00c0af94000010a1
+:10886000000000003000c28f0300438800004398de
+:108870002110600021204000520005247a33400f6f
+:108880000000000021184000460002243a00621453
+:10889000000000003000c28f0300438800004398ae
+:1088a0002110600021204000530005247a33400f3e
+:1088b0000000000021184000410002242e00621434
+:1088c000000000003000c28f03004388000043987e
+:1088d0002110600021204000540005247a33400f0d
+:1088e00000000000211840005400022422006214fd
+:1088f000000000003000c28f03004388000043984e
+:108900002110600021204000550005247a33400fdb
+:1089100000000000211840003300022416006214f9
+:10892000000000003000c28f03004388000043981d
+:108930002110600021204000420005247a33400fbe
+:108940000000000021184000290002240a006214df
+:10895000000000003000c28f070040a8040040b8ab
+:108960003000c38f030002241e0062a01c00c0afb1
+:108970004f000010000000003000c28f0300438849
+:1089800000004398211060001000c2af1000c28f99
+:10899000fe0143905500022408006214000000000c
+:1089a0001000c28fff014390aa000224030062144a
+:1089b0000000000007000010000000000400022476
+:1089c0008c8182a3040002241400c2a3360000108c
+:1089d000000000003000c38f1000c28fc90144881e
+:1089e000c601449821108000070062a8040062b804
+:1089f0001000c28fc20142901500c2a31500c2939d
+:108a00002000c2af2000c38f0f00622c2200401054
+:108a100000000000010002242000c38f0410620047
+:108a20002400c2af2400c38f5040623010004014b5
+:108a3000000000002400c38f0018623011004014b1
+:108a4000000000002400c38f0200623003004014c5
+:108a50000000000010000010000000003000c38f74
+:108a6000010002241e0062a00f00001000000000a0
+:108a70003000c38f020002241e0062a00a00001012
+:108a8000000000003000c38f030002241e0062a01b
+:108a90000500001000000000050002248c8182a364
+:108aa000050002241400c2a31400c2931c00c2af2c
+:108ab0001c00c28f21e8c0032c00bf8f2800be8f8e
+:108ac0003000bd270800e00300000000c0ffbd2704
+:108ad0003800bfaf3400beaf3000b0af21f0a0030c
+:108ae0004000c4af1c00c0a34000c28f07004388f1
+:108af00021206000040044984000c28f0300438896
+:108b0000000043982110600021284000d349400f05
+:108b1000000000002118400001000224070062103c
+:108b200000000000080002248c8182a308000224b7
+:108b30001c00c2a344010010000000004000c28fce
+:108b40000300438800004398211060002000c2af5a
+:108b50002000c28ffe0143905500022408006214d9
+:108b6000000000002000c28fff014390aa000224f1
+:108b70000300621400000000070000100000000065
+:108b8000030002248c8182a3030002241c00c2a3e0
+:108b90002d010010000000004000c28f0300438838
+:108ba0000000439821106000212040000e000524a1
+:108bb0008933400f000000002600c2a74000d08f7c
+:108bc0004000c28f030043880000439821106000da
+:108bd000212040000d0005247a33400f00000000e2
+:108be0001d0002a24000c48f4000c28f07004388ce
+:108bf000040043982600c297211062000b0082a84f
+:108c0000080082b84000d08f4000c28f0300438824
+:108c1000000043982110600021204000100005242e
+:108c20007a33400f000000001c0002a24000d08fe9
+:108c30004000c28f03004388000043982110600069
+:108c400021204000160005248933400f0000000059
+:108c500021284000ff00a4301a0002920000423098
+:108c60002118400021108000251062001a0002a285
+:108c700002120500ffff44301b0002920000423048
+:108c80002118400021108000251062001b0002a264
+:108c90004000c28f1a0043901b0042900012020055
+:108ca00025104300ffff42301c004014000000006c
+:108cb0004000d08f4000c28f0300438800004398db
+:108cc000211060002120400024000524a833400f1b
+:108cd0000000000021284000ffffa230ff004430c8
+:108ce0001a0002920000423021184000211080003a
+:108cf000251062001a0002a2ffffa2300212020039
+:108d0000ffff44301b000292000042302118400057
+:108d100021108000251062001b0002a24000c48fb9
+:108d20004000c28f0b00438821286000080045984e
+:108d30004000c28f1c0046904000c28f1a00439032
+:108d40001b0042900012020025104300ffff42303a
+:108d50000210c2702110a2000f0082a80c0082b87d
+:108d60004000d08f4000c28f03004388000043982a
+:108d70002110600021204000110005248933400f9c
+:108d80000000000021284000ff00a43014000292df
+:108d900000004230211840002110800025106200a0
+:108da000140002a202120500ffff443015000292d7
+:108db0000000423021184000211080002510620080
+:108dc000150002a24000c28f0300438800004398b0
+:108dd0002110600021204000130005248933400f3a
+:108de000000000001400c2af1400c28f0a0040143b
+:108df000000000004000c28f030043880000439839
+:108e0000211060002120400020000524a833400fdd
+:108e1000000000001400c2af4000c28f030043886e
+:108e20000000439821106000212040000b00052421
+:108e30008933400f000000002400c2a72400c2971d
+:108e400007004010000000002400c29701004230db
+:108e500003004014000000000700001000000000a4
+:108e6000030002248c8182a3030002242800c2afe5
+:108e700077000010000000004000c28f14004390f3
+:108e8000150042900012020025104300ffff4230ff
+:108e9000401902002400c29721106200ffff432402
+:108ea0002400c2971a006200f40140001210000072
+:108eb0001000c2af2600c4974000c28f1c0045902e
+:108ec0004000c28f1a0043901b0042900012020023
+:108ed00025104300ffff42300210a27021188200cb
+:108ee0001000c28f211862001400c28f23104300ab
+:108ef0001800c2af4000c38f4000c28f1d004490d5
+:108f00001800c28f1b004400f40180001210000002
+:108f1000190062a8160062b84000c28f1900438889
+:108f20001600439821106000f50f422c06004010f7
+:108f3000000000004000c38f010002241e0062a058
+:108f400010000010000000004000c28f190043888c
+:108f500016004398f4ff02342b104300060040141f
+:108f6000000000004000c38f020002241e0062a027
+:108f700004000010000000004000c38f0300022422
+:108f80001e0062a04000c28f1e0043900300022416
+:108f900014006214000000004000c28f03004388e8
+:108fa0000000439821106000212040002c0005247f
+:108fb000a833400f000000007c8182af4000c48fc6
+:108fc0004000c28f0f0043880c0043981000c28fee
+:108fd00021106200130082a8100082b81200001055
+:108fe000000000007c8180af4000c48f4000c28f31
+:108ff0000f004388212860000c0045984000c28f74
+:109000001400439015004290001202002510430006
+:10901000ffff423002110200ffff42302110a20088
+:10902000130082a8100082b82400c3970002022413
+:109030000500621000000000030002241c00c2a30f
+:10904000030002248c8182a31c00c2932800c2afbb
+:109050002800c28f21e8c0033800bf8f3400be8fc4
+:109060003000b08f4000bd270800e0030000000082
+:10907000f0ffbd270800beaf21f0a0031000c4af71
+:109080000000c0af1000c28f140042940000c2afb5
+:109090000000c28f001402000000c2af1000c28f97
+:1090a0001a0043940000c28f251043000000c2af95
+:1090b0000000c28f21e8c0030800be8f1000bd274a
+:1090c0000800e00300000000d8ffbd272400bfaf68
+:1090d0002000beaf21f0a0032800c4af2c00c5af14
+:1090e0001400c0af2800c28f07004010000000002d
+:1090f0002c00c28f0200422c03004014000000002c
+:109100000500001000000000ffff02241c00c2af99
+:10911000f6000010000000002c00c28fffff432467
+:109120002800c28f2b1062000500401000000000d4
+:10913000ffff02241c00c2afec0000100000000082
+:109140006c80829309004010000000009235400faf
+:10915000000000000500401000000000ffff022496
+:109160001c00c2afe10000100000000000a0023ca3
+:109170009c0444242128000000020624096b400faf
+:109180000000000000a0023c9c0442241000c2af7a
+:109190002800c28f1800c2af1800c48f1505023c0a
+:1091a0005b5642341900820010180000231083001f
+:1091b00042100200211062004213020080130200dc
+:1091c0001400c2af1800c58f1505023c5b5642342f
+:1091d0001900a200101800002310a3004210020082
+:1091e0002110620042230200211080008019020039
+:1091f0002318640000120300231043002310a20070
+:109200001800c2af1800c48f1004023c054142345c
+:109210001900820010180000231083004210020081
+:109220002110620042110200801902001400c28f56
+:10923000251043001400c2af1800c48f1004023c74
+:1092400005414234190082001018000023108300e9
+:109250004210020021106200421902002110600039
+:109260008011020023104300231082001800c2afb7
+:109270001800c28f010043241400c28f2510430040
+:109280001400c2af00a0023c9c0443241400c28f0f
+:1092900002140200bf0162a000a0023c9c0443240f
+:1092a0001400c28f02120200c00162a000a0023ca2
+:1092b0009c0443241400c28fc10162a01000c28f1d
+:1092c0002c00c48f2800c38f23188300cd0143a82e
+:1092d000ca0143b81000c28fcd014388ca01439828
+:1092e000211060003910422c0600401000000000e0
+:1092f0001000c38f01000224c20162a012000010fe
+:10930000000000001000c28fcd014388ca014398bd
+:109310003f00023c5ffd42342b1043000600401426
+:10932000000000001000c38f06000224c20162a0ea
+:109330000500001000000000ffff02241c00c2af67
+:109340006a000010000000001000c28f2800c38fc8
+:10935000c90143a8c60143b82800c38f2c00c28f9f
+:1093600021106200ffff42241800c2af1800c48f12
+:109370001505023c5b5642341900820010180000ab
+:1093800023108300421002002110620042130200e9
+:10939000801302001400c2af1800c58f1505023cef
+:1093a0005b5642341900a200101800002310a300dd
+:1093b00042100200211062004223020021108000ae
+:1093c00080190200231864000012030023104300d8
+:1093d0002310a2001800c2af1800c48f1004023c72
+:1093e0000541423419008200101800002310830048
+:1093f0004210020021106200421102008019020096
+:109400001400c28f251043001400c2af1800c48f8f
+:109410001004023c0541423419008200101800007b
+:109420002310830042100200211062004219020042
+:1094300021106000801102002310430023108200dd
+:109440001800c2af1800c28f010043241400c28f5d
+:10945000251043001400c2af00a0023c9c0443242a
+:109460001400c28f02140200c30162a000a0023cdb
+:109470009c0443241400c28f02120200c40162a0a3
+:1094800000a0023c9c0443241400c28fc50162a0ca
+:109490001000c28fbe0140a01000c38f55000224ef
+:1094a000fe0162a01000c38faaff0224ff0162a088
+:1094b0002120000000a0023c9c0445240100062459
+:1094c0005b4a400f00000000211840000100022408
+:1094d0000500621000000000ffff02241c00c2af64
+:1094e00002000010000000001c00c0af1c00c28f72
+:1094f00021e8c0032400bf8f2000be8f2800bd27b5
+:109500000800e0030000000070ffbd278c00bfaf23
+:109510008800beaf21f0a003211080009400c5afe9
+:109520009800c6af9000c2a32800c2274800c2af6f
+:109530008c8180a34800c28f00a0033c9c0463245c
+:10954000030043a8000043b8e748400f00000000b4
+:10955000654b400f0000000021184000010002246c
+:109560000700621000000000060002248c8182a324
+:10957000ffff02245c00c2afd8030010000000000f
+:109580002120000000a0023c9c044524d349400f48
+:109590000000000007004014000000001b0002242f
+:1095a0008c8182a3ffff03245c00c3afcb030010b8
+:1095b000000000004800c28f030043880000439869
+:1095c000211060002000c2af2000c28ffe01439036
+:1095d000550002246b006214000000002000c28fbe
+:1095e000ff014390aa0002246600621400000000fc
+:1095f0004800c28f03004388000043982110600098
+:1096000021204000360005247a33400f000000007e
+:10961000211840004600022450006214000000009f
+:109620004800c28f03004388000043982110600067
+:1096300021204000370005247a33400f000000004d
+:109640002118400041000224440062140000000080
+:109650004800c28f03004388000043982110600037
+:1096600021204000380005247a33400f000000001c
+:109670002118400054000224380062140000000049
+:109680004800c28f03004388000043982110600007
+:1096900021204000390005247a33400f00000000eb
+:1096a00021184000310002242c0062140000000048
+:1096b0004800c28f030043880000439821106000d7
+:1096c00021204000260005247a33400f00000000ce
+:1096d000211840002900022420006214000000002c
+:1096e0009000c2836000c2af6000c38f0d006010a5
+:1096f00000000000010002246000c38f030062101c
+:10970000000000001f000010000000001f000224e5
+:109710008c8182a3ffff02245c00c2af6f030010a4
+:10972000000000004800c28f070040a8040040b8b5
+:109730004800c48fb322400f000000001100401009
+:10974000000000001b0002248c8182a3ffff032481
+:109750005c00c3af610300100000000000a0023ce9
+:109760009c0442241000c2af4800c38f1000c28f77
+:10977000c9014488c601449821108000070062a8ee
+:10978000040062b89000c2837c00c2af7c00c38f2b
+:109790003302601000000000010002247c00c38f2f
+:1097a00003006210000000003802001000000000fa
+:1097b0001000c28fcd014388ca0143982110600078
+:1097c0001400c2af1400c28f3910422c2d0040107b
+:1097d000000000004800c38f010002241e0062a0a8
+:1097e0001000c38f01000224c20162a021200000ea
+:1097f00000a0023c9c044524010006245b4a400f63
+:1098000000000000070040140000000009000224ce
+:109810008c8182a3ffff02245c00c2af2f030010e3
+:10982000000000001400c28f2810422c06004014d3
+:10983000000000004800c38f020002241d0062a047
+:1098400004000010000000004800c38f0100022443
+:109850001d0062a000a0023c9c04442421280000ba
+:1098600000020624096b400f0000000000a0023c2b
+:109870009c044324320002243a0062a04d000010f0
+:10988000000000001400c38f3f00023c5ffd423423
+:109890002b10430041004014000000004800c38f1b
+:1098a000020002241e0062a01000c38f06000224e2
+:1098b000c20162a02120000000a0023c9c044524bb
+:1098c000010006245b4a400f00000000070040141e
+:1098d00000000000090002248c8182a3ffff032402
+:1098e0005c00c3affd020010000000001400c28f36
+:1098f000e8fd42241800c2af4800c38f01000224d3
+:109900001d0062a01800c28fedff03342b1062000f
+:109910000b004010000000004800c38f4800c28fb9
+:109920001d004290401002001d0062a01800c28f6e
+:10993000421002001800c2aff2ff00100000000049
+:109940004800c28f1d0042908100422c0700401445
+:1099500000000000040002248c8182a3ffff022487
+:109960005c00c2afdd0200100000000000a0023c5d
+:109970009c0444242128000000020624096b400fa7
+:109980000000000000a0023c9c0443243600022496
+:109990003a0062a007000010000000001700022437
+:1099a0008c8182a3ffff03245c00c3afcb020010b5
+:1099b000000000004800c28f1d00429040180200c5
+:1099c0001400c28f21106200dfff42245000c2af9a
+:1099d0004800c28f1e004390010002240900621457
+:1099e000000000004800c28f1d0043905501022472
+:1099f00002106270020042245400c2af0600001040
+:109a0000000000004800c28f1d00429000120200ba
+:109a1000020042245400c2af5400c38f5000c28fd2
+:109a200021106200ffff43245400c28f1b0062001c
+:109a3000f4014000121000005000c2af00a0033c2f
+:109a4000ebff02249c0462a000a0023c9c0443247f
+:109a50003c000224010062a000a0023c9c044324bc
+:109a600090ff0224020062a000a0023c9c04432458
+:109a70004d000224030062a000a0023c9c04432489
+:109a800043000224040062a000a0023c9c04432482
+:109a900048000224050062a000a0023c9c0443246c
+:109aa00050000224060062a000a0023c9c04432453
+:109ab00020000224070062a000a0023c9c04432472
+:109ac00046000224080062a000a0023c9c0443243b
+:109ad00041000224090062a000a0023c9c0443242f
+:109ae000540002240a0062a000a0023c9c0442240c
+:109af0000b0040a000a0023c9c044324020002246e
+:109b00000c0062a000a0023c9c0443244800c28fc9
+:109b10001d0042900d0062a000a0023c9c04432462
+:109b2000080002240e0062a000a0023c9c04422413
+:109b30000f0040a04800c38f4800c28f0700448830
+:109b40000400449821108000080042240b0062a801
+:109b5000080062b800a0023c9c04432402000224d6
+:109b6000100062a04800c38f020002241c0062a003
+:109b700000a0023c9c044224110040a000a0023c32
+:109b80009c04432402000224120062a04800c38ff8
+:109b90001400629000004230140062a01500629030
+:109ba0000000423002004234150062a000a0023cd6
+:109bb0009c044224130040a000a0023c9c044224c8
+:109bc000140040a000a0023c9c044324f8ff02249f
+:109bd000150062a000a0023c9c0443245000c28fe8
+:109be000160062a000a0023c9c0443245000c28fd7
+:109bf00002120200170062a04800c48f5000c68ff6
+:109c0000ffffc230ff0045301a0082900000423052
+:109c1000211840002110a000251062001a0082a027
+:109c2000ffffc23002120200ffff45301b0082908e
+:109c300000004230211840002110a00025106200d1
+:109c40001b0082a000a0023c9c0443243f0002248d
+:109c5000180062a000a0023c9c044224190040a00d
+:109c600000a0023c9c044324ffff02241a0062a0cf
+:109c700000a0023c9c0442241b0040a000a0023c27
+:109c80009c0444244800c28f070043880400439882
+:109c9000211060001c0082a000a0023c9c0444240f
+:109ca0004800c28f070043880400439821106000d9
+:109cb000021202001d0082a000a0023c9c04442469
+:109cc0004800c28f070043880400439821106000b9
+:109cd000021402001e0082a000a0023c9c04442446
+:109ce0004800c28f07004388040043982110600099
+:109cf000021602001f0082a000a0023c9c04432424
+:109d00001400c28f200062a000a0023c9c044324e7
+:109d10001400c28f02120200210062a000a0023cc7
+:109d20009c0443241400c28f02140200220062a08b
+:109d300000a0023c9c0443241400c28f02160200bf
+:109d4000230062a000a0023c9c044224240040a006
+:109d500000a0023c9c044224250040a000a0023c3c
+:109d60009c04432429000224260062a000a0023c97
+:109d70009c0444249400c28fffff0324241043005a
+:109d8000270082a000a0023c9c0442246400c2afd1
+:109d90009400c28f6800c2af6800c28f0400410403
+:109da000000000006800c38fff0063246800c3af99
+:109db0006800c38f03120300ffff03242410430035
+:109dc0006400c38f280062a000a0023c9c044224cf
+:109dd0006c00c2af9400c28f7000c2af7000c28f1f
+:109de0000500410400000000ffff02347000c38f33
+:109df000211862007000c3af7000c38f031403000a
+:109e0000ffff0324241043006c00c38f290062a0cd
+:109e100000a0023c9c0442247400c2af9400c28f94
+:109e20007800c2af7800c28f060041040000000035
+:109e3000ff00023cffff42347800c38f211862000c
+:109e40007800c3af7800c38f03160300ffff03241d
+:109e5000241043007400c38f2a0062a09800c28fb0
+:109e600029004010000000005800c0a35800c39310
+:109e70009800c28f21106200000042801300401041
+:109e8000000000005800c2930b00422c0f0040104d
+:109e90000000000000a0023c5800c3939c04422430
+:109ea000212062005800c3939800c28f21106200e5
+:109eb000000042902b0082a05800c293010042246f
+:109ec0005800c2a3e9ff0010000000005800c29330
+:109ed0000b00422c1b0040100000000000a0043cbe
+:109ee0005800c393010062245800c2a3ff006330ee
+:109ef0009c04822421186200200002242b0062a00e
+:109f0000f2ff0010000000005800c0a35800c293e8
+:109f10000b00422c0b0040100000000000a0023c8f
+:109f20005800c3939c044224211062002b0040a0df
+:109f30005800c293010042245800c2a3f3ff00104e
+:109f40000000000000a0023c9c04432446000224c0
+:109f5000360062a000a0023c9c044324410002247d
+:109f6000370062a000a0023c9c0443245400022459
+:109f7000380062a000a0023c9c044324310002246b
+:109f8000390062a000a0023c9c044324200002246b
+:109f90003b0062a000a0023c9c0443242000022459
+:109fa0003c0062a000a0023c9c0443242000022448
+:109fb0003d0062a000a0023c9c0443245500022402
+:109fc000fe0162a000a0023c9c044324aaff0224dc
+:109fd000ff0162a04800c48f4800c28f0b00438875
+:109fe00021286000080045984800c28f1c00469058
+:109ff0004800c28f1a0043901b00429000120200da
+:10a0000025104300ffff42300210c2702110a20051
+:10a010000f0082a80c0082b84800c28f0700438856
+:10a0200004004398211060002120400000a0023c61
+:10a030009c044524213000005b4a400f00000000d2
+:10a040001800401400000000090002248c8182a343
+:10a05000ffff02245c00c2af2001001000000000de
+:10a060004800c48fb322400f000000000d004010d4
+:10a07000000000001b0002248c8182a3ffff032448
+:10a080005c00c3af15010010000000001f00022497
+:10a090008c8182a3ffff02245c00c2af0f0100107d
+:10a0a0000000000000a0023c9c0444242128000081
+:10a0b00000020624096b400f0000000000a0033cd2
+:10a0c000f8ff02249c0462a000a0023c9c044324ec
+:10a0d000ffff0224010062a000a0023c9c04432474
+:10a0e000ffff0224020062a04800c28f1e004390be
+:10a0f00002000224050062140000000000a0023cdf
+:10a100009c044324ffff0224030062a04800c28f86
+:10a110001c004290ffff42244c00c2a74c00c39792
+:10a12000ffff02341f006210000000004800c28fd1
+:10a130000b00438821206000080044984c00c5971c
+:10a140004800c28f1a0043901b0042900012020088
+:10a1500025104300ffff42300210a2702110820040
+:10a160002120400000a0023c9c0445242130000036
+:10a170005b4a400f00000000050040140000000092
+:10a18000ffff02245c00c2afd400001000000000fa
+:10a190004c00c297ffff42244c00c2a7dfff001013
+:10a1a0000000000000a0023c9c0444242128000080
+:10a1b00004000624096b400f000000004800c28f15
+:10a1c0000b004388080043982110600001004224de
+:10a1d0005800c2a35800c5934800c28f0b004388a3
+:10a1e00021206000080044984800c28f1a00439064
+:10a1f0001b0042900012020025104300ffff423076
+:10a20000211082002b10a200290040100000000045
+:10a210004800c28f1c004290ffff42244c00c2a79e
+:10a220004c00c397ffff02341c00621000000000c6
+:10a230005800c4934c00c5974800c28f1a00439041
+:10a240001b0042900012020025104300ffff423025
+:10a250000210a270211082002120400000a0023cc8
+:10a260009c044524213000005b4a400f00000000a0
+:10a270000500401400000000ffff02245c00c2af94
+:10a2800096000010000000004c00c297ffff42241f
+:10a290004c00c2a7e2ff0010000000005800c2936b
+:10a2a000010042245800c2a3caff001000000000b1
+:10a2b0004800c28f14004390150042900012020023
+:10a2c00025104300ffff423040110200ff014224ed
+:10a2d0008000c2af8000c38f040061040000000052
+:10a2e0008000c28fff0142248000c2af8000c38f74
+:10a2f000431203001c00c2af010002245800c2a395
+:10a300005800c2931c00c38f2b104300170040104d
+:10a31000000000004800c28f0f0043880c004398e3
+:10a320005800c293211062002120400000a0023c8e
+:10a330009c044524213000005b4a400f00000000cf
+:10a340000500401400000000ffff02245c00c2afc3
+:10a3500062000010000000005800c2930100422477
+:10a360005800c2a3e6ff0010000000009800c28f52
+:10a3700049004010000000005800c0a35800c393db
+:10a380009800c28f2110620000004280130040102c
+:10a39000000000005800c2930b00422c0f00401038
+:10a3a0000000000000a0023c5800c3939c0442241b
+:10a3b000212062005800c3939800c28f21106200d0
+:10a3c00000004290000082a05800c2930100422485
+:10a3d0005800c2a3e9ff0010000000005800c2931b
+:10a3e0000b00422c0c0040100000000000a0043cb8
+:10a3f0005800c393010062245800c2a3ff006330d9
+:10a400009c0482242118620020000224000062a023
+:10a41000f2ff00100000000000a0023c9c04432456
+:10a42000080002240b0062a000a0023c9c0443240c
+:10a4300011000224110062a000a0023c9c044324ed
+:10a4400011000224130062a000a0023c9c044324db
+:10a4500011000224170062a04800c28f0f00438839
+:10a460000c004398211060002120400000a0023c15
+:10a470009c044524213000005b4a400f000000008e
+:10a480001500401400000000ffff03245c00c3af70
+:10a4900012000010000000004800c28f0f00438827
+:10a4a0000c004398211060002120400000a0023cd5
+:10a4b0009c044524213000005b4a400f000000004e
+:10a4c0000500401400000000ffff02245c00c2af42
+:10a4d00002000010000000005c00c0af5c00c28ff2
+:10a4e00021e8c0038c00bf8f8800be8f9000bd277d
+:10a4f0000800e00300000000d0ffbd272c00bfaf24
+:10a500002800beaf21f0a0033000c4af3400c5afb7
+:10a510003000c28f0000428c1000c2af3000c28fea
+:10a520003800428c1c00c2af3400c28f000042943d
+:10a53000021102001500c2a31000c28f1e0042903b
+:10a540002000c2af2000c38f010062281f0040140a
+:10a55000000000002000c38f030062281000401498
+:10a5600000000000030002242000c38f03006210db
+:10a570000000000015000010000000001000c28f55
+:10a580001500c3931d0042901b006200f4014000bf
+:10a59000101000001500c2a30c0000100000000005
+:10a5a0001c00c38f7c81828f0800621000000000b5
+:10a5b0001000c28f1500c3931d0042901b00620063
+:10a5c000f4014000101000001500c2a31000c48f59
+:10a5d0001c00c58fcd33400f000000001800c2af33
+:10a5e0001500c3931800c28f212062001000c28f93
+:10a5f0000300438800004398211060002128400098
+:10a60000213000005b4a400f0000000004004014ad
+:10a61000000000001400c0a30300001000000000b0
+:10a62000010002241400c2a31400c29321e8c00355
+:10a630002c00bf8f2800be8f3000bd270800e0032c
+:10a6400000000000d0ffbd272c00bfaf2800beaf28
+:10a6500021f0a0033000c4af3400c5af1c00c0af70
+:10a660003400c28f1e0042902400c2af02000224b8
+:10a670002400c38f19006210000000002400c38f63
+:10a6800003006228070040100000000001000224bf
+:10a690002400c38f17006210000000001900001092
+:10a6a00000000000030002242400c38f0300621096
+:10a6b000000000001300001000000000ff0f023c2b
+:10a6c000ffff42341800c2afff0f023cf8ff4234d4
+:10a6d0001400c2af0b00001000000000ffff0234a6
+:10a6e0001800c2aff8ff02341400c2af050000101a
+:10a6f00000000000ffff02341800c2aff80f022470
+:10a700001400c2af3000c28f0700401000000000ec
+:10a710003000c38f0100022403006210000000001b
+:10a720000500001000000000020002241c00c2af5f
+:10a7300035000010000000001c00c28f32004014e1
+:10a74000000000003400c48f3000c58f8c39400fea
+:10a75000000000001000c2af1000c38f1800c28fad
+:10a760000500621400000000010002241c00c2afba
+:10a77000f1ff0010000000001000c28f0700401021
+:10a78000000000001000c38f0100022403006210cb
+:10a79000000000000500001000000000020002247c
+:10a7a0001c00c2afe4ff0010000000001000c28fc8
+:10a7b0001400c38f2b10430003004014000000005e
+:10a7c000020002241c00c2af3400c48f3000c58fc9
+:10a7d0002130000021380000af3a400f0000000097
+:10a7e000211840001800c28f03006214000000000e
+:10a7f000010002241c00c2af1000c28f3000c2afa3
+:10a80000cdff0010000000003400c48f212800009c
+:10a810002130000001000724af3a400f0000000083
+:10a820001c00c38f02000224050062140000000017
+:10a83000010002242000c2af02000010000000004e
+:10a840002000c0af2000c28f21e8c0032c00bf8fc2
+:10a850002800be8f3000bd270800e0030000000084
+:10a86000c0ffbd273c00bfaf3800beaf21f0a00342
+:10a870004000c4af4400c5af2110c0004800c2a3cf
+:10a880004000c28f0000428c1400c2af4000c28f53
+:10a890003400428c1c00c2af4000c28f3800428c92
+:10a8a0002400c2af4400c28f000042940211020093
+:10a8b0002800c2a31400c28f1e0042903000c2af15
+:10a8c0003000c38f01006228230040140000000004
+:10a8d0003000c38f03006228130040140000000002
+:10a8e000030002243000c38f030062100000000048
+:10a8f00019000010000000001400c28f2800c3934c
+:10a900001d0042901b006200f40140001010000086
+:10a910002800c2a3ff0f023cf8ff42342000c2af60
+:10a920000d000010000000001c00c28f0800401045
+:10a93000000000001400c28f2800c3931d00429045
+:10a940001b006200f4014000101000002800c2a3a8
+:10a95000f8ff02342000c2af4800c2930600401442
+:10a96000000000004400c28f000042940f004230fb
+:10a9700096004014000000002800c2930600401416
+:10a98000000000004400c28f000042941000422cde
+:10a9900006004010000000004800c293030040146d
+:10a9a000000000002c000010000000001c00c28ffe
+:10a9b00004004014000000002400c0af2600001076
+:10a9c000000000004800c2930d004010000000008d
+:10a9d0004400c38f1400c28f1d004290001102007a
+:10a9e00000006394ffff42301b006200f40140004e
+:10a9f000121000002900c2a3030000100000000094
+:10aa0000010002242900c2a32900c29312004010b1
+:10aa1000000000001400c48f2400c58f8c39400f43
+:10aa2000000000002400c2af2400c38f2000c28faa
+:10aa30002b1062000300401400000000060000100c
+:10aa4000000000002900c293ffff42242900c2a396
+:10aa5000edff0010000000002400c28f2000c38f13
+:10aa60002b10430054004010000000004000c38f32
+:10aa70002400c28f380062ac1400c48f2400c58f3c
+:10aa8000cd33400f000000001800c2af2400c38f78
+:10aa90007c81828f13006214000000002800c393a1
+:10aaa0001800c28f212062001400c28f1300438857
+:10aab00010004398211060002b1082000900401400
+:10aac000000000001400c28f1e0043900300022407
+:10aad00004006210000000001000c0af450000102c
+:10aae000000000006c80829308004010000000000d
+:10aaf0009235400f000000000400401000000000ec
+:10ab00002c00c0af3d00001000000000688080af46
+:10ab10006e8080a32800c3931800c28f212062009a
+:10ab20001400c28f03004388000043982110600086
+:10ab300021284000d349400f0000000021184000a8
+:10ab40000100022404006210000000001000c0afe9
+:10ab500015000010000000004800c2930d004010d6
+:10ab6000000000001400c28f0300438800004398d7
+:10ab70004400c28f000042940f004230ffff423079
+:10ab800040110200211062001000c2af0600001048
+:10ab9000000000001400c28f0300438800004398a7
+:10aba000211060001000c2afffff0224148082afaa
+:10abb0001000001000000000010002246d8082a33c
+:10abc0001000c0af0b000010000000001400c28f86
+:10abd00003004388000043984400c28f0000429461
+:10abe0000f004230ffff423040110200211062008e
+:10abf0001000c2af1000c28f2c00c2af2c00c28f59
+:10ac000021e8c0033c00bf8f3800be8f4000bd2745
+:10ac10000800e00300000000d0ffbd272c00bfaffc
+:10ac20002800beaf21f0a0033000c4af3400c5af90
+:10ac30002110c0003800c2a31400c0af8c8180a3d3
+:10ac40001000c0a31000c2930b00422c0e00401055
+:10ac5000000000001000c3931000c22721206200f2
+:10ac60003000c38f1000c293211062002000429078
+:10ac7000080082a01000c293010042241000c2a369
+:10ac8000f0ff0010000000003400c28f000040a45c
+:10ac90003000c48f3400c58f7d2b400f00000000b2
+:10aca00013004010000000001800c2273800c393b2
+:10acb0003000c48f212840003400c68f2138600046
+:10acc000182c400f000000001400c2af1400c28f07
+:10acd00009004014000000003000c48f472b400fd3
+:10ace000000000001400c2af0300001000000000cc
+:10acf000140002241400c2af1400c28f8c8182a3fe
+:10ad00001400c28f21e8c0032c00bf8f2800be8f23
+:10ad10003000bd270800e00300000000d0ffbd2781
+:10ad20002c00bfaf2800beaf21f0a0033000c4af9d
+:10ad30003000c28f2c0042941c00c2a71400c2270e
+:10ad40003000c48f21284000ca32400f00000000ac
+:10ad50001000c2af1000c28f1f004014000000009e
+:10ad60001c00c2273000c48f21284000b72e400f9e
+:10ad7000000000002000c2af2000c38f1400c28f6b
+:10ad80001a0062a41400c38fff0f023c241062005b
+:10ad90001800c2af1800c28f021402001800c2af20
+:10ada0002000c38f1800c28f140062a41c00c227a9
+:10adb0003000c48f212840003e29400f00000000d1
+:10adc000211840000100022403006210000000006e
+:10add000090002241000c2af1000c28f21e8c00396
+:10ade0002c00bf8f2800be8f3000bd270800e00375
+:10adf00000000000d0ffbd272c00bfaf2800beaf71
+:10ae000021f0a0033000c4af3400c5af010002241c
+:10ae10001000c2a33000c38f3000c28f3400428cb8
+:10ae2000380062ac3000c48f3400c58f01000624a6
+:10ae3000182a400f000000001c00c2af1c00c28f87
+:10ae400005004014000000001b0002241000c2a3f3
+:10ae500074000010000000001000c39301000224e1
+:10ae60006d006214000000001100c0a33400c28f06
+:10ae7000000042941400c2a73000c48f3400c58f74
+:10ae800021300000182a400f000000001c00c2af53
+:10ae90001c00c28f000042901200c2a33400c38f76
+:10aea0003400c28f0000429401004224000062a4da
+:10aeb0001200c393e50002240400621000000000a9
+:10aec0001200c2930c004014000000001c00c28f4e
+:10aed00009004010000000001100c293010042244c
+:10aee0001100c2a3ff004230030040140000000024
+:10aef000e1ff0010000000001c00c28f3c00401465
+:10af0000000000003000c28f3800428c1800c2af31
+:10af10001800c38f7c81828f200062140000000023
+:10af20003000c28f0000428c1e00439003000224b8
+:10af30000500621000000000020002241000c2a3fd
+:10af4000c5ff0010000000003000c38f1800c28f42
+:10af5000080062ac3000c48f01000524be2c400ff5
+:10af600000000000211840001500022405006214b2
+:10af700000000000020002241000c2a3b6ff00106f
+:10af8000000000003400c38f1400c297000062a4c8
+:10af90001000c0a3b0ff0010000000003000c38ffd
+:10afa0001800c28f080062ac3000c48f0100052475
+:10afb000be2c400f000000002118400015000224a4
+:10afc0000500621400000000020002241000c2a369
+:10afd000a1ff0010000000003400c38f1400c297ce
+:10afe000000062a41000c0a39bff0010000000003e
+:10aff0001100c3930100022497ff621400000000b7
+:10b000001000c0a33400c38f1400c297000062a4d4
+:10b0100091ff0010000000003400c38f1400c2979d
+:10b02000000062a41000c29305004014000000005c
+:10b03000010002242000c2af020000100000000046
+:10b040002000c0af2000c28f21e8c0032c00bf8fba
+:10b050002800be8f3000bd270800e003000000007c
+:10b06000d8ffbd272400bfaf2000beaf21f0a00352
+:10b070002800c4af2c00c5af3000c6af2110e000df
+:10b080003400c2a31000c0a32800c38f2800c28fc1
+:10b090003400428c380062ac2800c48f3000c58f69
+:10b0a00001000624182a400f000000001400c2af5f
+:10b0b0001400c28f05004014000000001b00022491
+:10b0c0001800c2af5a000010000000001400c48f26
+:10b0d0002c00c58f0b000624296c400f00000000d7
+:10b0e0003400c39312000224060062140000000022
+:10b0f0001400c38f100002240b0062a00400001093
+:10b10000000000001400c38f200002240b0062a086
+:10b110001400c28f0c0040a01400c28f140040a481
+:10b120001400c28f1a0040a41400c28f1c0040ac4f
+:10b13000932c400f000000001400c38f778182938e
+:10b140000d0062a01400c38f788182970e0062a464
+:10b150001400c38f82818297100062a43400c393cd
+:10b16000120002240c006210000000001400c38fc3
+:10b170008a818297120062a41400c38f8e81829705
+:10b18000160062a41400c38f80818297180062a405
+:10b1900007000010000000001400c28f120040a43d
+:10b1a0001400c28f160040a41400c28f180040a4df
+:10b1b0002800c38f1400c28f1c00428c140062aca4
+:10b1c0002800c38f1400c28f0e0042941c0062a49a
+:10b1d0002800c38f1400c28f100042941e0062a486
+:10b1e0002800c38f1400c28f0b004290300062a46d
+:10b1f0002800c38f3000c28f000042942c0062a44c
+:10b200002800c48f3000c58f3e29400f0000000089
+:10b210002118400001000224030062100000000019
+:10b22000090002241000c2a31000c2931800c2af8c
+:10b230001800c28f21e8c0032400bf8f2000be8ffa
+:10b240002800bd270800e00300000000e0ffbd2744
+:10b250001800beaf21f0a0030800deaf0400c22733
+:10b260000c00c2af80bf023c3002428c1400c2af5f
+:10b2700080bf023c2002428c1000c2af0800c38f86
+:10b2800080bf023c2002428c000062ac0c00c38fe5
+:10b2900080bf023c3002428c000062ac0c00c28fc6
+:10b2a0001400c38f0000428ceeff62140000000007
+:10b2b0000800c28f1000c38f0000428ce9ff6214a7
+:10b2c000000000000200c3970000c2972510620032
+:10b2d000788182a70600c3970000c29725106200fc
+:10b2e000808182a721e8c0031800be8f2000bd27ff
+:10b2f0000800e00300000000d8ffbd272400bfaf16
+:10b300002000beaf21f0a0032800c4af2110a00090
+:10b310002c00c2a32800c28f0000428c1000c2afd4
+:10b320002800c28f0800428c1400c2af2800c48fce
+:10b33000162d400f000000001400c2af1400c28f91
+:10b340000500401400000000150002241c00c2afdc
+:10b350003a000010000000001000c28f1e00439051
+:10b360000100022409006214000000001000c48fd4
+:10b370001400c58ff80f062421380000af3a400fa3
+:10b380000000000015000010000000001000c28f37
+:10b390001e00439002000224090062140000000015
+:10b3a0001000c48f1400c58ff8ff06342138000048
+:10b3b000af3a400f0000000008000010000000003d
+:10b3c0001000c48f1400c58fff0f023cf8ff4634f5
+:10b3d00021380000af3a400f000000002800c28f63
+:10b3e0000800428c1800c2af1000c48f1800c58f2f
+:10b3f0001400c68f21380000af3a400f0000000053
+:10b400002800c38f1400c28f080062ac2c00c393c5
+:10b410000100022408006214000000001000c48f24
+:10b420001400c58f2933400f000000001c00c2af7c
+:10b4300002000010000000001c00c0af1c00c28f02
+:10b4400021e8c0032400bf8f2000be8f2800bd2745
+:10b450000800e00300000000c8ffbd273400bfafb4
+:10b460003000beaf21f0a0033800c4af1400c0af5d
+:10b470003800c28f0000428c1000c2af3800c28f6b
+:10b480000800428c1800c2af1000c28f1e0042900c
+:10b490002800c2af020002242800c38f19006210e6
+:10b4a000000000002800c38f03006228070040103e
+:10b4b00000000000010002242800c38f1700621062
+:10b4c000000000001900001000000000030002242a
+:10b4d0002800c38f0300621000000000130000105a
+:10b4e00000000000ff0f023cf7ff42342000c2af13
+:10b4f000ff0f023cffff42342400c2af0b000010dc
+:10b5000000000000f7ff02342000c2afffff02344a
+:10b510002400c2af0500001000000000f70f022455
+:10b520002000c2afffff02342400c2af1800c28f58
+:10b530000200422c03004010000000000200022420
+:10b540001800c2af1800c28f1c00c2af1000c48f19
+:10b550001800c58f8c39400f000000001800c28f02
+:10b5600029004010000000001000c48f1800c58f93
+:10b570008c39400f000000001400c2af1400c38fcc
+:10b580002400c28f04006214000000001800c0af45
+:10b590001d000010000000001400c28f03004014c2
+:10b5a0000000000018000010000000001800c28f0a
+:10b5b000010042241800c2af1400c38f2000c28fc4
+:10b5c0000a006210000000001000c28f19004388ba
+:10b5d000160043981800c28f2b1043000300401040
+:10b5e0000000000003000010000000000200022420
+:10b5f0001800c2af1800c38f1c00c28fd7ff62149f
+:10b60000000000001800c0af1800c28f21e8c0037e
+:10b610003400bf8f3000be8f3800bd270800e00324
+:10b6200000000000d8ffbd272400bfaf2000beaf40
+:10b6300021f0a0032800c4af480002241400c2afc8
+:10b640008c8180a32800c28f2c0042941000c2a7d6
+:10b650002800c28f1800428c0000427c420040103b
+:10b66000000000006c8082930a004010000000007f
+:10b670009235400f0000000006004010000000005e
+:10b68000090002248c8182a3ffff022457000010ce
+:10b690001c00c2af2800c28f0000448c212800008b
+:10b6a00021300000af3a400f010007242800c48f6a
+:10b6b000b72e400f1000c5271800c2af1800c28f68
+:10b6c00008004014000000001b0002248c8182a3ab
+:10b6d000ffff02241400c2af1400c28f4300001009
+:10b6e0001c00c2af932c400f000000001800c38f55
+:10b6f0008e818297160062a41800c38f8081829782
+:10b70000180062a4000000001800c38f2800c28f38
+:10b710001400428c1c0062ac1800c38f2800c28f3a
+:10b72000300042940b0062a02800c48f3e29400fd5
+:10b730001000c527030040100000000005000010a5
+:10b740001400c0af090002248c8182a3ffff0224f1
+:10b750001400c2af2800c48f1800838cfeff02249f
+:10b7600024106200180082ac1200c0a71200c29719
+:10b770000300422c16004010000000001200c39786
+:10b780002110600000110200231043008018020005
+:10b7900000a0023c24094224211862002800c28f24
+:10b7a00007006214000000001200c3977481822712
+:10b7b000211862000100022405000010000062a0b0
+:10b7c0001200c29701004224e8ff00101200c2a735
+:10b7d0001400c38f4800022402006214000000001d
+:10b7e0001400c0af1400c28f1c00c2af1c00c28f77
+:10b7f00021e8c0032400bf8f2000be8f0800e003b3
+:10b800002800bd27d0ffbd272800bfaf2400beaf52
+:10b810002000b0af21f0a0033000c4af3400c5afaa
+:10b820001800c0a33400c28f000042940f004230c1
+:10b8300011004014000000003400c28f0000429448
+:10b840000d004010000000003000c38f3000c28f98
+:10b850003400428c380062ac3000c48f3400c58f95
+:10b8600001000624182a400f000000001000c2af9b
+:10b8700007000010000000003000c48f3400c58fa6
+:10b8800021300000182a400f000000001000c2af55
+:10b890001000c28f000042901500c2a31000c28f9a
+:10b8a00004004010000000001500c2930500401481
+:10b8b00000000000020002241700c2a37f00001055
+:10b8c000000000001500c393e50002240500621487
+:10b8d00000000000010002241700c2a3770000103e
+:10b8e000000000001000c28f0b0042901500c2a3a0
+:10b8f0001400c0a31400c2930800422c180040108a
+:10b90000000000001000c38f1400c29321104300f8
+:10b91000000042901600c2a31600c29321204000ee
+:10b92000b06c400f000000001600c2a33000c48fae
+:10b930001800c393010062241800c2a3ff00623004
+:10b94000211882001600c293200062a01400c29346
+:10b95000010042241400c2a3e6ff00100000000012
+:10b960001000c28f0b0042901500c2a31000c28fbe
+:10b97000080042901600c2a31400c0a31400c29392
+:10b980000300422c18004010000000001000c38f7c
+:10b990001400c29321106200080042901600c2a356
+:10b9a0001600c29321204000b06c400f0000000040
+:10b9b0001600c2a33000c48f1800c3930100622494
+:10b9c0001800c2a3ff006230211882001600c29343
+:10b9d000200062a01400c293010042241400c2a3fc
+:10b9e000e6ff0010000000003000c38f3400c28f5b
+:10b9f000000042942c0062a41000c28f000042900c
+:10ba00001500c2a31500c393e500022405006214cb
+:10ba100000000000010002241700c2a30200001071
+:10ba2000000000001700c0a33000c38f1000c28fb9
+:10ba30001c00428c140062ac3000d08f1000c48f08
+:10ba40001c24400f00000000040002ae1000c28f52
+:10ba50000b0042901500c2a33000c38f1500c293a3
+:10ba6000300062a41500c293100042300b00401059
+:10ba7000000000003000c38f1000c28f0e004294ff
+:10ba80001c0062a43000c38f1000c28f10004294cb
+:10ba90001e0062a409000010000000003000c38fe7
+:10baa0001000c28f160042941c0062a43000c38fa5
+:10bab0001000c28f180042941e0062a41700c293a7
+:10bac00021e8c0032800bf8f2400be8f2000b08f64
+:10bad0003000bd270800e00300000000d8ffbd27ac
+:10bae0002400bfaf2000beaf21f0a0032800c4afe8
+:10baf0002c00c5af2800c38f2800c28f3400428cb1
+:10bb0000380062ac2800c48f2c00c58f01000624c9
+:10bb1000182a400f000000001000c2af1000c28fb2
+:10bb200004004014000000001800c0af31000010f5
+:10bb3000000000001000c28f000042901400c2a359
+:10bb40001400c29302004014000000001000c0afb7
+:10bb50001000c28f25004010000000001400c393a5
+:10bb6000e500022404006214000000001000c0afd1
+:10bb70001e000010000000001000c28f0b00429059
+:10bb80001400c2a31400c3930f0002241700621410
+:10bb9000000000002c00c38f2c00c28f00004294d4
+:10bba00001004224000062a42800c48f2c00c58f2d
+:10bbb00021300000182a400f000000001000c2af22
+:10bbc0001000c28f04004014000000001800c0af35
+:10bbd00008000010000000001000c28f0b0042900f
+:10bbe0001400c2a3e7ff0010000000001000c28f85
+:10bbf0001800c2af1800c28f21e8c0032400bf8f15
+:10bc00002000be8f2800bd270800e00300000000d0
+:10bc1000d0ffbd272c00bfaf2800beaf21f0a0038e
+:10bc20003000c4af3400c5af2110c0003800c2a33b
+:10bc30001800c0af3000c28f0000428c2000c2af9d
+:10bc40003000c28f3400428c1c00c2af3000c38f62
+:10bc50001c00c28f380062ac3000c48f3400c58f26
+:10bc600001000624182a400f000000001000c2af97
+:10bc70001000c28f070040140000000001000224e1
+:10bc80008c8182a31b0002242400c2af4500001057
+:10bc9000000000001000c28f000042901400c2a3f8
+:10bca0001000c28f04004010000000001400c29376
+:10bcb00005004014000000000b0002241800c2af71
+:10bcc0002e000010000000001400c393e5000224c1
+:10bcd00005006214000000000b0002241800c2af2f
+:10bce00026000010000000001000c28f0b004290e0
+:10bcf0001400c2a31000c38fe5ff0224000062a05d
+:10bd00001000c48f1c24400f000000001c00c2afb4
+:10bd10001800c28f07004014000000003000c48fdc
+:10bd20003400c58f3e29400f00000000050040147c
+:10bd300000000000010002241800c2af0f00001034
+:10bd4000000000001c00c38f7c81828f0b006210fa
+:10bd5000000000003800c2930800401000000000fe
+:10bd60001c00c48f2000c58f9129400f00000000e7
+:10bd7000000042380100422c1800c2af1800c28fe8
+:10bd800004004014000000008c8180a30300001018
+:10bd900000000000010002248c8182a31800c28fe1
+:10bda0002400c2af2400c28f21e8c0032c00bf8f43
+:10bdb0002800be8f3000bd270800e003000000000f
+:10bdc000c0ffbd273c00bfaf3800beaf21f0a003cd
+:10bdd0004000c4af4400c5af1100c0a3010002245d
+:10bde0002800c2a78c8180a34400c28f07004014a2
+:10bdf00000000000190002248c8182a3ffff0224ae
+:10be00003000c2afd1000010000000004400c28f1b
+:10be1000200042244000c48f21284000213000002f
+:10be2000a136400f00000000070040140000000091
+:10be3000120002248c8182a3ffff02243000c2afd3
+:10be4000c2000010000000001000c0a31000c29348
+:10be50000b00422c0e004010000000001000c393a5
+:10be60001000c227212062004400c38f1000c2933b
+:10be70002110620020004290080082a01000c293ae
+:10be8000010042241000c2a3f0ff001000000000d7
+:10be90004400c28f2c0042942a00c2a72800c0a7e9
+:10bea0004400c38f4400c28f3400428c380062ac1f
+:10beb0002800c2274400c48f212840000100062426
+:10bec000182a400f000000002c00c2af2c00c28fc7
+:10bed00007004014000000001b0002248c8182a394
+:10bee000ffff02243000c2af9800001000000000e5
+:10bef0001000c0a31000c2930b00422c120040108f
+:10bf0000000000002c00c38f1000c29321204300ca
+:10bf10001000c3931000c22721106200000083802c
+:10bf200008004280030062100000000001000224ab
+:10bf30001100c2a31000c293010042241000c2a34a
+:10bf4000ecff0010000000001100c2930700401435
+:10bf500000000000110002248c8182a3ffff022454
+:10bf60003000c2af79000010000000001100c0a333
+:10bf70006d8080a32800c2274400c48f2128400080
+:10bf800021300000182a400f000000002c00c2af32
+:10bf90002c00c28f0d004014000000006d808393c0
+:10bfa00001000224030062140000000032000010af
+:10bfb000000000001b0002248c8182a3ffff0224ea
+:10bfc0003000c2af61000010000000002c00c28fe2
+:10bfd0000000428003004014000000002600001012
+:10bfe000000000001000c0a31000c2930b00422c00
+:10bff00012004010000000002c00c38f1000c293fc
+:10c00000212043001000c3931000c22721106200ba
+:10c0100000008380080042800300621000000000de
+:10c02000010002241100c2a31000c29301004224a7
+:10c030001000c2a3ecff0010000000001100c2932a
+:10c040000700401400000000110002248c8182a32c
+:10c05000ffff02243000c2af3c00001000000000cf
+:10c060001100c0a32800c297010042242800c2a7e3
+:10c07000c0ff0010000000002a00c2972800c2a7dd
+:10c080004400c38f4400c28f3400428c380062ac3d
+:10c090002800c2274400c48f21284000b72e400f3b
+:10c0a000000000002c00c2af2c00c28f070040141b
+:10c0b000000000001b0002248c8182a3ffff0224e9
+:10c0c0003000c2af21000010000000001000c0a32b
+:10c0d0001000c2930b00422c0e0040100000000024
+:10c0e0002c00c38f1000c293212043004400c38f53
+:10c0f0001000c2932110620020004290000082a034
+:10c100001000c293010042241000c2a3f0ff0010ef
+:10c11000000000002800c2274400c48f21284000ee
+:10c120003e29400f000000000700401400000000fe
+:10c13000090002248c8182a3ffff02243000c2afd9
+:10c1400002000010000000003000c0af3000c28fbd
+:10c1500021e8c0033c00bf8f3800be8f4000bd27e0
+:10c160000800e00300000000d0ffbd272c00bfaf97
+:10c170002800beaf21f0a0033000c4af3400c5af2b
+:10c180001000c0af1400c0af1400c28f03004228db
+:10c190001b004010000000001400c38f7481822730
+:10c1a00021106200000042901000401000000000ca
+:10c1b0001400c38f7481822721106200000040a008
+:10c1c0001400c38f211060000011020023104300ef
+:10c1d0008018020000a0023c2409422421106200c1
+:10c1e0001000c2af06000010000000001400c28f53
+:10c1f000010042241400c2afe3ff00100000000061
+:10c200001000c28f0600401400000000200002242d
+:10c210008c8182a32000c0af7801001000000000d4
+:10c220001000c28f200042243000c48f212840001b
+:10c2300021300000a136400f000000000b00401428
+:10c24000000000001400c38f74818227211862004f
+:10c2500001000224000062a0120002248c8182a34b
+:10c260002000c0af65010010000000003400c28f44
+:10c27000000042901800c2a31000c38f00a0023c2f
+:10c28000d8094224000062ac1000c28f040040ac08
+:10c290001000c28f080040ac1000c28f2c0040a4d8
+:10c2a0001000c38f20000224300062a41000c38f4e
+:10c2b0001880828f3400428c340062ac1000c38f2f
+:10c2c0001880828f3800428c380062ac00a0023c9b
+:10c2d000f80944241000c58fa732400f0000000069
+:10c2e0001000c48f00a0023cf80945240100062478
+:10c2f000213800006e1f400f00000000db004014da
+:10c30000000000001800c293bfff42242400c2af07
+:10c310002400c38f3700622cce00401000000000c4
+:10c320002400c28f80180200029d023c580642245d
+:10c33000211062000000428c080040000000000054
+:10c340001000c28f2c0042941a00c2a71a00c22704
+:10c350001000c48f2128400001000624042f400f44
+:10c36000000000001c00c2af1c00c28f0c01401472
+:10c37000000000001a00c2271000c48f21284000ce
+:10c3800021300000062b400f000000001c00c2af4f
+:10c390001c00c28f02014014000000001a00c227d6
+:10c3a0001000c48f21284000770006247a20400f17
+:10c3b000000000001c00c2af1000c28f3000429489
+:10c3c0001000423005004010000000001f00022451
+:10c3d0008c8182a3ff0002241c00c2af1c00c28f0c
+:10c3e000ef004014000000001000c48f212800005e
+:10c3f000020006249e38400f000000001c00c2af5f
+:10c400003400c28f010043802b000224e400621438
+:10c41000000000001000c28f1800438c020063343b
+:10c42000180043acde000010000000001000c28fb6
+:10c430001400428c2d004010000000001000c28f3c
+:10c440002c0042941a00c2a71a00c2271000c48f01
+:10c4500021284000770006247a20400f00000000c9
+:10c460001c00c2af1000c28f300042941000423056
+:10c4700005004010000000001f0002248c8182a3f0
+:10c48000ff0002241c00c2af1c00c28fc400401475
+:10c49000000000001000c48f2128000002000624c4
+:10c4a0009e38400f000000001c00c2af1c00c28f6d
+:10c4b00003004010000000001a0002248c8182a3b7
+:10c4c0003400c28f010043802b000224b4006214a8
+:10c4d000000000001000c28f1800438c020063347b
+:10c4e000180043acae000010000000001000c28f26
+:10c4f0002c0042941a00c2a71a00c2271000c48f51
+:10c500002128400001000624042f400f00000000f5
+:10c510001c00c2af1c00c28fa1004014000000002c
+:10c520001a00c2271000c48f2128400021300000cb
+:10c53000062b400f000000001c00c2af1c00c28f81
+:10c5400097004014000000001a00c2271000c48f9a
+:10c5500021284000770006247a20400f00000000c8
+:10c560001c00c2af1000c28f300042941000423055
+:10c5700005004010000000001f0002248c8182a3ef
+:10c58000ff0002241c00c2af1c00c28f84004014b4
+:10c59000000000001000c48f2128000002000624c3
+:10c5a0009e38400f000000001c00c2af1c00c28f6c
+:10c5b00003004010000000001a0002248c8182a3b6
+:10c5c0003400c28f010043802b00022474006214e7
+:10c5d000000000001000c28f1800438c020063347a
+:10c5e000180043ac6e000010000000001000c28f65
+:10c5f0002c0042941a00c2a71a00c2271000c48f50
+:10c6000021284000720006247a20400f000000001c
+:10c610001c00c2af3400c28f010043802b000224f3
+:10c620005f006214000000001000c28f30004294ce
+:10c63000100042305a004014000000001000c28f69
+:10c640001800438c01006334180043ac5400001000
+:10c65000000000001f0002248c8182a3ff0002243e
+:10c660001c00c2af4e000010000000001000c48f7c
+:10c6700000a0023cf8094524a732400f000000004a
+:10c680001800c393770002240f006210000000001e
+:10c690001800c393570002240b0062100000000032
+:10c6a0001800c3936100022407006210000000001c
+:10c6b0001800c39341000224030062100000000030
+:10c6c00035000010000000001a00c0a71a00c227a1
+:10c6d0001000c48f2128400021300000062b400f9d
+:10c6e000000000001c00c2af1c00c28f2c004014d0
+:10c6f000000000001a00c2271000c48f212840004b
+:10c70000770006247a20400f000000001c00c2af12
+:10c710001000c28f300042941000423005004010db
+:10c72000000000001f0002248c8182a3ff0002246d
+:10c730001c00c2af1c00c28f190040140000000092
+:10c740001000c48f21280000020006249e38400fec
+:10c75000000000001c00c2af1c00c28f030040108c
+:10c76000000000001a0002248c8182a33400c28fd2
+:10c77000010043802b000224090062140000000025
+:10c780001000c28f1800438c02006334180043acc1
+:10c7900003000010000000000b0002241c00c2afc8
+:10c7a000d54a400f000000000600401000000000c5
+:10c7b0001000c48f1800838cfeff02242410620036
+:10c7c000180082ac1c00c28f09004010000000005d
+:10c7d0001400c38f74818227211862000100022493
+:10c7e000000062a01000c0af0200001000000000b6
+:10c7f0008c8180a31000c28f2000c2af2000c28fa6
+:10c8000021e8c0032c00bf8f2800be8f3000bd2759
+:10c810000800e00300000000f8ffbd270000beafe5
+:10c8200021f0a0030800c4af8c8180a30800c28f50
+:10c830001000428c21e8c0030000be8f0800bd2715
+:10c840000800e00300000000d8ffbd272400bfafb0
+:10c850002000beaf21f0a0032800c4af00a0023c1e
+:10c86000e80642241000c2af8c8180a3d54a400f55
+:10c870000000000007004010000000001800022423
+:10c880008c8182a3ffff02241800c2af5800001061
+:10c89000000000001000c28f200042242800c48f36
+:10c8a0002128400021300000a136400f0000000088
+:10c8b0000700401400000000120002248c8182a3b3
+:10c8c000ffff02241800c2af490000100000000062
+:10c8d0001000c38f00a0023cd8094224000062acc3
+:10c8e0001000c28f040040ac1000c28f080040aca2
+:10c8f0001000c28f2c0040a41000c38f200002241f
+:10c90000300062a41000c38f1880828f3400428ce4
+:10c91000340062ac1000c38f1880828f3800428cc4
+:10c92000380062ac00a0023cf80944241000c58f16
+:10c93000a732400f000000001000c48f00a0023c8e
+:10c94000f809452401000624213800006e1f400f1d
+:10c95000000000001400c2af1400c28f0700401096
+:10c96000000000000b0002248c8182a3ffff022440
+:10c970001800c2af1e000010000000001000c28f9f
+:10c9800030004294100042300700401000000000c8
+:10c99000130002248c8182a3ffff02241800c2af7f
+:10c9a00013000010000000001000c28f2c00422471
+:10c9b0001000c48f2128400001000624042f400fde
+:10c9c000000000001400c2af1400c28f0400401425
+:10c9d000000000001800c0af0500001000000000bb
+:10c9e000010002248c8182a3ffff02241800c2af41
+:10c9f0001800c28f21e8c0032400bf8f2000be8f23
+:10ca00002800bd270800e00300000000e8ffbd2764
+:10ca10001400bfaf1000beaf21f0a0031800c4afd8
+:10ca20006c80829303004010000000009235400f9c
+:10ca3000000000001800c28f100040ac1800c28f28
+:10ca40000e0040a41800c28f0c0040a41800c38f31
+:10ca50001800c28f0400428c080062ac688080af6e
+:10ca600021e8c0031400bf8f1000be8f1800bd273f
+:10ca70000800e00300000000f8ffbd270000beaf83
+:10ca800021f0a0038c81829321e8c0030000be8fb7
+:10ca90000800bd270800e00300000000e8ffbd27f4
+:10caa0001000beaf21f0a0031800c4af1c00c5af3a
+:10cab0001800c28f0400c2af1c00c28f0800c2afb2
+:10cac0003c0002240000c2a30c00c0a30c00c293cf
+:10cad0000000c3932b1043000e0040100000000024
+:10cae0000c00c3930400c28f212062000c00c3938a
+:10caf0000800c28f2110620000004290000082a056
+:10cb00000c00c293010042240c00c2a3efff0010ee
+:10cb10000000000021e8c0031000be8f1800bd27f0
+:10cb20000800e00300000000e0ffbd271c00bfafcd
+:10cb30001800beaf21f0a0032000c4af2400c5af91
+:10cb40001400c0af2000c28f0000428c1000c2afa2
+:10cb50002000c48f162d400f000000002118400057
+:10cb60002400c28f000043ac2400c28f0000428c1e
+:10cb70000500401400000000150002241400c2af9c
+:10cb800041000010000000001000c28f1e00439002
+:10cb90000100022410006214000000002400c28f73
+:10cba0001000c48f0000458cf80f062421380000c7
+:10cbb000af3a400f0000000021184000ffff023490
+:10cbc0002800621400000000090002241400c2af13
+:10cbd00024000010000000001000c28f1e004390cf
+:10cbe0000200022410006214000000002400c28f22
+:10cbf0001000c48f0000458cf8ff06342138000077
+:10cc0000af3a400f0000000021184000ffff02343f
+:10cc10001400621400000000090002241400c2afd6
+:10cc200010000010000000002400c28f1000c48f0c
+:10cc30000000458cff0f023cf8ff4634213800000d
+:10cc4000af3a400f0000000021184000ff0f023ce7
+:10cc5000ffff4234030062140000000009000224b8
+:10cc60001400c2af1400c28f07004014000000007f
+:10cc70002400c28f1000c48f0000458c2933400f60
+:10cc8000000000001400c2af1400c28f21e8c003ee
+:10cc90001c00bf8f1800be8f2000bd270800e003d6
+:10cca00000000000d8ffbd272400bfaf2000beafaa
+:10ccb00021f0a0032800c4af2c00c5af1800c0a30a
+:10ccc0002800c48f2c00c58fcd33400f000000001a
+:10ccd0001400c2af6c808293090040100000000075
+:10cce0009235400f000000000500401000000000d9
+:10ccf000090002241c00c2af340000100000000034
+:10cd0000688080af6e8082930c00401400000000a9
+:10cd10002800c28f03004388000043982110600060
+:10cd2000212040002128000000020624096b400f4a
+:10cd300000000000010002246e8082a31000c0a346
+:10cd40002800c28f1d0043901000c2932b10430097
+:10cd50001c004010000000001800c293190040148d
+:10cd6000000000001400c3270000628c2120400056
+:10cd700001004224000062ac2800c28f03004388f7
+:10cd8000000043982110600021284000213000005d
+:10cd90005b4a400f000000002118400001000224ff
+:10cda0000300621000000000090002241800c2a362
+:10cdb0001000c293010042241000c2a3e0ff001043
+:10cdc000000000001800c2931c00c2af1c00c28ffc
+:10cdd00021e8c0032400bf8f2000be8f2800bd279c
+:10cde0000800e00300000000f8ffbd270000beaf10
+:10cdf00021f0a0030800c4af2110a0000c00c2a7be
+:10ce00000c00c3970800c28f2110620000004290fe
+:10ce100021e8c0030000be8f0800bd270800e00322
+:10ce200000000000f0ffbd270800beaf21f0a00306
+:10ce30001000c4af2110a0001400c2a71400c397b3
+:10ce40001000c28f21106200000042900000c2a3b7
+:10ce50001400c3971000c28f21106200010042909d
+:10ce60000100c2a30100c2930200c2a70200c29740
+:10ce7000001202000200c2a70000c3930200c29782
+:10ce8000251043000200c2a70200c29721e8c00398
+:10ce90000800be8f1000bd270800e003000000005e
+:10cea000e0ffbd271c00bfaf1800beaf21f0a003fc
+:10ceb0002000c4af2110a0002400c2a72400c29704
+:10cec0002000c48f212840008933400f000000005b
+:10ced0001000c2a72400c29702004224ffff423084
+:10cee0002000c48f212840008933400f000000003b
+:10cef0001200c2a71200c2971400c2af1400c28f62
+:10cf0000001402001400c2af1000c3971400c28fb7
+:10cf1000251043001400c2af1400c28f21e8c003e3
+:10cf20001c00bf8f1800be8f2000bd270800e00343
+:10cf300000000000f0ffbd270800beaf21f0a003f5
+:10cf40001000c4af1400c5af1000c28f1e00429085
+:10cf50000400c2af0400c38f0100622834004014f3
+:10cf6000000000000400c38f030062281400401476
+:10cf700000000000030002240400c38f03006210bd
+:10cf8000000000002a000010000000001400c28f02
+:10cf9000feff43241000c28f1d00429002206270e9
+:10cfa0001000c28f130043881000439821106000c6
+:10cfb000211082000000c2af1d0000100000000020
+:10cfc0001400c28f07004010000000001400c38f3f
+:10cfd000010002240300621000000000090000109c
+:10cfe000000000001000c28f0f0043880c0043981f
+:10cff0001400c28f211062000000c2af0c000010ac
+:10d00000000000001400c28ffeff43241000c28ff6
+:10d010001d004290022062701000c28f13004388ee
+:10d020001000439821106000211082000000c2af60
+:10d030000000c28f21e8c0030800be8f1000bd278a
+:10d040000800e00300000000d8ffbd272400bfafa8
+:10d050002000beaf21f0a0032800c4af2110a00023
+:10d060002c00c2a38c8180a32c00c393d8ff022480
+:10d070002410620007004010000000001f0002247e
+:10d080008c8182a3ffff02241800c2af3c00001075
+:10d09000000000002800c28f2c0042941000c2a79c
+:10d0a0002800c38f2800c28f3400428c380062ac45
+:10d0b0002800c48f1000c527b72e400f00000000c5
+:10d0c0001400c2af1400c28f07004014000000001b
+:10d0d0001b0002248c8182a3ffff02241800c2af30
+:10d0e00027000010000000001400c28f0b004290c7
+:10d0f0000800423007004010000000001f0002241a
+:10d100008c8182a3ffff02241800c2af1c00001014
+:10d11000000000002800c28f30004294100042300e
+:10d1200007004010000000001400c28f2c00c393c1
+:10d13000100063340b0043a0040000100000000046
+:10d140001400c38f2c00c2930b0062a02800c48f70
+:10d150001000c5273e29400f0000000007004014c2
+:10d1600000000000090002248c8182a3ffff02243a
+:10d170001800c2af02000010000000001800c0af8d
+:10d180001800c28f21e8c0032400bf8f2000be8f8b
+:10d190002800bd270800e00300000000c0ffbd27f5
+:10d1a0003c00bfaf3800beaf21f0a0034000c4afc9
+:10d1b0004400c5af4800c6af4c00c7af4400c38fa2
+:10d1c0004800c28f021062701000c2af4000c28fd0
+:10d1d0001400c2af1c00c0af3000c0a74c00c28f0b
+:10d1e0001800428c0000427c08004014000000003f
+:10d1f0001d0002248c8182a3090002241c00c2affe
+:10d200003400c0af09010010000000001000c28f00
+:10d2100004004014000000003400c0af03010010ff
+:10d2200000000000d54a400f000000000800401038
+:10d2300000000000180002248c8182a31800022440
+:10d240001c00c2af3400c0aff800001000000000a6
+:10d250006e8080a34c00c28f0000428c1800c2afc9
+:10d260004c00c28f0e0042942000c2a74c00c28f17
+:10d270001000428c2800c2af4c00c28f1800c48f2f
+:10d280000800458ccd33400f000000002400c2afe1
+:10d290004c00c28f0c0043942400c28f2110430025
+:10d2a0002400c2af6880838f4c00c28f0f006210d1
+:10d2b000000000006c8082930a0040100000000013
+:10d2c0009235400f000000000600401000000000f2
+:10d2d000090002248c8182a33400c0afd300001067
+:10d2e000000000004c00c28f688082af1480838fe2
+:10d2f0002400c28f1e006210000000006c80829328
+:10d300000a004010000000009235400f00000000ad
+:10d310000600401000000000090002248c8182a356
+:10d320003400c0afc1000010000000006e8080a378
+:10d330001800c28f0300438800004398211060004a
+:10d340002400c48f21284000d349400f0000000072
+:10d3500005004014000000001b0002248c8182a301
+:10d36000080002241c00c2af2400c28f148082afc8
+:10d370004c00c28f1400428c2c00c2af1c00c28f24
+:10d380009b004014000000001000c28f9800401065
+:10d39000000000002800c38f2c00c28f050062141b
+:10d3a000000000004c00c28f1800438c040063345e
+:10d3b000180043ac2000c3970002022465006214e9
+:10d3c00000000000010002243200c2a36c8082939e
+:10d3d0000a004010000000009235400f00000000dd
+:10d3e0000600401000000000090002248c8182a386
+:10d3f0003400c0af8d000010000000002000c0a766
+:10d400004c00c38f4c00c28f0c0042940100422498
+:10d410000c0062a44c00c38f1800c28f1d00429004
+:10d420000c006394ffff42301500621400000000fe
+:10d430004c00c28f0c0040a44c00c28f1800428cdc
+:10d440008000427c09004010000000004c00c48fa6
+:10d4500021280000be2c400f000000001c00c2afbd
+:10d460003200c0a306000010000000004c00c48f72
+:10d47000010005241f21400f000000001c00c2af66
+:10d480001c00c38f15000224060062140000000077
+:10d49000150002248c8182a33400c0af6300001009
+:10d4a000000000001c00c28f2a0040140000000091
+:10d4b0004c00c28f1800c48f0800458ccd33400f3c
+:10d4c000000000002400c2af4c00c28f0c00439447
+:10d4d0002400c28f211043002400c2af4c00c28f31
+:10d4e000688082af3200c293180040100000000034
+:10d4f0001800c28f03004388000043982110600089
+:10d500002400c48f21284000d349400f00000000b0
+:10d510000a004014000000001b0002248c8182a33a
+:10d52000080002241c00c2afffff0224148082af57
+:10d530003400c0af3d000010000000002400c28f86
+:10d54000148082af03000010000000002400c28f8e
+:10d55000148082af1c00c28f88ff401400000000be
+:10d560001800c28f03004388212060000000449807
+:10d570002000c397010062242000c2a7ffff623091
+:10d58000211844001400c28f00004290000062a0e5
+:10d590001400c28f010042241400c2af2800c28fc1
+:10d5a000010042242800c2af1000c28fffff4224b6
+:10d5b0001000c2af3000c297010042243000c2a761
+:10d5c0004c00c28f1800428c8000427c0400401046
+:10d5d000000000002c00c28f010042242c00c2afca
+:10d5e000010002246c8082a364ff00100000000090
+:10d5f0004c00c38f2000c2970e0062a44c00c38f62
+:10d600002800c28f100062ac4c00c38f2c00c28f68
+:10d61000140062ac3000c3974400c28f1b0062004c
+:10d62000f4014000121000003400c2af3400c28f79
+:10d6300021e8c0033c00bf8f3800be8f4000bd27eb
+:10d640000800e00300000000d8ffbd272400bfafa2
+:10d650002000beaf21f0a0036880828f1800c2af07
+:10d660001800c28f0000428c1400c2af1800c28f95
+:10d670001400c48f0800458ccd33400f000000001b
+:10d680001000c2af1800c28f0c0043941000c28f6c
+:10d69000211043001000c2af1400c28f0300438862
+:10d6a00000004398211060001000c48f2128400022
+:10d6b000213000005b4a400f0000000005004014cc
+:10d6c00000000000090002241c00c2af030000108b
+:10d6d000000000006c8080a31c00c0af1c00c28f43
+:10d6e00021e8c0032400bf8f2000be8f2800bd2783
+:10d6f0000800e00300000000f8ffbd270000beaff7
+:10d7000021f0a0030800c4af8c8180a30800c28f61
+:10d710000800c38f1000448c1400628c2610820015
+:10d720000100422c21e8c0030000be8f0800bd2785
+:10d730000800e00300000000c0ffbd273c00bfafb1
+:10d740003800beaf21f0a0034000c4af4400c5af15
+:10d750004800c6af4c00c7af4400c38f4800c28f1b
+:10d76000021062701000c2af4000c28f1400c2af3e
+:10d770002800c0af2c00c0a78c8180a34c00c28fb2
+:10d780000000428c1800c2af4c00c28f0e004294c1
+:10d790002400c2a74c00c28f1000428c1c00c2aff4
+:10d7a0004c00c28f1800428c4000427c060040149e
+:10d7b000000000001e0002248c8182a33000c0af54
+:10d7c000a9000010000000006c8082930a00401045
+:10d7d000000000009235400f0000000006004010dd
+:10d7e00000000000090002248c8182a33000c0af39
+:10d7f0009d000010000000006880838f4c00c28fe5
+:10d8000026006210000000002400c39700020224da
+:10d8100022006210000000004c00c28f688082afbe
+:10d820004c00c28f1800c48f0800458ccd33400fc8
+:10d83000000000002000c2af4c00c28f0c004394d7
+:10d840002000c28f211043002000c2af6e8080a351
+:10d850001800c28f03004388000043982110600025
+:10d860002000c48f21284000d349400f0000000051
+:10d870000800401400000000080002248c8182a3ec
+:10d88000080002242800c2af3000c0af76000010ac
+:10d89000000000002000c28f148082af1000c28ff1
+:10d8a00065004010000000004c00c28f1400438c43
+:10d8b0001c00c28f07006214000000003d0002241b
+:10d8c0008c8182a33d0002242800c2af5a000010c0
+:10d8d000000000002400c397000202243c006214f0
+:10d8e000000000002400c0a74c00c38f4c00c28f72
+:10d8f0000c004294010042240c0062a44c00c38f2f
+:10d900001800c28f1d0042900c006394ffff42304c
+:10d910000f006214000000004c00c28f0c0040a4f5
+:10d920004c00c48f010005241f21400f000000009f
+:10d930002800c2af2800c28f050040100000000080
+:10d940000f0002248c8182a33b0000100000000025
+:10d950004c00c28f1800c48f0800458ccd33400f97
+:10d96000000000002000c2af4c00c28f0c004394a6
+:10d970002000c28f211043002000c2af4c00c28f94
+:10d98000688082af6e8080a31800c28f0300438836
+:10d9900000004398211060002000c48f212840001f
+:10d9a000d349400f000000000700401400000000b1
+:10d9b000080002248c8182a3080002242800c2af40
+:10d9c0001d000010000000002000c28f148082aff4
+:10d9d0001400c58f1800c28f030043882120600007
+:10d9e000000044982400c397010062242400c2a7c9
+:10d9f000ffff623021104400000042900000a2a00e
+:10da00001400c28f010042241400c2af1c00c28f58
+:10da1000010042241c00c2af2c00c2970100422426
+:10da20002c00c2a71000c28fffff42241000c2af1b
+:10da30009aff0010000000004c00c38f2400c29722
+:10da40000e0062a44c00c38f1c00c28f100062ac99
+:10da50002c00c3974400c28f1b006200f4014000f9
+:10da6000121000003000c2af3000c28f21e8c003a6
+:10da70003c00bf8f3800be8f4000bd270800e00388
+:10da800000000000c0ffbd273800bfaf3400beafac
+:10da90003000b0af21f0a0034000c4af4400c5afd8
+:10daa0002110c0004800c2a32800c0a32800c293d0
+:10dab0000b00422c0b004010000000002800c39314
+:10dac0004400c28f2118620020000224000062a0de
+:10dad0002800c293010042242800c2a3f3ff0010d3
+:10dae000000000004000c28f000043802e0002248e
+:10daf00005006210000000004000c28f000042805c
+:10db000004004014000000002c00c0af730000109f
+:10db1000000000004000c48f9b6b400f000000001d
+:10db20001400c2a71400c2970d00422c0800401038
+:10db3000000000001800c227212040004000c58fcf
+:10db4000336b400f000000000400001000000000d4
+:10db50002c00c0af61000010000000001800c227b8
+:10db60004800c3932120400021286000cf37400f98
+:10db70000000000004004014000000002c00c0afb2
+:10db800056000010000000001800c22721204000ad
+:10db90002e0005245d6c400f000000001000c2af95
+:10dba0001000c28f0f004010000000001000c28f54
+:10dbb000000040a01000c28f010042241000c2af3c
+:10dbc0001000c48f9b6b400f000000000400422c2b
+:10dbd00004004014000000002c00c0af3f00001003
+:10dbe000000000001800c227212040009b6b400f5e
+:10dbf000000000000900422c040040140000000056
+:10dc00002c00c0af35000010000000002800c0a3a9
+:10dc10002800d0931800c227212040009b6b400fa2
+:10dc2000000000002b1002020e0040100000000057
+:10dc30002800c3934400c28f212062002800c393b0
+:10dc40001000c2272110620008004290000082a04c
+:10dc50002800c293010042242800c2a3ecff001058
+:10dc6000000000001000c28f1a00401000000000e9
+:10dc70001000c28f0000428016004010000000001b
+:10dc80002800c0a32800d0931000c48f9b6b400fc6
+:10dc9000000000002b1002020e00401000000000e7
+:10dca0002800c3934400c28f212062002800c39340
+:10dcb0001000c28f2110620000004290080082a074
+:10dcc0002800c293010042242800c2a3edff0010e7
+:10dcd00000000000010002242c00c2af2c00c28f03
+:10dce00021e8c0033800bf8f3400be8f3000b08ff2
+:10dcf0004000bd270800e00300000000c8ffbd276a
+:10dd00003400bfaf3000beaf21f0a0033800c4af75
+:10dd10002110a0003c00c2a33c00c2933800c48f75
+:10dd200021284000cf37400f0000000004004014bd
+:10dd3000000000002800c0af7900001000000000c3
+:10dd40001000c0a31000c2930800422c1b0040101a
+:10dd5000000000001000c3933800c28f2110620041
+:10dd6000000043802e000224140062100000000016
+:10dd70001000c3933800c28f21106200000042805f
+:10dd80000e004010000000001000c3931000c227d6
+:10dd9000212062001000c3933800c28f211062005e
+:10dda00000004290080082a01000c29301004224ab
+:10ddb0001000c2a3e3ff0010000000001000c29397
+:10ddc0001100c2a31000c2930800422c0b004010a7
+:10ddd000000000001000c393010062241000c2a3e1
+:10dde000ff0063301000c2272118620020000224c7
+:10ddf000080062a0f3ff0010000000001100c393b0
+:10de00003800c28f21106200000043802e000224df
+:10de10001a006214000000001100c29301004224a5
+:10de20001100c2a31100c3933800c28f21106200f9
+:10de30000000428011004010000000001000c39359
+:10de4000010062241000c2a3ff0063301000c2274b
+:10de5000212062001100c393010062241100c2a3bb
+:10de6000ff0063303800c28f211062000000429032
+:10de7000080082a0ebff0010000000001000c29319
+:10de80000b00422c0b004010000000001000c39358
+:10de9000010062241000c2a3ff0063301000c227fb
+:10dea0002118620020000224080062a0f3ff001085
+:10deb000000000002300c0a31800c3832000022438
+:10dec00003006214000000005f0002241800c2a3d7
+:10ded0001000c0a31000c2930c00422c0e00401092
+:10dee000000000001000c3933800c28f21206200a0
+:10def0001000c3931000c227211062000800429056
+:10df0000000082a01000c293010042241000c2a3ae
+:10df1000f0ff001000000000010002242800c2af42
+:10df20002800c28f21e8c0033400bf8f3000be8fad
+:10df30003800bd270800e00300000000d8ffbd271f
+:10df40002400bfaf2000beaf21f0a0032800c4af63
+:10df50002110a0002c00c2a31800c0a32800c48f69
+:10df60009b6b400f000000001000c2af1400c0af58
+:10df70001400c28f1000c38f2a104300b500401058
+:10df8000000000001400c38f2800c28f211062001f
+:10df900000004280210042280800401000000000dc
+:10dfa0001400c38f2800c28f21106200000043803c
+:10dfb0000500022469006214000000001400c38ff1
+:10dfc0002800c28f2110620000004380220002243a
+:10dfd00062006210000000001400c38f2800c28f8e
+:10dfe00021106200000043802b0002245b006210bd
+:10dff000000000001400c38f2800c28f21106200af
+:10e00000000043802c000224540062100000000035
+:10e010001400c38f2800c28f2110620000004380cb
+:10e020002f0002244d006210000000001400c38f76
+:10e030002800c28f21106200000043803a000224b1
+:10e0400046006210000000001400c38f2800c28f39
+:10e0500021106200000043803b0002243f00621058
+:10e06000000000001400c38f2800c28f211062003e
+:10e07000000043803c0002243800621000000000d1
+:10e080001400c38f2800c28f21106200000043805b
+:10e090003d00022431006210000000001400c38f14
+:10e0a0002800c28f21106200000043803e0002243d
+:10e0b0002a006210000000001400c38f2800c28fe5
+:10e0c00021106200000043805b00022423006210e4
+:10e0d000000000001400c38f2800c28f21106200ce
+:10e0e000000043805c0002241c006210000000005d
+:10e0f0001400c38f2800c28f2110620000004380eb
+:10e100005d00022415006210000000001400c38f9f
+:10e110002800c28f21106200000043807c0002248e
+:10e120000e006210000000001400c38f2800c28f90
+:10e1300021106200000043802e0002240a006214b5
+:10e14000000000001800c3930100022403006210c5
+:10e150000000000004000010000000001c00c0af20
+:10e160003e000010000000002c00c2931400401478
+:10e17000000000001400c38f2800c28f211062002d
+:10e18000000043802a0002240a0062100000000000
+:10e190001400c38f2800c28f21106200000043804a
+:10e1a0003f00022403006210000000000400001081
+:10e1b000000000001c00c0af28000010000000009c
+:10e1c0001400c38f2800c28f21106200000043801a
+:10e1d0002e0002240300621400000000010002244b
+:10e1e0001800c2a31400c38f2800c28f2110620040
+:10e1f000000042806100422811004014000000002d
+:10e200001400c38f2800c28f2110620000004280da
+:10e210007b0042280a004010000000001400c38f59
+:10e220002800c28f212062001400c38f2800c28ff3
+:10e230002110620000004290e0ff4224000082a012
+:10e240001400c28f010042241400c2af48ff001026
+:10e2500000000000010002241c00c2af1c00c28f9d
+:10e2600021e8c0032400bf8f2000be8f2800bd27f7
+:10e270000800e00300000000c8ffbd273400bfaf66
+:10e280003000beaf21f0a0033800c4af3c00c5afe2
+:10e290004000c6af3c00c28f2000c2af3800c28f22
+:10e2a0000000428c1800c2af4000c28f2800c2afed
+:10e2b000010002242800c38f070062100000000044
+:10e2c000020002242800c38f0a0062100000000030
+:10e2d0000d000010000000003800c28f2000c38f26
+:10e2e0001000428c211062002000c2af0600001016
+:10e2f000000000003800c28f1400438c2000c28f41
+:10e30000231062002000c2af6c8082930b0040108b
+:10e31000000000009235400f000000000700401090
+:10e3200000000000090002248c8182a3ffff022468
+:10e330002400c2afb7000010000000003800c28ff8
+:10e340000400428c1400c2af3800c38f1400c28f87
+:10e35000080062ac3800c28f1400428c1400c2afb7
+:10e360002000c38f1400c28f2b1043000700401001
+:10e37000000000001f0002248c8182a3ffff032401
+:10e380002400c3afa3000010000000003800c48fb9
+:10e390001800838cfbff022424106200180082ac5a
+:10e3a0003800c38f2000c28f100062ac2000c28fe3
+:10e3b0002c00c2af2c00c28f0400410400000000fa
+:10e3c0002c00c38fff0163242c00c3af2c00c38f2c
+:10e3d000431203001000c2af1000c28f401a0200a7
+:10e3e0002000c28f231043002000c2af3800c38f2b
+:10e3f0002000c28f0e0062a41800c28f1d0043903f
+:10e400001000c28f1b004300f401600012100000d6
+:10e410001400c2af1800c28f1d0043901400c28fb9
+:10e42000021862701000c28f231043001000c2afa8
+:10e430003800c38f1000c28f0c0062a41400c28f7a
+:10e4400051004010000000003800c48f1400c58f38
+:10e450001f21400f000000001c00c2a31c00c2933b
+:10e4600049004010000000001c00c3933c0002243f
+:10e470003f006214000000003800c28f1800428c78
+:10e480000000427c1c004010000000003800c38fd8
+:10e490003800c28f0400428c080062ac1400c38fa5
+:10e4a0000100022408006210000000001400c28f66
+:10e4b000ffff42243800c48f212840001f21400f55
+:10e4c000000000001c00c2a33800c48f21280000f7
+:10e4d000be2c400f000000002b0040100000000088
+:10e4e0000f0002248c8182a3ffff02242400c2af0c
+:10e4f00048000010000000003800c38f3800c28fb1
+:10e500000400428c080062ac1400c28fffff42245a
+:10e510003800c48f212840001f21400f0000000058
+:10e520001c00c2a31c00c2930700401000000000a2
+:10e530000f0002248c8182a3ffff03242400c3afb9
+:10e5400034000010000000003800c38f00020224d5
+:10e550000e0062a43800c38f1800c28f1d004290c5
+:10e56000ffff42240c0062a407000010000000001e
+:10e570000f0002248c8182a3ffff02242400c2af7b
+:10e5800024000010000000003800c28f1800c48f63
+:10e590000800458ccd33400f000000001400c2afce
+:10e5a0003800c28f0c0042941000c2af1400c38f19
+:10e5b0001000c28f211062001400c2af688080afcb
+:10e5c0006e8080a31800c28f030043880000439828
+:10e5d000211060001400c48f21284000d349400f4f
+:10e5e0000000000007004014000000001b0002248f
+:10e5f0008c8182a3ffff03242400c3af0500001019
+:10e60000000000001400c28f148082af8c8180a3b0
+:10e610002400c0af2400c28f21e8c0033400bf8fa4
+:10e620003000be8f3800bd270800e0030000000066
+:10e63000c0ffbd273c00bfaf3800beaf21f0a00334
+:10e640004000c4af4400c5af6e8080a34000c28fbd
+:10e650001e0042903000c2af010002243000c38f80
+:10e660001200621000000000030002243000c38f7b
+:10e6700003006210000000001d00001000000000f8
+:10e680004400c28f801002001400c2afff0f023c92
+:10e69000ffff42342400c2afff0f023cf8ff4234b8
+:10e6a0002800c2af19000010000000004400c38f12
+:10e6b0002110600040100200211043001400c2af7e
+:10e6c0001400c28f010042301000c2a31400c28f98
+:10e6d000421002001400c2afffff02342400c2af98
+:10e6e000f80f02242800c2af08000010000000004c
+:10e6f0004400c28f401002001400c2afffff02347a
+:10e700002400c2aff8ff02342800c2af4000c28f1d
+:10e710000b004388080043981400c28f4212020085
+:10e72000211062001800c2af1400c28fff014230f6
+:10e730001400c2af1080838f1800c28f6c00621467
+:10e74000000000004000c28f1e004390030002241e
+:10e7500009006214000000001400c38f00a0023cf6
+:10e7600024074224211062000000428c1c00c2af2a
+:10e77000c2000010000000004000c28f1e00439045
+:10e780000200022409006214000000001400c38f7c
+:10e7900000a0023c240742242110620000004294a1
+:10e7a0001c00c2afb5000010000000004000c28f86
+:10e7b0001e00439001000224b0006214000000001b
+:10e7c0001400c38f00a0023c2407422421106200e1
+:10e7d000000042901c00c2af1000c2930400401021
+:10e7e000000000001c00c28f021102001c00c2af1a
+:10e7f0001400c28f01004224ff0142301400c2af56
+:10e800001400c28f22004014000000006480829334
+:10e810000d004010000000004000c48f21280000bf
+:10e820002130000001000724af3a400f0000000033
+:10e8300005004010000000002400c28f2c00c2af71
+:10e8400097000010000000001800c28f0100422451
+:10e850002120400000a0023c24074524d349400f5a
+:10e86000000000000700401400000000ffff023419
+:10e87000108082af2400c28f2c00c2af880000102d
+:10e88000000000001800c28f01004224108082aff7
+:10e890001400c38f00a0023c240742242110620010
+:10e8a000000042902000c2af1000c2930800401048
+:10e8b000000000002000c28f001902001c00c28f5f
+:10e8c000211043001c00c2af6c00001000000000cb
+:10e8d0002000c28f0f004230001a02001c00c28fbd
+:10e8e000211043001c00c2af6400001000000000b3
+:10e8f000648082930d004010000000004000c48f2f
+:10e90000212800002130000001000724af3a400f09
+:10e910000000000005004010000000002400c28f2d
+:10e920002c00c2af5e000010000000001800c48f71
+:10e9300000a0023c24074524d349400f00000000fa
+:10e940000700401400000000ffff0234108082af77
+:10e950002400c28f2c00c2af510000100000000044
+:10e960001800c28f108082af4000c28f1e004390fb
+:10e970000300022409006214000000001400c38f89
+:10e9800000a0023c24074224211062000000428cb7
+:10e990001c00c2af39000010000000004000c28f10
+:10e9a0001e004390020002240900621400000000cf
+:10e9b0001400c38f00a0023c2407422421106200ef
+:10e9c000000042941c00c2af2c00001000000000a8
+:10e9d0004000c28f1e0043900100022427006214f1
+:10e9e000000000001400c38f00a0023c2407422452
+:10e9f00021106200000042901c00c2af1000c293c0
+:10ea000004004010000000001c00c28f0211020030
+:10ea10001c00c2af1400c28f01004224ff0142302b
+:10ea20001400c2af1400c38f00a0023c240742248c
+:10ea300021106200000042902000c2af1000c2937b
+:10ea400008004010000000002000c28f00190200e2
+:10ea50001c00c28f211043001c00c2af0700001031
+:10ea6000000000002000c28f0f004230001a020098
+:10ea70001c00c28f211043001c00c2af1c00c28fbb
+:10ea80002800c38f2b104300030040140000000037
+:10ea90002800c28f1c00c2af1c00c28f2c00c2af66
+:10eaa0002c00c28f21e8c0033c00bf8f3800be8f0e
+:10eab0004000bd270800e00300000000c8ffbd279c
+:10eac0003400bfaf3000beaf21f0a0033800c4afa8
+:10ead0003c00c5af4000c6af2110e0004400c2a317
+:10eae0003800c28f1e004390030002241000621001
+:10eaf000000000003800c28f1e0043900200022474
+:10eb00000b006210000000003800c28f1e0043900e
+:10eb1000010002240600621000000000ff0f023c0a
+:10eb2000ffff42342400c2af4a0100100000000081
+:10eb30003800c28f1e0042902800c2af2800c38f49
+:10eb40000100622812004014000000002800c38f5a
+:10eb5000030062280c00401400000000030002249f
+:10eb60002800c38f0300621000000000080000109e
+:10eb700000000000ff0f023cffff42342000c2af44
+:10eb80000300001000000000ffff02342000c2afad
+:10eb90006e8080a34400c293280040100000000053
+:10eba0001000c0a31080828f1800c2af3800c28f3f
+:10ebb0001c0043901000c2932b1043001b00401018
+:10ebc000000000001080848f00a0023c2407452430
+:10ebd000213000005b4a400f000000000500401497
+:10ebe000000000002000c28f2400c2af19010010f5
+:10ebf000000000001000c293010042241000c2a3d4
+:10ec00003800c28f1a0043901b004290001202008d
+:10ec100025104300ffff43301800c28f211043002e
+:10ec20001800c2afe1ff001000000000648080a364
+:10ec30002400c0af07010010000000003800c28fa0
+:10ec40001e0042902c00c2af010002242c00c38f92
+:10ec50000c00621000000000030002242c00c38f8f
+:10ec6000030062100000000013000010000000000c
+:10ec70003c00c28f801002001400c2af11000010cf
+:10ec8000000000003c00c38f211060004010020013
+:10ec9000211043001400c2af1400c28f01004230a3
+:10eca0001100c2a31400c28f421002001400c2afb0
+:10ecb00004000010000000003c00c28f4010020061
+:10ecc0001400c2af3800c28f0b004388080043987d
+:10ecd0001400c28f42120200211062001c00c2af59
+:10ece0001400c28fff0142301400c2af1080838f26
+:10ecf0001c00c28f37006210000000006480829305
+:10ed000025004010000000001000c0a31080828f7a
+:10ed10001800c2af3800c28f1c0043901000c2938d
+:10ed20002b1043001b004010000000001080848f57
+:10ed300000a0023c24074524213000005b4a400f1c
+:10ed40000000000005004014000000002000c28ff9
+:10ed50002400c2afbf000010000000001000c293ea
+:10ed6000010042241000c2a33800c28f1a00439051
+:10ed70001b0042900012020025104300ffff4330a9
+:10ed80001800c28f211043001800c2afe1ff00102d
+:10ed900000000000648080a31c00c48f00a0023c1f
+:10eda00024074524d349400f000000000700401409
+:10edb00000000000ffff0234108082af2000c28fed
+:10edc0002400c2afa3000010000000001c00c28f8e
+:10edd000108082af3800c28f1e00439003000224cf
+:10ede00023006214000000001400c38f00a0023c46
+:10edf00024074224211862004000c28f000062a054
+:10ee00001400c38f00a0023c250742242118620091
+:10ee10004000c28f00ff423002120200000062a0d8
+:10ee20001400c38f00a0023c260742242120620068
+:10ee30004000c38fff00023c241062000214020055
+:10ee4000000082a01400c38f00a0023c27074224c8
+:10ee5000212062004000c38f000f023c241062009a
+:10ee600002160200000082a07700001000000000df
+:10ee70003800c28f1e004390020002241100621469
+:10ee8000000000001400c38f00a0023c24074224ad
+:10ee9000211862004000c28f000062a01400c38fde
+:10eea00000a0023c25074224211862004000c28fc6
+:10eeb00000ff423002120200000062a06200001057
+:10eec000000000003800c28f1e00439001000224a1
+:10eed0005d006214000000001400c38f00a0023c1b
+:10eee0002407422421106200000042901200c2a3b5
+:10eef0001100c2930a004010000000004000c28fc1
+:10ef00000f004230001902001200c2930f0042307d
+:10ef1000251062001200c2a30300001000000000d0
+:10ef20004000c28f1200c2a31400c38f00a0023c95
+:10ef300024074224211862001200c293000062a03c
+:10ef40001400c28f01004224ff0142301400c2affe
+:10ef50001400c28f1f004014000000003800c48f4e
+:10ef6000212800002130000001000724af3a400fa3
+:10ef70000000000005004010000000002000c28fcb
+:10ef80002400c2af33000010000000001c00c28f3c
+:10ef9000010042242120400000a0023c2407452417
+:10efa000d349400f0000000007004014000000009b
+:10efb000ffff0234108082af2000c28f2400c2af56
+:10efc00024000010000000001c00c28f0100422439
+:10efd000108082af1400c38f00a0023c240742249b
+:10efe00021106200000042901200c2a31100c293df
+:10eff00006004010000000004000c28f0211020015
+:10f000001200c2a30a000010000000004000c28fde
+:10f01000021202000f0044301200c393f0ff0224da
+:10f020002410620021188000251062001200c2a383
+:10f030001400c38f00a0023c240742242118620060
+:10f040001200c293000062a001000224648082a327
+:10f050002400c0af2400c28f21e8c0033400bf8f5a
+:10f060003000be8f3800bd270800e003000000001c
+:10f07000e8ffbd271400bfaf1000beaf21f0a00312
+:10f080001800c4af212000001800c58f21300000f7
+:10f090002c3c400f0000000021e8c0031400bf8f8b
+:10f0a0001000be8f1800bd270800e003000000001c
+:10f0b00070ffbd278800bfaf8400beaf8000b0af37
+:10f0c00021f0a003211080009400c5af9800c6afc6
+:10f0d0009000c2a3010002241200c2a79400c28fb4
+:10f0e0001800c2af2000c2277000c2af7000c48fea
+:10f0f0001880858fa732400f000000008c8180a30c
+:10f100001800c28f000042901000c2a31000c293ea
+:10f1100007004014000000001f0002248c8182a31d
+:10f12000ffff02247400c2afc40100100000000001
+:10f130001000c3937800c3af2e0002247800c38f61
+:10f1400007006210000000005c0002247800c38ffa
+:10f15000c100621000000000070100100000000064
+:10f160001800c28f010042241800c2af1800c28fdd
+:10f17000000042901000c2a31000c3932e0002248e
+:10f180008b006214000000001800c28f01004224ae
+:10f190001800c2af1800c28f000042901000c2a336
+:10f1a0007000c28f3400438c7c81828f0700621410
+:10f1b000000000001f0002248c8182a3ffff0224b4
+:10f1c0007400c2af9d010010000000007000c38fea
+:10f1d0007000c28f3400428c380062ac01000224ff
+:10f1e0001200c2a71200c2277000c48f212840005d
+:10f1f00001000624182a400f000000001400c2afce
+:10f200001400c28f07004014000000001b000224fd
+:10f210008c8182a3ffff03247400c3af8701001019
+:10f22000000000007000d08f1400c48f1c24400f19
+:10f2300000000000340002ae7000c38f7000c28f67
+:10f240003400428c380062ac7000c28f3400428cb3
+:10f250001c004014000000007000c28f5c000324fa
+:10f26000200043a0010002241100c2a31100c29398
+:10f270000b00422c0b004010000000007000c38ff8
+:10f280001100c2932118620020000224200062a015
+:10f290001100c293010042241100c2a3f3ff001029
+:10f2a000000000007000c38f7c81828f380062ac48
+:10f2b0007000c38f7c81828f340062ac1700001015
+:10f2c000000000007000c38f2e000224200062a006
+:10f2d0007000c38f2e000224210062a002000224cd
+:10f2e0001100c2a31100c2930b00422c0b0040106e
+:10f2f000000000007000c38f1100c293211862004b
+:10f3000020000224200062a01100c29301004224c8
+:10f310001100c2a3f3ff0010000000001200c0a7fc
+:10f320001200c2277000c48f21284000010006246b
+:10f33000182a400f000000000700401400000000e1
+:10f340001b0002248c8182a3ffff02247400c2af41
+:10f350003a010010000000001000c3935c0002247a
+:10f3600009006214000000001800c28f010042244e
+:10f370001800c2af1800c28f000042901000c2a354
+:10f38000f5ff0010000000001000c29368ff401459
+:10f39000000000001880848f7000c58fa732400fd6
+:10f3a000000000007400c0af240100100000000045
+:10f3b0001000c29308004014000000001880848fe1
+:10f3c0007000c58fa732400f000000007400c0af6e
+:10f3d0001a010010000000001000c3935c0002241a
+:10f3e00017006214000000001000c3935c000224a8
+:10f3f00009006214000000001800c28f01004224be
+:10f400001800c2af1800c28f000042901000c2a3c3
+:10f41000f5ff0010000000001000c29344ff4014ec
+:10f42000000000001880848f7000c58fa732400f45
+:10f43000000000007400c0af0001001000000000d8
+:10f440001f0002248c8182a3ffff03247400c3af3a
+:10f45000fa000010000000001800c28f01004224d2
+:10f460001800c2af1800c28f000042901000c2a363
+:10f470001000c3935c000224070062140000000027
+:10f480001f0002248c8182a3ffff02247400c2affc
+:10f49000ea000010000000001000c2931d0040149c
+:10f4a000000000001880838f7c81828f340062ac62
+:10f4b0001880838f7c81828f380062ac1880838fa4
+:10f4c0005c000224200062a0010002241100c2a3fb
+:10f4d0001100c2930b00422c0b00401000000000f2
+:10f4e0001880838f1100c29321186200200002242b
+:10f4f000200062a01100c293010042241100c2a3a7
+:10f50000f3ff0010000000007400c0afcb0000103b
+:10f51000000000007000c38f7c81828f340062acd9
+:10f520007000c38f7c81828f380062ac7000c38f03
+:10f530005c000224200062a0010002241100c2a38a
+:10f540001100c2930b00422cf9fe40100000000095
+:10f550007000c38f1100c2932118620020000224a2
+:10f56000200062a01100c293010042241100c2a336
+:10f57000f3ff0010000000001100c0a31000c293b0
+:10f5800019004010000000001000c3935c0002242a
+:10f5900015006210000000001100c2930c00422c04
+:10f5a000110040100000000000a0043c1100c393b3
+:10f5b000010062241100c2a3ff006330d806822438
+:10f5c000211862001000c293000062a01800c28fd0
+:10f5d000010042241800c2af000042901000c2a3f4
+:10f5e000e6ff0010000000001100c3930c0002248d
+:10f5f0000f006214000000001000c2930c004010c5
+:10f60000000000001000c3935c0002240800621098
+:10f61000000000001800c28f010042241800c2af91
+:10f62000000042901000c2a3f3ff00100000000091
+:10f6300000a0023c1100c393d806422421106200ae
+:10f64000000040a000a0023cd8064424212800006d
+:10f650003f37400f0000000005004014000000008c
+:10f66000ffff03247400c3af74000010000000000b
+:10f670001100c0a31100c2930b00422c17004010d0
+:10f68000000000001100c3931000c2272120620077
+:10f690007000c38f1100c2932110620020004290bd
+:10f6a000500082a07000c38f1100c293212062001d
+:10f6b00000a0023c1100c393d8064224211062002e
+:10f6c00000004290200082a01100c2930100422459
+:10f6d0001100c2a3e7ff00100000000000a0023ce0
+:10f6e000f80944247000c58fa732400f00000000c5
+:10f6f00000a0023cf80944247000c58f01000624d4
+:10f70000213800006e1f400f00000000070040106d
+:10f71000000000000c0002248c8182a3ffff022461
+:10f720007400c2af450000100000000000a0023cc1
+:10f73000f8094224300043941000022407006210ac
+:10f74000000000001f0002248c8182a3ffff03241d
+:10f750007400c3af39000010000000001100c0a306
+:10f760001100c2930b00422c0f004010000000005b
+:10f770007000c38f1100c2932120620000a0023ce0
+:10f780001100c393f8094224211062002000429026
+:10f79000200082a01100c293010042241100c2a3e4
+:10f7a000efff0010000000007000c38f00a0023cbb
+:10f7b000f80942240400428c340062ac7000c38f0c
+:10f7c0007000c28f3400428c380062ac1000c293cb
+:10f7d00008004014000000001880848f7000c58f5e
+:10f7e000a732400f000000007400c0af13000010eb
+:10f7f000000000001000c3935c0002244cfe621461
+:10f80000000000001800c28f010042241800c2af9f
+:10f810001800c28f000042901000c2a31000c293d3
+:10f82000f4ff4014000000001880848f7000c58f22
+:10f83000a732400f000000007400c0af7400c28ff8
+:10f8400021e8c0038800bf8f8400be8f8000b08f86
+:10f850009000bd270800e00300000000b0ffbd27b6
+:10f860004c00bfaf4800beaf21f0a0035000c4afb2
+:10f870005400c5af5000c28f0500401000000000ca
+:10f880005400c28f4000c2a303000010000000001b
+:10f890000a0002244000c2a34000c2931000c2a389
+:10f8a00000a0023cf80942241c00c2af2000c0a303
+:10f8b0003000c0af8c8180a35000c28f060040147e
+:10f8c0000000000000a0023c340a42241400c2af31
+:10f8d0000b000010000000005000c28f1400c2afe7
+:10f8e0005400c28f06004014000000001f000224d4
+:10f8f0008c8182a33c00c0afb30100100000000067
+:10f900001000c3831400c28f21106200ffff422445
+:10f910001800c2af1c00c48f1880858fa732400f1b
+:10f92000000000001c00c28f200043802e00022433
+:10f9300096006214000000001c00c28f210043806a
+:10f940002e00022491006214000000001c00c28fef
+:10f950003400428c2400c2af010002242800c2a758
+:10f960001c00c38f1c00c28f3400428c380062ac74
+:10f970002800c2271c00c48f212840000100062453
+:10f98000182a400f000000003800c2af3800c28fb4
+:10f9900006004014000000001b0002248c8182a39a
+:10f9a0003c00c0af88010010000000003800c48f88
+:10f9b0001c24400f00000000848182af8481828f6c
+:10f9c00006004014000000001c00c38f7c81828f61
+:10f9d000340062ac04000010000000001c00c38f63
+:10f9e0008481828f340062ac1c00c38f1c00c28fe4
+:10f9f0003400428c380062ac2800c0a72800c2271f
+:10fa00001c00c48f2128400001000624182a400f42
+:10fa1000000000003800c2af3800c28f060040145a
+:10fa2000000000001b0002248c8182a33c00c0afb8
+:10fa300065010010000000003800c48f1c24400f36
+:10fa400000000000848182af8481838f2400c28ff4
+:10fa500016006214000000008481838f2400c28f8e
+:10fa60002a006214000000003800c28f000043909a
+:10fa7000e50002240d006210000000003800c28f73
+:10fa80000b004390080002240800621000000000f0
+:10fa90003800c28f0b0043900f0002240300621055
+:10faa0000000000019000010000000002800c297ac
+:10fab000010042242800c2a72800c2271c00c48fce
+:10fac0002128400021300000182a400f00000000cb
+:10fad0003800c2af3800c28f06004014000000009a
+:10fae0001b0002248c8182a33c00c0af36010010b1
+:10faf000000000003800c48f1c24400f00000000ec
+:10fb0000848182afd0ff0010000000002c00c0af45
+:10fb10002c00c28f0b00422816004010000000008d
+:10fb20001c00c38f2c00c28f212062003800c38fbd
+:10fb30002c00c28f2110620000004290200082a0a1
+:10fb40001880838f2c00c28f212062003800c38f61
+:10fb50002c00c28f2110620000004290200082a081
+:10fb60002c00c28f010042242c00c2afe8ff00101d
+:10fb7000000000001c00c38f2400c28f340062ac60
+:10fb80001c00c38f2400c28f380062ac1c00c28fdf
+:10fb9000200043805c0002240a0062140000000080
+:10fba0001400c38f5c000224000062a01400c28f06
+:10fbb000010040a01400c28f3c00c2af020100103f
+:10fbc000000000001c00c28f3400438c7c81828fb7
+:10fbd00084006210000000000a0002242100c2a379
+:10fbe0001c00c38f2100c2832110620020004380cb
+:10fbf0002000022406006214000000002100c293cd
+:10fc0000ffff42242100c2a3f5ff00100000000006
+:10fc10002100c283080042282d004014000000008b
+:10fc20002100c2830800422819004014000000008f
+:10fc30003000c6270000c48c211880001400c28f39
+:10fc4000213862001c00c58f2100c393ffff62248e
+:10fc50002100c2a32014037c2110a20020004290a6
+:10fc60000000e2a0010084240000c4ac1000c383a3
+:10fc70003000c28feaff6214000000003000c0af05
+:10fc8000010002242000c2a3e5ff001000000000d4
+:10fc90003000c5270000a38c212060001400c28f13
+:10fca000212082002e000224000082a00100632493
+:10fcb0000000a3ac1000c3833000c28f04006214a4
+:10fcc000000000003000c0af010002242000c2a3e9
+:10fcd0001c00c38f2100c2832110620020004380da
+:10fce0002000022406006214000000002100c293dc
+:10fcf000ffff42242100c2a3f5ff00100000000016
+:10fd00002100c28319004004000000003000c62713
+:10fd10000000c48c211880001400c28f21386200ba
+:10fd20001c00c58f2100c393ffff62242100c2a3e2
+:10fd30002014037c2110a200200042900000e2a0c9
+:10fd4000010084240000c4ac1000c3833000c28fc3
+:10fd5000ebff6214000000003000c0af010002247d
+:10fd60002000c2a3e6ff0010000000003000c527fd
+:10fd70000000a38c212060001400c28f212082008b
+:10fd80005c000224000082a0010063240000a3acf8
+:10fd90001000c3833000c28f040062140000000012
+:10fda0003000c0af010002242000c2a31c00c38f9a
+:10fdb0001c00c28f3400428c380062ac1c00c48f1f
+:10fdc000f93f400f000000007eff401000000000df
+:10fdd000080002248c8182a33c00c0af7a0000108e
+:10fde000000000003000c28fffff42243000c2af8d
+:10fdf0002c00c0af2000c2934c0040100000000057
+:10fe00003000c28f2a00c2a73000c28f2c00c38fdf
+:10fe1000231043001b004018000000002c00c38f7b
+:10fe20001400c28f21106200000042903400c2a36f
+:10fe30002c00c38f1400c28f212062003000c38fba
+:10fe40001400c28f2110620000004290000082a0c6
+:10fe50003000c38f1400c28f211862003400c29397
+:10fe6000000062a03000c28fffff42243000c2af0a
+:10fe70002c00c28f010042242c00c2afe2ff001010
+:10fe8000000000002a00c297010042242c00c2afeb
+:10fe90001800c38f1400c28f231062003000c2af5d
+:10fea0003000c28f2c00c38f231043001b0040186a
+:10feb000000000002c00c38f1400c28f21106200cc
+:10fec000000042903400c2a32c00c38f1400c28fe4
+:10fed000212062003000c38f1400c28f2110620005
+:10fee00000004290000082a03000c38f1400c28f37
+:10fef000211862003400c293000062a03000c28f5b
+:10ff0000ffff42243000c2af2c00c28f0100422408
+:10ff10002c00c2afe2ff0010000000001800c28fea
+:10ff2000000040a026000010000000003000c28f3a
+:10ff30002a00c2a73000c28f2c00c38f23104300b9
+:10ff40001b004018000000002c00c38f1400c28f5b
+:10ff500021106200000042903400c2a32c00c38f25
+:10ff60001400c28f212062003000c38f1400c28fa2
+:10ff70002110620000004290000082a03000c38f78
+:10ff80001400c28f211862003400c293000062a0e6
+:10ff90003000c28fffff42243000c2af2c00c28f5e
+:10ffa000010042242c00c2afe2ff0010000000005c
+:10ffb0002a00c2971400c38f21104300010040a003
+:10ffc0001400c28f3c00c2af3c00c28f21e8c003c6
+:10ffd0004c00bf8f4800be8f5000bd270800e003d3
+:10ffe00000000000d8ffbd272400bfaf2000beaf37
+:10fff00021f0a0032800c4af010002241200c2a710
+:020000041d01dc
+:100000001200c2272800c48f2128400001000624c6
+:10001000182a400f000000001800c2af1800c28f5d
+:100020000500401400000000ff0002241c00c2afc5
+:10003000a7000010000000001800c48f1c24400f0f
+:1000400000000000848182af8481828f1b004014f5
+:10005000000000002800c38f5c000224200062a082
+:100060001000c0a31000c2930b00422c0b004010e4
+:10007000000000002800c38f1000c2932118620006
+:1000800020000224200062a01000c293010042243c
+:100090001000c2a3f3ff0010000000002800c38f6f
+:1000a0007c81828f340062ac2800c38f7c81828f78
+:1000b000380062ac85000010000000008481828f4f
+:1000c0001400c2af2800c38f8481828f340062acd9
+:1000d0002800c38f8481828f380062ac1200c2274f
+:1000e0002800c48f2128400001000624182a400f50
+:1000f000000000001800c2af1800c28f05004014b5
+:1001000000000000ff0002241c00c2af70000010bd
+:10011000000000001800c48f1c24400f00000000e5
+:10012000848182af8481828f060040140000000029
+:100130002800c38f7c81828f340062ac04000010e1
+:10014000000000002800c38f8481828f340062acdd
+:100150002800c38f2800c28f3400428c380062ac64
+:100160001200c0a71200c2272800c48f2128400017
+:1001700001000624182a400f000000001800c2af3a
+:100180001800c28f0500401400000000ff00022488
+:100190001c00c2af4e000010000000001800c48f09
+:1001a0001c24400f00000000848182af8481838f73
+:1001b0001400c28f16006214000000008481838f37
+:1001c0001400c28f29006214000000001800c28fc2
+:1001d00000004390e50002240d00621000000000c2
+:1001e0001800c28f0b004390080002240800621020
+:1001f000000000001800c28f0b0043900f00022483
+:100200000300621000000000180000100000000051
+:100210001200c2272800c48f21284000213000008e
+:10022000182a400f000000001800c2af1800c28f4b
+:100230000500401400000000ff0002241c00c2afb3
+:1002400023000010000000001200c29701004224a9
+:100250001200c2a71800c48f1c24400f0000000029
+:10026000848182afd1ff0010000000001000c0a305
+:100270001000c2930b00422c0e0040100000000042
+:100280002800c38f1000c293212062001800c38f82
+:100290001000c2932110430000004290200082a071
+:1002a0001000c293010042241000c2a3f0ff00100e
+:1002b000000000002800c38f1400c28f340062ac1d
+:1002c0002800c38f1400c28f380062ac1c00c0af7e
+:1002d0001c00c28f21e8c0032400bf8f2000be8f06
+:1002e0002800bd270800e00300000000e8ffbd274c
+:1002f0001400bfaf1000beaf21f0a0031800c4afc0
+:10030000212000001800c58f21300000cb40400f95
+:100310000000000021e8c0031400bf8f1000be8f52
+:100320001800bd270800e00300000000c8ffbd273b
+:100330003400bfaf3000beaf21f0a0032110800019
+:100340003c00c5af4000c6af3800c2a33c00c28f1e
+:100350001400c2af00a0023ce80642242800c2af4d
+:100360008c8180a3d54a400f000000000700401098
+:1003700000000000180002248c8182a3ffff0224e9
+:100380002c00c2af90010010000000001000c0a3bc
+:100390001400c28f000042801300401000000000d3
+:1003a0001400c28f000043802e0002240e00621051
+:1003b000000000001400c28f000043805c00022493
+:1003c00009006210000000001400c28f01004224e6
+:1003d0001400c2af1000c293010042241000c2a357
+:1003e000ebff0010000000001000c2930900422c37
+:1003f00007004014000000001f0002248c8182a32b
+:10040000ffff02242c00c2af6f01001000000000ab
+:100410001400c28f000043802e00022420006214ca
+:10042000000000001400c28f010042241400c2af7b
+:100430001000c0a31400c28f000042800e004010c4
+:10044000000000001400c28f000043805c00022402
+:1004500009006210000000001400c28f0100422455
+:100460001400c2af1000c293010042241000c2a3c6
+:10047000f0ff0010000000001000c2930400422ca6
+:1004800007004014000000001f0002248c8182a39a
+:10049000ffff02242c00c2af4b010010000000003f
+:1004a0001400c28f000043805c0002240600621426
+:1004b000000000001400c28f010042241400c2afeb
+:1004c000f7ff0010000000001400c28f00004280ff
+:1004d000aeff4014000000003c00c28f1400c2af09
+:1004e0002800c48f1880858fa732400f00000000bd
+:1004f0001400c28f000042901000c2a31000c393ea
+:100500002e00022457006214000000001400c28f65
+:10051000010042241400c2af1400c28f00004290b8
+:100520001000c2a31000c3932e0002240e0062101c
+:10053000000000001000c2930b00401000000000fb
+:100540001000c3935c00022407006210000000004a
+:100550001f0002248c8182a3ffff02242c00c2af63
+:1005600019010010000000001000c3932e000224a7
+:1005700023006214000000001880828f3400438c36
+:100580007c81828f07006214000000001f0002249b
+:100590008c8182a3ffff02242c00c2af0a0100104d
+:1005a000000000001400c28f010042241400c2affa
+:1005b0001400c28f000042901000c2a31000c39329
+:1005c0005c0002240a006210000000001000c293c8
+:1005d00007004010000000001f0002248c8182a34d
+:1005e000ffff02242c00c2aff70000100000000043
+:1005f000029d023c340744241c3c400f00000000d4
+:100600001000c3935c000224090062140000000083
+:100610001400c28f010042241400c2af1400c28f24
+:10062000000042901000c2a3f5ff0010000000007f
+:100630001000c293aeff4014000000001880848fa9
+:100640002800c58fa732400f000000001f000224c1
+:100650008c8182a3ffff02242c00c2afda000010bd
+:10066000000000001000c3935c0002243b006214f1
+:10067000000000001880838f7c81828f340062ac80
+:100680001880838f7c81828f380062ac1880838fc2
+:100690005c000224200062a0010002241000c2a31a
+:1006a0001000c2930b00422c0b0040100000000011
+:1006b0001880838f1000c29321186200200002244a
+:1006c000200062a01000c293010042241000c2a3c7
+:1006d000f3ff0010000000001400c28f010042244c
+:1006e0001400c2af1400c28f000042901000c2a3d9
+:1006f0001000c3935c0002240b0062140000000091
+:100700001880848f2800c58fa732400f000000009a
+:100710001f0002248c8182a3ffff02242c00c2afa1
+:10072000a9000010000000001000c29370ff4014e8
+:10073000000000001880848f2800c58fa732400f6a
+:10074000000000001f0002248c8182a3ffff02240e
+:100750002c00c2af9c000010000000002400c0a3c9
+:100760001400c28f000042901000c2a31100c0a369
+:100770001000c29319004010000000001000c39345
+:100780005c00022415006210000000001100c293fa
+:100790000c00422c11004010000000001100c39317
+:1007a000010062241100c2a3ff0063301000c227c1
+:1007b000211862001000c293080062a01400c28fca
+:1007c000010042241400c2af1400c28f0000429006
+:1007d0001000c2a3e6ff0010000000001100c39348
+:1007e0001000c22721106200080040a01800c38337
+:1007f0002e00022423006214000000001900c283ae
+:100800000f004010000000001900c3832e000224d6
+:100810000b006210000000001880848f2800c58f34
+:10082000a732400f000000001f0002248c8182a329
+:10083000ffff02242c00c2af630000100000000084
+:100840001900c3832e0002240e0062140000000071
+:100850001a00c2830b004010000000001880848f33
+:100860002800c58fa732400f000000001f0002249f
+:100870008c8182a3ffff02242c00c2af5200001023
+:10088000000000001800c227212040001c3c400f3f
+:1008900000000000030040100000000017000010de
+:1008a000000000001000c3935c00022409006214e1
+:1008b000000000001400c28f010042241400c2afe7
+:1008c0001400c28f000042901000c2a3f5ff001078
+:1008d000000000001000c293a1ff401400000000bf
+:1008e0001880848f2800c58fa732400f00000000b9
+:1008f0002c00c0af34000010000000001800c22718
+:10090000212040007942400f0000000009004014ff
+:10091000000000001880848f2800c58fa732400f88
+:1009200000000000ffff02242c00c2af26000010d0
+:10093000000000001800c227212040001c3c400f8e
+:10094000000000000b004010000000001880848fa1
+:100950002800c58fa732400f000000001b000224b2
+:100960008c8182a3ffff02242c00c2af160000106e
+:10097000000000001400c28f000043805c000224cd
+:1009800009006214000000001400c28f010042241c
+:100990001400c2af1400c28f000042901000c2a326
+:1009a000f4ff0010000000001000c2936cff401420
+:1009b000000000001880848f2800c58fa732400fe8
+:1009c000000000002c00c0af2c00c28f21e8c00343
+:1009d0003400bf8f3000be8f3800bd270800e00311
+:1009e00000000000c8ffbd273400bfaf3000beaf1d
+:1009f00021f0a0033800c4af00a0023cf809422453
+:100a00001000c2af1800c0a72400c0a32400c293e6
+:100a10000c00422c0f0040100000000000a0023c1f
+:100a20002400c393d8064224212062002400c393eb
+:100a30003800c28f2110620000004290000082a0a6
+:100a40002400c293010042242400c2a3efff00103f
+:100a50000000000000a0023cd80644242128000029
+:100a60003f37400f00000000060040140000000067
+:100a7000120002248c8182a32800c0af6f000010f6
+:100a8000000000002400c0a32400c2930b00422ced
+:100a90000f004010000000001000c38f2400c2931c
+:100aa0002120620000a0023c2400c393d806422407
+:100ab0002110620000004290200082a02400c29316
+:100ac000010042242400c2a3efff00100000000038
+:100ad0001000c38f1880828f3400428c340062acc7
+:100ae0001000c38f1880828f3800428c380062acaf
+:100af0001000c28f040040ac1000c28f080040ac50
+:100b00001000c38f1880828f0000428c000062acfe
+:100b10001800c2271000c48f2128400012000624ac
+:100b2000062b400f000000000400401000000000f1
+:100b30002800c0af410000100000000064808293d4
+:100b40000f004010000000001000c28f0000448c15
+:100b5000212800002130000001000724af3a400f97
+:100b60000000000006004010000000000900022400
+:100b70008c8182a32800c0af30000010000000006c
+:100b80001000c28f3400438c7c81828f0400621479
+:100b9000000000002000c0af0400001000000000b2
+:100ba0001000c28f3400428c2000c2af1000c38fef
+:100bb0001000c28f3400428c380062ac1800c2278b
+:100bc0001000c48f2128400001000624182a400f7d
+:100bd000000000001400c2af1400c28f06004014d1
+:100be000000000001b0002248c8182a32800c0affb
+:100bf00012000010000000001400c48f1c24400fdd
+:100c0000000000001c00c2af1000c28f0000448c26
+:100c10001c00c58f2000c68f1643400f0000000047
+:100c20000500401000000000010002242800c2afaf
+:100c300002000010000000002800c0af2800c28f92
+:100c400021e8c0033400bf8f3000be8f3800bd27bd
+:100c50000800e00300000000b0ffbd274c00bfaf5c
+:100c60004800beaf21f0a0035000c4af5400c5af90
+:100c70005800c6af1800c2273800c2af688080afe6
+:100c8000200002241200c2a75000c28f0300438834
+:100c9000000043982110600021204000212800001e
+:100ca00000020624096b400f000000002e00022401
+:100cb0001800c2a3010002241000c2a71000c297ae
+:100cc0000b00422c0b004010000000001000c397e6
+:100cd0001000c2272118620020000224080062a030
+:100ce0001000c297010042241000c2a7f3ff0010b9
+:100cf00000000000100002242300c2a32400c0a3af
+:100d00005400c28f3200c2a75400c38fff0f023cb1
+:100d100024106200021402002c00c2a73400c0afed
+:100d2000778182932500c2a3788182972600c2a78b
+:100d3000828182972800c2a72a00c0a72e00c0a7e0
+:100d40003000c0a71000c0a71000c2971200c397c0
+:100d50002b10430010004010000000005000c28f14
+:100d600003004388000043981000c29721204300ed
+:100d70001000c3973800c28f21106200000042901b
+:100d8000000082a01000c297010042241000c2a7f8
+:100d9000edff0010000000002e0002241900c2a385
+:100da0005800c28f3200c2a75800c38fff0f023c09
+:100db00024106200021402002c00c2a71000c0a779
+:100dc0001000c2971200c3972b104300120040106e
+:100dd000000000005000c28f0300438800004398c9
+:100de0001000c4971200c297211043002120440034
+:100df0001000c3973800c28f21106200000042909b
+:100e0000000082a01000c297010042241000c2a777
+:100e1000ebff0010000000005000c48f5400c58f8d
+:100e2000cd33400f000000003c00c2af5000c28f25
+:100e30000300438800004398211060003c00c48fe9
+:100e400021284000213000005b4a400f00000000d4
+:100e50000600401400000000090002248c8182a3d7
+:100e60004000c0af03000010000000000100022499
+:100e70004000c2af4000c28f21e8c0034c00bf8fca
+:100e80004800be8f5000bd270800e00300000000ae
+:100e9000e8ffbd271400bfaf1000beaf21f0a003d4
+:100ea0001800c4af2110a0001c00c2a31c00c293f4
+:100eb000212000001800c58f21300000213840009b
+:100ec000b843400f0000000021e8c0031400bf8faa
+:100ed0001000be8f1800bd270800e00300000000ce
+:100ee000b8ffbd274400bfaf4000beaf21f0a00354
+:100ef000211880004c00c5af5000c6af2110e000a3
+:100f00004800c3a35400c2a300a0023ce806422448
+:100f10001000c2af00a0023cf80942241400c2af86
+:100f20001c00c0a7029d023c3807448c38074324ac
+:100f30000400638c380742240800428c2800c4afa8
+:100f40002c00c3af3000c2af3400c0a38c8180a39b
+:100f50001000c48f1880858fa732400f000000005a
+:100f60004c00c48f1c3c400f0000000007004010e4
+:100f7000000000000c0002248c8182a3ffff0224e9
+:100f80003800c2af80020010000000001880828f7d
+:100f90003400438c7c81828f0900621000000000c5
+:100fa0001880828f1000c38f3400448c3400628c10
+:100fb00003008210000000000b0000100000000081
+:100fc0001880848f1000c58fa732400f00000000ea
+:100fd0001f0002248c8182a3ffff02243800c2afcd
+:100fe00069020010000000001c00c29701004224aa
+:100ff0001c00c2a71c00c2271880848f2128400033
+:1010000001000624182a400f000000001800c2af9b
+:101010001800c28f0b004014000000001880848f5d
+:101020001000c58fa732400f000000001b000224f3
+:101030008c8182a3ffff02243800c2af520200104d
+:10104000000000001c00c297010042241c00c2a73f
+:101050001c00c2271880848f212840002130000006
+:10106000182a400f000000001800c2af1800c28ffd
+:101070000b004014000000001880848f1000c58f02
+:10108000a732400f000000001b0002248c8182a3c5
+:10109000ffff02243800c2af3b0200100000000036
+:1010a0005400c2932b004014000000001800c28faf
+:1010b00000004280e8014010000000001800c28fcc
+:1010c00000004390e50002240b00621000000000c5
+:1010d0001880848f1000c58fa732400f00000000d9
+:1010e000160002248c8182a3ffff02243800c2afc5
+:1010f00025020010000000001c00c29701004224dd
+:101100001c00c2a71c00c2271880848f2128400021
+:1011100021300000182a400f000000001800c2af64
+:101120001800c28fe1ff4014000000001880848f77
+:101130001000c58fa732400f000000001b000224e2
+:101140008c8182a3ffff02243800c2af0e02001080
+:1011500000000000888180a32000c0a788818293be
+:10116000bd014014000000001800c28f0000428042
+:10117000ee004010000000001800c28f00004390f5
+:10118000e5000224c1006210000000001800c28fb8
+:101190000b00439008000224bc0062100000000015
+:1011a0001800c28f0b0043900f000224b70062109a
+:1011b000000000001800c28f0b0042901000423067
+:1011c00070004010000000002000c297010042247f
+:1011d0002000c2a72200c0a32200c2930800422c14
+:1011e00015004010000000001800c38f2200c293b9
+:1011f0002110430000004380200002240e006210f2
+:10120000000000002200c3931000c22721206200ca
+:101210001800c38f2200c2932110430000004290a7
+:10122000180082a02200c293010042242200c2a31f
+:10123000e9ff0010000000001800c28f0800438082
+:101240002000022425006210000000002200c39349
+:10125000010062242200c2a3ff0063301000c227f5
+:10126000211862002e000224180062a02300c0a3ef
+:101270002300c2930300422c18004010000000001d
+:101280001800c38f2300c29321106200080043801e
+:101290002000022411006210000000002200c3930d
+:1012a000010062242200c2a3ff0063301000c227a5
+:1012b000212062001800c38f2300c2932110620016
+:1012c00008004290180082a02300c293010042242b
+:1012d0002300c2a3e6ff0010000000002200c39319
+:1012e0001000c22721106200180040a02800c22769
+:1012f000212040001c3c400f000000000b0040106b
+:10130000000000001880848f1000c58fa732400fa6
+:10131000000000000c0002248c8182a3ffff022445
+:101320003800c2af98010010000000001880828fc2
+:101330001000c38f3400448c3400628c0b00821484
+:10134000000000001880848f1000c58fa732400f66
+:10135000000000001f0002248c8182a3ffff0224f2
+:101360003800c2af88010010000000000200022413
+:101370001c00c2a7010002246f8082a34600001057
+:10138000000000002800c227212040002128000082
+:101390000c000624096b400f000000002200c0a3cf
+:1013a0002200c2930b00422c0e00401000000000ef
+:1013b0001400c38f2200c293212062001800c38f43
+:1013c0002200c2932110430000004290200082a01e
+:1013d0002200c293010042242200c2a3f0ff0010a9
+:1013e000000000001400c38f00a0023cd809422472
+:1013f000000062ac1400c38f1c00c2972c0062a4d2
+:101400001400c38f1880828f3400428c340062ac89
+:101410001400c38f1880828f3800428c380062ac71
+:101420001400c28f040040ac1400c28f080040ac0e
+:101430001c00c2271400c48f21284000010006248c
+:10144000042f400f000000000b00401000000000bf
+:101450001880848f1000c58fa732400f0000000055
+:10146000010002248c8182a3ffff02243800c2af56
+:1014700045010010000000001c00c297010042243a
+:101480001c00c2a704000010000000001c00c2974e
+:10149000010042241c00c2a76f8082930f004010fd
+:1014a000000000006f8080a31880838f1880828fd7
+:1014b0003400428c380062ac1c00c2271880848f34
+:1014c0002128400001000624182a400f00000000d7
+:1014d0001800c2af08000010000000001c00c22766
+:1014e0001880848f2128400021300000182a400fe6
+:1014f000000000001800c2af1800c28f17ff401490
+:10150000000000001880848f1000c58fa732400fa4
+:10151000000000001b0002248c8182a3ffff022434
+:101520003800c2af18010010000000002000c29770
+:10153000c5004010000000001e00c0a71880838f67
+:101540001880828f3400428c380062ac1e00c227a3
+:101550001880848f2128400001000624182a400f9b
+:10156000000000001800c2af1800c28f0b0040142a
+:10157000000000001880848f1000c58fa732400f34
+:10158000000000001b0002248c8182a3ffff0224c4
+:101590003800c2affc000010000000001800c48f2b
+:1015a0001c24400f000000001e00c2a7029d023c48
+:1015b000340744241c3c400f000000000b00401086
+:1015c000000000001880848f1000c58fa732400fe4
+:1015d000000000000c0002248c8182a3ffff022483
+:1015e0003800c2afe8000010000000000200022432
+:1015f0001c00c2a71880838f1880828f3400428c11
+:10160000380062ac1c00c2271880848f212840005b
+:1016100001000624182a400f000000001800c2af85
+:101620001800c28f0b004014000000001880848f47
+:101630001000c58fa732400f000000001b000224dd
+:101640008c8182a3ffff02243800c2afce000010bd
+:10165000000000001800c48f1c24400f0000000090
+:10166000848182af1e00c3978481828f110062142f
+:10167000000000001e00c3978481828f2a0062143c
+:10168000000000001800c28f00004390e500022413
+:1016900008006210000000001800c28f0b00439089
+:1016a0000800022403006210000000001e00001069
+:1016b000000000001c00c297010042241c00c2a7c9
+:1016c0001c00c2271880848f212840002130000090
+:1016d000182a400f000000001800c2af1800c28f87
+:1016e0000b004014000000001880848f1000c58f8c
+:1016f000a732400f000000001b0002248c8182a34f
+:10170000ffff02243800c2af9f000010000000005d
+:101710001800c48f1c24400f00000000848182af99
+:10172000d0ff0010000000002800c2272120400048
+:10173000212800000c000624096b400f0000000067
+:101740002200c0a32200c2930b00422c0e004010c6
+:10175000000000002200c3931000c2272120620075
+:101760001800c38f2200c293211043000000429052
+:10177000180082a02200c293010042242200c2a3ca
+:10178000f0ff0010000000002800c22721204000c8
+:101790006946400f000000000b00401000000000f0
+:1017a0001880848f1000c58fa732400f0000000002
+:1017b000010002248c8182a3ffff02243800c2af03
+:1017c00071000010000000001c00c29701004224bc
+:1017d0001c00c2a71880838f1880828f3400428c2f
+:1017e000380062ac1c00c2271880848f212840007a
+:1017f00001000624182a400f000000001800c2afa4
+:101800001800c28f0b004014000000001880848f65
+:101810001000c58fa732400f000000001b000224fb
+:101820008c8182a3ffff02243800c2af5600001053
+:10183000000000002000c297ffff42242000c2a742
+:1018400046fe00100000000001000224888182a3ef
+:1018500042fe0010000000002800c22721204000a6
+:101860000c000524173e400f000000000900401442
+:10187000000000001880848f1000c58fa732400f31
+:1018800000000000ffff02243800c2af3e0000103d
+:10189000000000002800c22721204000212800006d
+:1018a0000c000624096b400f000000002200c0a3ba
+:1018b0002200c2930b00422c0e00401000000000da
+:1018c0002200c3931000c227212062001880838f5a
+:1018d0002200c2932110620020004290180082a0d2
+:1018e0002200c293010042242200c2a3f0ff001094
+:1018f00000000000029d023c340744241c3c400fc1
+:10190000000000000b004010000000001880848fd1
+:101910001000c58fa732400f000000000c00022409
+:101920008c8182a3ffff02243800c2af1600001092
+:10193000000000002800c227212040006946400f17
+:10194000000000000b004010000000001880848f91
+:101950001000c58fa732400f0000000001000224d4
+:101960008c8182a3ffff02243800c2af0600001062
+:10197000000000001880848f1000c58fa732400f30
+:10198000000000003800c0af3800c28f21e8c0035b
+:101990004400bf8f4000be8f4800bd270800e00311
+:1019a0000000000098ffbd276400bfaf6000beaf1d
+:1019b00021f0a0036800c4afd54a400f000000002a
+:1019c0000500401000000000ffff02245800c2afd5
+:1019d0004b000010000000001800c227212040002a
+:1019e0001880858fa732400f000000001400c0a3ac
+:1019f0001400c2930b00422c0e00401000000000a7
+:101a00001880838f1400c293212062001400c393b6
+:101a10006800c28f2110620000004290200082a066
+:101a20001400c293010042241400c2a3f0ff00106e
+:101a30000000000000a0023cf80944241880858fb3
+:101a4000a732400f000000001880848f00a0023ce5
+:101a5000f809452401000624213800006e1f400fbc
+:101a6000000000001000c2af1000c28f0a0040103a
+:101a7000000000001800c2271880848f2128400031
+:101a8000a732400f00000000ffff02245800c2af41
+:101a90001b000010000000001880828f2c004224e0
+:101aa0001880848f2128400001000624042f400f55
+:101ab000000000001000c2af1000c28f09004014e7
+:101ac000000000001800c2271880848f21284000e1
+:101ad000a732400f000000005800c0af08000010ff
+:101ae000000000001800c2271880848f21284000c1
+:101af000a732400f00000000ffff02245800c2afd1
+:101b00005800c28f21e8c0036400bf8f6000be8f01
+:101b10006800bd270800e0030000000098ffbd2713
+:101b20006400bfaf6000beaf21f0a0036800c4af87
+:101b30006c00c5af7000c6af1000c2275000c2af26
+:101b40008c8180a35000c28f200042246800c48f83
+:101b50002128400001000624a136400f00000000ab
+:101b60000700401400000000120002248c8182a3b0
+:101b7000ffff02245c00c2aff00000100000000074
+:101b80007000c28f300040a05b00c0a35b00c29316
+:101b90000c00422c14004010000000005b00c393b6
+:101ba0006800c28f21106200000042800e004010c9
+:101bb000000000007000c38f5b00c2932120620010
+:101bc0005b00c3936800c28f211062000000429046
+:101bd0001c0082a05b00c293010042245b00c2a3f0
+:101be000eaff0010000000007000c38f5b00c2938a
+:101bf000211062001c0040a07000c38f6c00c28fd7
+:101c0000290062a07000c38f1880828f3400428c3c
+:101c10002c0062ac5000c38f00a0023cd8094224c3
+:101c2000000062ac5000c28f040040ac5000c28f74
+:101c3000080040ac5000c28f2c0040a45000c38f5d
+:101c40006c00c28f300062a45000c38f1880828f56
+:101c50003400428c340062ac5000c38f1880828ff5
+:101c60003800428c380062ac00a0023cf8094424e1
+:101c70005000c58fa732400f000000005000c48ff5
+:101c800000a0023cf80945240100062401000724b5
+:101c90006e1f400f000000005400c2af5400c28ffe
+:101ca00007004010000000000b0002248c8182a37a
+:101cb000ffff02245c00c2afa00000100000000083
+:101cc0005000c28f2c0042945800c2a75800c2276f
+:101cd0005000c48f21284000720006247a20400f53
+:101ce000000000005400c2af5400c28f8f004014a7
+:101cf000000000005000c28f30004394080002240e
+:101d00005a006210000000005b00c0a35a00c0a38c
+:101d10005a00c2930800422c180040100000000036
+:101d20005000c38f5a00c2932110620020004380ec
+:101d30002000022411006210000000007000c38f18
+:101d40005b00c293212043005000c38f5a00c2930e
+:101d50002110620020004290000082a05b00c2932c
+:101d6000010042245b00c2a35a00c2930100422436
+:101d70005a00c2a3e6ff0010000000005000c28f0e
+:101d800028004380200002240d006214000000009f
+:101d90005000c28f290043802000022408006214f2
+:101da000000000005000c28f2a004380200002245f
+:101db0000300621400000000090000100000000091
+:101dc0007000c48f5b00c393010062245b00c2a358
+:101dd000ff006230211844002e000224000062a09f
+:101de000080002245a00c2a35a00c2930b00422cde
+:101df00018004010000000005000c38f5a00c2932a
+:101e00002110620020004380200002241100621093
+:101e1000000000007000c38f5b00c29321204300cc
+:101e20005000c38f5a00c2932110620020004290dc
+:101e3000000082a05b00c293010042245b00c2a3a9
+:101e40005a00c293010042245a00c2a3e6ff0010c8
+:101e5000000000007000c28f5b00c393211062007d
+:101e6000000040a017000010000000005b00c0a3ad
+:101e70005b00c2930b00422c0e00401000000000db
+:101e80007000c38f5b00c293212043005000c38fba
+:101e90005b00c2932110620020004290000082a0eb
+:101ea0005b00c293010042245b00c2a3f0ff00105c
+:101eb000000000007000c28f5b00c393211062001d
+:101ec000000040a07000c38f5000c28f30004294c9
+:101ed0000d0062a07000c38f5000c28f1400428cae
+:101ee000100062ac7000c48f5000c28f1e0042947c
+:101ef000001c02005000c28f1c004294211062009e
+:101f0000140082ac7000c38f5000c28f2c0042942a
+:101f1000180062ac7000c38f01000224300062a080
+:101f20005c00c0af05000010000000001b00022490
+:101f30008c8182a3ffff02245c00c2af5c00c28fd1
+:101f400021e8c0036400bf8f6000be8f6800bd271a
+:101f50000800e0030000000098ffbd276400bfaf49
+:101f60006000beaf21f0a0036800c4af1000c2271c
+:101f70005000c2af8c8180a36800c28f30004290b5
+:101f80000700401400000000070002248c8182a397
+:101f9000ffff02245c00c2afd6000010000000006a
+:101fa0006800c28f1880838f2c00448c3400628cb0
+:101fb00007008210000000001f0002248c8182a311
+:101fc000ffff02245c00c2afca0000100000000046
+:101fd0006800c28f1c0043245000c28f200042249e
+:101fe000212060002128400001000624a136400f76
+:101ff000000000000700401400000000120002244e
+:102000008c8182a3ffff02245c00c2afb9000010e4
+:10201000000000005000c38f00a0023cd8094224f9
+:10202000000062ac5000c28f040040ac5000c28f70
+:10203000080040ac5000c38f6800c28f1800428c6b
+:10204000010042242c0062a45000c38f6800c28f9c
+:1020500029004290300062a45000c38f1880828f04
+:102060003400428c340062ac5000c38f1880828fe1
+:102070003800428c380062ac00a0023cf8094424cd
+:102080005000c58fa732400f000000005000c48fe1
+:1020900000a0023cf80945240100062401000724a1
+:1020a0006e1f400f000000005400c2af5400c28fea
+:1020b00007004010000000000b0002248c8182a366
+:1020c000ffff02245c00c2af8a0000100000000085
+:1020d0005000c28f30004394080002245a0062105e
+:1020e000000000005800c0a35900c0a35900c293cb
+:1020f0000800422c18004010000000005000c38f60
+:102100005900c29321106200200043802000022465
+:1021100011006210000000006800c38f5800c293d5
+:10212000212043005000c38f5900c2932110620048
+:1021300020004290000082a05800c2930100422477
+:102140005800c2a35900c293010042245900c2a3ff
+:10215000e6ff0010000000005000c28f28004380fe
+:10216000200002240d006214000000005000c28f05
+:1021700029004380200002240800621400000000af
+:102180005000c28f2a004380200002240300621402
+:102190000000000009000010000000006800c48f6b
+:1021a0005800c393010062245800c2a3ff006230ac
+:1021b000211844002e000224000062a0080002241e
+:1021c0005900c2a35900c2930b00422c18004010c2
+:1021d000000000005000c38f5900c293211062001c
+:1021e0002000438020000224110062100000000043
+:1021f0006800c38f5800c293212043005000c38f52
+:102200005900c2932110620020004290000082a079
+:102210005800c293010042245800c2a35900c2933f
+:10222000010042245900c2a3e6ff00100000000094
+:102230006800c28f5800c39321106200000040a0c4
+:1022400017000010000000005800c0a35800c293ff
+:102250000b00422c0e004010000000006800c38fed
+:102260005800c293212043005000c38f5800c293ee
+:102270002110620020004290000082a05800c2930a
+:10228000010042245800c2a3f0ff0010000000002b
+:102290006800c28f5800c39321106200000040a064
+:1022a0006800c38f5000c28f300042940d0062a0be
+:1022b0006800c38f5000c28f1400428c100062acc3
+:1022c0006800c48f5000c28f1e004294001c0200a0
+:1022d0005000c28f1c00429421106200140082ac96
+:1022e0006800c38f5000c28f2c004294180062ac6b
+:1022f0005c00c0af5c00c28f21e8c0036400bf8fe8
+:102300006000be8f6800bd270800e00300000000e9
+:10231000f0ffbd270800beaf21f0a00388bf023c3c
+:102320001061428c0001427c0000c2af0000c38fec
+:10233000000062380100422c0000c2af0000c28fd2
+:1023400021e8c0030800be8f1000bd270800e0038d
+:1023500000000000f8ffbd270000beaf21f0a00381
+:102360000002022421e8c0030000be8f0800bd2740
+:102370000800e00300000000f8ffbd270000beaf2a
+:1023800021f0a0039081828f21e8c0030000be8f5e
+:102390000800bd270800e00300000000f8ffbd278b
+:1023a0000000beaf21f0a00388bf033c0061629033
+:1023b00010004234006162a088bf033c506062900c
+:1023c00002004234506062a088bf043c40608390a9
+:1023d000fdff022424106200406082a088bf033cfd
+:1023e0000061629008004234006162a021e8c003ed
+:1023f0000000be8f0800bd270800e00300000000b9
+:10240000e8ffbd271400bfaf1000beaf21f0a0034e
+:10241000ff4a400f0000000088bf033c50606290fc
+:1024200002004234506062a02110000021e8c00385
+:102430001400bf8f1000be8f1800bd270800e003f6
+:1024400000000000d0ffbd272c00bfaf2800beafaa
+:1024500021f0a0033000c4af2110a0003800c6afa7
+:102460003400c2a3080002241000c2a788bf043ca5
+:1024700050608390fdff022424106200506082a00f
+:10248000029d043c3400c393211060004010020000
+:1024900021104300801802004807822421106200a6
+:1024a000000042902000c2a33800c28f1c00c2afbf
+:1024b000029d043c3400c3932110600040100200d0
+:1024c0002110430080180200480782242110620076
+:1024d000010042901800c2a32000c28f4000423485
+:1024e0002000c2af2000c293212040000c4b400fbf
+:1024f000000000001f00c293212040000c4b400f41
+:10250000000000001e00c293212040000c4b400f31
+:10251000000000001d00c293212040000c4b400f22
+:10252000000000001c00c293212040000c4b400f13
+:10253000000000001800c293212040000c4b400f07
+:1025400000000000029d023c3400c393480744246d
+:102550002110600040100200211043008010020092
+:10256000211044000400428c0f00401000000000c5
+:10257000029d023c3400c3934807442421106000ac
+:10258000401002002110430080100200211044007e
+:102590000400438c010002240300621000000000cc
+:1025a0001000001000000000264b400f000000004b
+:1025b0001400c2a31000c297ffff42241000c2a75c
+:1025c0001400c393ff0002241a00621400000000ec
+:1025d0001000c2971700401000000000f2ff00102a
+:1025e00000000000029d023c3400c39348074424cd
+:1025f00021106000401002002110430080100200f2
+:10260000211044000400438c0200022409006214db
+:1026100000000000264b400f00000000264b400f3a
+:10262000000000001500c2a3264b400f0000000070
+:102630001400c2a3029d023c3400c3934807442403
+:1026400021106000401002002110430080100200a1
+:10265000211044000400438c010002241f00621476
+:10266000000000001400c0a31200c0a31200c39316
+:10267000ff00022419006210000000001400c29341
+:102680001600401400000000ffff02241000c2a743
+:10269000264b400f000000001400c2a31000c29798
+:1026a000ffff42241000c2a71400c293060040148a
+:1026b000000000001000c29703004010000000005e
+:1026c000f3ff0010000000001200c293010042243a
+:1026d0001200c2a3e5ff001000000000ff00042468
+:1026e0000c4b400f00000000029d043c3400c393db
+:1026f00021106000401002002110430080180200e9
+:10270000480782242110620008004290050040140e
+:102710000000000088bf023c506043900200633418
+:10272000506043a01400c28f3000c38f000062ac21
+:102730003000c28f21e8c0032c00bf8f2800be8f5d
+:102740003000bd270800e00300000000d0ffbd27d7
+:102750002c00bfaf2800beaf21f0a0033000c4aff3
+:102760003400c5af010002241900c2a33000c28f9b
+:10277000401202001c00c2af1400c22721204000fa
+:10278000070005241c00c68f1149400f00000000ff
+:102790001400c2930d004010000000001400c22776
+:1027a00021204000070005241c00c68f1149400f5e
+:1027b000000000001400c29304004010000000005c
+:1027c0002000c0af6200001000000000ff020224e1
+:1027d0001000c2a7400002241200c2a71200c29734
+:1027e00006004010000000001200c297ffff4224c4
+:1027f0001200c2a7f9ff001000000000264b400f96
+:10280000000000001800c2a31000c297ffff42247e
+:102810001000c2a7400002241200c2a71200c297f3
+:1028200006004010000000001200c297ffff422483
+:102830001200c2a7f9ff0010000000001800c393a7
+:10284000ff00022406006214000000001000c2977e
+:102850000300401000000000e8ff0010000000002e
+:102860001000c29707004010000000001800c3933a
+:10287000fe000224030062140000000004000010a7
+:10288000000000001900c0a3280000100000000094
+:102890001000c0a71000c2970002422c1d0040107b
+:1028a000000000003400c28f130040100000000040
+:1028b00080bf033cff000224205a62ac80bf023c70
+:1028c000105a428c0000427c0300401400000000bb
+:1028d000faff0010000000001000c3973400c28f00
+:1028e0002118620080bf023c205a428c000062a086
+:1028f0000300001000000000264b400f0000000005
+:102900001000c297010042241000c2a7e1ff00108e
+:1029100000000000ff0004240c4b400f00000000ea
+:10292000ff0004240c4b400f00000000ff000424b3
+:102930000c4b400f0000000088bf033c50606290c9
+:1029400002004234506062a01900c2932000c2af5e
+:102950002000c28f21e8c0032c00bf8f2800be8f4b
+:102960003000bd270800e00300000000d8ffbd27ad
+:102970002400bfaf2000beaf21f0a0032800c4afe9
+:102980002c00c5af2110c0003000c2a301000224fa
+:102990001800c2a32800c28f0700401400000000e6
+:1029a0003000c29304004014000000001800c0a3cf
+:1029b00061000010000000001400c3272800c28f2f
+:1029c000401202002120600009000524213040004f
+:1029d0001149400f000000001400c2930400401091
+:1029e000000000001800c0a34f000010000000000d
+:1029f000fe0004240c4b400f000000001000c0a794
+:102a00001000c2970002422c160040100000000087
+:102a100080bf043c1000c3972c00c28f21106200bd
+:102a200000004290205a82ac80bf023c105a428c77
+:102a30000000427c0300401400000000faff001078
+:102a40000000000080bf023c205a428c1200c2a34a
+:102a50001000c297010042241000c2a7e8ff001036
+:102a600000000000ff0004240c4b400f0000000099
+:102a7000ff0004240c4b400f00000000264b400fc9
+:102a8000000000001200c2a31200c2930f004330e6
+:102a90000500022404006210000000001800c0a31a
+:102aa0001e000010000000001000c0a780bf033c03
+:102ab000ff000224205a62ac80bf023c105a428cb4
+:102ac0000000427c0300401400000000faff0010e8
+:102ad0000000000080bf023c205a428c1200c2a3ba
+:102ae0001000c297010042241000c2a71200c29336
+:102af00006004014000000001000c29703004010c0
+:102b000000000000e9ff0010000000001000c29764
+:102b100002004014000000001800c0a3ff000424bd
+:102b20000c4b400f0000000088bf023c50604390f7
+:102b300002006334506043a01800c29321e8c00330
+:102b40002400bf8f2000be8f2800bd270800e003af
+:102b500000000000f8ffbd270000beaf21f0a00379
+:102b600088bf023c1061428cc000427cff004230b2
+:102b700021e8c0030000be8f0800bd270800e00365
+:102b800000000000f0ffbd270800beaf21f0a00349
+:102b9000211080001000c2a31000c2930000c2a345
+:102ba0000000c293ffff42240000c2a3ff00433095
+:102bb000ff0002240c006210000000000b2702241a
+:102bc0000400c2af0400c28fffff4224211840005e
+:102bd0000400c3afffff0224f1ff621000000000f9
+:102be000f8ff0010000000000000000021e8c00312
+:102bf0000800be8f0800e0031000bd27f8ffbd27c6
+:102c00000000beaf21f0a00380bf033c80bf023ca8
+:102c1000105a428cff7f4230105a62ac21e8c00348
+:102c20000000be8f0800bd270800e0030000000080
+:102c3000e0ffbd271c00bfaf1800beaf21f0a0030e
+:102c4000211080002000c2a380bf023c105a428c99
+:102c5000c000427c0300401400000000faff001096
+:102c60000000000080bf033c2000c293205a62ace9
+:102c7000ec7e400f000000001000c2a321100000f5
+:102c800021e8c0031c00bf8f1800be8f2000bd27a5
+:102c90000800e00300000000e8ffbd271400bfaffc
+:102ca0001000beaf21f0a00380bf023c105a428c3e
+:102cb000c000427c0300401400000000faff001036
+:102cc0000000000080bf033cff000224205a62acd9
+:102cd000ec7e400f00000000ff00423021e8c003fe
+:102ce0001400bf8f1000be8f1800bd270800e0033e
+:102cf00000000000f8ffbd270000beaf21f0a003d8
+:102d00000800c4af80bf023c105a40ac80bf033cf7
+:102d1000005a629040004234005a62a080bf043cd6
+:102d2000015a8390feff022424106200015a82a0ff
+:102d300088bf043c80618390bfff0224241062009e
+:102d4000806182a088bf043c81618390feff0224e1
+:102d500024106200816182a088bf043c806183905e
+:102d600080ff022425106200806182a080bf043ca5
+:102d7000015a839080ff022425106200015a82a02c
+:102d800021e8c0030000be8f0800bd270800e00353
+:102d900000000000c0ffbd273c00bfaf3800beaf41
+:102da00021f0a003010002241200c2a303000224a8
+:102db0001800c2a788bf033c5060629002004234f2
+:102dc000506062a02003042400800534f57e400f8b
+:102dd0000000000080bf023c3000c2af6202023c33
+:102de000005a42341c00c2af0600023c801a423432
+:102df0002000c2af2000c28f401802001c00c28f0a
+:102e00001b004300f4016000121000002800c2af54
+:102e10002000c28f401802001c00c28f1b0043001c
+:102e2000f4016000101000000400401000000000d9
+:102e30002800c28f010042242800c2af2800c28fa0
+:102e40000101422c03004014000000000001022494
+:102e50002800c2af2800c28f04004010000000000c
+:102e60002800c28fffff42242800c2af2800c28f73
+:102e7000ff0042302400c2af2400c28fff00423066
+:102e80003000c38f305a62ac01000424e14a400f85
+:102e9000000000001000c0a71000c2970a00422cda
+:102ea0000900401000000000ff0004240c4b400ffc
+:102eb000000000001000c297010042241000c2a7c9
+:102ec000f5ff00100000000088bf043c50608390b4
+:102ed000fdff022424106200506082a0010004243f
+:102ee000e14a400f000000001400c22721204000ea
+:102ef00021280000213000001149400f000000008f
+:102f00001400c393ff0002240800621000000000b8
+:102f10001400c293f700433001000224030062143e
+:102f2000000000000a000010000000001200c0a312
+:102f300088bf033c5060629002004234506062a03f
+:102f40001200c2932c00c2af7600001000000000f7
+:102f5000ff0f02241000c2a71400c2272120400046
+:102f600001000524213000001149400f000000003d
+:102f70001000c297ffff42241000c2a71400c293a2
+:102f800006004010000000001000c297030040102f
+:102f900000000000f0ff0010000000001000c297c9
+:102fa00008004014000000001200c0a388bf023ccb
+:102fb0005060439002006334506043a057000010fb
+:102fc0000000000002000424e14a400f000000005d
+:102fd00080bf023c3400c2af6202023c005a42345d
+:102fe0002800c2af3101023c002d42342400c2afa0
+:102ff0002400c28f401802002800c28f1b0043002b
+:10300000f4016000121000001c00c2af2400c28f47
+:10301000401802002800c28f1b004300f40160002a
+:103020001010000004004010000000001c00c28fbf
+:10303000010042241c00c2af1c00c28f0101422cbf
+:103040000300401400000000000102241c00c2af75
+:103050001c00c28f04004010000000001c00c28f42
+:10306000ffff42241c00c2af1c00c28fff00423091
+:103070002000c2af2000c28fff0042303400c38f57
+:10308000305a62ac1400c2272120400010000524f1
+:10309000213000001149400f000000001400c22739
+:1030a0002120400006000524000206241149400f9b
+:1030b00000000000ff0002241000c2a71000c29709
+:1030c0000e00401000000000212000002128000018
+:1030d000d349400f000000002118400001000224e5
+:1030e00006006210000000001000c297ffff42249b
+:1030f0001000c2a7f1ff0010000000001000c297ee
+:1031000006004014000000001200c0a388bf023c6b
+:103110005060439002006334506043a01200c29399
+:103120002c00c2af2c00c28f21e8c0033c00bf8f2f
+:103130003800be8f4000bd270800e00300000000fb
+:10314000e0ffbd271c00bfaf1800beaf21f0a003f9
+:10315000214080002400c5af2128c0002c00c7af4b
+:103160003000c28f3800c38f4000c48f2000c8a336
+:103170002800c5a31000c2a31100c3a31200c4a35a
+:103180004882838f6c82828f0e00621000000000e4
+:103190009880838301000224f9ff6214000000007c
+:1031a0006c82828f010043244882828ff4ff621474
+:1031b000000000004882828f6c8282aff0ff001016
+:1031c0000000000021100000b48182af2800c383fa
+:1031d0005800022403006214000000002c00c28f7b
+:1031e000b48182af1000c38358000224030062142c
+:1031f000000000003400c28fb48182af1100c3838d
+:103200005800022403006214000000003c00c28f3a
+:10321000b48182af1200c3835800022403006214f9
+:10322000000000004400c28fb48182af2800c28336
+:10323000580042380100432c1000c2835800423825
+:103240000100422c251862001100c2835800423848
+:103250000100422c251862001200c2835800423837
+:103260000100422c25106200050040100000000003
+:1032700001000224788082af0200001000000000ec
+:10328000788080af211800009c8183af2800c38321
+:103290005900022403006214000000002c00c28fb9
+:1032a0009c8182af1000c383590002240300621482
+:1032b000000000003400c28f9c8182af1100c383e4
+:1032c0005900022403006214000000003c00c28f79
+:1032d0009c8182af1200c383590002240300621450
+:1032e000000000004400c28f9c8182af2800c2838e
+:1032f000590042380100432c1000c2835900423863
+:103300000100422c251862001100c2835900423886
+:103310000100422c251862001200c2835900423875
+:103320000100422c25106200050040100000000042
+:10333000010002247c8082af020000100000000027
+:103340007c8080af21100000a88182af2800c38359
+:103350005a00022403006214000000002c00c28ff7
+:10336000a88182af1000c3835a00022403006214b4
+:10337000000000003400c28fa88182af1100c38317
+:103380005a00022403006214000000003c00c28fb7
+:10339000a88182af1200c3835a0002240300621482
+:1033a000000000004400c28fa88182af2800c283c1
+:1033b0005a0042380100432c1000c2835a004238a0
+:1033c0000100422c251862001100c2835a004238c5
+:1033d0000100422c251862001200c2835a004238b4
+:1033e0000100422c25106200050040100000000082
+:1033f00001000224808082af020000100000000063
+:10340000808080af21180000a08183af2800c38393
+:103410004900022403006214000000002c00c28f47
+:10342000a08182af1000c38349000224030062140c
+:10343000000000003400c28fa08182af1100c3835e
+:103440004900022403006214000000003c00c28f07
+:10345000a08182af1200c3834900022403006214da
+:10346000000000004400c28fa08182af2800c28308
+:10347000490042380100432c1000c2834900423801
+:103480000100422c251862001100c2834900423815
+:103490000100422c251862001200c2834900423804
+:1034a0000100422c251062000500401000000000c1
+:1034b00001000224848082af02000010000000009e
+:1034c000848080af21100000a48182af2800c383d4
+:1034d0004a00022403006214000000002c00c28f86
+:1034e000a48182af1000c3834a0002240300621447
+:1034f000000000003400c28fa48182af1100c3839a
+:103500004a00022403006214000000003c00c28f45
+:10351000a48182af1200c3834a0002240300621414
+:10352000000000004400c28fa48182af2800c28343
+:103530004a0042380100432c1000c2834a0042383e
+:103540000100422c251862001100c2834a00423853
+:103550000100422c251862001200c2834a00423842
+:103560000100422c25106200050040100000000000
+:1035700001000224888082af0200001000000000d9
+:10358000888080af2800c3834600022405006214af
+:10359000000000002c00c48fd87c400f0000000009
+:1035a000708082af1000c3834600022405006214bd
+:1035b000000000003400c48fd87c400f00000000e1
+:1035c000708082af1100c38346000224050062149c
+:1035d000000000003c00c48fd87c400f00000000b9
+:1035e000708082af1200c38346000224050062147b
+:1035f000000000004400c48fd87c400f0000000091
+:10360000708082af21180000ac8183af2800c38393
+:103610005000022403006214000000002c00c28f3e
+:10362000ac8182af1000c3835000022403006214f7
+:10363000000000003400c28fac8182af1100c38350
+:103640005000022403006214000000003c00c28ffe
+:10365000ac8182af1200c3835000022403006214c5
+:10366000000000004400c28fac8182af2110000036
+:10367000b08182af2800c383530002240300621488
+:10368000000000002c00c28fb08182af1000c38305
+:103690005300022403006214000000003400c28fb3
+:1036a000b08182af1100c38353000224030062146f
+:1036b000000000003c00c28fb08182af1200c383c3
+:1036c0005300022403006214000000004400c28f73
+:1036d000b08182af2000c3831400c3af470002242f
+:1036e0001400c38f07006210000000004d00022488
+:1036f0001400c38f4800621000000000a4000010f6
+:10370000000000002400c28f988182af9881828fd0
+:1037100003004014000000006a4e400f000000004b
+:103720009881838f010002240300621400000000ce
+:10373000894e400f000000009881838f0200022410
+:103740000300621400000000af4e400f00000000b4
+:103750009881838f0300022403006214000000009c
+:10376000c64e400f000000009881838f04000224a1
+:103770000300621400000000dd4e400f0000000056
+:103780009881838f1400022403006214000000005b
+:10379000f94e400f000000009881838f150002242d
+:1037a0000300621400000000034f400f00000000ff
+:1037b0009881838f1c000224030062140000000023
+:1037c0000d4f400f000000009881838f5a000224a3
+:1037d0000300621400000000154f400f00000000bd
+:1037e0009881838f5b0002240300621400000000b4
+:1037f000214f400f000000009881838f5c0002245d
+:103800006300621400000000294f400f0000000018
+:103810005f000010000000002400c28f948182af7e
+:10382000988180af708080af9481838f650002247f
+:103830000300621400000000374f400f000000003a
+:103840009481838f6700022403006214000000004b
+:10385000454f400f000000009481838f68000224d0
+:103860000300621400000000524f400f00000000ef
+:103870009481838f6a000224030062140000000018
+:10388000964f400f000000009481838f6b0002244c
+:103890000300621400000000a44f400f000000006d
+:1038a0009481838f6c0002240300621400000000e6
+:1038b000b24f400f000000009481838fdc0002248f
+:1038c0000300621400000000d04f400f0000000011
+:1038d0009481838fdd000224030062140000000045
+:1038e000dd4f400f000000009481838fde00022432
+:1038f0000300621400000000e94f400f00000000c8
+:103900009481838fdf000224030062140000000012
+:103910000350400f000000009481838fe0000224d8
+:1039200003006214000000001d50400f0000000062
+:103930009481838fe10002240300621400000000e0
+:103940002750400f000000009481838fe200022482
+:1039500003006214000000003050400f000000001f
+:103960009481838fe30002240300621400000000ae
+:103970006850400f000000009481838fe40002240f
+:103980000300621400000000a050400f000000007f
+:1039900021e8c0031c00bf8f1800be8f2000bd2788
+:1039a0000800e00300000000e8ffbd271400bfafdf
+:1039b0001000beaf21f0a0037080828f030040147e
+:1039c00000000000c0030224708082af7080848fea
+:1039d0009481858f6c66400f00000000b080838367
+:1039e0000100022403006214000000000100022410
+:1039f000098282a37480848f21280000e266400f30
+:103a000000000000c767400f0000000021e8c0036d
+:103a10001400bf8f1000be8f1800bd270800e00300
+:103a200000000000e8ffbd271400bfaf1000beafcc
+:103a300021f0a0037080828f03004014000000007a
+:103a4000f0000224708082af2c8182830500401038
+:103a5000000000007080828ffc81838f2110430062
+:103a6000708082af7080848f9481858f6c66400fe8
+:103a700000000000b0808383010002240300621470
+:103a80000000000001000224098282a37480848f58
+:103a900021280000e266400f00000000c767400fc9
+:103aa0000000000021e8c0031400bf8f1000be8f8b
+:103ab0001800bd270800e00300000000e8ffbd2754
+:103ac0001400bfaf1000beaf21f0a0037080828f42
+:103ad0000300401400000000f0000224708082af58
+:103ae0007080848f9481858f6c66400f0000000089
+:103af0007480848f01000524e266400f00000000fe
+:103b000021e8c0031400bf8f1000be8f1800bd272e
+:103b10000800e00300000000e8ffbd271400bfaf6d
+:103b20001000beaf21f0a0037080828f030040140c
+:103b300000000000f0000224708082af7080848f4b
+:103b40009481858f6c66400f000000007480848f24
+:103b500001000524e266400f0000000021e8c003d8
+:103b60001400bf8f1000be8f1800bd270800e003af
+:103b700000000000e0ffbd271c00bfaf1800beaf73
+:103b800021f0a0031000c0afac81848f2128000079
+:103b9000137d400f000000000300401400000000ef
+:103ba0000a00001000000000ac81848fd87c400f18
+:103bb00000000000c8000324021043701000c2afd0
+:103bc0001000c48fa71e400f0000000021e8c003b2
+:103bd0001c00bf8f1800be8f2000bd270800e00327
+:103be00000000000f8ffbd270000beaf21f0a003d9
+:103bf00014000224748082af21e8c0030000be8f4d
+:103c00000800bd270800e00300000000f8ffbd2702
+:103c10000000beaf21f0a00315000224748082af23
+:103c200021e8c0030000be8f0800bd270800e003a4
+:103c300000000000f8ffbd270000beaf21f0a00388
+:103c400021e8c0030000be8f0800bd270800e00384
+:103c500000000000e8ffbd271400bfaf1000beaf9a
+:103c600021f0a0039967400f0000000021e8c00385
+:103c70001400bf8f1000be8f1800bd270800e0039e
+:103c800000000000f8ffbd270000beaf21f0a00338
+:103c900021e8c0030000be8f0800bd270800e00334
+:103ca00000000000e8ffbd271400bfaf1000beaf4a
+:103cb00021f0a0036a4e400f000000004567400f4e
+:103cc0000000000021e8c0031400bf8f1000be8f69
+:103cd0001800bd270800e00300000000f8ffbd2722
+:103ce0000000beaf21f0a003b08083830200022455
+:103cf000030062140000000001000224098282a374
+:103d000021e8c0030000be8f0800bd270800e003c3
+:103d100000000000f8ffbd270000beaf21f0a003a7
+:103d2000b0808383020002240200621400000000bd
+:103d3000098280a321e8c0030000be8f0800bd27d0
+:103d40000800e00300000000e8ffbd271400bfaf3b
+:103d50001000beaf21f0a003b080838302000224d4
+:103d6000370062140000000004000424c452400f15
+:103d70000000000005000424c452400f00000000b1
+:103d800006000424c452400f000000000500042473
+:103d900021280000029d023c14084624213800001e
+:103da0004353400f00000000448080af0100022414
+:103db000488182a3b081848f21280000137d400fa9
+:103dc0000000000003004014000000000500001087
+:103dd00000000000b081848fd87c400f00000000fc
+:103de0004c8082afa663400f000000000100042455
+:103df000481d400f000000009751400f00000000d8
+:103e00004452400f00000000fb51400f0000000032
+:103e10004480828f06004014000000004c80828f96
+:103e20000300401000000000f3ff0010000000003d
+:103e3000488180a305000424c452400f0000000004
+:103e400021e8c0031400bf8f1000be8f1800bd27eb
+:103e50000800e00300000000f8ffbd270000beaf2f
+:103e600021f0a003010002243c8182a388bf033c0f
+:103e70001061629020004234106162a021e8c0030a
+:103e80000000be8f0800bd270800e003000000000e
+:103e9000f8ffbd270000beaf21f0a0033c8180a346
+:103ea00088bf043c10618390dfff0224241062006d
+:103eb000106182a021e8c0030000be8f0800bd276a
+:103ec0000800e00300000000e8ffbd271400bfafba
+:103ed0001000beaf21f0a003b08083830200022453
+:103ee000110062140000000021200000b081858fc5
+:103ef000137d400f0000000003004004000000009c
+:103f00000500001000000000b081848fd87c400fb5
+:103f100000000000048082afa91b400f00000000d9
+:103f200001000224498182a321e8c0031400bf8f4d
+:103f30001000be8f1800bd270800e003000000003d
+:103f4000f8ffbd270000beaf21f0a00388bf043cee
+:103f5000d1608390f7ff022424106200d16082a018
+:103f600021e8c0030000be8f0800bd270800e00361
+:103f700000000000f8ffbd270000beaf21f0a00345
+:103f800088bf023cd160439008006334d16043a0f5
+:103f900021e8c0030000be8f0800bd270800e00331
+:103fa00000000000e8ffbd271400bfaf1000beaf47
+:103fb00021f0a003b0808383020002240d0062146c
+:103fc0000000000021200000b081858f137d400f8c
+:103fd0000000000003004004000000000500001085
+:103fe00000000000b081848fd87c400f00000000ea
+:103ff000408182af21e8c0031400bf8f1000be8f44
+:104000001800bd270800e00300000000e8ffbd27fe
+:104010001400bfaf1000beaf21f0a003b0808383b7
+:10402000020002240d0062140000000021200000a4
+:10403000b081858f137d400f000000000300400415
+:10404000000000000500001000000000b081848f17
+:10405000d87c400f00000000388182af21e8c00307
+:104060001400bf8f1000be8f1800bd270800e003aa
+:1040700000000000f8ffbd270000beaf21f0a00344
+:1040800001000224348182a321e8c0030000be8f16
+:104090000800bd270800e00300000000f8ffbd276e
+:1040a0000000beaf21f0a003348180a321e8c0034b
+:1040b0000000be8f0800bd270800e00300000000dc
+:1040c000d8ffbd272400bfaf2000beaf1c00b1af9a
+:1040d0001800b0af21f0a0034882838f6c82828fda
+:1040e0000e0062100000000098808383010002240b
+:1040f000f9ff6214000000006c82828f01004324eb
+:104100004882828ff4ff6214000000004882828f90
+:104110006c8282aff0ff0010000000003159400fa8
+:104120000000000088bf023c9061428c4002427c4b
+:104130000300401400000000faff0010000000001f
+:10414000ec80848f017a400f000000002180400045
+:1041500021886000f080848f017a400f0000000009
+:104160001000a0af1400a0af2120000221282002df
+:104170002130400021386000f95b400f0000000052
+:1041800021e8c0032400bf8f2000be8f1c00b18f28
+:104190001800b08f2800bd270800e00300000000d1
+:1041a000e8ffbd271400bfaf1000beaf21f0a00391
+:1041b000b0808383020002242b0062140000000000
+:1041c00001000224448182af21200000b081858f4c
+:1041d000137d400f000000000300400400000000b9
+:1041e0000d00001000000000b081848f017a400fa4
+:1041f0000000000021204000212860008f76400f41
+:10420000000000002120400021286000687a400f53
+:1042100000000000288182af21200000ac81858f42
+:10422000137d400f00000000030040040000000068
+:104230000d00001000000000ac81848f017a400f57
+:104240000000000021204000212860008f76400ff0
+:10425000000000002120400021286000687a400f03
+:1042600000000000548182af21e8c0031400bf8f1a
+:104270001000be8f1800bd270800e00300000000fa
+:10428000f8ffbd270000beaf21f0a003b0808383fc
+:10429000020002240200621400000000448180af8a
+:1042a00021e8c0030000be8f0800bd270800e0031e
+:1042b00000000000e8ffbd271400bfaf1000beaf34
+:1042c00021f0a0032120000021280000029d023cd3
+:1042d00004164624213800004353400f000000001c
+:1042e000010004241c00052400a0023c740a46249a
+:1042f000213800004353400f000000000200042456
+:1043000021280000029d023c181646242138000096
+:104310004353400f00000000030004242128000044
+:10432000029d023c28164624213800004353400fca
+:1043300000000000b080838f020002240800621495
+:10434000000000000400042421280000029d023c1b
+:1043500034164624213800004353400f000000006b
+:1043600021e8c0031400bf8f1000be8f1800bd27c6
+:104370000800e00300000000d0ffbd272c00bfaf05
+:104380002800beaf21f0a0031000c427029d023c0c
+:10439000401645249080868f486e400f0000000034
+:1043a000020004245a0005241000c627213800000a
+:1043b0004353400f000000001881828f3e004018d8
+:1043c000000000001881848fae7c400f00000000c8
+:1043d000029d033c212040005816658c237c400f31
+:1043e000000000002000c2af2000c48f017a400fff
+:1043f0000000000021304000213860001000c42778
+:10440000029d023c44164524486e400f0000000007
+:10441000030004244b0005241000c62721380000a7
+:104420004353400f000000000480848fae7c400f97
+:104430000000000021204000017a400f0000000031
+:10444000029d063c21204000212860006416c78c94
+:104450006016c68cd977400f000000002120400074
+:10446000212860002a7a400f00000000b88182af46
+:10447000b881848f017a400f000000002130400095
+:10448000213860001000c427029d023c44164524d8
+:10449000486e400f00000000040004244b00052477
+:1044a0001000c627213800004353400f00000000d1
+:1044b0000800001000000000030004244b00052445
+:1044c000029d023c50164624213800004353400f01
+:1044d000000000004460400f000000007960400fc1
+:1044e00000000000b080838f020002240d006214df
+:1044f000000000009751400f000000006c81828393
+:1045000003004010000000004452400f0000000073
+:10451000498182830300401000000000fb51400fde
+:104520000000000021e8c0032c00bf8f2800be8fd0
+:104530003000bd270800e00300000000e8ffbd27b1
+:104540001400bfaf1000beaf21f0a0032120000077
+:1045500021280000029d023c041646242138000058
+:104560004353400f000000000100042421280000f4
+:10457000029d023c68164624213800004353400f38
+:104580000000000088bf023c5061428c0000427c69
+:104590000a0040100000000005000424212800004b
+:1045a000029d023c7c164624213800004353400ff4
+:1045b00000000000080000100000000005000424b6
+:1045c00021280000029d023c881646242138000064
+:1045d0004353400f00000000029d023c2481848f61
+:1045e000a816458c137d400f000000000300400416
+:1045f000000000000a000010000000000300042476
+:1046000021280000029d023c941646242138000017
+:104610004353400f000000000400001000000000a1
+:1046200003000424c452400f000000004452400f15
+:10463000000000009751400f00000000fb51400fa8
+:104640000000000021e8c0031400bf8f1000be8fdf
+:104650001800bd270800e00300000000d0ffbd27c0
+:104660002c00bfaf2800beaf21f0a003029d023c8a
+:104670002481848fe416458c137d400f00000000d8
+:104680000a00401000000000029d023c2481848f3b
+:10469000e816458c137d400f000000000300401019
+:1046a00000000000260000100000000007000424a5
+:1046b000c452400f00000000029d023c2481848f00
+:1046c000e416458c137d400f0000000003004010ed
+:1046d0000000000008000010000000000700042493
+:1046e0000a000524029d023cac1646242138000035
+:1046f0004353400f00000000029d023c2481848f40
+:10470000e816458c137d400f0000000003004010a8
+:10471000000000002f00001000000000070004242b
+:104720000a000524029d023cc016462421380000e0
+:104730004353400f0000000026000010000000005e
+:104740002481848fd87c400f000000002000c2af7d
+:104750001000c427029d023cd41645242000c68fb9
+:10476000486e400f00000000070004242d000524bf
+:104770001000c627213800004353400f00000000fe
+:1047800088bf023c5061428c0000427c0a0040100d
+:10479000000000000700042423000524029d023cc1
+:1047a000dc164624213800004353400f000000006f
+:1047b0000800001000000000070004242300052466
+:1047c000029d023ce0164624213800004353400f6e
+:1047d0000000000021e8c0032c00bf8f2800be8f1e
+:1047e0003000bd270800e00300000000d0ffbd2717
+:1047f0002c00bfaf2800beaf21f0a0030480848f3f
+:104800006666023c676642341800820010100000a1
+:1048100083180200c3170400231062002000c2aff7
+:104820001000c427029d023cec1645242000c68fd0
+:10483000486e400f000000000700042455000524c6
+:104840001000c627213800004353400f000000002d
+:104850000400042421280000029d023c3416462452
+:10486000213800004353400f000000000480848f73
+:10487000ae7c400f0000000021204000017a400f74
+:1048800000000000029d063c21204000212860001d
+:10489000fc16c78cf816c68cd977400f00000000b4
+:1048a00021204000212860002a7a400f00000000eb
+:1048b000b88182afb881848f017a400f0000000078
+:1048c00021304000213860001000c427029d023cc6
+:1048d00044164524486e400f0000000004000424e4
+:1048e0004b0005241000c627213800004353400f19
+:1048f00000000000498180a321e8c0032c00bf8f85
+:104900002800be8f3000bd270800e0030000000033
+:10491000d8ffbd272400bfaf2000beaf21f0a00309
+:104920004c80828f02004104000000004c8080af68
+:104930001000c427029d023cd41645244c80868f6b
+:10494000486e400f000000000700042421280000ea
+:104950001000c627213800004353400f000000001c
+:104960006c8180a321e8c0032400bf8f2000be8f8c
+:104970002800bd270800e00300000000e0ffbd277d
+:104980001c00bfaf1800beaf21f0a00321108000b3
+:104990002000c2a31000c0a31000c2930800422c44
+:1049a0002000401000000000b0ff03241000c2935c
+:1049b00021106200ff00423021204000c256400f0b
+:1049c0000000000021200000c256400f000000003f
+:1049d00010000424c256400f000000001100c0a3c4
+:1049e0001100c2830a004004000000002000c293ae
+:1049f00021204000e456400f000000001100c29347
+:104a0000010042241100c2a3f5ff001000000000c5
+:104a10001000c293010042241000c2a3deff001068
+:104a20000000000021e8c0031c00bf8f1800be8feb
+:104a30002000bd270800e00300000000e0ffbd27c4
+:104a40001c00bfaf1800beaf21f0a00321108000f2
+:104a50002400c5af2000c2a3b0ff03242000c293ee
+:104a600021106200ff00423021204000c256400f5a
+:104a70000000000021200000c256400f000000008e
+:104a800010000424c256400f000000001000c0a314
+:104a90001000c2932400c38f2a1043000900401065
+:104aa0000000000018000424e456400f000000003d
+:104ab0001000c293010042241000c2a3f4ff0010b2
+:104ac000000000002400c28f1000c2a31000c283a7
+:104ad000090040040000000021200000e456400fbf
+:104ae000000000001000c293010042241000c2a385
+:104af000f6ff00100000000021e8c0031c00bf8f7b
+:104b00001800be8f2000bd270800e0030000000051
+:104b1000e0ffbd271c00bfaf1800beaf21f0a0030f
+:104b2000211080002000c2a3b0ff03242000c29304
+:104b300021106200ff00423021204000c256400f89
+:104b40000000000021200000c256400f00000000bd
+:104b500010000424c256400f000000001000c0a343
+:104b60001000c28309004004000000002120000062
+:104b7000e456400f000000001000c29301004224e0
+:104b80001000c2a3f6ff00100000000021e8c003df
+:104b90001c00bf8f1800be8f2000bd270800e00357
+:104ba00000000000d8ffbd272400bfaf2000beaf2b
+:104bb00021f0a003211080002800c2a32800c29386
+:104bc0001c00c2af010002241c00c38f150062103c
+:104bd000000000001c00c38f020062280600401085
+:104be000000000001c00c28f0900401000000000ff
+:104bf0001400001000000000020002241c00c38ffb
+:104c00000d006210000000000e0000100000000007
+:104c1000029d023c280842241400c2af0900001083
+:104c200000000000029d023c280c42241400c2af88
+:104c30000400001000000000029d023c28104224e5
+:104c40001400c2af1000c0a31000c2930800422c91
+:104c500028004010000000001000c293c0110200a4
+:104c60001800c2afb0ff03241000c29321106200ed
+:104c7000ff00423021204000c256400f00000000db
+:104c800021200000c256400f000000001000042444
+:104c9000c256400f000000001100c0a31100c283e3
+:104ca0000f004004000000001100c3931400c28fe5
+:104cb000211862001800c28f21106200000042908b
+:104cc00021204000e456400f000000001100c29374
+:104cd000010042241100c2a3f0ff001000000000f8
+:104ce0001000c293010042241000c2a3d6ff00109e
+:104cf0000000000021e8c0032400bf8f2000be8f09
+:104d00002800bd270800e00300000000d0ffbd27f9
+:104d10002c00bfaf2800beaf21f0a0033000c4af0d
+:104d20003400c5af3800c6af2110e0003c00c2a37c
+:104d30001c00c0af3400c28f1000c2a31000c29389
+:104d40000f0042301100c2a31000c29302110200f2
+:104d5000100042341200c2a33000c28fb0ff0324ff
+:104d600021106200ff00423021204000c256400f57
+:104d7000000000001100c29321204000c256400fe5
+:104d8000000000001200c29321204000c256400fd4
+:104d9000000000001400c0af1400c38f3800c28fa1
+:104da00021106200000042909700401000000000b7
+:104db0001400c38f3800c28f21106200000042909f
+:104dc0005300422c14004010000000002000c527b2
+:104dd0001400c38f3800c28f21106200000044907d
+:104de000211080008018020021186400029d023cfe
+:104df0002814422460ff4224211062002120a000d8
+:104e00002128400005000624af6a400f0000000082
+:104e10003c000010000000001400c38f3800c28f57
+:104e200021106200000042907f00422c2e004010b2
+:104e3000000000001400c38f3800c28f21106200f0
+:104e4000000042905c00422c14004014000000005e
+:104e50002000c5271400c38f3800c28f21106200c4
+:104e60000000449021108000801802002118640086
+:104e7000029d023c281542245cfe4224211062005f
+:104e80002120a0002128400005000624af6a400f21
+:104e9000000000001b000010000000002000c527db
+:104ea0001400c38f3800c28f2110620000004490ac
+:104eb000211080008018020021186400029d023c2d
+:104ec0002815422461fe4224211062002120a00006
+:104ed0002128400005000624af6a400f00000000b2
+:104ee00008000010000000002000c2272120400020
+:104ef000029d023c2814452405000624af6a400f99
+:104f0000000000001800c0af1800c28f0500422842
+:104f100032004010000000001c00c28f80004228b8
+:104f20001b004010000000003c00c2930a00401427
+:104f3000000000001800c38f1000c227211043009a
+:104f40001000429021204000e456400f0000000075
+:104f50000a000010000000001800c38f1000c227d4
+:104f6000211043001000429027100200ff00423041
+:104f700021204000e456400f000000001c00c28fba
+:104f8000010042241c00c2af0f000010000000000e
+:104f90003000c28fb1ff032421106200ff004230b5
+:104fa00021204000c256400f000000001800c38faf
+:104fb0001000c22721104300100042902120400021
+:104fc000e456400f000000001800c28f0100422488
+:104fd0001800c2afccff001000000000212000002c
+:104fe000e456400f000000001c00c28f0100422464
+:104ff0001c00c2af1400c28f010042241400c2afd3
+:1050000065ff00100000000021e8c0032c00bf8fe6
+:105010002800be8f3000bd270800e003000000001c
+:10502000e8ffbd271400bfaf1000beaf21f0a00302
+:10503000212000005f52400f0000000021200000ee
+:105040000a000524029d023c041646242138000073
+:105050004353400f00000000010004241400052405
+:10506000029d023c00174624213800004353400fa4
+:10507000000000000200042414000524029d023cec
+:1050800008174624213800004353400f0000000059
+:105090000300042414000524029d023c1417462436
+:1050a000213800004353400f000000000400042496
+:1050b00014000524029d023c2017462421380000dc
+:1050c0004353400f00000000050004241400052491
+:1050d000029d023c2c174624213800004353400f08
+:1050e0000000000021e8c0031400bf8f1000be8f35
+:1050f0001800bd270800e00300000000e8ffbd27fe
+:105100001400bfaf1000beaf21f0a00321200000ab
+:105110005f52400f00000000212000000a0005241b
+:10512000029d023c04164624213800004353400fe0
+:10513000000000000100042421280000029d023c20
+:105140003c174624213800004353400f0000000064
+:105150000400042421280000029d023c4417462438
+:10516000213800004353400f0000000005000424d4
+:1051700021280000029d023c4c17462421380000e3
+:105180004353400f000000000600042421280000c3
+:10519000029d023c54174624213800004353400f1f
+:1051a0000000000021e8c0031400bf8f1000be8f74
+:1051b0001800bd270800e00300000000e8ffbd273d
+:1051c0001400bfaf1000beaf21f0a00321200000eb
+:1051d0005f52400f00000000212000000a0005245b
+:1051e000029d023c04164624213800004353400f20
+:1051f000000000000100042414000524029d023c6c
+:105200005c174624213800004353400f0000000083
+:1052100021e8c0031400bf8f1000be8f1800bd2707
+:105220000800e00300000000e8ffbd271400bfaf46
+:105230001000beaf21f0a00301000424c452400faf
+:10524000000000000100042414000524029d023c1b
+:1052500020174624213800004353400f000000006f
+:1052600021e8c0031400bf8f1000be8f1800bd27b7
+:105270000800e00300000000e8ffbd271400bfaff6
+:105280001000beaf21f0a003212000005f52400fac
+:10529000000000000100042421280000029d023cbf
+:1052a0006c174624213800004353400f00000000d3
+:1052b00021e8c0031400bf8f1000be8f1800bd2767
+:1052c0000800e00300000000d8ffbd272400bfafa6
+:1052d0002000beaf21f0a0032800c4af2c00c5af52
+:1052e0003000c6af2110e0003400c2a3212000002e
+:1052f0005f52400f0000000001000424212800003c
+:10530000029d023c80174624213800004353400f81
+:10531000000000002800c48f017a400f0000000048
+:1053200021304000213860001000c427029d023c5b
+:105330008c174524486e400f000000000300042431
+:10534000212800001000c627213800004353400fd9
+:10535000000000002c00c48f017a400f0000000004
+:1053600021304000213860001000c427029d023c1b
+:1053700094174524486e400f0000000004000424e8
+:10538000212800001000c627213800004353400f99
+:10539000000000003400c283130040100000000031
+:1053a0003000c48f017a400f00000000213040001f
+:1053b000213860001000c427029d023c9c17452440
+:1053c000486e400f00000000050004242128000062
+:1053d0001000c627213800004353400f0000000092
+:1053e000080000100000000005000424212800002f
+:1053f000029d023ca4174624213800004353400f6d
+:105400000000000021e8c0032400bf8f2000be8ff1
+:105410002800bd270800e00300000000e8ffbd27ca
+:105420001400bfaf1000beaf21f0a0032120000088
+:105430005f52400f000000002120000021280000e2
+:10544000029d023cb0174624213800004353400f10
+:10545000000000000200042421280000029d023cfc
+:10546000bc174624213800004353400f00000000c1
+:105470000400042421280000029d023ccc1746248d
+:10548000213800004353400f0000000021e8c00312
+:105490001400bf8f1000be8f1800bd270800e00366
+:1054a00000000000e8ffbd271400bfaf1000beaf32
+:1054b00021f0a0031800c4af1c00c5af2110c0002c
+:1054c0002000c2a31800c28f0800422c73014010b4
+:1054d000000000001800c28f80180200029d023cec
+:1054e000e4174224211062000000428c08004000b2
+:1054f000000000002000c393010004241c00c58f9d
+:10550000029d023cdc174624213860004353400fc3
+:1055100000000000020004241c00c58f029d023c14
+:10552000e0174624213800004353400f00000000dc
+:10553000030004241c00c58f029d023ce017462492
+:10554000213800004353400f0000000004000424f1
+:105550001c00c58f029d023ce01746242138000044
+:105560004353400f00000000050004241c00c58fb9
+:10557000029d023ce0174624213800004353400faf
+:1055800000000000060004241c00c58f029d023ca0
+:10559000e0174624213800004353400f000000006c
+:1055a000070004241c00c58f029d023ce01746241e
+:1055b000213800004353400f000000003701001065
+:1055c00000000000010004241c00c58f029d023c65
+:1055d000e0174624213800004353400f000000002c
+:1055e0002000c393020004241c00c58f029d023cce
+:1055f000dc174624213860004353400f00000000b0
+:10560000030004241c00c58f029d023ce0174624c1
+:10561000213800004353400f000000000400042420
+:105620001c00c58f029d023ce01746242138000073
+:105630004353400f00000000050004241c00c58fe8
+:10564000029d023ce0174624213800004353400fde
+:1056500000000000060004241c00c58f029d023ccf
+:10566000e0174624213800004353400f000000009b
+:10567000070004241c00c58f029d023ce01746244d
+:10568000213800004353400f0000000003010010c8
+:1056900000000000010004241c00c58f029d023c94
+:1056a000e0174624213800004353400f000000005b
+:1056b000020004241c00c58f029d023ce017462412
+:1056c000213800004353400f000000002000c39326
+:1056d000030004241c00c58f029d023cdc174624f5
+:1056e000213860004353400f0000000004000424f0
+:1056f0001c00c58f029d023ce017462421380000a3
+:105700004353400f00000000050004241c00c58f17
+:10571000029d023ce0174624213800004353400f0d
+:1057200000000000060004241c00c58f029d023cfe
+:10573000e0174624213800004353400f00000000ca
+:10574000070004241c00c58f029d023ce01746247c
+:10575000213800004353400f00000000cf0000102c
+:1057600000000000010004241c00c58f029d023cc3
+:10577000e0174624213800004353400f000000008a
+:10578000020004241c00c58f029d023ce017462441
+:10579000213800004353400f0000000003000424a0
+:1057a0001c00c58f029d023ce017462421380000f2
+:1057b0004353400f000000002000c3930400042462
+:1057c0001c00c58f029d023cdc1746242138600076
+:1057d0004353400f00000000050004241c00c58f47
+:1057e000029d023ce0174624213800004353400f3d
+:1057f00000000000060004241c00c58f029d023c2e
+:10580000e0174624213800004353400f00000000f9
+:10581000070004241c00c58f029d023ce0174624ab
+:10582000213800004353400f000000009b0000108f
+:1058300000000000010004241c00c58f029d023cf2
+:10584000e0174624213800004353400f00000000b9
+:10585000020004241c00c58f029d023ce017462470
+:10586000213800004353400f0000000003000424cf
+:105870001c00c58f029d023ce01746242138000021
+:105880004353400f00000000040004241c00c58f97
+:10589000029d023ce0174624213800004353400f8c
+:1058a000000000002000c393050004241c00c58fe5
+:1058b000029d023cdc174624213860004353400f10
+:1058c00000000000060004241c00c58f029d023c5d
+:1058d000e0174624213800004353400f0000000029
+:1058e000070004241c00c58f029d023ce0174624db
+:1058f000213800004353400f0000000067000010f3
+:1059000000000000010004241c00c58f029d023c21
+:10591000e0174624213800004353400f00000000e8
+:10592000020004241c00c58f029d023ce01746249f
+:10593000213800004353400f0000000003000424fe
+:105940001c00c58f029d023ce01746242138000050
+:105950004353400f00000000040004241c00c58fc6
+:10596000029d023ce0174624213800004353400fbb
+:1059700000000000050004241c00c58f029d023cad
+:10598000e0174624213800004353400f0000000078
+:105990002000c393060004241c00c58f029d023c16
+:1059a000dc174624213860004353400f00000000fc
+:1059b000070004241c00c58f029d023ce01746240a
+:1059c000213800004353400f000000003300001056
+:1059d00000000000010004241c00c58f029d023c51
+:1059e000e0174624213800004353400f0000000018
+:1059f000020004241c00c58f029d023ce0174624cf
+:105a0000213800004353400f00000000030004242d
+:105a10001c00c58f029d023ce0174624213800007f
+:105a20004353400f00000000040004241c00c58ff5
+:105a3000029d023ce0174624213800004353400fea
+:105a400000000000050004241c00c58f029d023cdc
+:105a5000e0174624213800004353400f00000000a7
+:105a6000060004241c00c58f029d023ce01746245a
+:105a7000213800004353400f000000002000c39372
+:105a8000070004241c00c58f029d023cdc1746243d
+:105a9000213860004353400f0000000021e8c0039c
+:105aa0001400bf8f1000be8f1800bd270800e00350
+:105ab00000000000f8ffbd270000beaf21f0a003ea
+:105ac0000800c4af80bf033c0800c28f205a62acfc
+:105ad00080bf023c105a428c0000427c03004014fc
+:105ae00000000000faff00100000000080bf023c30
+:105af000205a428c21e8c0030000be8f0800bd2759
+:105b00000800e00300000000e8ffbd271400bfaf5d
+:105b10001000beaf21f0a003211080001800c2a326
+:105b200088bf043c10618390bfff022424106200f0
+:105b3000106182a088bf043c50608390dfff022484
+:105b400024106200506082a01800c29321204000ff
+:105b5000ad56400f0000000088bf033c50606290cb
+:105b600020004234506062a088bf033c1061629004
+:105b700040004234106162a021e8c0031400bf8fce
+:105b80001000be8f1800bd270800e00300000000d1
+:105b9000e8ffbd271400bfaf1000beaf21f0a00387
+:105ba000211080001800c2a388bf033c10616290de
+:105bb00040004234106162a088bf043c5060839072
+:105bc000dfff022424106200506082a01800c293fc
+:105bd00021204000ad56400f0000000088bf033c6c
+:105be0005060629020004234506062a088bf033c45
+:105bf0001061629040004234106162a021e8c0034d
+:105c00001400bf8f1000be8f1800bd270800e003ee
+:105c100000000000e0ffbd271c00bfaf1800beafb2
+:105c200021f0a003211080002000c2a31000c0a317
+:105c30001000c2930800422c200040100000000019
+:105c4000b0ff03241000c29321106200ff00423015
+:105c500021204000c256400f00000000212000001b
+:105c6000c256400f0000000010000424c256400f2e
+:105c7000000000001100c0a31100c2830a0040040c
+:105c8000000000002000c29321204000e456400f95
+:105c9000000000001100c293010042241100c2a3c1
+:105ca000f5ff0010000000001000c2930100422424
+:105cb0001000c2a3deff00100000000021e8c003b6
+:105cc0001c00bf8f1800be8f2000bd270800e00316
+:105cd00000000000e0ffbd271c00bfaf1800beaff2
+:105ce00021f0a0031000c0af80bf033c208102342c
+:105cf000005a62ac88bf043c10618390bfff02244d
+:105d000024106200106182a088bf043c5060839020
+:105d1000dfff022424106200506082a088bf033c91
+:105d2000106162907f004230106162a01000c0af2d
+:105d30001000c28fd007422c060040100000000067
+:105d40001000c28f010042241000c2aff8ff001003
+:105d50000000000088bf043c1061839080ff022493
+:105d600025106200106182a01000c0af1000c28f29
+:105d7000d007422c06004010000000001000c28f27
+:105d8000010042241000c2aff8ff00100000000024
+:105d900088bf023c5060439020006334506043a0b1
+:105da000d5000424c256400f000000001000042457
+:105db000c256400f00000000d3000424c256400f1a
+:105dc0000000000021200000c256400f000000002b
+:105dd000a8000424c256400f000000003f00042425
+:105de000c256400f00000000d8000424c256400fe5
+:105df0000000000021200000c256400f00000000fb
+:105e000040000424c256400f00000000a0000424fb
+:105e1000c256400f00000000c8000424c256400fc4
+:105e200000000000da000424c256400f0000000009
+:105e300012000424c256400f000000008100042418
+:105e4000c256400f00000000f0000424c256400f6c
+:105e500000000000a4000424c256400f000000000f
+:105e6000d9000424c256400f00000000f2000424b0
+:105e7000c256400f00000000a6000424c256400f86
+:105e80000000000026000424c256400f000000005d
+:105e900001000424c256400f000000002120000031
+:105ea000c256400f0000000021200000c256400fe3
+:105eb0000000000001000424c256400f0000000052
+:105ec000212000000557400f000000001000c0af67
+:105ed0001000c28fd007422c0600401000000000c6
+:105ee0001000c28f010042241000c2aff8ff001062
+:105ef00000000000af000424c256400f0000000064
+:105f000021e8c0031c00bf8f1800be8f2000bd27f2
+:105f10000800e00300000000e8ffbd271400bfaf49
+:105f20001000beaf21f0a003212000005f52400fff
+:105f30000000000001000424e952400f00000000ae
+:105f4000c8000424e14a400f0000000021200000a6
+:105f50005f52400f0000000021200000e952400f76
+:105f600000000000c8000424e14a400f00000000c7
+:105f700021e8c0031400bf8f1000be8f1800bd279a
+:105f80000800e00300000000e0ffbd271c00bfafd9
+:105f90001800beaf21f0a003075a400f0000000018
+:105fa000c657400f0000000088bf023c5060428c82
+:105fb000c000427c0300401400000000faff001003
+:105fc000000000006d5b400f000000001000c2af39
+:105fd0001000c28f1400c2af010002241400c38f4e
+:105fe00018006210000000001400c38f0200622835
+:105ff00006004010000000001400c28f0d00401089
+:1060000000000000e8ff0010000000000200022471
+:106010001400c38f1000621000000000030002246f
+:106020001400c38f1400621000000000deff001097
+:10603000000000002258400f00000000daff0010ae
+:106040000000000001000424ac60400f00000000cc
+:10605000d5ff001000000000b080838302000224fe
+:10606000d1ff6214000000003a1e400f0000000043
+:10607000cdff001000000000f261400f00000000a2
+:10608000c9ff001000000000d0ffbd272c00bfafeb
+:106090002800beaf21f0a0032c8180a3df5a400f5f
+:1060a000000000000101401000000000212000005d
+:1060b0005f52400f00000000212000000a0005246c
+:1060c000029d023c08184624213800004353400f2b
+:1060d0000000000088bf023c5060428cc000427c3f
+:1060e0000300401400000000faff00100000000050
+:1060f000c448400f000000001900401400000000d8
+:106100000200042421280000029d023c1c184624a1
+:10611000213800004353400f000000000400042415
+:1061200021280000029d023c30184624213800003e
+:106130004353400f00000000fa000424e14a400fde
+:106140000000000088bf023c9061428c4002427c0b
+:10615000e7ff401400000000d40000100000000021
+:1061600002000424c452400f000000000400042474
+:10617000c452400f00000000505c400f00000000bf
+:1061800088bf023c5060428cc000427c0300401437
+:1061900000000000faff00100000000088bf023c71
+:1061a0009061428c4002427c0300401400000000d9
+:1061b000be00001000000000c080838f0300022496
+:1061c0000700621000000000c080838f01000224dd
+:1061d00003006210000000007f00001000000000bb
+:1061e000f261400f000000000300401400000000b6
+:1061f000ae0000100000000003000224ac8082af5b
+:10620000212000005f52400f00000000ad50400f01
+:1062100000000000e965400f0000000001000424b8
+:10622000bd61400f0000000088bf023c9061428cbd
+:106230004002427c21004014000000003159400f10
+:106240000000000088bf023c9061428c4002427c0a
+:106250000300401400000000faff001000000000de
+:106260004882838f6c82828f0e00621000000000d3
+:106270009880838301000224f9ff6214000000006b
+:106280006c82828f010043244882828ff4ff621463
+:10629000000000004882828f6c8282aff0ff001005
+:1062a00000000000ec80848ff080858f213000009a
+:1062b00021380000f95b400f00000000de50400f65
+:1062c00000000000505e400f0000000000a0023cf3
+:1062d000400a422401004390280002240300621473
+:1062e00000000000f7ff001000000000b35e400f48
+:1062f00000000000e881838319828683f88182830d
+:106300001000a2afe081828f1400a2af08828283c6
+:106310001800a2af1c82828f1c00a2afe981828389
+:106320002000a2afdc81828f2400a2af2120600078
+:10633000cc81858fbc81878f504c400f00000000be
+:10634000c95f400f00000000b08083830200022478
+:106350000300621400000000a91b400f00000000b1
+:1063600088bf023c5061428c4001427c06004014d0
+:1063700000000000010002242c8182a3fc81828f96
+:106380000a004224fc8182af88bf023c5061428ceb
+:106390000001427c060040140000000001000224bd
+:1063a0002c8182a3fc81828ff6ff4224fc8182af84
+:1063b00098808283010042382b1802009c80828fd3
+:1063c0002b10020025106200220040100000000087
+:1063d00095ff001000000000212000005f52400fd8
+:1063e000000000000200042421280000029d023c5d
+:1063f00040184624213800004353400f000000009d
+:106400000300042421280000029d023c5418462465
+:10641000213800004353400f000000000400042412
+:1064200021280000029d023c641846242138000007
+:106430004353400f0000000088bf023c9061428c33
+:106440004002427c0300401000000000faff0010f0
+:106450000000000021200000481d400f0000000047
+:1064600021200000bd61400f00000000d081828f1c
+:10647000f08182aff081848f892d400f00000000f1
+:10648000075a400f000000000755400f00000000b1
+:1064900088bf023c9061428c4002427c0300401065
+:1064a00000000000faff00100000000021e8c00317
+:1064b0002c00bf8f2800be8f3000bd270800e003ee
+:1064c00000000000e8ffbd271400bfaf1000beaf02
+:1064d00021f0a00388bf023c9061428c4002427cc4
+:1064e0000300401400000000faff0010000000004c
+:1064f00004000424c452400f0000000005000424de
+:10650000c452400f0000000006000424c452400f93
+:10651000000000000500042421280000029d023c28
+:106520007c184624213800004353400f000000002f
+:1065300001000224208282a3c881848ff481858f88
+:106540000c82868f21380000f95b400f00000000ac
+:106550000500042421280000029d023c3018462436
+:10656000213800004353400f000000004452400f08
+:10657000000000009751400f00000000f4010424c7
+:10658000e14a400f0000000088bf023c9061428c4d
+:106590004002427c0300401000000000f3ff0010a6
+:1065a00000000000208280a305000424c452400f94
+:1065b0000000000001000424481d400f00000000fe
+:1065c000524f400f0000000021e8c0031400bf8fad
+:1065d0001000be8f1800bd270800e0030000000077
+:1065e000e0ffbd271c00bfaf1800beaf21f0a00325
+:1065f0002000c4af02000424c452400f0000000079
+:1066000003000424c452400f0000000004000424ce
+:10661000c452400f0000000005000424c452400f83
+:106620000000000006000424c452400f00000000d7
+:1066300007000424c452400f000000002000c28f55
+:106640001000c2af1000c38f0700601000000000f0
+:10665000010002241000c38f22006210000000001d
+:106660003f00001000000000030004242128000067
+:10667000029d023c84184624213800004353400ff9
+:1066800000000000b0808383020002240b0062142b
+:106690000000000021200000481d400f0000000005
+:1066a0000400042421280000029d023c9018462486
+:1066b000213800004353400f00000000c881848f40
+:1066c000f481858f0c82868f21380000f95b400fa2
+:1066d0000000000001000224988082a3270000101f
+:1066e000000000000300042421280000029d023c59
+:1066f000a0184624213800004353400f000000003a
+:10670000b0808383020002240b00621400000000aa
+:1067100021200000481d400f000000000400042458
+:1067200021280000029d023c9018462421380000d8
+:106730004353400f00000000c881848ff481858f8f
+:106740000c82868f21380000f95b400f00000000aa
+:1067500001000224988082a30800001000000000bd
+:106760000300042421280000029d023cb4184624a2
+:10677000213800004353400f0000000005000424ae
+:1067800021280000029d023cc41846242138000044
+:106790004353400f0000000096000424e14a400fdc
+:1067a000000000000500042421280000029d023c96
+:1067b000d4184624213800004353400f0000000045
+:1067c00096000424e14a400f0000000088bf023c0c
+:1067d0009061428c4002427c0300401000000000a7
+:1067e000e6ff00100000000088bf023c9061428c70
+:1067f0004002427c0300401400000000faff001039
+:106800000000000021e8c0031c00bf8f1800be8fed
+:106810002000bd270800e00300000000e8ffbd27be
+:106820001400bfaf1000beaf21f0a00381bf033c36
+:106830006090629020004234609062a088bf043c67
+:1068400040608390dfff022424106200406082a039
+:1068500088bf043c00618390bfff022424106200c3
+:10686000006182a088bf033c006162907f004230db
+:10687000006162a081bf043c61908390f7ff022415
+:1068800024106200619082a088bf033c4160629046
+:1068900008004234416062a081bf043c6190839053
+:1068a000efff022424106200619082a088bf033ca5
+:1068b0004160629010004234416062a081bf033c9d
+:1068c0006090629001004234609062a088bf033cf7
+:1068d0004060629001004234406062a081bf033c8e
+:1068e0006090629004004234609062a081bf033cdb
+:1068f0006090629008004234609062a081bf033cc7
+:106900006090629010004234609062a081bf043cad
+:106910006190839080ff022425106200619082a024
+:1069200088bf033c4060629004004234406062a033
+:1069300088bf033c4060629008004234406062a01f
+:1069400088bf033c4060629010004234406062a007
+:1069500088bf043c4160839080ff022425106200c0
+:10696000416082a088bf033c4061629010004234c5
+:10697000406162a088bf033c4061629020004234c5
+:10698000406162a088bf033c816162900200423492
+:10699000816162a088bf033ce061629010004234d4
+:1069a000e06162a088bf033ce06162902000423455
+:1069b000e06162a088bf033ce06162904000423425
+:1069c000e06162a088bf033ce16162901000423444
+:1069d000e16162a088bf033ce26162900200423440
+:1069e000e26162a088bf033ce2616290040042342d
+:1069f000e26162a088bf033ce1616290080042341a
+:106a0000e16162a088bf033cc06062901000423424
+:106a1000c06062a088bf033c816062902000423465
+:106a2000816062a088bf033c816062904000423474
+:106a3000816062a088bf033ce16162902000423423
+:106a4000e16162a088bf033ce061629002004234d1
+:106a5000e06162a088bf033ce061629001004234c3
+:106a6000e06162a081bf023c009040ac81bf023c6b
+:106a7000109040ac81bf033c021f0224209062ac06
+:106a800081bf023c509040ac81bf043c0190839098
+:106a900080ff022425106200019082a088bf043c80
+:106aa00040618390feff022424106200406182a0b6
+:106ab00088bf043c50618390feff022424106200d2
+:106ac000506182a088bf043c00618390dfff0224f4
+:106ad00024106200006182a088bf043c1061839092
+:106ae000dfff022424106200106182a088bf043cf2
+:106af000c1608390f7ff022424106200c16082a06d
+:106b000088bf043cd1608390f7ff02242410620008
+:106b1000d16082a080bf023c007040ace965400fac
+:106b2000000000009a1d400f000000003557400f84
+:106b300000000000107f400f000000002c8180a3a7
+:106b4000fc8180af029d023cd818428cc88182af84
+:106b5000029d023cdc18428cf48182af21100000bf
+:106b60000c8282af21e8c0031400bf8f1000be8fdb
+:106b70001800bd270800e00300000000d8ffbd2773
+:106b80002400bfaf2000beaf21f0a0031000c0afb3
+:106b90001400c0a31000c28f1f00401400000000aa
+:106ba0000c0004241e1d400f00000000a08082afd6
+:106bb000a880838fa080828f21106200a88082af7e
+:106bc000a480828f01004224a48082afa480828f9f
+:106bd00004004228efff401400000000a880828fcc
+:106be0001800c2af1800c28f04004104000000006a
+:106bf0001800c38f030063241800c3af1800c38fad
+:106c0000831003001000c2afa48080afa88080afc3
+:106c1000e0ff0010000000001000c28f0e004004d2
+:106c2000000000001000c28fc90042280a00401076
+:106c300000000000010002241400c2a3010004248b
+:106c400014000524029d023ce0184624213800006f
+:106c50004353400f000000001000c28fc8004228bc
+:106c60000e004014000000001000c28f9101422865
+:106c70000a00401000000000020002241400c2a319
+:106c80000100042414000524029d023cec18462453
+:106c9000213800004353400f000000001000c28f55
+:106ca000900142280e004014000000001000c28f26
+:106cb000590242280a00401000000000030002248c
+:106cc0001400c2a30100042414000524029d023c08
+:106cd000fc184624213800004353400f00000000f8
+:106ce0001000c28f580242280e004014000000001d
+:106cf0001000c28f210342280a004010000000004b
+:106d0000040002241400c2a301000424140005247a
+:106d1000029d023c0c194624213800004353400fc9
+:106d2000000000001000c28f200342280e00401413
+:106d3000000000001000c28fe90342280a00401042
+:106d400000000000050002241400c2a30100042476
+:106d500014000524029d023c20194624213800001d
+:106d60004353400f000000001000c28ffc03422874
+:106d700009004014000000001400c0a30100042416
+:106d800014000524029d023c3019462421380000dd
+:106d90004353400f000000001400c28321e8c003e9
+:106da0002400bf8f2000be8f2800bd270800e0030d
+:106db00000000000e0ffbd271c00bfaf1800beaf01
+:106dc00021f0a0031000c0afdf5a400f0000000008
+:106dd000b08082a30854400f00000000815b400f88
+:106de000000000001000c2af1000c28f21e8c003f5
+:106df0001c00bf8f1800be8f2000bd270800e003d5
+:106e000000000000e0ffbd271c00bfaf1800beafb0
+:106e100021f0a0031000c0af88bf023c5060428c3c
+:106e2000c000437c010002246700621400000000df
+:106e300005000424a71e400f0000000088bf023c8c
+:106e40005060428c0001427c13004014000000009e
+:106e500005000424a71e400f0000000088bf023c6c
+:106e60005060428c0001427c03004014000000008e
+:106e7000faff0010000000001000c28f0100422441
+:106e80001000c2af1000c28f04004228020040145c
+:106e9000000000001000c0af88bf023c5060428c70
+:106ea000c003427c130040140000000005000424cd
+:106eb000a71e400f0000000088bf023c5060428cbb
+:106ec000c003427c0300401400000000faff0010e1
+:106ed000000000001000c28fffff42241000c2af6c
+:106ee0001000c28f030041040000000003000224d0
+:106ef0001000c2af1000c28f1400c2af0100022404
+:106f00001400c38f1b006210000000001400c38f28
+:106f10000200622806004010000000001400c28f2a
+:106f20000d00401000000000bbff0010000000003a
+:106f3000020002241400c38f15006210000000003c
+:106f4000030002241400c38f180062100000000028
+:106f5000b1ff0010000000000200042421280000fe
+:106f6000010006242955400f00000000aaff001070
+:106f70000000000003000424212800000100062472
+:106f80002955400f00000000a3ff00100000000082
+:106f90000400042421280000010006242955400f84
+:106fa000000000009cff0010000000000500042409
+:106fb00021280000010006242955400f0000000090
+:106fc00095ff0010000000001000c28f21e8c003f0
+:106fd0001c00bf8f1800be8f2000bd270800e003f3
+:106fe00000000000d0ffbd272c00bfaf2800beafbf
+:106ff00021f0a0033000c4af3400c5af3800c6afe5
+:107000002110e0003c00c2a388bf033c0100023c09
+:10701000641062ac88bf033c0100023c681062aca3
+:1070200001000224bc8082af47000224e88182a3d1
+:10703000cc8180af58000224198282a33000c28f15
+:10704000bc8182af59000224f88182a33400c28f30
+:10705000e08182af3c00c2830700401000000000c6
+:107060005a000224088282a33800c28f1c8282af99
+:107070000400001000000000088280a3211000001e
+:107080001c8282af46000224e98182a32110000005
+:10709000dc8182afe881838319828683f8818283d1
+:1070a0001000a2afe081828f1400a2af0882828319
+:1070b0001800a2af1c82828f1c00a2afe9818283dc
+:1070c0002000a2afdc81828f2400a2af21206000cb
+:1070d000cc81858fbc81878f504c400f0000000011
+:1070e000e88180a3cc8180af198280a321100000a9
+:1070f000bc8182aff88180a321100000e08182afc3
+:10710000088280a3211000001c8282afe98180a345
+:1071100021100000dc8182afbc8080affa00042423
+:10712000e14a400f0000000021e8c0032c00bf8f9f
+:107130002800be8f3000bd270800e00300000000db
+:10714000e8ffbd271400bfaf1000beaf21f0a003c1
+:10715000988083830100022406006214000000006e
+:10716000988080a3d08180af9c8080af8c8080afde
+:10717000908080af1b1f400f0000000003004014f0
+:1071800000000000fbff001000000000aa5c400fa0
+:107190000000000088bf023c9061428c4002427cab
+:1071a000030040140000000039000010000000003f
+:1071b000f35d400f00000000c08082af00a0023ce1
+:1071c000740a4424029d023c3c1945245a30400f65
+:1071d00000000000f08182aff081828fd08182af09
+:1071e000f081828f000042380100422c25104200bd
+:1071f00020004010000000000200042421280000ac
+:10720000029d023c40194624213800004353400fa0
+:10721000000000000300042428000524029d023c15
+:1072200050194624213800004353400f000000004d
+:107230000400042421280000029d023c301846244a
+:10724000213800004353400f00000000fa000424de
+:10725000e14a400f0000000088bf023c9061428c70
+:107260004002427ce4ff40140000000008000010cf
+:1072700000000000020004245a000524029d023c84
+:1072800060194624213800004353400f00000000dd
+:1072900021e8c0031400bf8f1000be8f1800bd2767
+:1072a0000800e0030000000080ffbd277c00bfafa6
+:1072b0007800beaf21f0a003200002244800c2a342
+:1072c000029d023c6819428c5000c2af01000224aa
+:1072d0005800c2af5c00c0af6000c0af5000c22712
+:1072e0004800c39321204000212860001000c627d9
+:1072f000c746400f000000005800c2af5800c28fc0
+:10730000370040140000000001000224c88082af52
+:107310001000c427d647400f000000005800c2af3d
+:107320005800c28f0400401400000000c880828f03
+:1073300001004224c88082af5800c28f030040146d
+:1073400000000000f2ff0010000000006000c28f8b
+:1073500023004014000000005000c2274800c393df
+:1073600021204000212860001000c627c746400f9a
+:10737000000000005800c2af01000224c48082afa8
+:10738000010002245c00c2af5c00c28fc880838f02
+:107390002a1043000a004010000000001000c4271b
+:1073a000d647400f000000005800c2af5c00c28ffb
+:1073b000010042245c00c2aff3ff00100000000097
+:1073c000c880828fc48082af02000424212800007c
+:1073d0001000c627213800004353400f0000000072
+:1073e0005800c28f2900401000000000c88080af04
+:1073f000c48080af0200042421280000029d023cca
+:107400006c194624213800004353400f000000004f
+:107410000300042421280000029d023c8019462418
+:10742000213800004353400f0000000005000424f1
+:1074300021280000029d023c9419462421380000b6
+:107440004353400f000000000600042421280000e0
+:10745000029d023ca4194624213800004353400fea
+:1074600000000000fa000424e14a400f0000000080
+:1074700088bf023c9061428c4002427cddff401498
+:1074800000000000cb000010000000005800c28f78
+:10749000a50040140000000088bf023c5060428cf0
+:1074a0000001427c330040140000000088bf023c11
+:1074b0005060428c0001427c030040140000000038
+:1074c000faff0010000000001e000424e14a400ff3
+:1074d000000000001000c427d647400f0000000045
+:1074e0005800c2af5800c28f0f00401400000000c7
+:1074f000c480828fc880838f2a10620005004010ec
+:1075000000000000c880828fc48082af100000108d
+:1075100000000000c480828f01004224c48082af3a
+:107520000b000010000000005000c2274800c39369
+:1075300021204000212860001000c627c746400fc8
+:10754000000000005800c2af01000224c48082afd6
+:1075500002000424c452400f000000000200042472
+:10756000212800001000c627213800004353400f97
+:107570000000000088bf023c5060428cc003427c87
+:107580003f0040140000000088bf023c5060428c65
+:10759000c003427c0300401400000000faff00100a
+:1075a000000000001e000424e14a400f000000001b
+:1075b0001000c427d647400f000000005800c2af9b
+:1075c0005800c28f0300401400000000f8ff0010b4
+:1075d000000000005000c2274800c3932120400053
+:1075e000212860001000c627c746400f0000000099
+:1075f0005800c2afc480828fffff4224c48082af94
+:10760000c480828f0500401400000000c880828f73
+:10761000c48082af010002246000c2af01000224d6
+:107620005c00c2af5c00c28fc480838f2a1043000d
+:107630000a004010000000001000c427d647400f89
+:10764000000000005800c2af5c00c28f010042245d
+:107650005c00c2aff3ff0010000000000200042431
+:10766000c452400f00000000020004242128000042
+:107670001000c627213800004353400f00000000cf
+:107680000600042421280000029d023cb019462473
+:10769000213800004353400f000000006800c2275b
+:1076a00021204000029d023cb8194524c480868fe9
+:1076b000486e400f000000006800c2270600042446
+:1076c0001900052421304000213800004353400fa9
+:1076d000000000000600042441000524029d023c35
+:1076e000bc194624213800004353400f000000001d
+:1076f0006800c22721204000029d023cb8194524a1
+:10770000c880868f486e400f000000006800c227c6
+:10771000060004245a0005242130400021380000ce
+:107720004353400f0000000088bf023c9061428c30
+:107730004002427c03004014000000001d000010c5
+:107740000000000088bf023c5060428cc000427cb8
+:10775000010042380100432c5800c28f000042381b
+:107760000100422c241062000300401000000000c1
+:1077700046ff00100000000088bf023c5060428cb1
+:10778000c000437c010002240300621400000000da
+:10779000d2fe00100000000000a0023c740a442445
+:1077a0001000c527336b400f000000002000c28f7f
+:1077b000e48182af21e8c0037c00bf8f7800be8fd8
+:1077c0008000bd270800e00300000000f0ffbd2797
+:1077d0000800beaf21f0a003080002240100c2a3ec
+:1077e0000100c293500040100000000000a0023cc5
+:1077f0000100c393740a42242110620000004380f8
+:107800002e000224430062140000000000a0023c8d
+:107810000100c393740a42242110620001004280d7
+:10782000470042380100442c00a0023c0100c393f1
+:10783000740a422421106200020042804300423850
+:107840000100422c2420820000a0023c0100c393ce
+:10785000740a422421106200030042804f00423823
+:107860000100422c2410820007004010000000009c
+:10787000010002240000c2a3010002240400c2afe0
+:10788000290000100000000000a0023c0100c3938a
+:10789000740a4224211062000100428042004238f2
+:1078a0000100442c00a0023c0100c393740a42244e
+:1078b0002110620002004280460042380100422c42
+:1078c0002420820000a0023c0100c393740a4224d9
+:1078d0002110620003004280420042380100422c25
+:1078e0002410820007004010000000000300022462
+:1078f0000000c2a3030002240400c2af0a0000106b
+:10790000000000000000c0a30400c0af060000108b
+:10791000000000000100c293ffff42240100c2a347
+:10792000afff0010000000000400c28f21e8c00378
+:107930000800be8f1000bd270800e0030000000013
+:10794000d0ffbd272c00bfaf2800beaf21f0a003a1
+:10795000010002242000c2af2400c0af988080a3a1
+:10796000d081828ff08182af9080828f010042248b
+:10797000908082af00a0033c3e000224400a62a037
+:10798000f081848f8c80858f213000009e38400fdd
+:107990000000000006004010000000000100042468
+:1079a0007859400f0000000001000224988082a353
+:1079b000988082833f0040140000000018828427d2
+:1079c0000100052401000624f081878fce35400f89
+:1079d000000000009c8082af00a0023c2000c38f0a
+:1079e000400a42242118620018828293000062a09b
+:1079f0002000c28f010042242000c2af188283837e
+:107a00002800022415006214000000001882842758
+:107a10000100052401000624f081878fce35400f38
+:107a2000000000009c8082aff081848fbe35400f43
+:107a300000000000030040100000000007000010dc
+:107a400000000000188283830a00022403006210f1
+:107a500000000000edff001000000000f081848fa6
+:107a6000be35400f0000000008004010000000007c
+:107a7000f081848f892d400f000000000100022456
+:107a8000988082a307000010000000001882838302
+:107a90000a0002240300621000000000c7ff00106b
+:107aa00000000000f081848f0632400f00000000cb
+:107ab0008c8082af21e8c0032c00bf8f2800be8fce
+:107ac0003000bd270800e00300000000e0ffbd27f4
+:107ad0001c00bfaf1800beaf21f0a00301000224bc
+:107ae0001000c2af1400c0af01000224948082af26
+:107af00000a0023c400a4224010043900d000224f1
+:107b00000300621400000000dc0000100000000010
+:107b10009480838f0100022427006214000000007b
+:107b20001400c28f0a0040140000000000a0023cb4
+:107b30001000c38f400a42242110620000004290ce
+:107b4000e88182a31000c28f010042241000c2af5e
+:107b50001400c38fd48182272120620000a0023c40
+:107b60001000c38f400a422421106200000042909e
+:107b7000000082a01400c28f010042241400c2af92
+:107b800000a0023c1000c38f400a42242110620072
+:107b9000000043902000022407006214000000004f
+:107ba0001000c28f010042241000c2af1400c0af09
+:107bb00002000224948082af9480838f020002240a
+:107bc00027006214000000001400c28f0a00401455
+:107bd0000000000000a0023c1000c38f400a4224b5
+:107be0002110620000004290198282a31000c28f0f
+:107bf000010042241000c2af1400c38f24828227e8
+:107c00002120620000a0023c1000c38f400a4224e1
+:107c10002110620000004290000082a01400c28f78
+:107c2000010042241400c2af00a0023c1000c38f28
+:107c3000400a4224211062000000439020000224e8
+:107c400007006214000000001000c28f01004224ef
+:107c50001000c2af1400c0af03000224948082afb2
+:107c60009480838f03000224270062140000000028
+:107c70001400c28f0a0040140000000000a0023c63
+:107c80001000c38f400a422421106200000042907d
+:107c9000f88182a31000c28f010042241000c2affd
+:107ca0001400c38f008282272120620000a0023cc2
+:107cb0001000c38f400a422421106200000042904d
+:107cc000000082a01400c28f010042241400c2af41
+:107cd00000a0023c1000c38f400a42242110620021
+:107ce00000004390200002240700621400000000fe
+:107cf0001000c28f010042241000c2af1400c0afb8
+:107d000004000224948082af9480838f04000224b4
+:107d100027006214000000001400c28f0a00401403
+:107d20000000000000a0023c1000c38f400a422463
+:107d30002110620000004290088282a31000c28fce
+:107d4000010042241000c2af1400c38f10828227aa
+:107d50002120620000a0023c1000c38f400a422490
+:107d60002110620000004290000082a01400c28f27
+:107d7000010042241400c2af00a0023c1000c38fd7
+:107d8000400a422421106200000043902000022497
+:107d900007006214000000001000c28f010042249e
+:107da0001000c2af1400c0af05000224948082af5f
+:107db0009480838f050002241900621400000000e3
+:107dc0001400c28f0a0040140000000000a0023c12
+:107dd0001000c38f400a422421106200000042902c
+:107de000e98182a31000c28f010042241000c2afbb
+:107df0001400c38fc08182272120620000a0023cb2
+:107e00001000c38f400a42242110620000004290fb
+:107e1000000082a01400c28f010042241400c2afef
+:107e200000a0023c1000c38f400a422421106200cf
+:107e3000000043900a0002240300621400000000c6
+:107e40000e000010000000001000c28f010042244c
+:107e50001000c2af00a0023c1000c38f400a4224b1
+:107e600021106200000043900d0002240300621004
+:107e7000000000001eff001000000000d4818427d5
+:107e8000096d400f00000000cc8182af248284275e
+:107e9000026d400f000000002120400021286000fa
+:107ea0002a7a400f00000000bc8182af0082842744
+:107eb000026d400f000000002120400021286000da
+:107ec0002a7a400f00000000e08182af10828427f0
+:107ed000026d400f000000002120400021286000ba
+:107ee0002a7a400f000000001c8282afc0818427e4
+:107ef000026d400f0000000021204000212860009a
+:107f00002a7a400f00000000dc8182af21e8c00324
+:107f10001c00bf8f1800be8f2000bd270800e003a3
+:107f200000000000f0ffbd270800beaf21f0a00355
+:107f3000310002240000c2af0000c28f0b004010cd
+:107f40000000000000a0023c0000c38f400a422451
+:107f500021106200000040a00000c28fffff4224f9
+:107f60000000c2aff4ff0010000000000000c28f4c
+:107f7000030040140000000000a0023c400a40a0a2
+:107f8000e88180a3070002240000c2af0000c28f76
+:107f90000a004010000000000000c38fd481822737
+:107fa00021106200000040a00000c28fffff4224a9
+:107fb0000000c2aff5ff0010000000000000c28ffb
+:107fc0000200401400000000d48180a3198280a325
+:107fd000070002240000c2af0000c28f0a00401058
+:107fe000000000000000c38f24828227211062005d
+:107ff000000040a00000c28fffff42240000c2af7b
+:10800000f5ff0010000000000000c28f02004014c5
+:1080100000000000248280a3f88180a307000224ce
+:108020000000c2af0000c28f0a0040100000000034
+:108030000000c38f0082822721106200000040a050
+:108040000000c28fffff42240000c2aff5ff001006
+:10805000000000000000c28f020040140000000079
+:10806000008280a3088280a3070002240000c2af20
+:108070000000c28f0a004010000000000000c38f03
+:108080001082822721106200000040a00000c28ff1
+:10809000ffff42240000c2aff5ff00100000000007
+:1080a0000000c28f0200401400000000108280a374
+:1080b000e98180a3070002240000c2af0000c28f44
+:1080c0000a004010000000000000c38fc08182271a
+:1080d00021106200000040a00000c28fffff422478
+:1080e0000000c2aff5ff0010000000000000c28fca
+:1080f0000200401400000000c08180a321e8c003fa
+:108100000800be8f1000bd270800e003000000003b
+:10811000e0ffbd271c00bfaf1800beaf21f0a003d9
+:10812000211000001000c2af6c82828f4882838fc2
+:108130002a1062000a004010000000006c82838f49
+:108140004882828f2310620021204000ae7c400fc5
+:10815000000000001000c2af090000100000000085
+:108160006c82838f4882828f231062000002422437
+:1081700021204000ae7c400f000000001000c2af84
+:10818000029d023c1000c48fc019458c237c400f17
+:10819000000000001000c2af029d023c1000c48f1e
+:1081a000c419458cb57b400f000000001000c2af21
+:1081b0001000c48fd87c400f00000000060004248b
+:1081c000212840008f52400f0000000021e8c0032a
+:1081d0001c00bf8f1800be8f2000bd270800e003e1
+:1081e00000000000d8ffbd272000bfaf1c00beafbd
+:1081f0001800b0af21f0a003211000001000c2afa2
+:108200008c80848fae7c400f0000000021804000f5
+:10821000e481848fae7c400f00000000212000022a
+:1082200021284000237c400f000000001000c2af56
+:10823000029d023c1000c48fc819458cb57b400fcd
+:10824000000000001000c2af029d023cc819448c1f
+:108250001000c58f137d400f000000000300400494
+:10826000000000000400001000000000029d023c1d
+:10827000c819428c1000c2af1000c48fd87c400fc8
+:108280000000000005000424212840008f52400f08
+:108290000000000021e8c0032000bf8f1c00be8f3b
+:1082a0001800b08f2800bd270800e0030000000080
+:1082b000c8ffbd273400bfaf3000beaf21f0a00320
+:1082c000211080003800c2a3211000002000c2af9e
+:1082d000211000002400c2af211000002800c2af0e
+:1082e0004882838f6c82828f03006210000000003e
+:1082f000fbff00100000000088bf033c0100023caf
+:10830000641062ac88bf023c681040ac60ea023482
+:108310004c8182af008180a3018180a3028180a370
+:1083200001000424bd61400f000000003f54400fd5
+:108330000000000088bf023c5060428cc000427cbc
+:108340000300401400000000faff001000000000cd
+:1083500088bf023c9061428c4002437c01000224b1
+:10836000d80062140000000001000224048182afe2
+:108370004c81828fe9034228040040140000000071
+:108380004c81828fb5ff42244c8182af4c81828f19
+:108390006500422804004014000000004c81828fd8
+:1083a000fbff42244c8182af4c81828f9001422896
+:1083b0000300401000000000900102244c8182afb5
+:1083c00088bf023c5060428cc000427c04004014d4
+:1083d00000000000848280af01000224008182a39b
+:1083e00088bf023c5060428c8000427c05004014f3
+:1083f0000000000001000224848282af01000224f8
+:10840000008182a388bf023c5060428cc000427c45
+:10841000070040100000000088bf023c5060428c02
+:108420008000427c0200401000000000008180a318
+:1084300088bf023c5060428cc003427c0400401460
+:1084400000000000648280af01000224018182a349
+:1084500088bf023c5060428c0001427c0500401401
+:108460000000000001000224648282af01000224a7
+:10847000018182a388bf023c5060428cc003427cd1
+:10848000070040100000000088bf023c5060428c92
+:108490000001427c0200401000000000018180a326
+:1084a00088bf023c5061428c4001427c0400401471
+:1084b00000000000708280af01000224028182a3cc
+:1084c00088bf023c5061428c0001427c0500401490
+:1084d0000000000001000224708282af010002242b
+:1084e000028182a388bf023c5061428c4001427ce1
+:1084f000070040100000000088bf023c5061428c21
+:108500000001427c0200401000000000028180a3b4
+:1085100000818283090040140000000001818283f1
+:108520000600401400000000028182830300401412
+:108530000000000060ea02344c8182af3800c28340
+:1085400083ff4010000000003482848fae7c400f17
+:108550000000000021204000017a400f00000000d0
+:10856000029d063c2120400021286000dc19c78cb8
+:10857000d819c68ca378400f0000000021204000cd
+:10858000212860002a7a400f000000002000c2afbe
+:108590002000c48f017a400f00000000213040000d
+:1085a000213860001000c427029d023cd0194524e8
+:1085b000486e400f00000000040004244000052421
+:1085c0001000c627213800004353400f0000000070
+:1085d0006882848fae7c400f0000000021204000a4
+:1085e000017a400f00000000029d063c212040005f
+:1085f00021286000dc19c78cd819c68ca378400fdd
+:108600000000000021204000212860002a7a400f4d
+:10861000000000002400c2af2400c48f017a400f84
+:108620000000000021304000213860001000c42705
+:10863000029d023cd0194524486e400f0000000006
+:1086400005000424400005241000c627213800003e
+:108650004353400f000000003c82848fae7c400feb
+:1086600000000000029d033c21204000e019658cc1
+:10867000237c400f000000002800c2af2800c48ff8
+:10868000017a400f000000002130400021386000d6
+:108690001000c427029d023cd0194524486e400fab
+:1086a0000000000006000424400005241000c62736
+:1086b000213800004353400f0000000024ff001049
+:1086c00000000000048180af88bf023c0100033c31
+:1086d000641043ac88bf023c681040ac21e8c00382
+:1086e0003400bf8f3000be8f3800bd270800e00384
+:1086f00000000000f8ffbd270000beaf21f0a0037e
+:108700000800c4af0800c38f0100022418006214df
+:108710000000000088bf043cd0608390f7ff022473
+:1087200024106200d06082a088bf043cd160839096
+:10873000fbff022424106200d16082a088bf043ca9
+:1087400051608390dfff022424106200516082a0f8
+:1087500088bf033c0100023c641062ac88bf033c4c
+:108760000100023c681062ac120000100000000022
+:1087700088bf033cd060629008004234d06062a0a1
+:1087800088bf033cd160629004004234d16062a093
+:1087900088bf033c5160629020004234516062a067
+:1087a00088bf033c0100023c641062ac88bf023cfd
+:1087b000681040ac21e8c0030000be8f0800bd2750
+:1087c0000800e00300000000e0ffbd271c00bfaf71
+:1087d0001800beaf21f0a0039e54400f000000001f
+:1087e000008180a3018180a3028180a3e965400ffd
+:1087f0000000000001000424bd61400f00000000e3
+:1088000001000224048182aff40102244c8182af72
+:108810000300042421280000029d023ce4194624a0
+:10882000213800004353400f0000000001000224e3
+:10883000708282af01000224028182a31000c0afc7
+:108840001000c38f0300023c3f0d42342a10430046
+:1088500006004014000000001000c28f01004224f6
+:108860001000c2aff6ff001000000000028180a3dc
+:108870000300042421280000029d023cf019462434
+:10888000213800004353400f00000000e803022499
+:108890004c8182af01000224648282af0100022475
+:1088a000018182a31000c0af1000c28f5fea0334c1
+:1088b0002a10620006004014000000001000c28f61
+:1088c000010042241000c2aff7ff001000000000ba
+:1088d000018180a30300042421280000029d023ca2
+:1088e000fc194624213800004353400f00000000cb
+:1088f000e80302244c8182af88bf023cd060428ce6
+:108900000001427c210040140000000088bf023cae
+:108910009061428c4002427c1c004010000000002c
+:1089200001000224848282af88bf023cd060428c66
+:108930000001427c0a0040140000000088bf023c95
+:108940009061428c4002427c050040100000000013
+:1089500001000224008182a3f3ff00100000000048
+:10896000008180a31000c0af1000c28f204e4228ab
+:10897000e1ff4010000000001000c28f01004224ff
+:108980001000c2aff8ff0010000000000100022438
+:10899000008182a31000c0af1000c28f10274228b0
+:1089a00006004010000000001000c28f01004224a9
+:1089b0001000c2aff8ff001000000000008180a38b
+:1089c00060ea02344c8182af88bf023cd060428ca6
+:1089d0000001427c260040100000000088bf023cdd
+:1089e0009061428c4002427c210040100000000057
+:1089f000848280af88bf023cd060428c0001427c00
+:108a00000a0040100000000088bf023c9061428cc8
+:108a10004002427c050040100000000001000224da
+:108a2000008182a3f3ff001000000000008180a3fa
+:108a30001000c0af1000c28fd007422806004010bf
+:108a4000000000001000c28f010042241000c2afdd
+:108a5000f8ff001000000000d2d10224348282af5f
+:108a60003482828f388282afd7ff0010000000006e
+:108a70000300042421280000029d023c081a462419
+:108a8000213800004353400f00000000e803022497
+:108a90004c8182af88bf023c9060428c4003427c94
+:108aa000200040140000000088bf023c9061428c0e
+:108ab0004002427c1b00401000000000648280af36
+:108ac00088bf023c9060428c4003427c0a00401404
+:108ad0000000000088bf023c9061428c4002427c52
+:108ae000050040100000000001000224018182a363
+:108af000f3ff001000000000018180a31000c0af50
+:108b00001000c28f204e4228e2ff401000000000fb
+:108b10001000c28f010042241000c2aff8ff001005
+:108b20000000000001000224018182a31000c0aff8
+:108b30001000c28f102742280600401000000000dd
+:108b40001000c28f010042241000c2aff8ff0010d5
+:108b500000000000018180a360ea02344c8182aff2
+:108b600088bf023c9060428c4003427c270040104a
+:108b70000000000088bf023c9061428c4002427cb1
+:108b8000220040100000000001000224648282af35
+:108b900088bf023c9060428c4003427c0a00401037
+:108ba0000000000088bf023c9061428c4002427c81
+:108bb000050040100000000001000224018182a392
+:108bc000f3ff001000000000018180a31000c0af7f
+:108bd0001000c28fd007422806004010000000009d
+:108be0001000c28f010042241000c2aff8ff001035
+:108bf0000000000035220224688282af6882828fe2
+:108c0000508282afd6ff0010000000000300042451
+:108c100021280000029d023c141a4624213800003d
+:108c20004353400f00000000f40102244c8182af46
+:108c300088bf023c9060428c8003427c200040143c
+:108c40000000000088bf023c9061428c4002427ce0
+:108c50001b00401000000000708280af88bf023c03
+:108c60009060428c8003427c0a00401400000000a7
+:108c700088bf023c9061428c4002427c050040105b
+:108c80000000000001000224028182a3f3ff001013
+:108c900000000000028180a31000c0af1000c28f4e
+:108ca000d0074228e2ff4010000000001000c28ff1
+:108cb000010042241000c2aff8ff001000000000c5
+:108cc00001000224028182a31000c0af1000c28ff5
+:108cd0001027422806004010000000001000c28f3c
+:108ce000010042241000c2aff8ff00100000000095
+:108cf000028180a3881302244c8182af88bf023c8a
+:108d00009060428c8003427c2600401000000000ee
+:108d100088bf023c9061428c4002427c210040109e
+:108d20000000000001000224708282af88bf023c74
+:108d30009060428c8003427c0a00401000000000da
+:108d400088bf023c9061428c4002427c050040108a
+:108d50000000000001000224028182a3f3ff001042
+:108d600000000000028180a31000c0af1000c28f7d
+:108d7000d007422806004010000000001000c28ffb
+:108d8000010042241000c2aff8ff001000000000f4
+:108d90003c8280af3c82828f5c8282afd7ff001022
+:108da00000000000048180af88bf033c0100023c4a
+:108db000641062ac88bf023c681040ac88bf023cc3
+:108dc0009061428c4002427c170040140000000079
+:108dd0000300042421280000029d023c201a46249e
+:108de000213800004353400f000000001000c0afc6
+:108df0001000c38f1e00023c7f8442342a104300bf
+:108e000006004014000000001000c28f0100422440
+:108e10001000c2aff6ff0010000000001400c0af49
+:108e200016000010000000000300042421280000a8
+:108e3000029d023c301a4624213800004353400f63
+:108e4000000000001000c0af1000c38f1e00023ce5
+:108e50007f8442342a1043000600401400000000c2
+:108e60001000c28f010042241000c2aff6ff0010b4
+:108e700000000000010002241400c2af1400c28fe1
+:108e800021e8c0031c00bf8f1800be8f2000bd2743
+:108e90000800e00300000000e8ffbd271400bfaf9a
+:108ea0001000beaf21f0a00301000224788082af41
+:108eb000010002247c8082af808080aff401022414
+:108ec0004c8182afc881848f017a400f000000007e
+:108ed000029d063c2120400021286000441ac78cd6
+:108ee000401ac68cd977400f0000000021204000b6
+:108ef000212860002a7a400f00000000608282afc3
+:108f0000f481848f017a400f00000000029d063c2e
+:108f10002120400021286000441ac78c401ac68cca
+:108f2000d977400f00000000212040002128600078
+:108f30002a7a400f00000000548282af6082848f42
+:108f4000256a400f00000000308282af5482848f77
+:108f5000256a400f00000000808282af88bf033c7a
+:108f60000100023c641062ac88bf033c0100023c7b
+:108f7000681062acc767400f00000000788080afc7
+:108f80007c8080affa000424e14a400f000000001a
+:108f900021e8c0031400bf8f1000be8f1800bd274a
+:108fa0000800e0030000000000e85d4100681a408e
+:108fb00000701b40c0ffbd273c00bbaf00601b40e2
+:108fc00082d21a003800bbaf847a5b7f44201b7cbe
+:108fd00000609b403400beaf3000a4af2c00a3afb4
+:108fe0002800a2af21f0a0030400c0a30481828f57
+:108ff0009800401000000000fc80828f0800c2af83
+:10900000010002240800c38f260062100000000047
+:109010000800c38f02006228060040100000000014
+:109020000800c28f090040100000000082000010fc
+:1090300000000000020002240800c38f6b006210d1
+:10904000000000007c0000100000000088bf043c0d
+:10905000d060828c8482838fc439627cd06082ac81
+:1090600088bf043cd060828c6482838f444a627cd7
+:10907000d06082ac88bf043c5060828c7082838f49
+:10908000444a627c506082ac80bf033c05000224ed
+:10909000200c62ac01000224fc8082af660000104c
+:1090a00000000000008182831200401000000000d8
+:1090b00088bf033cd060629004004234d06062a05c
+:1090c0008482828f06004014000000003482828f68
+:1090d00001004224348282af0b0000100000000027
+:1090e0003482828fffff4224348282af0600001058
+:1090f0000000000088bf043cd0608390fbff022486
+:1091000024106200d06082a001818283120040108e
+:109110000000000088bf033cd1606290010042342f
+:10912000d16062a06482828f0600401400000000bb
+:109130006882828f01004224688282af0b00001097
+:10914000000000006882828fffff4224688282afa5
+:10915000060000100000000088bf043cd16083902e
+:10916000feff022424106200d16082a0028182836b
+:10917000120040100000000088bf033c5160629064
+:1091800001004234516062a07082828f0600401458
+:10919000000000003c82828f010042243c8282afaa
+:1091a0000b000010000000003c82828fffff422471
+:1091b0003c8282af060000100000000088bf043c23
+:1091c00051608390feff022424106200516082a04f
+:1091d00080bf023c0a000324200c43ac020002249e
+:1091e000fc8082af140000100000000080bf033c30
+:1091f0004c81828f200c62ac88bf043cd06083908d
+:10920000fbff022424106200d06082a088bf043ccf
+:10921000d1608390feff022424106200d16082a0fe
+:1092200088bf043c51608390feff0224241062003a
+:10923000516082a0fc8080af80bf023c100c40ac2b
+:1092400088bf033c0100023c341062ac48010010ae
+:1092500000000000f880828f2400c2af01000224c9
+:109260002400c38fa5006210000000002400c38ffb
+:109270000200622806004010000000002400c28f97
+:109280000900401000000000340100100000000040
+:10929000020002242400c38f0d01621000000000b0
+:1092a0002e010010000000002c82828f8c004014e0
+:1092b000000000004882838f6c82828f88006210d9
+:1092c0000000000000a0043c4882828f8018020049
+:1092d000800a8224211062000000428c4c8282affe
+:1092e00000a0043c4882828f80180200800a8224f9
+:1092f00021106200000040ac4882828f01004224ad
+:10930000488282af4882828f0c00c2af0c00c38fac
+:109310001000c3af1000c28f040041040000000021
+:109320001000c38fff0163241000c3af1000c38f70
+:1093300043120300401202000c00c38f231062008e
+:10934000488282af010002242c8282af0008023cd6
+:109350000000c2af030002240400c2a34c82828f2b
+:109360000000c38f241043002a00401000000000ba
+:109370000400c2931400c2af050002241400c38f7e
+:1093800017006210000000001400c38f060062285e
+:109390000700401000000000030002241400c38fe7
+:1093a00009006210000000004200001000000000f0
+:1093b000070002241400c38f0f0062100000000099
+:1093c0003c0000100000000088bf023c5160439048
+:1093d00002006334516043a036000010000000001a
+:1093e00088bf023cd160439002006334d16043a047
+:1093f000300000100000000088bf043cd060839063
+:1094000080ff022425106200d06082a02900001095
+:10941000000000000400c2931800c2af050002243f
+:109420001800c38f18006210000000001800c38fde
+:10943000060062280700401000000000030002241c
+:109440001800c38f0900621000000000190000100e
+:1094500000000000070002241800c38f11006210f2
+:1094600000000000130000100000000088bf043c52
+:1094700051608390fdff022424106200516082a09d
+:109480000c0000100000000088bf043cd1608390f5
+:10949000fdff022424106200d16082a005000010ac
+:1094a0000000000088bf023cd06043907f00633022
+:1094b000d06043a00400c293020042240400c2a36f
+:1094c0000000c28f801002000000c2af0000c28ff7
+:1094d0000300401000000000a0ff0010000000008a
+:1094e00080bf023c05000324200c43ac0100022491
+:1094f000f88082af99000010000000002c82828f5b
+:109500006c004010000000000004023c0000c2afec
+:10951000020002240400c2a34c82828f0000c38f89
+:10952000241043002d004010000000000400c293ee
+:109530001c00c2af040002241c00c38f170062107d
+:10954000000000001c00c38f0500622807004010c7
+:1095500000000000020002241c00c38f09006210fa
+:109560000000000048000010000000000600022477
+:109570001c00c38f110062100000000042000010a8
+:109580000000000088bf023c51604390010063343a
+:10959000516043a03c0000100000000088bf033c65
+:1095a000d160629001004234d16062a001000224c7
+:1095b0000600c2a3340000100000000088bf033c76
+:1095c000d060629004004234d06062a001000224a6
+:1095d0000500c2a32c000010000000000400c2938c
+:1095e0002000c2af040002242000c38f18006210c4
+:1095f000000000002000c38f050062280700401013
+:1096000000000000020002242000c38f0900621045
+:10961000000000001c0000100000000006000224f2
+:109620002000c38f1200621000000000160000101e
+:109630000000000088bf043c51608390feff0224bc
+:1096400024106200516082a00f0000100000000092
+:1096500088bf043cd1608390feff02242410620086
+:10966000d16082a00600c0a3070000100000000027
+:1096700088bf043cd0608390fbff0224241062006a
+:10968000d06082a00500c0a30400c293020042245f
+:109690000400c2a30000c28f801002000000c2af0d
+:1096a0000000c28f03004010000000009aff00106d
+:1096b0000000000080bf023c0a000324200c43ace1
+:1096c00002000224f88082af240000100000000095
+:1096d0002c82828f0c00401000000000ffff02343b
+:1096e0000000c2af4c82838f0000c28f2410620042
+:1096f000248082af80bf033c2480828f200c62ac28
+:10970000040000100000000080bf033c8813022406
+:10971000200c62ac88bf043cd0608390fbff022425
+:1097200024106200d06082a088bf043cd160839086
+:10973000feff022424106200d16082a088bf043c96
+:1097400051608390feff022424106200516082a0c9
+:10975000f88080af2c8280af4c8280af80bf023c0b
+:10976000100c40ac88bf033c0100023c341062acda
+:1097700021e8c0033400be8f3000a48f2c00a38fdb
+:109780002800a28f00606041c00000003c00ba8f3a
+:1097900000709a403800ba8f4000bd2700609a40a0
+:1097a00018000042e8ffbd271400bfaf1000beaf95
+:1097b00021f0a00380bf033c30800234000662ac7d
+:1097c00081bf043c00f28390f7ff02242410620062
+:1097d00000f282a081bf033c61906290010042349c
+:1097e000619062a088bf043c41608390feff022428
+:1097f00024106200416082a081bf033c61906290ae
+:1098000002004234619062a088bf043c41608390b2
+:10981000fdff022424106200416082a081bf033c4e
+:109820006190629020004234619062a088bf043c45
+:1098300041608390dfff022424106200416082a017
+:1098400088bf033cc060629010004234c06062a0d8
+:1098500088bf043cc1608390feff02242410620094
+:10986000c16082a088bf043cc1608390fdff0224d8
+:1098700024106200c16082a088bf043cc160839054
+:10988000fbff022424106200c16082a088bf033c59
+:109890008160629020004234816062a088bf043cf5
+:1098a000c0608390fbff022424106200c06082a08d
+:1098b00088bf033cc06062907f004230c06062a0fd
+:1098c00088bf043cc0608390f7ff0224241062002c
+:1098d000c06082a088bf033c816062904000423437
+:1098e000816062a088bf033cd0606290080042346f
+:1098f000d06062a088bf033cd16062900400423413
+:10990000d16062a088bf033c516062902000423465
+:10991000516062a080bf023c000c40ac80bf033ca1
+:1099200010000224080c62ac80bf023c100c40ac5a
+:1099300080bf033cf4010224200c62ac88bf033cce
+:109940001c000224d41062ac88bf033c1c0002241b
+:10995000d81062ac107f400f0000000088bf033cad
+:109960000100023c341062ac80bf033c0080023432
+:10997000080c62ac88bf033c0100023c641062ac7e
+:1099800088bf023c681040ac488280af6c8280afd8
+:10999000408180af388180af21e8c0031400bf8fc1
+:1099a0001000be8f1800bd270800e0030000000073
+:1099b000e0ffbd271c00bfaf1800beaf21f0a00321
+:1099c0002000c4af2400c5af2000c28f188182af31
+:1099d0002400c28f748282af2000c38f8888023c2b
+:1099e00089884234180062001010000021104300e2
+:1099f00043210200c3170300231082002000c2afde
+:109a00002000c28f090040100000000006df033470
+:109a10002000c28f1a006200f40140001210000002
+:109a20004c8182af0300001000000000d007022428
+:109a30004c8182af3881828f050040180000000001
+:109a40003881828fd08082af0300001000000000b8
+:109a5000ee020224d08082af4c81848fd079400ff7
+:109a600000000000029d063c2120400021286000eb
+:109a70004c1ac78c481ac68cd977400f00000000da
+:109a80002120400021286000687a400f000000007b
+:109a9000cc8082af098282831a004014000000004b
+:109aa0004081828f05004018000000004081828fb5
+:109ab0004c8182af0300001000000000ee0202247f
+:109ac0004c8182af34818283150040140000000075
+:109ad0002880838f0100022403006214000000002c
+:109ae000b81e400f0000000088bf023c1061439088
+:109af00001006334106143a0288080af080000108b
+:109b0000000000002880828f030040140000000045
+:109b1000de1e400f0000000001000224288082affa
+:109b2000bc80828f12004010000000004081828fb4
+:109b300007004018000000004081828f4c8182aff6
+:109b40004081828fcc8082af0500001000000000b1
+:109b5000ee0202244c8182afee020224cc8082af5e
+:109b600088bf023c1061439001006334106143a040
+:109b700021e8c0031c00bf8f1800be8f2000bd2746
+:109b80000800e00300000000e8ffbd271400bfaf9d
+:109b90001000beaf21f0a0031800c4af2110a00038
+:109ba0001c00c2a31800c38f14000224030062101b
+:109bb000000000002100001000000000029d023c97
+:109bc000b481848f501a458cb57b400f0000000093
+:109bd000608282af029d023c9c81848f501a458c2a
+:109be000b57b400f00000000548282af029d023c12
+:109bf000a881848f501a458cb57b400f000000006f
+:109c0000888282af6082848f256a400f0000000046
+:109c1000308282af5482848f256a400f000000009a
+:109c2000808282af8882848f256a400f0000000006
+:109c3000588282af3100001000000000b481848f90
+:109c4000017a400f00000000029d063c21204000e8
+:109c5000212860005c1ac78c581ac68cd977400f2f
+:109c60000000000021204000212860002a7a400fd7
+:109c700000000000608282af9c81848f017a400fd7
+:109c800000000000029d063c2120400021286000c9
+:109c90005c1ac78c581ac68cd977400f0000000098
+:109ca00021204000212860002a7a400f0000000097
+:109cb000548282af029d023ca881848f601a458c39
+:109cc000b57b400f00000000888282af6082848fe5
+:109cd000256a400f00000000308282af5482848fda
+:109ce000256a400f00000000808282af8882848f46
+:109cf000256a400f00000000588282af21e8c003af
+:109d00001400bf8f1000be8f1800bd270800e003ad
+:109d100000000000d8ffbd272400bfaf2000beaf69
+:109d200021f0a0033882838f3482828f2310620057
+:109d3000088182af5082838f6882828f23106200f5
+:109d40000c8182af5c82838f3c82828f2310620001
+:109d5000108182af348280af688280af3c8280af56
+:109d60000881848fd079400f00000000029d063cde
+:109d700021204000212860006c1ac78c681ac68c0c
+:109d8000a378400f0000000021204000212860003f
+:109d90002a7a400f000000001000c2af0c81848faf
+:109da000d079400f00000000029d063c21204000b9
+:109db000212860006c1ac78c681ac68ca378400fe3
+:109dc0000000000021204000212860002a7a400f76
+:109dd000000000001400c2af1081848f6666023c50
+:109de000676642341800820010100000831a0200d7
+:109df000c31704002310620021204000ae7c400ff6
+:109e0000000000001800c2af029d023c1000c48f89
+:109e1000701a458c1a7b400f00000000c88182af89
+:109e2000029d023c1400c48f741a458c1a7b400fab
+:109e300000000000f48182af1800c48f21280000c8
+:109e40001a7b400f000000000c8282af21e8c003a3
+:109e50002400bf8f2000be8f2800bd270800e0032c
+:109e600000000000f8ffbd270000beaf21f0a003f6
+:109e70003482838f3882828f0700621000000000d6
+:109e80003882838f0881828f231862003482828f08
+:109e900021104300348282af6882838f5082828f88
+:109ea00007006210000000005082838f0c81828fb7
+:109eb000231862006882828f21104300688282af7b
+:109ec0003c82838f5c82828f07006210000000005a
+:109ed0005c82838f1081828f231862003c82828f84
+:109ee000211043003c8282af029d023c781a428cd2
+:109ef000c88182af029d023c7c1a428cf48182af01
+:109f0000211000000c8282af21e8c0030000be8f48
+:109f10000800bd270800e00300000000e0ffbd27a7
+:109f20001c00bfaf1800beaf21f0a0036882828f73
+:109f30001000a2af3c82828f1400a2af3082848fc7
+:109f40008082858f5882868f3482878fdd67400fad
+:109f500000000000c769400f0000000021e8c003b6
+:109f60001c00bf8f1800be8f2000bd270800e00333
+:109f70000000000098ffbd276400bfaf6000beafc7
+:109f800021f0a0036800c4af6c00c5af7000c6af7d
+:109f90007400c7af1000c0af010002241400c2afac
+:109fa000010002241800c2af010002241c00c2af4d
+:109fb0007400c38f6800c28f231062002000c2affc
+:109fc0007800c38f6c00c28f231062002400c2afe0
+:109fd0007c00c38f7000c28f231062002800c2afc4
+:109fe0002000c38f2000c28f211062002c00c2af5e
+:109ff0002400c38f2400c28f211062003000c2af42
+:10a000002800c38f2800c28f211062003400c2af25
+:10a010006800c28f3800c2af6c00c28f3c00c2af74
+:10a020007000c28f4000c2af4400c0af4800c0af54
+:10a030004c00c0af5000c0af5400c0af5800c0af1c
+:10a040005c00c0a37880828f0300401400000000f1
+:10a050002000c0af2c00c0af7c80828f0300401472
+:10a06000000000002400c0af3000c0af8080828fad
+:10a0700003004014000000002800c0af3400c0af4f
+:10a080002000c28f07004014000000007400c28f3f
+:10a090006800c2af3482828f308282afd480828fd8
+:10a0a000b48182af2400c28f07004014000000007a
+:10a0b0007800c28f6c00c2af6882828f808282afcc
+:10a0c000d880828f9c8182af2800c28f0700401405
+:10a0d000000000007c00c28f7000c2af3c82828f03
+:10a0e000588282afdc80828fa88182af2000c28f2d
+:10a0f000130041040000000088bf033cd060629060
+:10a100007f004230d06062a07f0003245c00c293d5
+:10a11000241043005c00c2a3ffff02241400c2af5e
+:10a120002000c28f231002002000c2af2c00c28f7b
+:10a13000231002002c00c2af0a0000100000000033
+:10a1400088bf043cd060839080ff02242510620009
+:10a15000d06082a05c00c39380ff022425106200bf
+:10a160005c00c2a32400c28f140041040000000060
+:10a1700088bf043cd1608390fdff0224241062005c
+:10a18000d16082a05c00c393dfff02242410620030
+:10a190005c00c2a3ffff02241800c2af2400c28fdc
+:10a1a000231002002400c2af3000c28f231002002f
+:10a1b0003000c2af080000100000000088bf033c60
+:10a1c000d160629002004234d16062a05c00c29310
+:10a1d000200042345c00c2a32800c28f1200410458
+:10a1e0000000000088bf033c5160629002004234ce
+:10a1f000516062a05c00c293080042345c00c2a3bc
+:10a20000ffff02241c00c2af2800c28f23100200ef
+:10a210002800c2af3400c28f231002003400c2af46
+:10a220000a0000100000000088bf043c51608390c9
+:10a23000fdff022424106200516082a05c00c393e1
+:10a24000f7ff0224241062005c00c2a32000c28f2a
+:10a25000000042380100432c2400c28f0000423825
+:10a260000100422c24106200060040100000000093
+:10a270002800c28f0300401000000000d080828fb1
+:10a280004c8182af2800c38f2000c28f2a10620049
+:10a29000010044382800c38f2400c28f2a106200b6
+:10a2a000010042382410820003004010000000002a
+:10a2b000010002241000c2af2000c38f2800c28f0b
+:10a2c0002a106200010044382000c38f2400c28f8e
+:10a2d0002a1062000100423824108200030040105e
+:10a2e00000000000020002241000c2af2400c38f4f
+:10a2f0002000c28f2a106200010044382400c38f5e
+:10a300002800c28f2a106200010042382410820007
+:10a310000300401000000000030002241000c2af40
+:10a320002000c28f000042380100432c2400c28f5d
+:10a33000000042380100422c241862002800c28f1d
+:10a34000000042380100422c24106200020040103c
+:10a35000000000001000c0af1000c38f01000224f5
+:10a360004a006214000000004000c38f1c00c28f2e
+:10a37000211062004000c2af4400c38f2c00c28f86
+:10a38000211062004400c2af4800c38f3000c28f6a
+:10a39000211062004800c2af4400c38f2800c28f62
+:10a3a0002a1043000e004010000000003800c38f48
+:10a3b0001400c28f211062003800c2af4400c38f66
+:10a3c0003400c28f231062004400c2af0100022497
+:10a3d0005000c2af5c00c293400042345c00c2a394
+:10a3e0004800c28f2800c38f2a1062000e00401060
+:10a3f000000000003c00c38f1800c28f21106200d3
+:10a400003c00c2af4800c38f3400c28f23106200eb
+:10a410004800c2af010002245400c2af5c00c293e6
+:10a42000100042345c00c2a35c00c29304004234ba
+:10a430005c00c2a35c00c3935000c28f202c027c3e
+:10a440005400c28f2014027c212060002130400083
+:10a450005c6a400f000000005000c0af5400c0af65
+:10a460005800c0af5c00c393abff0224241062000d
+:10a470005c00c2a34000c38f7c00c28f0300621047
+:10a4800000000000b8ff0010000000001000c38fa3
+:10a49000020002244a006214000000003800c38f4a
+:10a4a0001400c28f211062003800c2af4c00c38f6d
+:10a4b0003400c28f211062004c00c2af4800c38f2d
+:10a4c0003000c28f211062004800c2af4c00c38f21
+:10a4d0002000c28f2a1043000e0040100000000030
+:10a4e0004000c38f1c00c28f211062004000c2af29
+:10a4f0004c00c38f2c00c28f231062004c00c2afef
+:10a50000010002245800c2af5c00c2930400423430
+:10a510005c00c2a34800c28f2000c38f2a106200d3
+:10a520000e004010000000003c00c38f1800c28fd6
+:10a53000211062003c00c2af4800c38f2c00c28fc4
+:10a54000231062004800c2af010002245400c2afd1
+:10a550005c00c293100042345c00c2a35c00c29352
+:10a56000400042345c00c2a35c00c3935000c28f21
+:10a57000202c027c5400c28f2014027c2120600019
+:10a58000213040005c6a400f000000005000c0af66
+:10a590005400c0af5800c0af5c00c393abff0224af
+:10a5a000241062005c00c2a33800c38f7400c28f05
+:10a5b0000300621000000000b8ff0010000000005f
+:10a5c0001000c38f030002244e006214000000003c
+:10a5d0003c00c38f7800c28f4a0062100000000068
+:10a5e0003c00c38f1800c28f211062003c00c2af34
+:10a5f0004400c38f2c00c28f211062004400c2af00
+:10a600004c00c38f3400c28f211062004c00c2afd7
+:10a610004400c38f2400c28f2a1043000e00401054
+:10a62000000000003800c38f1400c28f21106200a8
+:10a630003800c2af4400c38f3000c28f23106200c5
+:10a640004400c2af010002245000c2af5c00c293bc
+:10a65000400042345c00c2a34c00c28f2400c38f70
+:10a660002a1062000e004010000000004000c38f5e
+:10a670001c00c28f211062004000c2af4c00c38f8b
+:10a680003000c28f231062004c00c2af01000224d0
+:10a690005800c2af5c00c293040042345c00c2a305
+:10a6a0005c00c293100042345c00c2a35c00c39300
+:10a6b0005000c28f202c027c5400c28f2014027cd8
+:10a6c00021206000213040005c6a400f0000000043
+:10a6d0005000c0af5400c0af5800c0af5c00c3937f
+:10a6e000abff0224241062005c00c2a33c00c38fb5
+:10a6f0007800c28f0300621000000000b8ff001055
+:10a700000000000021e8c0036400bf8f6000be8f1e
+:10a710006800bd270800e00300000000f8ffbd2727
+:10a720000000beaf21f0a0033082828f348282af5e
+:10a730008082828f688282af5882828f3c8282af11
+:10a74000e080828fec8082afe480828ff08082afe5
+:10a75000e880828ff48082afd480828fe08082afe5
+:10a76000d880828fe48082afdc80828fe88082afe5
+:10a77000b481828fd48082af9c81828fd88082af57
+:10a78000a881828fdc8082af211000007c8282afa2
+:10a7900021100000448282af21100000408282af6d
+:10a7a00021100000608282af21100000548282af2d
+:10a7b00021100000888282af308280af808280af1b
+:10a7c000588280af21e8c0030000be8f0800bd277b
+:10a7d0000800e00300000000d0ffbd272c00bfaf41
+:10a7e0002800beaf21f0a0033000c4af3000c48ffa
+:10a7f000017a400f00000000212040002128600065
+:10a800001000c6274876400f000000001800c2afb5
+:10a810001c00c3af1000c48f1400c58f687a400fae
+:10a82000000000002000c2af029d023c801a448c50
+:10a83000841a458c1800c68f1c00c78fab7a400f56
+:10a840000000000003004018000000000800001095
+:10a85000000000002000c28f010042242000c2af8f
+:10a860002000c28f2400c2af0300001000000000cf
+:10a870002000c28f2400c2af2400c28f21e8c00391
+:10a880002c00bf8f2800be8f3000bd270800e003da
+:10a8900000000000d0ffbd272c00bfaf2800beafd6
+:10a8a00021f0a0033000c4af3000c48f017a400f04
+:10a8b0000000000021204000212860001000c62771
+:10a8c0004876400f000000001800c2af1c00c3af64
+:10a8d0001000c48f1400c58f687a400f000000007c
+:10a8e0002000c2af029d023c881a448c8c1a458c11
+:10a8f0001800c68f1c00c78fab7a400f0000000005
+:10a9000003004018000000000400001000000000d8
+:10a910002000c28f010042242000c2af029d023cf1
+:10a920001800c48f1c00c58f901a468c941a478c4f
+:10a93000ab7a400f00000000030040180000000048
+:10a9400004000010000000002000c28fffff42241e
+:10a950002000c2af2000c28f21e8c0032c00bf8faf
+:10a960002800be8f3000bd270800e0030000000073
+:10a97000e0ffbd271800beaf21f0a003211080002a
+:10a980002118a0002120c0002000c2a32400c3a3de
+:10a990002800c4a30000c0af2000c2930000c2afd3
+:10a9a0000000c28f001602000000c2af2400c28364
+:10a9b00008004010000000002800c283050040107d
+:10a9c00000000000cc80828f0400c2af03000010a2
+:10a9d000000000004c81828f0400c2af0000c28fd3
+:10a9e0000400c38f251043000000c2af6c82828f29
+:10a9f000010042240800c2af0800c28f0c00c2afa1
+:10aa00000c00c38f04006104000000000c00c48f20
+:10aa1000ff0184240c00c4af0c00c38f4312030059
+:10aa2000401202000800c48f231882004882828fdf
+:10aa30000300621400000000ecff001000000000a2
+:10aa400000a0043c6c82828f80180200800a82245d
+:10aa5000211862000000c28f000062ac6c82828ffd
+:10aa6000010042246c8282af6c82828f1000c2afe0
+:10aa70001000c38f1400c3af1400c48f04008104fe
+:10aa8000000000001400c28fff0142241400c2af76
+:10aa90001400c38f43120300401202001000c48f41
+:10aaa000231082006c8282af21e8c0031800be8fa1
+:10aab0002000bd270800e0030000000021108000f6
+:10aac0005600c0100c00ca2c4d0040152618a400da
+:10aad0000300633023380400290060100300e730ce
+:10aae0000600e0102330c7000000a3980300a388ed
+:10aaf0002128a700000083b8212087000f00c33061
+:10ab00002338c3001100e010213060002138e50037
+:10ab10000000a3980300a3880400a8980700a88851
+:10ab20000800a9980b00a9880c00aa980f00aa8811
+:10ab3000000083ac040088ac080089ac1000a52498
+:10ab400010008424f2ffa714fcff8aac0300c3307a
+:10ab50002338c3002a00e010213060002138e500ce
+:10ab60000000a3980300a3880400a5240400842403
+:10ab7000fbffa714fcff83ac2100001000000000c5
+:10ab80000500e0102330c7000000a3982128a7008b
+:10ab9000000083b8212087000f00c3302338c30092
+:10aba0000d00e010213060002138e5000000a38c8a
+:10abb0000400a88c0800a98c0c00aa8c000083acaf
+:10abc000040088ac080089ac1000a524100084247f
+:10abd000f6ffa714fcff8aac0300c3302338c30080
+:10abe0000700e010213060002138e5000000a38c50
+:10abf0000400a52404008424fcffa714fcff83acfc
+:10ac00000600c0102138c5000000a3900100a52453
+:10ac100001008424fcffa714ffff83a00800e003c9
+:10ac200000000000211080002600c0101000ca2c77
+:10ac30001f004015ff00a530005205002528aa007e
+:10ac4000005405002528aa00030083300500601089
+:10ac5000040007242338e3002330c700000085b830
+:10ac6000212087000f00c3302338c3000800e01004
+:10ac7000213060002138e400000085ac040085ac80
+:10ac8000080085ac10008424fbff8714fcff85ac12
+:10ac90000300c3302338c3000500e01021306000fa
+:10aca0002138e40004008424feff8714fcff85acf7
+:10acb0000400c0102138c40001008424feff871462
+:10acc000ffff85a00800e00300000000254085008c
+:10acd000030008310300001121108000380000102b
+:10ace0000000aa900000aa8c0101093c010129354d
+:10acf000c07909002340490124400f0107000011d9
+:10ad000024600a0105008811000000000000a5244d
+:10ad10000000aa902a000010000084240400ab8cdc
+:10ad200000008aac2340690124400f010700001194
+:10ad300024600b0105008811000000000400a52418
+:10ad40000000aa901e000010040084240800aa8cb1
+:10ad500004008bac2340490124400f01070000117f
+:10ad600024600a0105008811000000000800a524e5
+:10ad70000000aa9012000010080084240c00ab8c84
+:10ad800008008aac2340690124400f01070000112c
+:10ad900024600b0105008811000000000c00a524b0
+:10ada0000000aa90060000100c0084241000aa8c59
+:10adb0000c008bac10008424ceff00101000a524e2
+:10adc0000300401500008aa00800e0030000000016
+:10add0000100ab900300601501008ba00800e003a8
+:10ade000000000000200aa900300401502008aa0a3
+:10adf0000800e003000000000300ab9003006015b2
+:10ae000003008ba00800e003000000000400aa90eb
+:10ae10000300401504008aa00800e00300000000c1
+:10ae20000500ab900300601505008ba00800e0034f
+:10ae3000000000000600aa900300401506008aa04a
+:10ae40000800e003000000000700ab90030060155d
+:10ae500007008ba00800e003000000000800aa9093
+:10ae600008008424d6ff00100800a52400008a9062
+:10ae70002110800003004015000000000800e003de
+:10ae80000000022401008a90030040150000000029
+:10ae90000800e0030100022402008a90030040152c
+:10aea000000000000800e0030200022403008a9072
+:10aeb00003004015822004000800e0030300022480
+:10aec000010084248020040000008a8c0101093cd8
+:10aed00001012935c07909002340490124400f01af
+:10aee0000600001124600a0104008811000000001f
+:10aef00000008a90220000100000842404008b8c43
+:10af00002340690124400f010600001124600b0159
+:10af1000040088110000000004008a90180000104e
+:10af20000400842408008a8c2340490124400f0136
+:10af30000600001124600a010400881100000000ce
+:10af400008008a900e000010080084240c008b8cee
+:10af50002340690124400f010600001124600b0109
+:10af600004008811000000000c008a90040000100a
+:10af70000c00842410008a8cd7ff00101000842459
+:10af80000400401500000000000084240800e003d5
+:10af90002310820001008a90040040150000000088
+:10afa000010084240800e0032310820002008a903c
+:10afb0000400401500000000020084240800e003a3
+:10afc0002310820003008a90030084240800e00319
+:10afd00023108200b0ffbd270000a1af0400a2af84
+:10afe0000800a3af0c00a4af1000a5af1400a6afdb
+:10aff0001800a7af1c00a8af2000a9af2400aaaf7b
+:10b000002800abaf2c00acaf3000adaf3400aeaf1a
+:10b010003800afaf3c00b8af4000b9af4400bfaf9d
+:10b02000124000004800a8af104000005000a8af38
+:10b0300000680440006005408a6e400f0000000078
+:10b040005000a88f110000014800a88f13000001d4
+:10b050000000a18f0400a28f0800a38f0c00a48f12
+:10b060001000a58f1400a68f1800a78f1c00a88fb2
+:10b070002000a98f2400aa8f2800ab8f2c00ac8f52
+:10b080003000ad8f3400ae8f3800af8f3c00b88fea
+:10b090004000b98f4400bf8f5000bd27c0000000a2
+:10b0a000180000422518a40003006230200040145c
+:10b0b000214080000400c92c1c0020152138a0006c
+:10b0c0000000af8cfefe183cfffe053727700f0016
+:10b0d0002168e50180800c3c2458ae0180808335d6
+:10b0e00024506301120040552128e0002148a000af
+:10b0f000212860000000e28cfcffc6240400d92c4b
+:10b10000000082ac0400e724080020170400842417
+:10b110000000ed8c27600d002158a90124506c011e
+:10b1200024184501f4ff60500000e28c2128e00063
+:10b130000e00c010ffffc2240000a790ffffc6242e
+:10b14000000087a00100a524f9ffe0140100842479
+:10b150000600c010ffffc224ffff0324ffff4224ac
+:10b16000000080a0fdff4314010084240800e003d8
+:10b17000211000010300823018004014ff00a530a8
+:10b18000003a05002540a7000034080025380601d4
+:10b190008080033c21308000fefe043cfffe8934a9
+:10b1a000808068340000cf8c2610e7012168e90117
+:10b1b00027700f0027c8020021c049002458ae01a3
+:10b1c00024601903245068010300401524188801e5
+:10b1d000f4ff60500400c6242120c00000008390ca
+:10b1e000ff00693003002515211080000800e003ee
+:10b1f00000000000f9ff6014010084240800e0034f
+:10b2000021100000e0ffbd2700a0053c1000b0affa
+:10b210000000b0241800b2af1400b1af219080003c
+:10b2200000a0113c1c00bfaf596e400f212000024e
+:10b230001c01238e01000424380064ac5d6e400fb5
+:10b24000212000021c01228e1000508c0d000012e3
+:10b250001c012a8e0400028e08004018ffff4724bc
+:10b2600080480700214030010800068d09f8c00021
+:10b27000040007aef8ff00100400028ef3ff001078
+:10b280000000108e3400428d0300401000000000ca
+:10b2900009f8400000000000ad6e400f2120400280
+:10b2a000029d073cad1ae62421108600000045905f
+:10b2b000200082240100a3300800e0030a1083006c
+:10b2c000029d073cad1ae62421108600000045903f
+:10b2d000e0ff82240200a3300800e0030a1083008c
+:10b2e000029d053cad1aa32421208300000082901a
+:10b2f0000800e00307004230029d053cad1aa3247c
+:10b3000021208300000082900800e0030300423007
+:10b310000800e0038000822c029d053cad1aa324a6
+:10b3200021208300000082900800e00320004230ca
+:10b33000029d053cad1aa3242120830000008290c9
+:10b340000800e00304004230029d053cad1aa3242e
+:10b3500021208300000082900800e00317004230a3
+:10b36000029d053cad1aa324212083000000829099
+:10b370000800e00302004230029d053cad1aa32400
+:10b3800021208300000082800800e0039700423003
+:10b39000029d053cad1aa324212083000000829069
+:10b3a0000800e00310004230029d053cad1aa324c2
+:10b3b00021208300000082800800e00388004230e2
+:10b3c000029d053cad1aa324212083000000829039
+:10b3d0000800e00301004230029d053cad1aa324a1
+:10b3e00021208300000082900800e00344004230e6
+:10b3f0000800e0037f0082300800e0032000822480
+:10b400000800e003e0ff8224e8ffbd271000bfaf83
+:10b410008c6d400f212800001000bf8f0800e00352
+:10b420001800bd27e8ffbd27212800001000bfaf8e
+:10b43000116d400f0a0006241000bf8f0800e003c2
+:10b440001800bd27000083802138800021500000b3
+:10b4500021700000215800000e00601021680000db
+:10b46000029d093cad1a2825211068000000428089
+:10b4700088004330080060500000e3800100e724aa
+:10b480000000ec800300801121188801f8ff0010f3
+:10b49000000062800000e3802b0008240300681095
+:10b4a0002d000f2404006f14000000002d007838d8
+:10b4b00001000e2f0100e7241100c0141000032426
+:10b4c0000000e280300019241c0059140a000624f0
+:10b4d0000100e7240000e380780009240800062426
+:10b4e0000400691001000d2458000c2414006c1491
+:10b4f000ff7f023c0100e72410000010100006242a
+:10b500000f00c314ff7f023c0000ef8030000824ce
+:10b510000c00e815ffff43340100e7240000e3803e
+:10b52000780018240400781001000d245800192414
+:10b5300004007914ffff43340100e724ff7f023c3d
+:10b54000ffff43341a006600f401c0002148e00008
+:10b550000000e7802400e01012600000029d083c1b
+:10b56000ad1a1825217860002110f80000004390e2
+:10b570000400793007002017d0ffe824030068306a
+:10b580001900001101006330a9fff924c9ffe82464
+:10b590000a4023032a18060101007938c21708005f
+:10b5a000253859001100e05401006f2d2a388a0116
+:10b5b0000800e01401000d24080060550100292551
+:10b5c0000250467123c8ea012a10280302004050a5
+:10b5d0002150480101000b2401002925000027818a
+:10b5e000e2ffe0542110f80001006f2d2460cf012c
+:10b5f00023300a000b50cc000800601121104001dc
+:10b6000022000b2400a00a3c04024bad0300c0152d
+:10b610000080023cff7f0e3cffffc2350200a010fd
+:10b620000a488d000000a9ac0800e00300000000fb
+:10b63000e8ffbd271000bfaf537d400f00000000a2
+:10b640001000bf8f0800e0031800bd27e8ffbd27ea
+:10b650001000bfaf0400828c21188000ffff062479
+:10b66000010004242128400003004610000060acc3
+:10b6700004000010040066ac986e400f000000004b
+:10b68000212840001000bf8f2110a0000800e00317
+:10b690001800bd27e8ffbd271000b0af1400bfaff2
+:10b6a00010008394020062300e0040102180800060
+:10b6b0000000838c0e0060041400bf8f0c00848c8b
+:10b6c00003006410232883009a6e400f0800048e44
+:10b6d0000800058e0c00068e040005ae0300001065
+:10b6e000000006aeffff0724040087ac1400bf8fe4
+:10b6f0001000b08f211000000800e0031800bd27e3
+:10b70000d8ffbd271c00b1af1800b0af2000bfaffd
+:10b710000c00a28c2180a00021888000010005245b
+:10b7200006004014212000021000a4279a6e400f4a
+:10b730001000b1a323000010000000ae0000068e30
+:10b74000ffff03240100c5240d00a314000005ae73
+:10b750000800078e00a0083c040405250800e0143a
+:10b760008000062410000a96040005ae100049353a
+:10b77000000006ae080005ae0c0006ae100009a6db
+:10b78000a56d400f0000000000000e8e04000c8e1e
+:10b79000ffffcd2501008b250a00042400000dae1b
+:10b7a000000091a10700241604000bae10001896ab
+:10b7b00008000f330300e01121200002a56d400fa7
+:10b7c00000000000211020022000bf8f1c00b18f5c
+:10b7d0001800b08f0800e0032800bd27e0ffbd2758
+:10b7e0001000b0af0280c5701800b2af1400b1af46
+:10b7f0001c00bfaf2188c000219080001100001202
+:10b80000212800001000e6942120e0000100c23051
+:10b81000060040104000c3341000e3a400a0043c24
+:10b820000900032407000010040283aca56d400f3b
+:10b8300000000000212800029a6e400f21204002e3
+:10b84000212820021c00bf8f1800b28f1400b18f76
+:10b850001000b08f2110a0000800e0032000bd27d9
+:10b8600010008794ffffe330241065004000e634a9
+:10b870000600401001000324100086a409000524de
+:10b8800000a0043c040285ac211800000800e0037d
+:10b8900021106000c8ffbd27ffffa9242128c00098
+:10b8a0002130e000029d073c21408000ffff0b2477
+:10b8b0001000a42782000a240c1de2243000bfaf30
+:10b8c0002200aba72000aaa71c00a9af1400a8afb4
+:10b8d0002800a2af1000a9af6d6f400f1800a8afed
+:10b8e0001400a38f3000bf8f3800bd270800e0038d
+:10b8f000000060a02110a000ff7f053ce8ffbd27ed
+:10b900002138c000ffffa5341000bfaf256e400fe7
+:10b91000213040001000bf8f0800e0031800bd2751
+:10b92000e8ffbd272110a000ff7f053c2000a6af47
+:10b930002400a7afffffa5342000a7271000bfaf4a
+:10b94000256e400f213040001000bf8f0800e0033b
+:10b950001800bd270800e003211000000800e003e4
+:10b96000211000000800e003211000000800e0039f
+:10b97000211000000800e003211000000800e0038f
+:10b98000211000000800e003211000000800e0037f
+:10b99000211000000800e003211000000800e0036f
+:10b9a000211000000800e003ffff02240800e0036c
+:10b9b000000000000800e003000000000800e003b1
+:10b9c000000000000800e003000000000800e003a1
+:10b9d000000000000800e003000000000000828c6e
+:10b9e000e8ffbd27040040141000bfaf020003248d
+:10b9f00009f8a000000083ac1000bf8f21100000e8
+:10ba00000800e0031800bd270800e003ffff022440
+:10ba10000800e003ffff02240800e00321100000fb
+:10ba20000800e0032110a000ffff0010000000004c
+:10ba3000ffff0010000000000800e003000000000d
+:10ba40000800e0030000000000601a40bfff1b3c3c
+:10ba5000ffff7b3724d05b0300609a401800004250
+:10ba60000800e003ffff0224e0ffbd271400b1af90
+:10ba70001000b0af1800bfaf218880000800801010
+:10ba80002180a000070000121800bf8f0000248250
+:10ba90001375400fffff1026faff0010010031263a
+:10baa0001800bf8f1400b18f1000b08f0800e003a2
+:10bab0002000bd27ffff001000000000e0ffbd27b1
+:10bac0001800b2af1400b1af1000b0af1c00bfaf90
+:10bad000218880002190c0000c00a010ffffb0243e
+:10bae00000002482d874400f21284002ffff032465
+:10baf000ffff10260300431401003126040000104c
+:10bb0000ffff0224f7ff03560000248221100000eb
+:10bb10001c00bf8f1800b28f1400b18f1000b08fbf
+:10bb20000800e0032000bd27e0ffbd271800b2afea
+:10bb30001400b1af1000b0af1c00bfaf2180a00057
+:10bb4000219080002188c0000d0000122100022eeb
+:10bb5000200007240b3802022128e00021202002c7
+:10bb600021304002af6e400f23800702ffff032405
+:10bb7000f5ff4314ffff0224030000101c00bf8fd9
+:10bb8000211000001c00bf8f1800b28f1400b18f6d
+:10bb90001000b08f0800e0032000bd27d0ffbd27b4
+:10bba0001400b1af2188e0004000a78f1800b2afa9
+:10bbb0001000b0af0100f2302180c0000100432e20
+:10bbc0001c00b3af2a981102029d063c241073009a
+:10bbd0002800b6af2400b5af2000b4af2c00bfaf33
+:10bbe00021a0a000d01bc624ffff1624232830026a
+:10bbf00021a880000400401021180000ca6e400fe8
+:10bc000000000000211840002120800221280002ad
+:10bc10000e0076102130a002af6e400f0000000031
+:10bc20000b0056102a2030020a0040520a802402db
+:10bc3000029d053cd01ba6242120a0020300601217
+:10bc400023283002ca6e400f000000002a20300274
+:10bc50000a802402211000022c00bf8f2800b68f1a
+:10bc60002400b58f2000b48f1c00b38f1800b28f52
+:10bc70001400b18f1000b08f0800e0033000bd2722
+:10bc8000c8ffbd272c00b5af1c00b1af21a8c00074
+:10bc90002188e00021300000213800002800b4afe6
+:10bca0002400b3af2000b2af1800b0af3000bfaf78
+:10bcb000219080002198a0004800b48fab7a400ffb
+:10bcc0004c00b08311004010029d023cc81c468c01
+:10bcd000cc1c478c21204002d977400f21286002dc
+:10bce00021204000212860004876400f1000a62740
+:10bcf0000b000010029d063c000025a20000a48e4f
+:10bd000001008324210000100000a3aed079400f71
+:10bd1000d0ff04261000a2af1400a3af029d063c82
+:10bd2000d01cc48cd41cc58c1400a78fab7a400fd8
+:10bd30001000a68f16004104211020022e000624b8
+:10bd40003000052400008d822660a60101008b2da5
+:10bd500023208b0200008a90ffff942401004825d5
+:10bd6000204c087c3a0027290800e014000088a035
+:10bd7000f4ff9114000085a0dfffa05631000524d8
+:10bd800031000e24ffff2ea2ffff312621102002da
+:10bd90003000bf8f2c00b58f2800b48f2400b38fe4
+:10bda0002000b28f1c00b18f1800b08f0800e00394
+:10bdb0003800bd2718fbbd27e404bfafe004beafc9
+:10bdc000dc04b7afd804b6afd404b5afd004b4af79
+:10bdd000cc04b3afc804b2afc404b1afc004b0afb9
+:10bde0001800838cec04a5af1000628ce804a4afab
+:10bdf0000100052409f84000f004a6af9404a0afa8
+:10be000034054010ffff0324ec04a68f0000c4801b
+:10be10000100c52429058010ec04a5af25000724e6
+:10be200006008710ec04a88fd874400fe804a58f93
+:10be30009404a48f1f0500100100832400001281c8
+:10be40000b004416ffff0624e804a58fd874400faa
+:10be500025000424ec04ac8f9404aa8f01008b25e8
+:10be600001004925ec04abafe7ff00109404a9af33
+:10be70009c04a0af2d0007242b00052420000424df
+:10be80002300032430000224030047169c04ad8fd6
+:10be9000100000100100a835030045169c04ae8f69
+:10bea0000c0000100200c835030044169c04af8f3c
+:10beb000080000100400e835030043169c04b08f0e
+:10bec0000400001008000836080042169c04b18fd8
+:10bed00010002836ec04b28f9c04a8af0100532652
+:10bee000ec04b3afe8ff0010000072822a001424b3
+:10bef0000e005416d0ff4526f004a28ffcff1f242d
+:10bf000003005e2424b0df03ec04b98f0000d88e58
+:10bf100001003727ec04b7af9804b8af0000f282f5
+:10bf20000400d52611000010f004b5af0a00a32cc0
+:10bf3000160060109804a0af0a0003249804ac8f88
+:10bf4000ec04ad8f025883710100aa25ec04aaaf5e
+:10bf50002148720100005281d0ff2825d0ff4426dd
+:10bf60000a00872cf5ffe0149804a8af9804a88f66
+:10bf7000070001052e0011249c04b08f23700800d7
+:10bf800001000f369c04afaf9804aeaf2e00112411
+:10bf90002600511668000c24ec04b28f2a000624f7
+:10bfa00001005326ec04b3af000072820d00461668
+:10bfb000d0ff4226f004be8fec04b78f0300d827d1
+:10bfc0000100f626fcff192424a81903ec04b6afdf
+:10bfd0000000d2820000a68e0400b4260f000010dc
+:10bfe000f004b4af0a005f2c0f00e0132130000012
+:10bff0000a000324ec04aa8f0220c3700100482524
+:10c00000ec04a8af2148920000001281d0ff47261f
+:10c010000a00e52cf7ffa014d0ff26250000c32856
+:10c02000ffff0b240b30630168000c2412004c1638
+:10c030006c001524ec04a58f0100ad800700b2153b
+:10c040009c04b38f9c04b08f0100ae2480000f3697
+:10c050009c04afaf03000010ec04aeaf00017136da
+:10c060009c04b1afec04b28f01005426ec04b4afd1
+:10c07000270000100000928212005516710007245c
+:10c08000ec04a48f010096800700d2169c04bf8f99
+:10c090009c04b98f01009724000838379c04b8af7e
+:10c0a00003000010ec04b7af0002fe379c04beafe3
+:10c0b000ec04a58f0100a224ec04a2af1400001030
+:10c0c00000005280090047164c000b24ec04aa8f94
+:10c0d0009c04a88f01004425ec04a4af00009280ca
+:10c0e000000809350a0000109c04a9af09004b168e
+:10c0f000ec04b18fec04ae8f9c04ac8f0100cd2515
+:10c10000ec04adaf000483350000b2819c04a3af02
+:10c11000ec04b18f9c04a38f0100302602006f3025
+:10c120000400e011ec04b0affbff14242498740069
+:10c130009c04b3af9c04a58f0100b5300400a0128d
+:10c14000bcff4326efff172424b0b7009c04b6af12
+:10c150003500782c5504001321100000029d053c89
+:10c1600080f80300f01ba22421f0e2030000d98f25
+:10c1700008002003000000009c04a78f0002f23496
+:10c180009c04b2af9c04aa8ff7ff0424001048352a
+:10c19000244804010d0000109c04a9af9c04a38f47
+:10c1a00000026b349c04abaf15000010080014248f
+:10c1b0009c04ad8f0002ac359c04acaf9c04af8fe7
+:10c1c000f7ff10242470f0019c04aeaf0c000010a7
+:10c1d0000a0014249c04b38f00407136070000103d
+:10c1e0009c04b1af9c04b58f0040b4369c04b4af3e
+:10c1f0009c04b78f0802f6369c04b6af10001424d6
+:10c20000ffff18240300d8149c04be8f0400001004
+:10c2100001000624efff1f2424c8df039c04b9afec
+:10c220009c04a58f0010b6300b00c0120008a2308d
+:10c230000c004014f004ab8ff004a98ffcff022423
+:10c24000030027252410e2000000528c2120400228
+:10c2500010000010c32f120009004010f004ad8f31
+:10c26000f004ab8ff8ff0a240700642524408a00fd
+:10c270000000048d0400058d070000100800022551
+:10c28000fcff0c240300a32524106c000000448c48
+:10c290002128000004004224f004a2af2180800085
+:10c2a0002188a0002198c0005f00b2270800c012ba
+:10c2b00021b800000700a10421180000238010000d
+:10c2c000238811002b10100023882202010017245c
+:10c2d000211800001b001016212800021a007114fa
+:10c2e00025101102330000129c04ae8f0040c631ad
+:10c2f0001b00b400f4018002102000000a008f2807
+:10c300000300e05137009124040000103000842421
+:10c3100057009024212020020a2006021b00b400ae
+:10c32000f4018002000044a2ffff7326ffff5226a3
+:10c3300012a80000eeffa016122800001e00001038
+:10c34000ffff6226251011021a004010c3af14002f
+:10c3500021282002213080022138a0024580400f90
+:10c36000212000020a00582806000017300045244a
+:10c370009c04bf8f570059240040fe3337004524ea
+:10c380000a283e03000045a22120000221282002a5
+:10c3900021308002267f400f2138a00221804000fa
+:10c3a0002188600025104300ffff5226e6ff0010a1
+:10c3b000ffff7326ffff6226070040049c04a88f3e
+:10c3c00030000324ffff4224000043a2fdff41048c
+:10c3d000ffff52269c04a88f100013312500601225
+:10c3e0009c04ae8f2000a5279804a98f233845020e
+:10c3f00021282701080002310c004010c1ffa424ad
+:10c400000800082407008816feff8c2401004b82d8
+:10c4100030000a2404006a511000833a030000101f
+:10c42000c0ffa4241000833a0a2083010900c052ef
+:10c43000ffff83240600e056ffff84249c04a68fa0
+:10c440000600cd300300a011ffff8324ffff8424ea
+:10c45000ffff8324070062049c04ae8f3000022497
+:10c46000ffff6324000042a2fdff6104ffff52268c
+:10c470009c04ae8f0800c4311600801008000f2401
+:10c4800008008f5610001124010050823000032450
+:10c490000400035210001124000043a20d000010fc
+:10c4a000ffff52260b009116212840029c04b28ff8
+:10c4b000ffffa324004054320200801658000424d9
+:10c4c00078000424300015240000a4a0ffff72248b
+:10c4d000000075a01000c012010045260b00e016f8
+:10c4e0002d0002249c04b78f0200f6320300c01214
+:10c4f0009c04b98f050000102b000224040038337f
+:10c50000050000530100452620000224000042a23d
+:10c51000ffff52260100452623f0a5031f0300104c
+:10c520006000c627f004ac8ff8ff0a2407008b25b3
+:10c5300024406a010000098d0400078d6000a9af46
+:10c540006400a7af6000b08f6400b18f08000525bc
+:10c550000055337eff077f3af004a5af2300e017b4
+:10c56000a004a6af212000022128200221300002d1
+:10c57000ab7a400f213820020700405021200002f2
+:10c58000029d033c9804a78fe804a48ff01c652447
+:10c59000040300100300062421282002213000009b
+:10c5a000ab7a400f2138000009004304029d043c8f
+:10c5b000029d063c9c04ad8f9804a78fe804a48fcd
+:10c5c000fc1cc52404000624f80200101000adafc6
+:10c5d000f41c85249c04ae8f9804a78fe804a48fd4
+:10c5e00004000624f10200101000aeafffff0f247c
+:10c5f0000400cf14a404a0af0600142413000010fc
+:10c60000a004b4af2800d5281100a01621400002d4
+:10c6100067005e3a4700593a2bb81e002bc019003c
+:10c6200024b0f8020600c016d9ffc2249c04b38fc0
+:10c6300008007f320400e01327000724d9ffc2243a
+:10c64000a404a2af27000724a004a7af2140000242
+:10c65000214820026900a0a39004a0afa004be8fcf
+:10c66000a804b2af0a002106b404a0af2150000113
+:10c67000029d083cdc1c058d2d000924268825021e
+:10c680007002a9a3214040010200001021482002ad
+:10c690007002a0a38004a627212000014876400f45
+:10c6a000212820016900ad276902ac2721a860007c
+:10c6b000ffff8b250100a32521a04000b804a3aff4
+:10c6c000ac04a3af2198600024000010b004abaf0d
+:10c6d000c81c108fcc1c118f2120c0022128e00221
+:10c6e00021382002a378400f213000022120400091
+:10c6f000212860008004a6274876400f029d173c41
+:10c70000e01ce68ee41ce78e21204000212860001a
+:10c710008804a2afd076400f8c04a3af2120400044
+:10c720002130000221286000d977400f21382002f3
+:10c7300021204000687a400f21286000b004af8fac
+:10c74000300056240000f6a19004ae8fffffe425d0
+:10c750000100c625b004a4af9004a6af8004b68f34
+:10c760008404b78f21300000213800002120c0024e
+:10c77000ab7a400f2128e002d5ff4014029d183cff
+:10c78000650019246c00591266005f2a0600e01348
+:10c790006600072445000224670042124700022475
+:10c7a000030000100000000005004712670002248b
+:10c7b000580142126900a68300020010b804b08f2d
+:10c7c0009004b28f10004012b804a38fb004a58f5c
+:10c7d0006902a9270100a4242b5089000e004011f2
+:10c7e000a004ad8f00008b906902ac270100842467
+:10c7f0002b408c0000006ba2faff0015010073268d
+:10c8000005000010a004ad8f30001324000073a0b9
+:10c8100001007324a004ad8f0600a0152e0004248f
+:10c820009c04ae8f0800c6310500c0102120800294
+:10c830002e000424000064a201007326212080023f
+:10c840002128a00221300000ab7a400f21380000df
+:10c850002f004010a004af8f1d00e01121208002a6
+:10c86000029d113cc81c268ecc1c278e21208002e4
+:10c87000d977400f2128a002212040002128600004
+:10c880004876400f8804a6278804a48f8c04a58fbf
+:10c8900021a04000687a400f21a860003000562493
+:10c8a000ffffde27000076a20800c01301007326f8
+:10c8b000212080022128a00221300000ab7a400f05
+:10c8c00021380000e7ff4014029d113c2120800226
+:10c8d0002128a00221300000ab7a400f213800004f
+:10c8e0000b004010b804a78fffff7726213000000f
+:10c8f0007002b027212080022128a0021000b7afcb
+:10c900001800b0af206f400f1400a0afac04a2af6e
+:10c91000a801c013ffffc22730000424ffff032437
+:10c92000ffff4224000064a2fdff431401007326b0
+:10c93000a10100106900a6839004b88f390000138c
+:10c9400021208002b004a28fb804b98f01005f904b
+:10c950000100432400003fa30500c0170100302759
+:10c960009c04b28f080047321800e01001006d24cb
+:10c97000b804aa8f2e000924010049a11200c01397
+:10c9800002005025b004a88f6902a52702000325e4
+:10c990002b1065000a0040100000000000006b90a2
+:10c9a000ffffde2700000ba20700c01301001026c6
+:10c9b000010063246902ac27f6ff00102b106c0005
+:10c9c0001500c0179004a48f01006d246902a627ea
+:10c9d0002b98a601100060129004a48fffff0e2672
+:10c9e0001000aeaf010075807002b4271400b5af1f
+:10c9f0001800b4afb804a78f21a0000021a8000040
+:10ca00009004a62721208002206f400f2128a00239
+:10ca1000ac04a2af9004a48fffff83243d0000105c
+:10ca20009004a3af2128a00221300000ab7a400f70
+:10ca3000213800002b004010b804a78fffff02240c
+:10ca40009004a2af029d0f3cc81ce68dcc1ce78d64
+:10ca500021208002d977400f2128a0022120400008
+:10ca6000212860004876400f8804a6278804b08fec
+:10ca70008c04b18f213000002138000021200002f9
+:10ca80002128200221a04000ab7a400f21a860009d
+:10ca9000030040149004b68fe9ff0010ffffc22688
+:10caa00021200002687a400f21282002b804b18fab
+:10cab00030005024000030a20500c01701003026cd
+:10cac0009c04b88f080017331300e0122120800265
+:10cad000b804b98f2e001f24020030270d0000106b
+:10cae00001003fa3300002240000e2a00500c017af
+:10caf0000100f0249c04aa8f080052310600401265
+:10cb000021208002b804a98f2e000524010025a150
+:10cb100002003025212080022128a00221300000bf
+:10cb2000ab7a400f213800002f00401000000000b9
+:10cb30001d00c01321208002029d0b3cc81c668d85
+:10cb4000cc1c678d21208002d977400f2128a002bc
+:10cb500021204000212860004876400f8804a62745
+:10cb60008804a48f8c04a58f21a04000687a400f10
+:10cb700021a8600030004824ffffde27000008a243
+:10cb80000800c01301001026212080022128a002e5
+:10cb900021300000ab7a400f21380000e7ff40143d
+:10cba000029d0b3c212080022128a00221300000a0
+:10cbb000ab7a400f213800000b004010ac04a78f67
+:10cbc0007002ac27ffff13269004a62721208002c5
+:10cbd0002128a0021000b3af1800acaf206f400fa7
+:10cbe0001400a0afac04a2af0700c013ffffc22720
+:10cbf00030000424ffff0324ffff4224000004a2ae
+:10cc0000fdff431401001026b404be8f1400c0536e
+:10cc10009004a48f9c04a68f0800cd301000a0556e
+:10cc20009004a48f30000324ac04b58f2ba0b00275
+:10cc30000600805200001682ffff102600000e82c0
+:10cc4000fbffc3112ba0b002000016822e00cf3aca
+:10cc50000100e42d23180402010070249004a48f25
+:10cc6000a804b18f02000526000011a2060081046d
+:10cc70007804a8272d001724232004002130a000c9
+:10cc800004000010010017a22b001824010018a2b4
+:10cc90002130a0000a00902817000016213800015a
+:10cca0000a0005241a008500f401a000ffffe72414
+:10ccb000101000001220000030005f240a009928a4
+:10ccc000f8ff20130000ffa0ffffe52430008a24b6
+:10ccd0002b18a800ffffeaa0b60060102198c00042
+:10cce0000000a7900100a5240000c7a02b18a800f1
+:10ccf000f9ff00100100c624300089243000082408
+:10cd00000000a8a00100a9a00200a624a90000100c
+:10cd10002198c000a004ab8f010010249004a38fc1
+:10cd20000b80cb032a2803021300a014feff4d261c
+:10cd300016006014b004ae8f212080022128a002ca
+:10cd400021300000ab7a400f213800001e00401057
+:10cd5000b804a48f029d0c3ce81c868dec1c878dca
+:10cd600021208002ab7a400f2128a0021600410446
+:10cd7000b804a48ffeff4d2601001324ffff1e26da
+:10cd8000a804adafecfe0010b404b3af6902a6274f
+:10cd90000100c4252bf086000e00c0130000000027
+:10cda00000008f906902b627010084242b1896009a
+:10cdb00000006fa2ffff1026f9ff60140100732628
+:10cdc000040000100000000030001124000091a0b9
+:10cdd00001009324060000162e0019249c04b88f2d
+:10cde000080017330500e012219000002e001924de
+:10cdf000000079a201001224010073262120800284
+:10ce00002128a00221300000ab7a400f2138000019
+:10ce10004c0040509c04b58f380000122120800245
+:10ce2000029d113ccc1c278ec81c268e212080021e
+:10ce3000d977400f2128a002212040008804a6278e
+:10ce40004876400f212860008804a48f8c04a58fa9
+:10ce500021a04000687a400f21a8600030005f24c4
+:10ce600000007fa28804a48f8c04a58f21300000cd
+:10ce700021380000ab7a400f0100732615004014e2
+:10ce80009004a28fe7ff4050029d113c1200001059
+:10ce9000ffff1026cc1c278e21208002d977400f5f
+:10cea0002128a00221204000212860004876400f60
+:10ceb0008804a6278804a48f8c04a58f21a0400095
+:10cec000687a400f21a8600030004a2400006aa25e
+:10ced00001007326ffff10260700001221208002a8
+:10cee0002128a00221300000ab7a400f2138000039
+:10cef000e8ff4014c81c268e212080022128a002b1
+:10cf000021300000ab7a400f213800000d00405066
+:10cf10009c04b58fb804a78fffff68267002a9276d
+:10cf200021300000212080022128a0021000a8af9b
+:10cf30001800a9af206f400f1400a0afac04a2af3f
+:10cf40009c04b58f0800b4320b0080120000000072
+:10cf500018000012ffff022630000424ffff032404
+:10cf6000ffff4224000064a2fdff4314010073266a
+:10cf7000110000106900a6830f0040126900a6830b
+:10cf800030000324ac04b28f2b8053020600005201
+:10cf900000006c82ffff732600006782fbffe31036
+:10cfa0002b80530200006c822e008b392b280b0043
+:10cfb000219865026900a683b804b08fac04ad8fd8
+:10cfc0007002a3936900be270b80c60305006010a2
+:10cfd00023886d02ffff102601003126110000108a
+:10cfe000000003a29c04ae8f0200d3310600601241
+:10cff0009c04b68fffff10262b000324010031266e
+:10d0000008000010000003a20400cf320600e01167
+:10d010009c04bf8fffff102620000424000004a200
+:10d02000010031269c04bf8fa404b98f9804a88ff7
+:10d030000100f433219039020100982e2a98480209
+:10d0400024b813030700e01221200000029d023cd7
+:10d05000e804a48fd01b4624ca6e400f2328120177
+:10d0600021204000ffff152405009510e804a68f3d
+:10d0700021200002af6e400f212820022120400015
+:10d08000a404a58f274004002b5008002b4805005e
+:10d09000248849010600201200000000e804a48f43
+:10d0a000029d103cca6e400fb01b06262120400096
+:10d0b0000c0095109804a78f0b0080122a28f2000c
+:10d0c0000a0060120b3845029804b48f029d153c8b
+:10d0d000e804a48fd01ba626ca6e400f2328920214
+:10d0e0009804a78f2a28f2000b3845026f00001021
+:10d0f0002110e000f004b38ffcff062403007e261d
+:10d100002458c60300006d8d9c04ac8f9804a78f33
+:10d11000e804a48f040072257804a52701000624e2
+:10d120007804ada31000acaf20000010f004b2af43
+:10d13000f004a48ffcff0324030096242478c30288
+:10d140000000f18d0400ee25f004aeaf04002016bf
+:10d1500021802002029d173c041df126218020021f
+:10d16000ffff18240900d814ffffc3249b6b400f56
+:10d170002120200207000010218002020600201357
+:10d1800021282002ffff632401001026fbff630417
+:10d190000000198221282002233011029804a78f51
+:10d1a000e804a48f9c04bf8f1000bfafe76e400f50
+:10d1b000000000003e0000109404ad8f9c04b18f6d
+:10d1c000000822320d0040109c04ab8ff004a58fa4
+:10d1d000fcff07240300b52424a0a7029404a88f11
+:10d1e00000008a8ec34f080004009026f004b0af00
+:10d1f000000048ad2c000010040049ad000272315f
+:10d200000b0040529c04a38ff004af8ffcff0e2450
+:10d210000300f32524306e020000cc8c9404ad8f03
+:10d220000400de24f004beaf1f00001000008dad2e
+:10d23000f004a48f000176300900c012030083249b
+:10d24000fcff022424f862000000f78f9404b88fda
+:10d250000400f927f004b9af130000100000f8a68d
+:10d260009c04aa8f8000513109002012fcff0c247d
+:10d27000fcff152424a075000000898e9404a88f5b
+:10d2800004009026f004b0af07000010000028a1b1
+:10d2900024586c000000678d9404a58f040072254b
+:10d2a000f004b2af0000e5ac211000009404ad8f93
+:10d2b0002118a201d4fa00109404a3afe804ae8fa1
+:10d2c0009404be8f1000d395ffff03244000663204
+:10d2d0000a18c603e404bf8fe004be8fdc04b78fd6
+:10d2e000d804b68fd404b58fd004b48fcc04b38fd8
+:10d2f000c804b28fc404b18fc004b08f2110600085
+:10d300000800e003e804bd2700a0063ce8ffbd27b5
+:10d310001c01c28c1000bfaf211880000400448c97
+:10d320002130a0006d6f400f212860001000bf8fda
+:10d330000800e0031800bd270800e003ffff0224f7
+:10d340000800e003211080000800e0032110000025
+:10d350000800e003211000000800e003010002249f
+:10d36000e0ffbd271400b1af1000b0af1800bfaf91
+:10d370001800a38c2180a0001000628c21888000fe
+:10d380002120a00009f840000100052419004010e8
+:10d39000ffff03240000078e0a00283affffe6245f
+:10d3a00021202002212800020100032d0600c004d4
+:10d3b000000006ae10000b96c0006a7d24484301b1
+:10d3c000070020112130200218000c8e0400908ddf
+:10d3d00009f80002000000000500001021304000a4
+:10d3e0000400058e0100a4240000b1a0040004aed6
+:10d3f0002118c0001800bf8f1400b18f1000b08f2b
+:10d40000211060000800e0032000bd27e8ffbd27d1
+:10d410001000bfafd874400f000000001000bf8f95
+:10d420000800e0031800bd2700a0033ce8ffbd276b
+:10d430001c01628c1000bfafd874400f0400458cf3
+:10d440001000bf8f0800e0031800bd272024047cd3
+:10d4500080bf033c1062658c0002a27cfdff40107f
+:10d460000000000080bf033c206264ac0800e003c1
+:10d47000000000004050050042550a00c04a050067
+:10d48000427d040025482f01c042040000800e3c6c
+:10d4900025482e0140680700426d0d00c06207005c
+:10d4a000427d060025608f01c05a060025608e016e
+:10d4b0002470c501ffff4f25fe07e12d5600201007
+:10d4c00000000000ffffaf25fe07e12d6e002010d9
+:10d4d0000000000023384d014b00e0040000000074
+:10d4e00042400800c07f090025400f014248090062
+:10d4f00042580b00c07f0c0025586f0142600c00a1
+:10d500002b780b0123400b012b102f0123482f01f7
+:10d510002b782c012578e2010500e01123482c012d
+:10d5200021400b012b780b0121482c0121482f01b0
+:10d530002a780001214008012148290121482f01b2
+:10d54000ffffe724eeffe1040000000008002015c3
+:10d5500025500d0003000015000000000d00001014
+:10d5600000000a242548000100000824e0ff4a25a5
+:10d57000203827710700e010000000002350470109
+:10d58000223007000630c8000440e8000448e900e3
+:10d59000254826011400401d00000000010007245a
+:10d5a0002338ea002000e12c0500201400000000d0
+:10d5b0002540090000000924faff0015e0ffe724d8
+:10d5c0000800e01000000000253009000640e800d7
+:10d5d0000648e90020000f242338e7010430e60064
+:10d5e0002540060100000a24c2220800407d0900ef
+:10d5f00025208f0040280900022b0500007d0a002d
+:10d600002528af002528ae002510040025180500a8
+:10d610000800e003000000003b004015000000008f
+:10d620002a780001214008012148290121482f01c1
+:10d6300025782801a3ffe011000000000800201554
+:10d640000000000003000015000000009dff001016
+:10d6500000000a242548000100000824e0ff4a25b4
+:10d660002038277197ffe010000000002350470189
+:10d67000223007000630c8000440e8000448e900f2
+:10d6800090ff0010254826011b00a0150000000097
+:10d690002a78600121586b0121608c0121608f0183
+:10d6a00025788b011800e0110000000008008015ab
+:10d6b00000000000030060150000000085ff00105e
+:10d6c00000000d242560600100000b24e0ffad2563
+:10d6d000203887717fffe010000000002368a70159
+:10d6e000223007000630cb000458eb000460ec0049
+:10d6f00078ff00102560860140780c002578eb014a
+:10d70000c1ffe01100000000f8ff053cbeff001063
+:10d710000000042440380500423d0700ffffe924d3
+:10d72000fe07212d0c0020100000000002fce72461
+:10d730000f80013cffff21342428a100e03f013c81
+:10d740002528a1000000c7ac2510040025180500fd
+:10d750000800e003000000001300e01400000000d7
+:10d760004048050025482401f6ff20110000000074
+:10d770000080013c2440a1000100e724ffffe724d2
+:10d780002a488000212084002128a5002128a90002
+:10d790001000013c2b08a100f8ff2014000000003d
+:10d7a000e2ff00102528a800f8ff053c0000072430
+:10d7b000e4ff00102520070040480500424d090005
+:10d7c000ffff2c25fe07812d0f0020100000000018
+:10d7d00021482601ffff2c25fe07812d2100201066
+:10d7e000000000000f80013cffff21342428a1002d
+:10d7f000006509002528ac00251004002518050047
+:10d800000800e003000000000063050025608401bb
+:10d81000f9ff80110000000004002011000000004a
+:10d82000f8ff053cf4ff0010000004240100292546
+:10d830000080013c2450a100ffff29252a608000c0
+:10d84000212084002128a5002128ac001000013ce3
+:10d850002b08a100f8ff201400000000dcff0010de
+:10d860002528aa00c04205004265040025400c019d
+:10d87000c03a04000080013c254001010080013cc9
+:10d88000050020192428a100f07f013c2528a100d3
+:10d89000d9ff00100000042401000a24235049018c
+:10d8a0002000412d0700201400000000e0ff4a2165
+:10d8b0002b2007000d00081025380401f8ff001088
+:10d8c00000000834090040110000000022580a003e
+:10d8d00004206701045868010638470106404801e2
+:10d8e00002008010253867010200e7340004e724b5
+:10d8f0000004ec2c21400c01c262070001008c31b5
+:10d900002338ec00c22207004065080025208c0067
+:10d910004060080002630c00b7ff00102528ac002f
+:10d9200025380400254005000080013c2458a10052
+:10d9300040480500424d0900ffff2c25fe07812dc0
+:10d94000370020100000000033040a24235049014e
+:10d95000350041292f00201000000000200041293f
+:10d960000600201400000000e0ff4a250000042407
+:10d970000628450105000010042845010300401950
+:10d98000000000000620440104204401234005015a
+:10d990002338e4000000c4ac0400c5ac0800001546
+:10d9a0000b0029250300e014000000000d0000100a
+:10d9b000000009242540e00000000724e0ff29259d
+:10d9c000202004710700801000000000234824017b
+:10d9d00022500400065047010438870004408800a4
+:10d9e00025400a01c22207004065080025208c005e
+:10d9f00040280800022b0500006509002528ac001e
+:10da00002528ab0025100400251805000800e003b8
+:10da1000000000000400cbacfaff00100000c0ac16
+:10da2000fcff201100000000f8ff053c000004246a
+:10da30000000c4acf3ff00100400c5ac0080013c42
+:10da40002440a10040380500423d0700ff070124a3
+:10da50002a00e1100000000033040a2423384701a3
+:10da60002200e018000000003500e1280800201422
+:10da7000000000002a000015000000002550a4004e
+:10da800024004015000000002500001000000000e8
+:10da900005000015000000002b50040023200400a6
+:10daa000232805002328aa001f00ea3001000924ca
+:10dab00004484901234809002000e12804002014fb
+:10dac0000000000000000424020000102428a90027
+:10dad0002420890005000015000000002b500400e0
+:10dae00023200400232805002328aa002510040071
+:10daf000251805000800e0030000000000530500a1
+:10db0000255044010900401500000000f7ff0010f7
+:10db100000000000f03f053cf4ff0010000004246a
+:10db200025280800f1ff001000000424f8ff053c40
+:10db3000eeff0010000004240080013c2638e100c4
+:10db400040580500425d0b00c0520500427d0400b4
+:10db500025504f01c04a04000080083c2550480170
+:10db60004070070042750e00c06a0700427d060043
+:10db70002568af01c06206002568a801ffff6f2578
+:10db8000fe07e12d8d00201000000000ffffcf25d3
+:10db9000fe07e12dbb002010000000000080013cca
+:10dba0002428a10023406e012c0000110000000079
+:10dbb00015000019000000002000012d07002014ae
+:10dbc00000000000e0ff08212b300c0023000d10a6
+:10dbd0002560a601f8ff001000000d341f000011a1
+:10dbe000000000002220080004308c0004208d007a
+:10dbf00006600c0106680d011800c01025608c003d
+:10dc00001600001002008c3525580e002340080035
+:10dc10002000012d0700201400000000e0ff082173
+:10dc20002b3009000d000a1025484601f8ff0010ae
+:10dc300000000a3409000011000000002220080042
+:10dc40000430890004208a000648090106500a01b0
+:10dc50000200c01025488900020029352678a70057
+:10dc60001c00e0050000000021482c012b782c014d
+:10dc700021504d0121504f0102004d1100000000c4
+:10dc80002b784d013700e0110000000001002f311a
+:10dc90000200e0110000000002002935424809009e
+:10dca000c07f0a0025482f0142500a000080013c35
+:10dcb0002550410101006b25ff0701242900611552
+:10dcc00000000000f07f013c2528a1003700001073
+:10dcd000000004242b782c0123482c012b104f0129
+:10dce00023504f012b784d012578e2010700e01108
+:10dcf00023504d010080013c2628a1002b7809000b
+:10dd00002348090023500a0023504f010800401502
+:10dd10000000000003002015000000000d000010ae
+:10dd200000000b242550200100000924e0ff6b2592
+:10dd300020404871070000110000000023586801ce
+:10dd400022200800062089000448090104500a0125
+:10dd500025504401257849010200e015000000002b
+:10dd60000000052468006019000000000004292557
+:10dd700000042f2d21504f012b784f0121586f01a6
+:10dd8000c27a09000100ef3123482f01c2220900a5
+:10dd9000407d0a0025208f0040780a00027b0f009a
+:10dda0002528af00007d0b002528af0025100400ba
+:10ddb000251805000800e003000000002a78200173
+:10ddc0002148290121504a012300601521504f01ab
+:10ddd000257849011400e0110000000008004015fa
+:10dde00000000000030020150000000067ff001085
+:10ddf00000000b242550200100000924e0ff6b25c2
+:10de00002040487161ff00110000000023586801a4
+:10de100022200800062089000448090104500a0154
+:10de20005aff001025504401ff0701241500c111bd
+:10de3000000000002140e700257806010300e015fe
+:10de400000000000d9ffe0040000000025100600db
+:10de5000d8ff001025180700257849012700e01594
+:10de600000000000ff070124d0ffc11500000000e2
+:10de70002678a7002100e00500000000f3ff001055
+:10de8000000000002a78800121608c012168ad012a
+:10de90001700c0152168af012578ac01c3ffe01160
+:10dea000000000000800a01500000000030080151d
+:10deb0000000000039ff001000000e2425688001da
+:10dec00000000c24e0ffce252040a87133ff001194
+:10ded000000000002370c8012220080006208c00ea
+:10dee00004600c0104680d012cff00102568a401da
+:10def0002578ac01d5ffe01100000000f8ff053cdb
+:10df0000aaff0010000004240100082423400b0194
+:10df10002000012d0700201400000000e0ff082170
+:10df20002b3009000d000a1025484601f8ff0010ab
+:10df300000000a340900001100000000222008003f
+:10df40000430890004208a000648090106500a01ad
+:10df50000200c010254889000200293583ff001007
+:10df600000000b244050050042550a00c04a05003d
+:10df7000427d040025482f01c042040000800e3c71
+:10df800025482e0140680700426d0d00c062070061
+:10df9000427d060025608f01c05a060025608e0173
+:10dfa0002628a7002428ae00ffff4f25fe07e12dfd
+:10dfb0004700201000000000ffffaf25fe07e12d05
+:10dfc0006f0020100000000002fcaf2521504f011f
+:10dfd00019002c01123800001070000019000b010c
+:10dfe000122000001030000019002b011258000010
+:10dff000106800002130cb002b78cb002138ed00d9
+:10e000002138ef000200ed10000000002b78ed0039
+:10e010002170cf0119000c011240000010480000cf
+:10e020002130c8002b78c8002138e9002138ef00e2
+:10e030000200e910000000002b78e9002170cf01f8
+:10e04000257886000200e011000000000100e7349e
+:10e0500025480e0006002005254007002a7800010b
+:10e06000214008012148290121482f01ffff4a25ad
+:10e07000ffff4f25fe07e12d680020100000000083
+:10e080000004082500040f2d21482f012b782f01b3
+:10e0900021504f01c27a08000100ef3123400f01e7
+:10e0a000c2220800407d090025208f004078090029
+:10e0b000027b0f002528af00007d0a002528af0055
+:10e0c00025100400251805000800e00300000000ea
+:10e0d0002a78000121400801214829011c0040152f
+:10e0e00021482f01257828011400e01100000000cc
+:10e0f00008002015000000000300001500000000cb
+:10e10000adff001000000a2425480001000008248b
+:10e11000e0ff4a2520702e71a7ffc011000000000b
+:10e1200023504e0122380e000638e8000440c80192
+:10e130000448c901a0ff001025482701ff0701245a
+:10e140003300a11100000000ddff001000000000fe
+:10e15000257828012e00e015000000000500a0151c
+:10e160000000000040780c002578eb012800e01149
+:10e1700000000000ff0701242100a115000000009d
+:10e180002a78600121586b0121608c011900a015cb
+:10e1900021608f0125788b011400e0110000000040
+:10e1a000080080150000000003006015000000005a
+:10e1b00085ff001000000d242560600100000b2485
+:10e1c000e0ffad25203086717fffc0100000000009
+:10e1d0002368a601227006000670cb010458cb000c
+:10e1e0000460cc0078ff001025608e01b4ff0010a1
+:10e1f0000000042425788b010500e01500000000d4
+:10e20000f07f013c2528a100adff00100000042490
+:10e21000f8ff053caaff001000000424f8ff401d91
+:10e220000000000001000e242370ca012000c12d4f
+:10e230000700201400000000e0ffce212b30080072
+:10e240000d00091025402601f8ff001000000934d8
+:10e250000900c0110000000022380e000430e80060
+:10e260000438e9000640c8010648c9010200c01090
+:10e270002540e800020008350004082500040f2da1
+:10e2800021482f0183ff0010c257090040500500ac
+:10e2900042550a00c04a0500427d040025482f016e
+:10e2a000c042040000800e3c25482e014068070053
+:10e2b000426d0d00c0620700427d060025608f019f
+:10e2c000c05a060025608e012628a7002428ae002b
+:10e2d000ffff4f25fe07e12dcb00201000000000be
+:10e2e000ffffaf25fe07e12df40020100000000025
+:10e2f00023504d01ff034a2542400800c07f09001a
+:10e3000025400f0142480900023c0c00f401e000e6
+:10e310001b0027011270000010480000ffff86312b
+:10e320001900ce0012200000004c0900027c0800f9
+:10e3300025482f012b7824010600e01123482401f1
+:10e34000ffffce2521482c012b082c01fcff2010bb
+:10e3500000000000f401e0001b002701123800005b
+:10e36000104800001900c70012200000004c0900ee
+:10e37000ffff0f3125482f012b7824010600e01103
+:10e3800023482401ffffe72421482c012b082c01fe
+:10e39000fcff20100000000000740e002170c70177
+:10e3a0001900cb01123800001020000000000824e2
+:10e3b0002b780701234007012b102f0123482f0141
+:10e3c0002b7824012578e2010b00e0112348240179
+:10e3d000ffffce2521400b012b780b0121482c019a
+:10e3e00021482f0102002c11000000002b782c0185
+:10e3f000f7ffe0110000000006002c1500000000ef
+:10e4000025200b002548080000000d242a000010dc
+:10e4100025380d00023c0c00f401e0001b00270130
+:10e420001268000010480000ffff86311900cd007f
+:10e4300012200000004c0900027c080025482f0132
+:10e440002b7824010600e01123482401ffffad25ad
+:10e4500021482c012b082c01fcff2010000000009b
+:10e46000f401e0001b0027011238000010480000f2
+:10e470001900c70012200000004c0900ffff0f31f7
+:10e4800025482f012b7824010600e01123482401a0
+:10e49000ffffe72421482c012b082c01fcff201052
+:10e4a00000000000006c0d002168a7011900ab01fd
+:10e4b0001238000010200000000008242b7807010b
+:10e4c000234007012b102f0123482f012b78240113
+:10e4d0002578e2010b00e01123482401ffffad2560
+:10e4e00021400b012b780b0121482c0121482f01e1
+:10e4f00002002c11000000002b782c01f7ffe01126
+:10e50000000000000600c005000000002a78a001fd
+:10e510002168ad012170ce012170cf01ffff4a2596
+:10e52000257828010200e011000000000100ad354f
+:10e5300025480e0025400d00ffff4f25fe07e12d69
+:10e5400015002010000000000004082500040f2d15
+:10e5500021482f012b782f0121504f01c27a08004a
+:10e560000100ef3123400f01c2220800407d090065
+:10e5700025208f0040780900027b0f002528af007e
+:10e58000007d0a002528af0025100400251805008d
+:10e590000800e003000000004400401d00000000ef
+:10e5a00001000e242370ca012000c12d0700201491
+:10e5b00000000000e0ffce212b2008000d00091014
+:10e5c00025402401f8ff0010000009340900c011a3
+:10e5d0000000000022300e000420c8000430c900f2
+:10e5e0000640c8010648c901020080102540c80045
+:10e5f000020008350004082500040f2d21482f01d2
+:10e60000d6ff0010c25709002a78000121400801f6
+:10e61000214829011700401521482f01257828019c
+:10e620001400e011000000000800201500000000a8
+:10e63000030000150000000029ff001000000a245c
+:10e640002548000100000824e0ff4a2520702e71b3
+:10e6500023ffc0110000000023504e0122300e00a5
+:10e660000630c8000440c8010448c9011cff00105e
+:10e670002548260105004d150000000040780c00db
+:10e680002578eb012b00e01100000000ff070124ba
+:10e690000a00a11100000000bbff401100000000b3
+:10e6a000257828012300e01500000000f07f013ce0
+:10e6b0002528a100b4ff0010000004242a7860017e
+:10e6c00021586b0121608c011700a01521608f017a
+:10e6d00025788b01f5ffe01100000000080080158f
+:10e6e00000000000030060150000000000ff0010a3
+:10e6f00000000d242560600100000b24e0ffad2523
+:10e7000020708e71fafec011000000002368ae0177
+:10e7100022300e000630cb000458cb010460cc013f
+:10e72000f3fe00102560860125788b010200e011c0
+:10e7300000000000f8ff053c93ff001000000424d7
+:10e740000000052425480500253805002530040073
+:10e750000c00c010000000000600c1040000000012
+:10e760000080093c2b5005002328050023300600bb
+:10e770002330ca001e0407242040c8702338e80054
+:10e7800004300601c24205004055060025400a013a
+:10e790004050060002530a0025482a010055070090
+:10e7a00025482a0125100800251809000800e00363
+:10e7b0000000000000000524253805002530040075
+:10e7c0000500c010000000001e0407242048c97086
+:10e7d0002338e90004302601c242050040550600f6
+:10e7e00025400a0140480600024b09000055070079
+:10e7f00025482a0125100800251809000800e00313
+:10e8000000000000c23d0400ff00e7300080013c32
+:10e8100024308100ffffe924fe00212d0c00201090
+:10e82000000000008003e724404a0400024b090076
+:10e830002530c900402f0400004d07002530c900d5
+:10e8400025100500251806000800e0030000000060
+:10e850000000052421208400f7ff80100000000044
+:10e860000900e01400000000ffffe72421208400dd
+:10e870008000013c2b088100fbff201400000000f9
+:10e88000e8ff001000000000ff07072400ff013c24
+:10e89000010021342b088100e7ff20140000000054
+:10e8a000e5ff0010f8ff063cc03a0500425d040099
+:10e8b0002538eb00c03204000080013c2538e1001f
+:10e8c0000080013c2448a10040400500424508006a
+:10e8d00080fc0825ffff0b25fe00612d1100201094
+:10e8e000000000000200c010000000000100e7343a
+:10e8f0008000e7248000eb2c21400b01025a070026
+:10e9000001006b312338eb0040380700423a070022
+:10e91000c05d08002538eb002510e9000800e00381
+:10e92000000000007f040124070001150000000022
+:10e9300040580700255866010300601100000000e0
+:10e94000f6ff0010c0ff023cff0001290400201464
+:10e9500000000000807f013cf0ff00102510210125
+:10e9600001000a24235048012000412d03002014f7
+:10e9700000000000e9ff00102510090020000c2411
+:10e9800023608a01045887012530cb0006384701ef
+:10e99000000008240080013cd2ff00102538e1006f
+:10e9a000c03a0500425504002538ea000080013cc9
+:10e9b0002538e1004050050042550a001e04062497
+:10e9c0002330ca000b00c018000000002000c12c3a
+:10e9d0000200201400000000000007340200a1041f
+:10e9e0000638c70023380700251007000800e00399
+:10e9f0000000000002008010000000000100a534ab
+:10ea0000f07f013c010021342b08a10003002014f9
+:10ea100000000000f5ff00100080023cff7f023c78
+:10ea2000f2ff0010ffff4234c03a050042550400d7
+:10ea30002538ea000080013c2538e10040500500ff
+:10ea400042550a001e0406242330ca000b00c004ed
+:10ea5000000000002000c12c020020140000000073
+:10ea6000000007340200a1040638c700233807005d
+:10ea7000251007000800e0030000000002008010dd
+:10ea8000000000000100a534f07f013c01002134aa
+:10ea90002b08a1000300201400000000f5ff001067
+:10eaa0000080023cf3ff0010ffff0224feff092458
+:10eab000405005004058070025586401255866015c
+:10eac00025504b0103004015000000003c000010e1
+:10ead00000000224020080104040050001000825cb
+:10eae000e0ff013c010021342b0801013600201019
+:10eaf000000000000200c01040400700010008258f
+:10eb0000e0ff013c010021342b0801012e00201000
+:10eb1000000000001600a104000000000300e00453
+:10eb20000000000026000010ffff02242b5086008a
+:10eb3000232086002b58aa002328aa002b50a700c8
+:10eb400025504b01030040112328a7001c00001092
+:10eb5000010002242550a400030040110000000021
+:10eb600017000010ffff022415000010000002240f
+:10eb70000300e10400000000110000100100022465
+:10eb80002b508600232086002b58aa002328aa0099
+:10eb90002b50a70025504b01030040112328a7004c
+:10eba00007000010ffff02242550a40003004011bd
+:10ebb00000000000020000100100022400000224f6
+:10ebc0000800e00300000000fdff00102510090010
+:10ebd0000080013c2628a10025100400251805000e
+:10ebe0000800e00300000000ff7f013cffff21342c
+:10ebf0002428a10025100400251805000800e003c2
+:10ec000000000000020080104040050001000825bf
+:10ec1000e0ff013c010021342b0801010300201416
+:10ec2000000000000c000010010002240200c010cf
+:10ec30004040070001000825e0ff013c01002134ad
+:10ec40002b08010103002014000000000200001046
+:10ec500001000224000002240800e003000000007c
+:10ec60000080013c2628a100c24d0400ff0029318c
+:10ec7000c25d0500ff006b310080073c00420400cc
+:10ec8000254007010052050025504701ffff2d25b3
+:10ec9000fe00a12d6100201000000000ffff6d2587
+:10eca000fe00a12d770020100000000023602b0142
+:10ecb0000d008005000000002000812903002014c1
+:10ecc000000000001500001002000a2425300a0090
+:10ecd00006508a0104688a011000a6110000000095
+:10ece0000e00001002004a3525480b0023600c007e
+:10ecf00020008129030020140000000007000010fc
+:10ed000002000824253008000640880104688801b4
+:10ed10000200a611000000000200083524608700f0
+:10ed2000266885011000a0050000000021400a01ae
+:10ed30002b680a011700a0110000000001000d312e
+:10ed40000200a01100000000020008354240080047
+:10ed500001002925ff0001240e00211500000000fc
+:10ed60000c000010000008242b680a010400a01108
+:10ed700023400a0123400800030000102660870199
+:10ed800050000011000000002030067123482601c9
+:10ed90000440c8000e002019000000008000082573
+:10eda00080000d2d21482d01026a08000100ad31bf
+:10edb00023400d014040080042420800c06d090098
+:10edc00025400d0125100c010800e00300000000a3
+:10edd000010006242330c9002000c12c3900201076
+:10ede000000000000080013c2540010120000d24ae
+:10edf0002368a6010448a801020020110640c800ab
+:10ee0000010008350000092480000d25e3ffa1055d
+:10ee100000000000e1ff0010010009240e00201591
+:10ee20000000000021400801050000110000000062
+:10ee300020600c7123482c0198ff001004408801c9
+:10ee4000ff0001240f006111000000000080013c60
+:10ee50001800a11400000000216808011b00a01583
+:10ee600000000000ff0001241400611500000000f4
+:10ee7000266885001500a005000000000d000010a8
+:10ee800000000000080060150000000021504a0149
+:10ee90000a0040110000000020604c7123586c01f2
+:10eea00082ff001004508a0121684a010700a01562
+:10eeb00000000000c4ff001025100500c2ff001074
+:10eec00025100400c0ff001000000224beff001047
+:10eed000c0ff023cc23d0400ff00e730c24d050008
+:10eee000ff00293100800a3c003204002530ca00ae
+:10eef0000042050025400a012660850024504c018f
+:10ef0000ffffec24fe00812d2100201000000000f6
+:10ef1000ffff2c25fe00812d360020100000000090
+:10ef20001900c800125800000200601110300000e3
+:10ef30000100c6340300c004000000004030060099
+:10ef4000ffffe72482ff2c252138ec00ffffec2493
+:10ef5000fe00812d3a002010000000008000c62431
+:10ef60008000cc2c2138ec000262060001008c31bc
+:10ef70002330cc004030060042320600c065070056
+:10ef80002530cc002510ca000800e0030000000076
+:10ef90000d00e014000000002130c6000500c01084
+:10efa000000000002058cb702338eb00d8ff001081
+:10efb00004306601ff0001241f0021110000000041
+:10efc00015000010000000002160c6001a00801526
+:10efd000000000000400201500000000216008016e
+:10efe0001500801100000000ff0001240f00211512
+:10eff000000000000a002015000000002140080168
+:10f00000050000110000000020580b7123482b015f
+:10f01000c3ff001004406801dbff001025100a0048
+:10f02000216008010400801500000000807f013c81
+:10f03000d5ff001025104101d3ff0010c0ff023c96
+:10f04000faffe01c0000000001000b2423586701b8
+:10f050002000612df0ff20100000000020000c2493
+:10f0600023608b01043886010200e010063066013f
+:10f070000200c634000007248000cc24b7ff8105bd
+:10f0800000000000b5ff00100100072400800b3cc9
+:10f09000c2450400ff000831c2550500ff004a3197
+:10f0a000003a04002538eb00004a050025482b01f2
+:10f0b0002670850024586e01ffff0e25fe00c12d2d
+:10f0c0003f00201000000000ffff4e25fe00c12d74
+:10f0d00053002010000000002b08e900030020145a
+:10f0e0000000000042380700010008258263090083
+:10f0f000f40180011b00ec00122000001030000021
+:10f10000ff3f2d311900a4011228000080330600b2
+:10f110002b70c5000400c0112330c500ffff8424fc
+:10f120002130c9002b70c900f40180011b00cc0004
+:10f1300012380000103000001900a701122800004a
+:10f14000803306002b70c5000400c0112330c500b9
+:10f15000ffffe7242130c9002b70c9008073040031
+:10f160002138ee000200c010003907000100e7342a
+:10f170007e000e242370ca0121400e01ffff0e25e0
+:10f18000fe00c12d34002010000000008000e724a4
+:10f190008000ee2c21400e01027207000100ce31ea
+:10f1a0002338ee0040380700423a0700c0750800d7
+:10f1b0002538ee002510eb000800e00300000000f9
+:10f1c00008000015000000002138e7000500e010ed
+:10f1d000000000002060ec7023400c01baff00101a
+:10f1e000043887010400481500000000217029013f
+:10f1f0002f00c01100000000ff0001240800411191
+:10f200000000000012000011000000002170e70063
+:10f210002700c015000000002200001000000000c0
+:10f220000800401500000000214829011d002011a0
+:10f230000000000020602c7123504c01a6ff00103c
+:10f2400004488901217029011900c015000000003f
+:10f25000d9ff001025100b001200001d0000000057
+:10f2600001000c24236088012000812df8ff20106c
+:10f270000000000020000e242370cc010440c701d0
+:10f2800002000011063887010200e734000008245c
+:10f290008000ee24bdffc10500000000bbff001090
+:10f2a00001000824807f013cc3ff0010251061018c
+:10f2b000c1ff0010c0ff023c0080013c1200801022
+:10f2c000243081000200810400000000232004009b
+:10f2d0009e000524203887702328a7000420e4001e
+:10f2e000800084248000882c2128a8000342040088
+:10f2f000010008312320880040200400422204003d
+:10f30000c045050025208800251086000800e00380
+:10f31000000000000f008010000000009e00062486
+:10f32000202885702330c5000420a4008000842498
+:10f330008000872c2130c700023a04000100e7302a
+:10f34000232087004020040042220400c03d060024
+:10f3500025208700251004000800e00300000000bd
+:10f36000002a04000080013c2528a100c23d0400c1
+:10f37000ff00e7309e0006242330c7000c00c018b1
+:10f38000000000002000c12803002014000000003d
+:10f390000500001000000224020081040628c500b8
+:10f3a00023280500251005000800e00300000000e8
+:10f3b000807f013c010021342b08810003002014d0
+:10f3c00000000000f8ff00100080023cff7f023cbc
+:10f3d000f5ff0010ffff4234002a04000080013cca
+:10f3e0002528a100c23d0400ff00e7309e0006244e
+:10f3f0002330c7000c00c004000000002000c1281a
+:10f40000030020140000000005000010000002248a
+:10f41000020081040628c5002328050025100500e8
+:10f420000800e00300000000807f013c010021345f
+:10f430002b0881000300201400000000f8ff0010da
+:10f440000080023cf6ff0010ffff0224feff0824ac
+:10f4500040300400403805002548c7001b0020113b
+:10f460000000000000ff013c010021342b08c10016
+:10f47000190020100000000000ff013c01002134b1
+:10f480002b08e1001400201000000000020081049d
+:10f4900042300600233006000200a1044238070073
+:10f4a000233807002a08c7000300201000000000ce
+:10f4b00007000010ffff02242a08e60003002010c6
+:10f4c00000000000020000100100022400000224dd
+:10f4d0000800e00300000000fdff001025100800f8
+:10f4e00040100400421002000800e0030000000089
+:10f4f0000080013c261081000800e00300000000ad
+:10f500004030040000ff013c010021342b08c10001
+:10f5100003002014000000000a0000100100022473
+:10f520004030050000ff013c010021342b08c100e0
+:10f53000030020140000000002000010010002245b
+:10f54000000002240800e00300000000b8ffbd270f
+:10f550004800a4af4000beaf3400b5af3000b4af38
+:10f560002c00b3af4400bfaf3c00b7af3800b6af1c
+:10f570002800b2af2400b1af2000b0af00008880f7
+:10f58000029d063cad1ac4242110040100004780ee
+:10f590004800b38f8800e3304c00a5af1000a0af47
+:10f5a0001400a0af21f000001800a0af21a00000bf
+:10f5b0000800601021a80000010073260000688286
+:10f5c000215004010000498188002531fbffa0542f
+:10f5d000010073262d000424d40004112b000c24f8
+:10f5e000d7000c5101007326ad1ad72421701701e2
+:10f5f0000000cd910400a6311b00c01001000f24b3
+:10f60000029d163c1800afafc81cc68ecc1cc78e1e
+:10f61000d0ff12252128a002d977400f2120800297
+:10f620002120400221a84000d079400f21a0600095
+:10f63000213040002120a0022128800221386000d2
+:10f64000d076400f010073260000688225f0d203b7
+:10f65000219017010000519221a040000400303297
+:10f66000e9ff001621a860002e0016248a0016511a
+:10f67000010073261800a48f280080104c00a48f6e
+:10f680004500063965000d390100ab2d0100cc2c79
+:10f6900025406c01210000114c00a48f010073264d
+:10f6a000000064822d000e2421280000af008e107f
+:10f6b000213800002b000f24a3008f500100732677
+:10f6c00021c09700000016930400d7320d00e0120d
+:10f6d000029d193cad1a2627809005002150450255
+:10f6e00040280a00010073262148a400000064821b
+:10f6f000211886000000629004005f30f6ffe017da
+:10f70000d0ff25251400b18f238005000b280702a8
+:10f71000213825021400a7af4c00a48f05008010eb
+:10f720004800ab8f1800ac8f4c00a88f0a986c0172
+:10f73000000013ad1400a28f28004010029d1f3c52
+:10f74000c39f0200029d0f3c26705300029d0d3c9a
+:10f75000681de68d6c1de78d2390d30121b040001c
+:10f76000181db32503000010090003241000001227
+:10f7700021180002ffff702407c01202c0c8030056
+:10f7800001001733214033032120c000f7ffe012ae
+:10f790002128e0000000068dd977400f0400078d76
+:10f7a0002138600021304000f2ff001621180002cd
+:10f7b0006a00c00621208002d977400f2128a002cc
+:10f7c0002120400021286000647e400f2130c002cb
+:10f7d00021a0400021a86000029d1f3c741df68fef
+:10f7e000040080162438b602f07f023c5800e21074
+:10f7f00022000324259095020100452e2b501e0067
+:10f800002448aa005d002055220015241000a78f6f
+:10f810000e00e014211080022118a0024400bf8fc6
+:10f820004000be8f3c00b78f3800b68f3400b58fd4
+:10f830003000b48f2c00b38f2800b28f2400b18f1a
+:10f840002000b08f0800e0034800bd27212080027f
+:10f85000f47a400f2128a00221a0400021a86000d6
+:10f86000211080022118a0024400bf8f4000be8feb
+:10f870003c00b78f3800b68f3400b58f3000b48f9e
+:10f880002c00b38f2800b28f2400b18f2000b08fde
+:10f890000800e0034800bd270000688221f8170136
+:10f8a0000000f9930400383372ff0013029d163ce8
+:10f8b000010003241800a3afc81cc68ecc1cc78e41
+:10f8c000d0ff12252128a002d977400f21208002e5
+:10f8d0002120400221804000d079400f2188600023
+:10f8e0002138600021282002212000022130400020
+:10f8f000d076400f01007326000068821400a98fa3
+:10f900002150170121a0400000004291ffff252552
+:10f910000400473021a8600025f0d203e6ffe01480
+:10f920001400a5af57ff00104500063901007326eb
+:10f930000000688201000b242bff00101000abaf09
+:10f9400029ff0010000068825dff00100000648243
+:10f9500000a01e3cadff00100402c3afa378400f0f
+:10f960002128a00297ff00102120400001007326eb
+:10f970000000648252ff00100100072400a0143c24
+:10f98000040295ae21a00000a0ff001021a80000f5
+:10f990000055a77cffffe324fe07622c2140800076
+:10f9a0002150c000c007ab7c3f0040100098a97cec
+:10f9b000029d043c7c1d858c01fce424253025013e
+:10f9c0002148c00021788a00c04809004257080039
+:10f9d000ff03e72525482a014100e018c040080040
+:10f9e000070006311d00c014c000057d40670900f6
+:10f9f000c2300800ff07e4282540cc003100801009
+:10fa0000c2480900029d033c7c1d798c21780000ce
+:10fa100024c039012550f801070040512138000069
+:10fa200021100001029d083c8c1d058d21404000e5
+:10fa3000247025012148c001c06a0b002520a701c0
+:10fa40000035040021600000252088012528c90018
+:10fa5000211080000800e0032118a0000300a22468
+:10fa60002118000021400201029d183c2bc8020110
+:10fa700021482301841d0f8f21483901216800008e
+:10fa800024502f012560aa01d9ff80114067090089
+:10fa9000c07709004240080025400e014248090095
+:10faa000d2ff00100100e7240400e01421108000c0
+:10fab000253889002900e014026809000800e003e5
+:10fac0002118a000c06a0b00ff07a735002d070012
+:10fad00021200000211080000800e0032118a00070
+:10fae00001001924233027033800d82818000053b8
+:10faf00001000824232806002000a2302718c00097
+:10fb00000660c800041869000668c90040180300b0
+:10fb1000256083012000c3300b60a3010b68030044
+:10fb200021500001040040140418a8000218090024
+:10fb30000440a300251848012b20030021280000c1
+:10fb4000254084012548a501a5ff00102138e600c5
+:10fb500021480000a2ff00102138e60002fc042426
+:10fb60000300a0152018a37120700e712000c3257a
+:10fb7000f5ff632494ff601021788a00271060004d
+:10fb80000438690006104800043068004210020082
+:10fb90002538e200200062300b38c2000b30020032
+:10fba000232083002140c00086ff00102148e00090
+:10fbb00080bf033c105a648c0000827cfdff401023
+:10fbc0000000000080bf033c205a628c0800e00364
+:10fbd000000000001f008f30029d0e3c80600f006f
+:10fbe000901dcd2521308d0100c00b3c0220093c29
+:10fbf000e01f6a3500e028350000c38c2438a800d7
+:10fc000024208a0080bf023c8001a57c252087003b
+:10fc1000305a43ac0500a01480bf053c40001924b5
+:10fc200080bf183c145a19af80bf053c005aa4ace1
+:10fc30000800e003000000000800e00300606241eb
+:10fc4000e8ffbd271000bfaf006805408000063cfc
+:10fc50002520a600006884400010032488bf023cd1
+:10fc6000247f400f081043ac1000bf8f0800e00352
+:10fc70001800bd2701008430030080100000000040
+:10fc80000800e003206060410800e003006060417c
+:10fc90000800e003206062412118e0002140a0003c
+:10fca0002138c0003a006014216080002b10a600ab
+:10fcb0008c004010000000002030c670c200c0144c
+:10fcc00023280600023407001b000601f401c000cf
+:10fcd000ffffeb3002740c001248000010c000005f
+:10fce0001250000002482b71007c18002528ee01fc
+:10fcf0002b68a9001b000601f401c0000900a051f7
+:10fd00002320a9002128a7002b40a70004000015ec
+:10fd1000ffff4a252bc8a900fc002057ffff4a25fa
+:10fd20002320a9001b008600f401c000ffff8331df
+:10fd30001268000010280000124800000258ab7141
+:10fd400000140500254043002b600b011b008600ba
+:10fd5000f401c00009008051005c0a002140070145
+:10fd60002b3007010400c014ffffa9252b700b01e5
+:10fd70002b380e0023482701005c0a00252069016a
+:10fd800021300000211080000800e0032118c0008d
+:10fd90002b58a30021200000faff6015213000003d
+:10fda000204869708e0020112b10870120000d243f
+:10fdb0002370a901045023010678c70125684f016b
+:10fdc00006c8c50102540d001b002a03f4014001be
+:10fdd00006c0cc0104282501ffffaf312570b80013
+:10fde00004c02c01021c0e00043827011220000060
+:10fdf000105800001260000002408f70004c0b0091
+:10fe0000255823012b3068011b002a03f40140010f
+:10fe10000b00c0502318680121586d012b106d0193
+:10fe200006004014ffff8c242b3068010400c01032
+:10fe300023186801ffff8c2521586d0123186801e4
+:10fe40001b006a00f4014001ffffcb3112480000a3
+:10fe5000104000001230000002482f7100240800fa
+:10fe600025408b002bc809011b006a00f4014001ea
+:10fe70000b002053007c0c0021400d012b280d01ac
+:10fe80000600a014ffffc6242b7009010400c01156
+:10fe9000007c0c0021400d01ffffc624007c0c00fb
+:10fea0002520e60119008700102800002318090109
+:10feb0002b60650009008055ffff842412100000ac
+:10fec0002668a3002b5002030100b82d24380a0332
+:10fed000acffe05021300000ffff8424a9ff001098
+:10fee000213000004500c01001000a242050ea70b3
+:10fef0004900401520000924232807010100062499
+:10ff0000024c0700ffffed301b00a900f4012001a7
+:10ff100002cc0c0012500000101800001258000013
+:10ff200002504d7100240300254099002b700a01f6
+:10ff30001b00a900f40120010900c01123780a0167
+:10ff4000214007012b2807010400a014ffff6b25a7
+:10ff50002b100a016b004054ffff6b2523780a0128
+:10ff60001b00e901f4012001ffff983112c80000d5
+:10ff7000104000001250000002602d730074080051
+:10ff80002540d8012b680c011b00e901f401200178
+:10ff90000900a011001c0b00214007012b4807019c
+:10ffa00005002015ffff2a272b380c012b600700c6
+:10ffb00023504c01001c0b0025206a0021108000fa
+:10ffc0000800e0032118c0000620a4000418c8009f
+:10ffd000254064000460cc003aff00100438c700dc
+:10ffe0002b20650001004538255085002b200a0094
+:10fff000211080000800e0032118c0001b0046010a
+:020000041d02db
+:10000000f401c000123800002050ea70bbff40111c
+:10001000232807012000092423782a0104384701f6
+:1000200006c8e801024c07001b002903f401200167
+:100030000670ec0104104801ffffed3025784e00fa
+:1000400002240f001230000010280000127000007f
+:100050000240cd70001c0500255864002bc06801cb
+:100060001b002903f40120010a00001304604c0165
+:10007000215867012b50670106004015ffffce2471
+:100080002bc068010400001323c86801ffffce25c0
+:100090002158670123c868011b002903f4012001ce
+:1000a000ffffe43112280000104000001230000071
+:1000b0000250ad70001c0800254064002b580a0156
+:1000c0001b002903f40120010b00601100c40e0085
+:1000d000214007012b10070107004014ffffa62451
+:1000e0002b780a010500e05125300603ffffc624e6
+:1000f0002140070100c40e002530060382ff0010d6
+:1001000023280a0195ff00102140070104ff001079
+:100110002128a700e8ffbd272140e0001000b2af72
+:100120000c00b1af0800b0af2190a0032150c00077
+:1001300021588000400000152138a0002b10a60097
+:100140005c0040102070ce707900c01523280e008e
+:10015000024c0a001b00e900f4012001ffff4f31af
+:1001600002640b00128000001030000002280f72a1
+:10017000006c06002530ac012b40c5001b00e900d7
+:10018000f40120010a0000112318c5002130ca0023
+:100190002b38ca000600e0142318c5002bc8c50080
+:1001a0000000383b2188ca000b3038022318c500f4
+:1001b0001b006900f4012001ffff713112c800002b
+:1001c00010c0000002582f73007c18002540f10178
+:1001d0002b380b011b006900f40120010a00e0101c
+:1001e00023180b0121400a012b480a0106002015a3
+:1001f00023180b012b100b0121200a0100004a38a3
+:100200000b408a0023180b010660c3010300401253
+:100210002168000000004cae04004dae0000a28f2b
+:100220000400a38f1000b28f0c00b18f0800b08fb4
+:100230000800e0031800bd272b70a8000a00c05179
+:1002400020700e711000b28f0c00b18f0800b08fbb
+:10025000211080002118a0000000a4af0400a5af69
+:100260000800e0031800bd273700c01520000f2448
+:100270002b6886000100ac392b3005012528cc0005
+:100280000700a0102160600123808a002388e80015
+:100290002b40900023382802215800022160600181
+:1002a000deff40122168e00000004caedbff0010d2
+:1002b00004004dae7e00c0100100092420704e7174
+:1002c0008200c01520000f242330ea00024c0a00ef
+:1002d000ffff4f311b00c900f401200102240b0075
+:1002e000124000001028000002380f71001c0500a9
+:1002f000252864002b10a7001b00c900f401200171
+:10030000abff40102318a7002128aa002b30aa0019
+:10031000a7ffc0542318a7002b80a70000000d3aa8
+:100320002160aa000b288d01a1ff00102318a7004f
+:100330000620a4000418c701253864000450c60133
+:1003400083ff00100458cb0123c0ee010448c8010c
+:1003500006c806032578390106200503024c0f0064
+:100360001b008900f401200106380b030468c50155
+:10037000fffff13125c8a7010480cb010438ca0171
+:10038000021c19001230000010600000125800001a
+:100390000250d170002c0c002540a3002b100a0144
+:1003a0001b008900f40120010b00405023180a01b2
+:1003b00021400f012b100f0106004014ffffcb243a
+:1003c0002b200a010400801023180a01ffff6b256f
+:1003d00021400f0123180a011b006900f4012001cc
+:1003e000ffff2533125000001040000012300000c3
+:1003f0000250517100640800254085012b880a01d4
+:100400001b006900f40120010b00201200140b00f6
+:1004100021400f012b680f010700a015ffffc62424
+:100420002bc80a010500201325484600ffffc624fb
+:1004300021400f0100140b00254846001900270138
+:100440001030000023400a012b58060107006015f8
+:10045000122800002660c8000100912d2b1805020b
+:100460002420230206008010000000002350a70073
+:100470002b38aa002368cf002330a7012128400190
+:1004800066ff401223780502232806012b400f0245
+:100490002380a8000430100306c0cf012560d800d7
+:1004a0000668d00100004cae5cff001004004daea9
+:1004b0001b002601f401c0001250000020704e7194
+:1004c00082ffc0112330ea0020000f242380ee01b8
+:1004d0000450ca0106200702024c0a001b008900d2
+:1004e000f401200106680b020430c701ffff4f3101
+:1004f0002538cd00021c07001260000010400000eb
+:1005000002308f71002c08002540a3002b1006013b
+:100510001b008900f4012001050040100458cb01a4
+:1005200021400a012b880a01190020122b10060114
+:10053000231806011b006900f4012001ffffe530cc
+:1005400012680000106000000238af7100440c0017
+:10055000253005012b20c7001b006900f401200194
+:100560005cff80502330c7002130ca002b80ca00b6
+:1005700058ff00562330c7002bc8c7000000383b87
+:100580002188ca000b30380252ff00102330c70008
+:100590000000593821c00a01e5ff00100b40190383
+:020000040000fa
+:020000041d02db
+:1005a00000040000ff030000fe030000fc03000045
+:1005b000fa030000f7030000f2030000ec03000060
+:1005c000e3030000d8030000c9030000b6030000e5
+:1005d0009f03000083030000610300003b03000051
+:1005e00010030000e1020000af0200007b020000e7
+:1005f0004702000013020000e0010000b10100000a
+:10060000840100005a0100003501000013010000c0
+:10061000f4000000d9000000c1000000000000004c
+:1006200000000000389c2c41000000000000394010
+:10063000000080bf00c0794400c07944000080bf42
+:10064000000020410000000000000000389c2c4108
+:1006500000000000000039402cc4009d54c6009ddd
+:1006600054c6009d54c6009d54c6009d54c6009dae
+:1006700054c6009d54c6009d54c6009d54c6009d9e
+:1006800054c6009d54c6009d54c6009d54c6009d8e
+:1006900054c6009d54c6009d54c6009decc5009de7
+:1006a00054c6009d54c6009d54c6009d54c6009d6e
+:1006b00040c3009d54c6009d54c6009d54c6009d75
+:1006c00054c6009d54c6009d54c6009d54c6009d4e
+:1006d00054c6009d54c6009d2cc4009d54c6009d68
+:1006e00054c6009d54c6009d54c6009d54c6009d2e
+:1006f00054c6009d54c6009d54c6009d54c6009d1e
+:1007000054c6009d54c6009d54c6009d54c6009d0d
+:1007100054c6009d54c6009d54c6009decc5009d66
+:1007200054c6009d54c6009d54c6009d54c6009ded
+:1007300040c3009d2e2e00002020202020202020bd
+:1007400020202000000000000095000000000000b4
+:100750000000000001f9000000000000000000009f
+:1007600009af000000000000010000000a1b0000ab
+:1007700000000000010000000cc3000000000000a9
+:10078000000000000daf00000200000000000000ab
+:1007900010ff0000000000000000000011ff00003a
+:1007a000000000000100000012ff00000000000037
+:1007b0000100000018ff0000000000000100000020
+:1007c00019ff0000000000000100000020ff0000f1
+:1007d000000000000000000021ff000000000000f9
+:1007e0000000000026df0000010000000000000003
+:1007f0003773000000000000000000003a250000f0
+:1008000003000000000000003b2500000000000085
+:100810000000000054454d5045524154555245206a
+:100820004348414e47450000000000000000000022
+:1008300000000000000000000000000000000000b8
+:1008400000000000000000000000000000000000a8
+:100850000000000000000000000000000000000098
+:10086000e0e0606060ffff6363e3e3030303ffff17
+:100870000000000000000000000000000000000078
+:100880000000000000000000000000000000000068
+:100890000000000000000000000000000000000058
+:1008a0000000000000000000000000000000000048
+:1008b0000000000000000000000000000000000038
+:1008c0000000000000000000000000000000000028
+:1008d0000000000000000000000000000000000018
+:1008e000ffffc0c0c0c7c7c6c6ffff060606070792
+:1008f00000000000000000000000000000000000f8
+:1009000000000000000000000000000000000000e7
+:1009100000000000000000000000000000000000d7
+:1009200000000000000000000000000000000000c7
+:1009300000000000000000000000000000000000b7
+:1009400000000000000000000000000000000000a7
+:100950000000000000000000000000000000000097
+:100960000000000000000000000000000000000087
+:100970000000000000000000000000000000000077
+:100980000000000000000000000000000000000067
+:100990000000000000000000000000000000000057
+:1009a000000000000000000000000040c0c0c0c007
+:1009b000c0c0c0c0c0c0c0c0c0c0c0c08080000037
+:1009c0000000000000000000000000000000000027
+:1009d0000000000000000000000000000000000017
+:1009e00000000000000040c0c0c0c0c0c0c0c08047
+:1009f000000000000080c0c0c0c0c0c0c0c0400037
+:100a000000000000000000000000000000000000e6
+:100a100000000000000000000000000000000000d6
+:100a2000000000000000000000000000ffffffffca
+:100a3000ffffff7171f1f1ffffffffff7f3f00003c
+:100a4000009c9c9c9c9c9c9c9c9cfcfcfcfcfcf846
+:100a5000f0000004fcfcfcfcfcfcf81c1c1cfcfc76
+:100a6000fcfcfcf8f00000ffffff0f7fffffffff23
+:100a7000fce000e0fc3f07ffffffffffffff00007f
+:100a800000009c9c9c9c9c9c9c9c9cfcfcfcfcfcfe
+:100a9000f8f0000000fcfcfcfcfcfcf81c1c1cfc3e
+:100aa000fcfcfcfcf8f00000000000407f7f7f7f32
+:100ab0007f7f7f400000073f7f7f7f7f7c7040000b
+:100ac0003f7f7f7f7f7f7f7171717f7f7f7f7f7fa0
+:100ad0007f400000ffffffffffffff7070707f7f10
+:100ae0007f7f7f7f3f00407f7f7f0000031f7f7fee
+:100af0007f7f7f0f0100407f7f7f7f7f7f7f400070
+:100b0000003f7f7f7f7f7f7f7171717f7f7f7f7fde
+:100b10007f7f4000407f7f7f7f7f7f7f4000407fdf
+:100b20007f7f7f7f7f7f400000000000000000008b
+:100b300000000000000000000000000000000000b5
+:100b400000000000000000000000000000000000a5
+:100b50000000000007070707070707040000000060
+:100b60000000000000000000000000000000000085
+:100b70000000000000000000000000000000000075
+:100b80000000000000000000000000000000000065
+:100b90000000000000000000000000000000000055
+:100ba0000000000000000000000000000000000045
+:100bb0000000000000000000000000000000000035
+:100bc0000000000000000000000000000000000025
+:100bd0000000000000000000000000000000000015
+:100be0000000000000000000000000000000000005
+:100bf00000000000000000000000000000000000f5
+:100c000000000000000000000000000000000000e4
+:100c100000000000000000000000000000000000d4
+:100c200000000000000000000000000000000000c4
+:100c300000000000000000000000000000000000b4
+:100c400000000000000000000000000000000000a4
+:100c5000000000000000000000c060301088e45474
+:100c60006e6e26f32f272323272ff3266e5664cc90
+:100c7000983020e08000000000000000000000002c
+:100c80000000000000000000000000000000000064
+:100c90000000000000000000000000000000000054
+:100ca0000000000000000000000000000000000044
+:100cb0000000000000000000000000000000000034
+:100cc0000000000000000000000000000000000024
+:100cd000000000000000c0fc472632f93f10080861
+:100ce00008f80f0908080808080809ff080808108c
+:100cf000173df326655ffcc0000000000000000007
+:100d000000000000000000000000000000000000e3
+:100d100000000000000000000000000000000000d3
+:100d200000000000000000000000000000000000c3
+:100d300000000000000000000000000000000000b3
+:100d400000000000000000000000000000000000a3
+:100d50000000000000000f74c888107fd0302060b1
+:100d6000607fc04040404040404040ff60602030d5
+:100d700010f01f90d8e87c0f000000000000000079
+:100d80000000000000000000000000000000000063
+:100d90000000000000000000000000000000000053
+:100da0000000000000000000000000000000000043
+:100db0000000000000000000000000000000000033
+:100dc0000000000000000000000000000000000023
+:100dd000000000000000000003070d3b276e5ca828
+:100de000c888977cd090101090d03c97d8e8b8cca9
+:100df00067371b0d07010000000000000000000025
+:100e000000000000000000000000000000000000e2
+:100e100000000000000000000000000000000000d2
+:100e200000000000000000000000000000c0c04002
+:100e30004040c0c08000c000c0c0c0c08080c000b2
+:100e400080c0c0c0c0000000000000c0c0c0c0c062
+:100e500000000000c0c0c0c0c0c0c080000080c092
+:100e6000c0c1c1c1810303c383030101010000802c
+:100e7000c00000000000c0c0404040c0c080000072
+:100e8000c0c000000080c00000c0c0c0c08080c0e2
+:100e90000080c0c0c0c00000000080c0c0c0c00052
+:100ea000000000000000000000000000003f3f269e
+:100eb0002226361f0f003f0000003f3f00000000c9
+:100ec00033333434343c18000000003f3d04040444
+:100ed000040404003f3f060e1e1e362700061f3086
+:100ee000303030301f06003f030f1c38381c0f0312
+:100ef0003f00000000003f3f262226361f0f000063
+:100f00000001033e03010000000000003f0000005c
+:100f1000001f1f3434343434340033333434343c1d
+:100f200018000000000000000000000000000000a9
+:100f300000000000000000000000000000000000b1
+:100f400000000000000000000000000000000000a1
+:100f50000000000080808000e0f0f81818b0a000c9
+:100f6000e0f0f818f8f0e000f8f8f810f8f8f018e9
+:100f7000f8f8f00000000000000000000000000091
+:100f80000000000000000000000000000000000061
+:100f90000000000000000000000000000000000051
+:100fa0000000000000000000000000000000000041
+:100fb0000000000000000000000000000000000031
+:100fc0000000000000000000000000000000000021
+:100fd00000000000030303000001030303010000fd
+:100fe00000010303030100000303030003030300e4
+:100ff00003030300000000000000000000000000e8
+:1010000000000000000000000000000000000000e0
+:1010100000000000000000000000000000000000d0
+:1010200000000000000000000000000000000000c0
+:1010300000000000000000000000000000000000b0
+:1010400000000000000000000000000000000000a0
+:101050000000000000000000000000000000000090
+:101060000000000000000000000000000000000080
+:101070000000000000000000000000000000000070
+:101080000000000000000000000000000000000060
+:101090000000000000000000000000000000000050
+:1010a0000000000000000000000000000000000040
+:1010b0000000000000000000000000000000000030
+:1010c0000000000000000000000000000000000020
+:1010d0000000000000000000000000000000000010
+:1010e0000000000000000000000000000000000000
+:1010f00000000000000000000000000000000000f0
+:1011000000000000000000000000000000000000df
+:1011100000000000000000000000000000000000cf
+:1011200000000000000000000000000080402020bf
+:1011300040800000000000000000000000000000ef
+:10114000000000000000000000000000000000009f
+:10115000000000000000000000000000000000008f
+:10116000000000000000000000000000000000007f
+:10117000000000000000000000000000000000006f
+:10118000000000000000000000000000000000005f
+:10119000000000000000000000000000000000004f
+:1011a00000000000000000000000fc0300c0c0c000
+:1011b000c00003fc00000000000000000000000070
+:1011c00000000000000000000000020502003c4298
+:1011d0008181816600000000000000000000000026
+:1011e00000000000000000000000000000000000ff
+:1011f00000000000000000000000000000000000ef
+:1012000000008040201010080808040404040408aa
+:1012100008081010204080000000000000000000be
+:1012200000000000000000000000ff0000ffffffc2
+:10123000ff0000ff000000000000000000000000b0
+:10124000000000000000000000000000000080809e
+:10125000808000000000000000000000000000008e
+:10126000000000000000000000000000000000007e
+:10127000800000008000000000000000000000006e
+:10128000f00e010000000000000080e0e0e000003f
+:10129000000000000000010ef0000000000000004f
+:1012a00000000000000000000000ff0000ffffff42
+:1012b000ff0000ff00000000000000000000000030
+:1012c00000000000000000000000000000007f049b
+:1012d000040000324a4a7c007e04027c00000000c8
+:1012e00000000000000000000000000000000003fb
+:1012f00004631c3348300000000000f00808f000d0
+:10130000010e3040880404020101000000000000ca
+:10131000000000008040300e01e010902000e0103e
+:1013200010e000000000000080c0fff0f8ffffffa9
+:10133000fff8f0ffc0800000000000000000000087
+:10134000000000000000000000000000000000009d
+:10135000000000000000000000000000000000008d
+:10136000000000000000000000000000000000007d
+:10137000000000000000000000000003040403005f
+:10138000000000000001010202020404040404023f
+:101390000202010100000000000709080700070819
+:1013a0000807000000000000ffffffffffffffff36
+:1013b000ffff7f3f1f0f0000000000000000000043
+:1013c000000000000000000000020502003c428115
+:1013d00081816600000000000000000000000000a5
+:1013e00000000000000000000000000000000000fd
+:1013f00000000000000000000000000000ff0919cc
+:10140000294680ff1111110e00ff0678807806ff33
+:1014100000000000000000000000000000000000cc
+:101420000000000000000000000000000000005f5d
+:1014300000000003000300143e143e14242a7f2af7
+:1014400012433308666136495522500005030000f7
+:10145000001c2241000041221c0014083e08140810
+:10146000083e08080050300000080808080800601e
+:1014700060000020100804023e5149453e04027fee
+:101480000000426151494622414949361814127ff1
+:101490001027454545393e4949493201017109073f
+:1014a0003649494936264949493e0036360000004a
+:1014b000563600000814224100141414141400417c
+:1014c00022140802015109063e4159555e7e090960
+:1014d000097e7f494949363e414141227f41414190
+:1014e0003e7f494949417f090909013e4141493a45
+:1014f0007f0808087f00417f4100304040403f7f27
+:10150000081422417f404040407f020c027f7f024e
+:1015100004087f3e4141413e7f090909061e212101
+:10152000215e7f0909097600264949493201017f78
+:1015300001013f4040403f1f2040201f7f201020de
+:101540007f41221c22410708700807615149454329
+:10155000007f410000020408102004020102044040
+:1015600040404040000102040020545454787f441d
+:101570004444383844444444384444447f38545400
+:10158000541804047e0505085454543c7f08040490
+:101590007800447d40002040443d007f10284400f6
+:1015a00000417f40007c047804787c08040478388b
+:1015b000444444387c14141408081414147c007c2b
+:1015c000080404485454542004043f44443c40401c
+:1015d000207c1c2040201c3c4030403c44281028eb
+:1015e000440c5050503c4464544c44000836414133
+:1015f00000007f00004141360800020102040200a1
+:10160000000000005261704d616e2076312e302e48
+:10161000382d4572696b0000472d436f6465204c7f
+:10162000696e653a0000000048656164205370658a
+:1016300065643a004578742e20526174653a000062
+:101640002531750025352e31666d6d2f7300000034
+:101650004e6f74205365740000007042000000005b
+:1016600079e9263108acac3f4578747275646572cf
+:1016700020436f6e74726f6c0000000048656174e7
+:101680006572204f6e200000486561746572204fbe
+:1016900066660000203c31303043204d6f746f721d
+:1016a000204f4646000000000000c84254454d50ff
+:1016b00045524154555245204552524f5200000068
+:1016c000544845524d4953544f52204552524f525f
+:1016d0000000000025337543000000002a000000d0
+:1016e0002000000000c07944000080bf25337552ff
+:1016f000504d00000000000084471b47acc5a73fc9
+:101700004d454e550000000052554e2046494c456f
+:10171000000000004d414e55414c204d4f564500b4
+:10172000544f4f4c2053455455500000484f4d45a1
+:1017300020544f4f4c204845414400004d414e55e8
+:10174000414c0000585f537465703a00595f537400
+:1017500065703a005a5f537465703a004155544fb2
+:101760003a204c6f6164696e672e2e00484f4d49d8
+:101770004e4720504c4541534520574149540000a5
+:101780004d4f564520544f3a00000000583d253635
+:101790002e326600593d25362e3266005a3d2536da
+:1017a0002e3266004e4f205a204d4f564500000005
+:1017b00050726f672e456e640000000052657475ac
+:1017c000726e20746f204d656e7500003c3c3c20ad
+:1017d0005072657373204573632e00003e00000055
+:1017e000202000009c5a019df454019dc455019d88
+:1017f0009456019d6457019d3458019d0459019de3
+:10180000d459019d000000005261704d616e207638
+:10181000312e302e382d4572696b0000496e73658c
+:1018200072742053442d43617264206f7200000073
+:101830003c3c45534320544f20524553554d4500a1
+:10184000496e76616c69642046696c6520547970d4
+:1018500065000000506c65617365206f6e6c7920c7
+:10186000757365002a2e424642206f72202a2e4749
+:10187000434f2046696c657300000000504155538a
+:10188000450000004572726f7220544553540000a9
+:101890004578747275646572204f464600000000fa
+:1018a00046696c65204572726f72203a7365656b8c
+:1018b00020707400556e6b6e6f776e204572726f7c
+:1018c00072000000203c45534320544f20524553a2
+:1018d000554d45003c000000000002430000c8c216
+:1018e000546f6f6c3a2050656e000000546f6f6c3f
+:1018f0003a2045787472756465720000546f6f6c9d
+:101900003a2045787472756465723200546f6f6c5a
+:101910003a204e6f7420446566696e65640000006d
+:10192000546f6f6c3a20526f75746572000000003e
+:10193000546f6f6c3a204e6f6e65000072000000ad
+:1019400046696c65204572726f722020202000006d
+:1019500046696c65204e6f7420466f756e6400009a
+:101960004f70656e000000002a2e2a0046696e64e2
+:10197000204669727374204572726f720000000015
+:101980004e6f2066696c6573206f6e2063617264b0
+:1019900000000000537769746368204f46462f4f5c
+:1019a0004e000000746f20526573657400000000e3
+:1019b00046696c6500000000253375006f66000005
+:1019c000000000440000fe420000fe420000000053
+:1019d00025362e3266000000cdcccccccce4554070
+:1019e000000020455a20444f574e20202020200040
+:1019f0005920464f5257415244202000484f4d45f0
+:101a00002058202020200000484f4d4520592020fc
+:101a100020200000484f4d45205a20202020000063
+:101a2000484f4d452041424f52544544000000006c
+:101a3000484f4d4520434f4d504c45544500000004
+:101a4000cdcccccccce4554039b4c876be9ff63f63
+:101a50000000c84200000000cdcccccccce4554006
+:101a60000000204500000000cdcccccccce455409b
+:101a700000808443000048c3000002430000c8c245
+:101a8000000000000000e03f000000000000e03f18
+:101a9000000000000000e0bf4cb6019d00b7019db2
+:101aa00094b6019ddcb7019d60b8019d0020202007
+:101ab00020202020202028282828282020202020fe
+:101ac00020202020202020202020202020801010d6
+:101ad000101010101010101010101010100404042a
+:101ae00004040404040404101010101010104141e8
+:101af00041414141010101010101010101010101d6
+:101b000001010101010101011010101010104242e9
+:101b100042424242020202020202020202020202a5
+:101b20000202020202020202101010102000000045
+:101b300000000000000000000000000000000000a5
+:101b40000000000000000000000000000000000095
+:101b50000000000000000000000000000000000085
+:101b60000000000000000000000000000000000075
+:101b70000000000000000000000000000000000065
+:101b80000000000000000000000000000000000055
+:101b90000000000000000000000000000000000045
+:101ba0000000000000000000000000000000000035
+:101bb0003030303030303030303030303030303025
+:101bc0003030303030303030303030303030303015
+:101bd0002020202020202020202020202020202005
+:101be00020202020202020202020202020202020f5
+:101bf00078c1019d24c5019da8d2019d24c5019de8
+:101c0000a8d2019da8d2019da8d2019da8d2019d74
+:101c1000a8d2019da8d2019da8d2019d9cc1019d81
+:101c2000e4c1019da8d2019da8d2019da8d2019d29
+:101c3000a8d2019db0c1019da8d2019da8d2019d4d
+:101c4000d4c1019da8d2019da8d2019da8d2019d19
+:101c5000a8d2019da8d2019da8d2019da8d2019d24
+:101c6000a8d2019da8d2019da8d2019df4d0019dca
+:101c700084c1019d24c5019d24c5019d24c5019dec
+:101c8000a8d2019d84c1019da8d2019da8d2019d29
+:101c9000a8d2019da8d2019dbcd1019da8c1019de2
+:101ca000f0c1019da8d2019da8d2019d30d1019d16
+:101cb000a8d2019dbcc1019da8d2019da8d2019dc1
+:101cc000fcc1019d00000000000000000000244055
+:101cd0000000000000001040000000000000008034
+:101ce0007b14ae47e17a843f2d431cebe2361a3f6a
+:101cf0004e614e002b496e66000000002d496e6655
+:101d000000000000286e756c6c29000038d3019d1e
+:101d100040d3019d48d3019d50d3019d58d3019dcf
+:101d200000000000000014400000000000003940e6
+:101d300000000000008883400000000084d71741a5
+:101d40000080e03779c34142176e05b5b5b89344ba
+:101d5000f5f93fe9034f3849321d30f9487782528f
+:101d60003cbf737fdd4f1565000000000000f03fb1
+:101d7000ffffffffffffff7f0000000000001000db
+:101d80000000000000000001ffffffffffff0f0049
+:101d9000ff0000003f0000000f00000003000000f3
+:101da000df000000370000000d000000020000000e
+:101db000bf0000002f0000000b0000000200000028
+:101dc0009f00000027000000090000000100000043
+:101dd0007f0000001f00000007000000010000005d
+:101de0005f00000017000000050000000000000078
+:101df0003f0000000f000000030000000000000092
+:101e00001f000000070000000100000000000000ab
+:020000040000fa
+:020000041d02db
+:101e10000c00000000000000010001041f0c1d0068
+:101e20000c0000001400000098fc019d7c040000e0
+:101e30000c00000000000000010001041f0c1d0048
+:101e40001c000000140000001401029d8c0400001e
+:101e5000440e185011107c11117d11127e000000eb
+:020000040000fa
+:020000041d02db
+:101e600000000000ffffffff000000000000000076
+:101e70000000000000000000000000000000000062
+:101e8000840000a0a00000a0bc0000a0800000a072
+:101e90007c0300a001000000000000000000000022
+:101ea0000000000000000000000000000000000032
+:101eb0000000000000000000000000000000000022
+:101ec0000000000000000000000000000000000012
+:101ed0000000000000000000000000000000000002
+:101ee00000000000ffffffffffffffff00000000fa
+:101ef000000400000910000000000000981a029d74
+:101f0000ffffffff000000000000000000040000d1
+:101f10000a10010000000000981a029dffffffff59
+:101f200000000000000000000000000002000200ad
+:101f300000000000981a029dfdffffff0000000056
+:101f40000000000000000000000000000000000091
+:041f5000000000008d
+:020000040000fa
+:020000041d02db
+:101f540090010000f5ff000001000000ffff0000f9
+:101f6400ffffffff9c0600a0010000001e00000010
+:0c1f7400ffff000001000000200000a0a2
+:00000001FF
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.map b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.map new file mode 100644 index 00000000..327a10b2 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.map @@ -0,0 +1,2008 @@ +Archive member included because of file (symbol)
+
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memcpy.o)
+ OLED.o (memcpy)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memset.o)
+ FSIO.o (memset)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strcpy.o)
+ FSIO.o (strcpy)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strlen.o)
+ FSIO.o (strlen)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(general-exception.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (_general_exception_context)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ FSIO.o (strncpy)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ FSIO.o (strchr)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (exit)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ FSIO.o (tolower)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ RapMan.o (atof)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ RapMan.o (atoi)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o) (strtol)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o) (strtod)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o) (_libc_data)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o) (_filbuf_simple)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ OLED.o (sprintf)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o) (pthread_mutex_lock)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(general-exception.o) (_general_exception_handler)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (_bootstrap_exception_handler)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (_on_reset)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (_on_bootstrap)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-nmi-handler.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o (_nmi_handler)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o) (_mon_getc)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o) (_mon_write)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o) (_exit)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctype.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o) (_ctype)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(errno.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o) (errno)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o) (vfprintf)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o) (_io_strfuncs)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o) (fputc)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o) (_mon_putc)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(mod32.o)
+ Stepper.o (modf)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(ceil32.o)
+ G_Code.o (ceil)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(dp32.o)
+ Extruder.o (dpsub)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(fp32.o)
+ Extruder.o (fpsub)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o) (__strtod)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o) (__ldexp)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ SD-SPI.o (getcSPI2)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ SD-SPI.o (OpenSPI2)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ Extruder.o (INTDisableInterrupts)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ Extruder.o (INTEnableSystemMultiVectoredInt)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ Extruder.o (INTRestoreInterrupts)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_brg_tbl_lib.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o) (SpiBrgConvTbl)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o) (INTEnableInterrupts)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_udivdi3.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o) (__udivdi3)
+C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_umoddi3.o)
+ C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o) (__umoddi3)
+
+Allocating common symbols
+Common symbol size file
+
+fDim_1 0x4 RapMan.o
+LineBuffer 0x32 RapMan.o
+S_F_Code 0x4 Extruder.o
+Dim_4 0x8 RapMan.o
+LowValue 0x4 Extruder.o
+SBReady 0x4 Stepper.o
+M_Code 0x4 G_Code.o
+gDataBuffer 0x200 FSIO.o
+SCB 0x800 Stepper.o
+X_Rest_mm 0x4 RapMan.o
+Fraction 0x4 Extruder.o
+G_Code 0x4 G_Code.o
+iInst_Code 0x4 RapMan.o
+temperature1 0x4 Extruder.o
+Reverse_Steps 0x4 Extruder.o
+gFileSlotOpen 0x3 FSIO.o
+FilePointer 0x4 RapMan.o
+gTimeCrtMS 0x1 FSIO.o
+MDD_SDSPI_finalLBA 0x4 SD-SPI.o
+lX_Steps 0x4 Stepper.o
+Inst_Code 0x8 RapMan.o
+GY 0x4 G_Code.o
+lSaveSteps_X 0x4 Stepper.o
+cwd 0x3c FSIO.o
+defaultString 0xd FSIO.o
+tempCWDobj 0x3c FSIO.o
+fDim_4 0x4 RapMan.o
+fDim_2 0x4 RapMan.o
+FeedRate_ManualChange
+ 0x1 Extruder.o
+SaveFileSize 0x4 RapMan.o
+lHomeStepsX 0x4 Stepper.o
+lSaveSteps_Z 0x4 Stepper.o
+Delta_Z 0x4 Stepper.o
+StepReady 0x4 Extruder.o
+FastMoveMotorEnable
+ 0x1 Extruder.o
+Delta_Y 0x4 Stepper.o
+Message 0x14 Extruder.o
+GI_Val 0x4 G_Code.o
+GJ_Val 0x4 G_Code.o
+gFATBuffer 0x200 FSIO.o
+SBR 0x4 Stepper.o
+gTimeCrtTime 0x2 FSIO.o
+gFileArray 0xb4 FSIO.o
+FatRootDirClusterValue
+ 0x4 FSIO.o
+GZ 0x4 G_Code.o
+SBCode 0x4 Stepper.o
+G_CodeRapidZMove 0x4 Extruder.o
+gDiskData 0x20 FSIO.o
+lHomeStepsY 0x4 Stepper.o
+Y_Steps 0x4 Stepper.o
+gTimeWrtDate 0x2 FSIO.o
+Inst_Code_Letter 0x1 RapMan.o
+Dim_4_Letter 0x1 RapMan.o
+Ops_mode 0x4 RapMan.o
+pointer 0x4 RapMan.o
+Y_Rest_mm 0x4 RapMan.o
+Dim_2_Letter 0x1 RapMan.o
+lZ_Steps 0x4 Stepper.o
+ManualChange 0x4 RapMan.o
+EnableFanControl 0x1 Extruder.o
+G_CodeRapidXYMove 0x4 Extruder.o
+Dim_2 0x8 RapMan.o
+lHomeStepsZ 0x4 Stepper.o
+X_Steps 0x4 Stepper.o
+Dim_3_Letter 0x1 RapMan.o
+ExtruderStatus 0x1 RapMan.o
+Set_Y_Dir 0x4 Stepper.o
+gTimeCrtDate 0x2 FSIO.o
+Z_Rest_mm 0x4 RapMan.o
+Ex_Reverse 0x4 Extruder.o
+Change_M104 0x1 Extruder.o
+lSaveSteps_Y 0x4 Stepper.o
+SBW 0x4 Stepper.o
+GP_Val 0x4 G_Code.o
+Set_Z_Dir 0x4 Stepper.o
+S_M_Code 0x4 Stepper.o
+SBuf 0x1 Stepper.o
+TempClusterCalc 0x4 FSIO.o
+GS_Val 0x4 G_Code.o
+Delta_X 0x4 Stepper.o
+lY_Steps 0x4 Stepper.o
+dirCleared 0x1 FSIO.o
+RPM_Change 0x1 Extruder.o
+gFileTemp 0x3c FSIO.o
+GX 0x4 G_Code.o
+Feed_Rate 0x4 Extruder.o
+Dim_3 0x8 RapMan.o
+CharBuffer 0x1 RapMan.o
+defaultArray 0xa FSIO.o
+Range 0x4 Extruder.o
+Dim_1_Letter 0x1 RapMan.o
+Prime_Steps 0x4 Extruder.o
+Reverse_Step_Count 0x4 Extruder.o
+fDim_3 0x4 RapMan.o
+Set_X_Dir 0x4 Stepper.o
+DataVal 0x4 Extruder.o
+PauseFlag 0x1 RapMan.o
+HighValue 0x4 Extruder.o
+raw_temperature 0x4 Extruder.o
+Dim_1 0x8 RapMan.o
+TempVal 0x4 Extruder.o
+ExtrusionRate 0x4 OLED.o
+Temp_Change 0x1 Extruder.o
+gTimeAccDate 0x2 FSIO.o
+Prime_Step_Count 0x4 Extruder.o
+FSerrno 0x1 FSIO.o
+SaveFileName 0xc RapMan.o
+Z_Steps 0x4 Stepper.o
+gTimeWrtTime 0x2 FSIO.o
+
+Microchip PIC32 Memory-Usage Report
+
+kseg0 Program-Memory Usage
+section address length [bytes] (dec) Description
+------- ---------- ------------------------- -----------
+.text 0x9d006a00 0x19ba0 105376 Application's executable code
+.rodata 0x9d0205a0 0x1870 6256 Read-only constant data
+.eh_frame 0x9d021e10 0x50 80 Stack unwind info
+.data 0x9d021e60 0xf4 244 Data-initialization template
+.sdata 0x9d021f54 0x2c 44 Small data-initialization template
+ Total kseg0_program_mem used : 0x1b580 112000 22.3% of 0x7a600
+
+kseg0 Boot-Memory Usage
+section address length [bytes] (dec) Description
+------- ---------- ------------------------- -----------
+.startup 0x9d006490 0x1e0 480 C startup code
+ Total kseg0_boot_mem used : 0x1e0 480 19.9% of 0x970
+
+Exception-Memory Usage
+section address length [bytes] (dec) Description
+------- ---------- ------------------------- -----------
+.app_excpt 0x9d005180 0x10 16 General-Exception handler
+.vector_8 0x9d005300 0x8 8 Interrupt Vector 8
+.vector_12 0x9d005380 0x8 8 Interrupt Vector 12
+.vector_16 0x9d005400 0x8 8 Interrupt Vector 16
+ Total exception_mem used : 0x28 40 1.0% of 0x1000
+
+kseg1 Boot-Memory Usage
+section address length [bytes] (dec) Description
+------- ---------- ------------------------- -----------
+.reset 0x9d006000 0x10 16 Reset handler
+.bev_excpt 0x9d006380 0x10 16 BEV-Exception handler
+ Total kseg1_boot_mem used : 0x20 32 2.7% of 0x490
+ --------------------------------------------------------------------------
+ Total Program Memory used : 0x1b7a8 112552 22.1% of 0x7c400
+ --------------------------------------------------------------------------
+
+
+kseg1 Data-Memory Usage
+section address length [bytes] (dec) Description
+------- ---------- ------------------------- -----------
+.data 0xa0000000 0xf4 244 Initialized data
+.sdata 0xa00000f4 0x2c 44 Small initialized data
+.sbss 0xa0000120 0x25c 604 Small uninitialized data
+.bss 0xa000037c 0xf04 3844 Uninitialized data
+.stack 0xa0001280 0x400 1024 Minimum space reserved for stack
+ Total kseg1_data_mem used : 0x1680 5760 17.6% of 0x8000
+ --------------------------------------------------------------------------
+ Total Data Memory used : 0x1680 5760 17.6% of 0x8000
+ --------------------------------------------------------------------------
+
+Memory Configuration
+
+Name Origin Length Attributes
+kseg0_program_mem 0x9d006a00 0x0007a600 xr
+kseg0_boot_mem 0x9d006490 0x00000970
+exception_mem 0x9d005000 0x00001000
+kseg1_boot_mem 0x9d006000 0x00000490
+debug_exec_mem 0xbfc02000 0x00000ff0
+config3 0xbfc02ff0 0x00000004
+config2 0xbfc02ff4 0x00000004
+config1 0xbfc02ff8 0x00000004
+config0 0xbfc02ffc 0x00000004
+kseg1_data_mem 0xa0000000 0x00008000 w !x
+sfrs 0xbf800000 0x00100000
+*default* 0x00000000 0xffffffff
+
+Linker script and memory map
+
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+LOAD Extruder.o
+LOAD FSIO.o
+LOAD SD-SPI.o
+LOAD G_Code.o
+LOAD OLED.o
+LOAD RapMan.o
+LOAD Stepper.o
+ 0x00000001 __MPLAB_BUILD = 0x1
+ 0x00000001 __MPLAB_DEBUG = 0x1
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a
+START GROUP
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libdsp.a
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral_32MX440F256H.a
+END GROUP
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a
+ 0x00000400 PROVIDE (_min_stack_size, 0x400)
+ 0x00000000 PROVIDE (_min_heap_size, 0x0)
+LOAD C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/./proc/32MX440F256H\processor.o
+ 0x00000001 PROVIDE (_vector_spacing, 0x1)
+ 0x9d005000 _ebase_address = 0x9d005000
+ 0x9d006000 _RESET_ADDR = 0x9d006000
+ 0x9d006380 _BEV_EXCPT_ADDR = 0x9d006380
+ 0x9d006480 _DBG_EXCPT_ADDR = 0x9d006480
+ 0xbfc02000 _DBG_CODE_ADDR = 0xbfc02000
+ 0x9d005180 _GEN_EXCPT_ADDR = (_ebase_address + 0x180)
+
+.config_BFC02FF0
+ *(.config_BFC02FF0)
+
+.config_BFC02FF4
+ 0xbfc02ff4 0x4
+ *(.config_BFC02FF4)
+ .config_BFC02FF4
+ 0xbfc02ff4 0x4 RapMan.o
+
+.config_BFC02FF8
+ 0xbfc02ff8 0x4
+ *(.config_BFC02FF8)
+ .config_BFC02FF8
+ 0xbfc02ff8 0x4 RapMan.o
+
+.config_BFC02FFC
+ 0xbfc02ffc 0x4
+ *(.config_BFC02FFC)
+ .config_BFC02FFC
+ 0xbfc02ffc 0x4 RapMan.o
+
+.reset 0x9d006000 0x10
+ *(.reset)
+ .reset 0x9d006000 0x10 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+ 0x9d006000 _reset
+
+.bev_excpt 0x9d006380 0x10
+ *(.bev_handler)
+ .bev_handler 0x9d006380 0x10 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+
+.dbg_excpt 0x9d006480 0x0
+ 0x9d006480 . = (. + DEFINED (_DEBUGGER)?0x8:0x0)
+
+.dbg_code 0xbfc02000 0x0
+ 0xbfc02000 . = (. + DEFINED (_DEBUGGER)?0xff0:0x0)
+
+.app_excpt 0x9d005180 0x10
+ *(.gen_handler)
+ .gen_handler 0x9d005180 0x10 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+
+.vector_0 0x9d005200 0x0
+ *(.vector_0)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_0) <= (_vector_spacing << 0x5))), function at exception vector 0 too large)
+
+.vector_1 0x9d005220 0x0
+ *(.vector_1)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_1) <= (_vector_spacing << 0x5))), function at exception vector 1 too large)
+
+.vector_2 0x9d005240 0x0
+ *(.vector_2)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_2) <= (_vector_spacing << 0x5))), function at exception vector 2 too large)
+
+.vector_3 0x9d005260 0x0
+ *(.vector_3)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_3) <= (_vector_spacing << 0x5))), function at exception vector 3 too large)
+
+.vector_4 0x9d005280 0x0
+ *(.vector_4)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_4) <= (_vector_spacing << 0x5))), function at exception vector 4 too large)
+
+.vector_5 0x9d0052a0 0x0
+ *(.vector_5)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_5) <= (_vector_spacing << 0x5))), function at exception vector 5 too large)
+
+.vector_6 0x9d0052c0 0x0
+ *(.vector_6)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_6) <= (_vector_spacing << 0x5))), function at exception vector 6 too large)
+
+.vector_7 0x9d0052e0 0x0
+ *(.vector_7)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_7) <= (_vector_spacing << 0x5))), function at exception vector 7 too large)
+
+.vector_8 0x9d005300 0x8
+ *(.vector_8)
+ .vector_8 0x9d005300 0x8 Extruder.o
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_8) <= (_vector_spacing << 0x5))), function at exception vector 8 too large)
+
+.vector_9 0x9d005320 0x0
+ *(.vector_9)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_9) <= (_vector_spacing << 0x5))), function at exception vector 9 too large)
+
+.vector_10 0x9d005340 0x0
+ *(.vector_10)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_10) <= (_vector_spacing << 0x5))), function at exception vector 10 too large)
+
+.vector_11 0x9d005360 0x0
+ *(.vector_11)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_11) <= (_vector_spacing << 0x5))), function at exception vector 11 too large)
+
+.vector_12 0x9d005380 0x8
+ *(.vector_12)
+ .vector_12 0x9d005380 0x8 Extruder.o
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_12) <= (_vector_spacing << 0x5))), function at exception vector 12 too large)
+
+.vector_13 0x9d0053a0 0x0
+ *(.vector_13)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_13) <= (_vector_spacing << 0x5))), function at exception vector 13 too large)
+
+.vector_14 0x9d0053c0 0x0
+ *(.vector_14)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_14) <= (_vector_spacing << 0x5))), function at exception vector 14 too large)
+
+.vector_15 0x9d0053e0 0x0
+ *(.vector_15)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_15) <= (_vector_spacing << 0x5))), function at exception vector 15 too large)
+
+.vector_16 0x9d005400 0x8
+ *(.vector_16)
+ .vector_16 0x9d005400 0x8 Stepper.o
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_16) <= (_vector_spacing << 0x5))), function at exception vector 16 too large)
+
+.vector_17 0x9d005420 0x0
+ *(.vector_17)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_17) <= (_vector_spacing << 0x5))), function at exception vector 17 too large)
+
+.vector_18 0x9d005440 0x0
+ *(.vector_18)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_18) <= (_vector_spacing << 0x5))), function at exception vector 18 too large)
+
+.vector_19 0x9d005460 0x0
+ *(.vector_19)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_19) <= (_vector_spacing << 0x5))), function at exception vector 19 too large)
+
+.vector_20 0x9d005480 0x0
+ *(.vector_20)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_20) <= (_vector_spacing << 0x5))), function at exception vector 20 too large)
+
+.vector_21 0x9d0054a0 0x0
+ *(.vector_21)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_21) <= (_vector_spacing << 0x5))), function at exception vector 21 too large)
+
+.vector_22 0x9d0054c0 0x0
+ *(.vector_22)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_22) <= (_vector_spacing << 0x5))), function at exception vector 22 too large)
+
+.vector_23 0x9d0054e0 0x0
+ *(.vector_23)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_23) <= (_vector_spacing << 0x5))), function at exception vector 23 too large)
+
+.vector_24 0x9d005500 0x0
+ *(.vector_24)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_24) <= (_vector_spacing << 0x5))), function at exception vector 24 too large)
+
+.vector_25 0x9d005520 0x0
+ *(.vector_25)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_25) <= (_vector_spacing << 0x5))), function at exception vector 25 too large)
+
+.vector_26 0x9d005540 0x0
+ *(.vector_26)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_26) <= (_vector_spacing << 0x5))), function at exception vector 26 too large)
+
+.vector_27 0x9d005560 0x0
+ *(.vector_27)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_27) <= (_vector_spacing << 0x5))), function at exception vector 27 too large)
+
+.vector_28 0x9d005580 0x0
+ *(.vector_28)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_28) <= (_vector_spacing << 0x5))), function at exception vector 28 too large)
+
+.vector_29 0x9d0055a0 0x0
+ *(.vector_29)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_29) <= (_vector_spacing << 0x5))), function at exception vector 29 too large)
+
+.vector_30 0x9d0055c0 0x0
+ *(.vector_30)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_30) <= (_vector_spacing << 0x5))), function at exception vector 30 too large)
+
+.vector_31 0x9d0055e0 0x0
+ *(.vector_31)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_31) <= (_vector_spacing << 0x5))), function at exception vector 31 too large)
+
+.vector_32 0x9d005600 0x0
+ *(.vector_32)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_32) <= (_vector_spacing << 0x5))), function at exception vector 32 too large)
+
+.vector_33 0x9d005620 0x0
+ *(.vector_33)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_33) <= (_vector_spacing << 0x5))), function at exception vector 33 too large)
+
+.vector_34 0x9d005640 0x0
+ *(.vector_34)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_34) <= (_vector_spacing << 0x5))), function at exception vector 34 too large)
+
+.vector_35 0x9d005660 0x0
+ *(.vector_35)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_35) <= (_vector_spacing << 0x5))), function at exception vector 35 too large)
+
+.vector_36 0x9d005680 0x0
+ *(.vector_36)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_36) <= (_vector_spacing << 0x5))), function at exception vector 36 too large)
+
+.vector_37 0x9d0056a0 0x0
+ *(.vector_37)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_37) <= (_vector_spacing << 0x5))), function at exception vector 37 too large)
+
+.vector_38 0x9d0056c0 0x0
+ *(.vector_38)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_38) <= (_vector_spacing << 0x5))), function at exception vector 38 too large)
+
+.vector_39 0x9d0056e0 0x0
+ *(.vector_39)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_39) <= (_vector_spacing << 0x5))), function at exception vector 39 too large)
+
+.vector_40 0x9d005700 0x0
+ *(.vector_40)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_40) <= (_vector_spacing << 0x5))), function at exception vector 40 too large)
+
+.vector_41 0x9d005720 0x0
+ *(.vector_41)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_41) <= (_vector_spacing << 0x5))), function at exception vector 41 too large)
+
+.vector_42 0x9d005740 0x0
+ *(.vector_42)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_42) <= (_vector_spacing << 0x5))), function at exception vector 42 too large)
+
+.vector_43 0x9d005760 0x0
+ *(.vector_43)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_43) <= (_vector_spacing << 0x5))), function at exception vector 43 too large)
+
+.vector_44 0x9d005780 0x0
+ *(.vector_44)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_44) <= (_vector_spacing << 0x5))), function at exception vector 44 too large)
+
+.vector_45 0x9d0057a0 0x0
+ *(.vector_45)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_45) <= (_vector_spacing << 0x5))), function at exception vector 45 too large)
+
+.vector_46 0x9d0057c0 0x0
+ *(.vector_46)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_46) <= (_vector_spacing << 0x5))), function at exception vector 46 too large)
+
+.vector_47 0x9d0057e0 0x0
+ *(.vector_47)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_47) <= (_vector_spacing << 0x5))), function at exception vector 47 too large)
+
+.vector_48 0x9d005800 0x0
+ *(.vector_48)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_48) <= (_vector_spacing << 0x5))), function at exception vector 48 too large)
+
+.vector_49 0x9d005820 0x0
+ *(.vector_49)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_49) <= (_vector_spacing << 0x5))), function at exception vector 49 too large)
+
+.vector_50 0x9d005840 0x0
+ *(.vector_50)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_50) <= (_vector_spacing << 0x5))), function at exception vector 50 too large)
+
+.vector_51 0x9d005860 0x0
+ *(.vector_51)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_51) <= (_vector_spacing << 0x5))), function at exception vector 51 too large)
+
+.vector_52 0x9d005880 0x0
+ *(.vector_52)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_52) <= (_vector_spacing << 0x5))), function at exception vector 52 too large)
+
+.vector_53 0x9d0058a0 0x0
+ *(.vector_53)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_53) <= (_vector_spacing << 0x5))), function at exception vector 53 too large)
+
+.vector_54 0x9d0058c0 0x0
+ *(.vector_54)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_54) <= (_vector_spacing << 0x5))), function at exception vector 54 too large)
+
+.vector_55 0x9d0058e0 0x0
+ *(.vector_55)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_55) <= (_vector_spacing << 0x5))), function at exception vector 55 too large)
+
+.vector_56 0x9d005900 0x0
+ *(.vector_56)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_56) <= (_vector_spacing << 0x5))), function at exception vector 56 too large)
+
+.vector_57 0x9d005920 0x0
+ *(.vector_57)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_57) <= (_vector_spacing << 0x5))), function at exception vector 57 too large)
+
+.vector_58 0x9d005940 0x0
+ *(.vector_58)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_58) <= (_vector_spacing << 0x5))), function at exception vector 58 too large)
+
+.vector_59 0x9d005960 0x0
+ *(.vector_59)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_59) <= (_vector_spacing << 0x5))), function at exception vector 59 too large)
+
+.vector_60 0x9d005980 0x0
+ *(.vector_60)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_60) <= (_vector_spacing << 0x5))), function at exception vector 60 too large)
+
+.vector_61 0x9d0059a0 0x0
+ *(.vector_61)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_61) <= (_vector_spacing << 0x5))), function at exception vector 61 too large)
+
+.vector_62 0x9d0059c0 0x0
+ *(.vector_62)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_62) <= (_vector_spacing << 0x5))), function at exception vector 62 too large)
+
+.vector_63 0x9d0059e0 0x0
+ *(.vector_63)
+ 0x00000001 ASSERT (((_vector_spacing == 0x0) || (SIZEOF (.vector_63) <= (_vector_spacing << 0x5))), function at exception vector 63 too large)
+
+.startup 0x9d006490 0x1e0
+ *(.startup)
+ .startup 0x9d006490 0x1e0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+
+.text 0x9d006a00 0x19ba0
+ 0x9d006a00 _text_begin = .
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ .text 0x9d006a00 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+ .text 0x9d006a18 0x1254 Extruder.o
+ 0x9d007520 Extruder_Status
+ 0x9d007668 InitExtruder
+ 0x9d006d2c T3InterruptHandler
+ 0x9d007b78 Extruder_Prime
+ 0x9d0078e8 Manual_Extruder
+ 0x9d006a18 T2InterruptHandler
+ 0x9d006fb4 Control_Temperature
+ 0x9d007ae0 Extruder_Reverse
+ 0x9d007478 Read_Analog
+ 0x9d006ea4 Control_Stepper_Motor
+ 0x9d007a34 delay_us
+ 0x9d0072b0 Thermistor_LookUp
+ 0x9d007a9c delay_ms
+ .text 0x9d007c6c 0xa6a4 FSIO.o
+ 0x9d00df3c ValidateChars
+ 0x9d00c818 FSftell
+ 0x9d00ca0c FSrewind
+ 0x9d00c848 FSremove
+ 0x9d00ca78 FSerror
+ 0x9d00adf4 FindEmptyEntries
+ 0x9d00ad1c CreateFirstCluster
+ 0x9d010e90 FSrmdir
+ 0x9d00b2f8 FILEallocate_new_cluster
+ 0x9d00cde8 ReadByte
+ 0x9d00f0b0 chdirhelper
+ 0x9d00ffe4 GetPreviousEntry
+ 0x9d00b060 PopulateEntries
+ 0x9d00b24c CacheTime
+ 0x9d00d6f8 FSfeof
+ 0x9d009070 GetFullClusterNumber
+ 0x9d00cb28 FILECreateHeadCluster
+ 0x9d00d738 FSfread
+ 0x9d00d048 FSattrib
+ 0x9d00f070 FSchdir
+ 0x9d00cca4 EraseCluster
+ 0x9d0119a4 eraseDir
+ 0x9d011f58 FindNext
+ 0x9d00e278 FSfseek
+ 0x9d00e630 ReadFAT
+ 0x9d010c58 writeDotEntries
+ 0x9d00b804 Fill_File_Object
+ 0x9d00b624 FSfclose
+ 0x9d00cea0 ReadDWord
+ 0x9d00c168 FSfopen
+ 0x9d00cf34 Cluster2Sector
+ 0x9d00eabc WriteFAT
+ 0x9d00ca9c FileObjectCopy
+ 0x9d00badc LoadDirAttrib
+ 0x9d00bc10 FILEerase
+ 0x9d00847c FILEget_next_cluster
+ 0x9d00a860 Cache_File_Entry
+ 0x9d00b458 FATfindEmptyCluster
+ 0x9d0109e4 CreateDIR
+ 0x9d00f85c FSgetcwd
+ 0x9d0085f0 DISKmount
+ 0x9d00ac18 CreateFileEntry
+ 0x9d00a4f8 Write_File_Entry
+ 0x9d00bdc0 FSrename
+ 0x9d009508 FSformat
+ 0x9d008acc LoadBootSector
+ 0x9d0081e8 FILEopen
+ 0x9d007db8 FILEfind
+ 0x9d00da84 FormatFileName
+ 0x9d011b1c FindFirst
+ 0x9d0090c8 FSCreateMBR
+ 0x9d010ee0 rmdirhelper
+ 0x9d00d648 flushData
+ 0x9d00ce24 ReadWord
+ 0x9d00d19c FSfwrite
+ 0x9d00dcfc FormatDirName
+ 0x9d0102ec FSmkdir
+ 0x9d0086b4 LoadMBR
+ 0x9d00a644 FAT_erase_cluster_chain
+ 0x9d01032c mkdirhelper
+ 0x9d007c6c FSInit
+ .text 0x9d012310 0xe30 SD-SPI.o
+ 0x9d01239c MDD_SDSPI_InitIO
+ 0x9d012378 MDD_SDSPI_ReadCapacity
+ 0x9d012c30 WriteSPIM
+ 0x9d012d94 MDD_SDSPI_MediaInitialize
+ 0x9d01296c MDD_SDSPI_SectorWrite
+ 0x9d012b54 MDD_SDSPI_WriteProtectState
+ 0x9d012c98 MDD_SDSPI_ReadMedia
+ 0x9d012310 MDD_SDSPI_MediaDetect
+ 0x9d012bfc CloseSPIM
+ 0x9d012b84 Delayms
+ 0x9d012354 MDD_SDSPI_ReadSectorSize
+ 0x9d012cf4 OpenSPIM
+ 0x9d01274c MDD_SDSPI_SectorRead
+ 0x9d012400 MDD_SDSPI_ShutdownMedia
+ 0x9d012444 SendMMCCmd
+ .text 0x9d013140 0x1174 G_Code.o
+ 0x9d014074 M_Code_M224
+ 0x9d013e90 M_Code_M107
+ 0x9d0139a8 G_Code_G0
+ 0x9d013a24 G_Code_G1
+ 0x9d0140c0 M_Code_M226
+ 0x9d013e58 M_Code_M106
+ 0x9d013be4 G_Code_G20
+ 0x9d013cdc M_Code_M101
+ 0x9d013b74 G_Code_G4
+ 0x9d01409c M_Code_M225
+ 0x9d013c84 G_Code_G91
+ 0x9d014280 M_Code_M228
+ 0x9d013140 G_CodeRun
+ 0x9d013f74 M_Code_M221
+ 0x9d013d48 M_Code_M104
+ 0x9d013fa4 M_Code_M222
+ 0x9d013c34 G_Code_G28
+ 0x9d013c0c G_Code_G21
+ 0x9d013abc G_Code_G2
+ 0x9d01400c M_Code_M223
+ 0x9d013c54 G_Code_G90
+ 0x9d0141a0 M_Code_M227
+ 0x9d013b18 G_Code_G3
+ 0x9d013d14 M_Code_M103
+ 0x9d013ec8 M_Code_M108
+ 0x9d013f40 M_Code_M220
+ 0x9d013ca4 G_Code_G92
+ .text 0x9d0142b4 0x1cd4 OLED.o
+ 0x9d0151bc OLED_Auto_Screen
+ 0x9d0152c8 OLED_RapManMove_Screen
+ 0x9d015b08 write_command
+ 0x9d015278 OLED_Home_Screen
+ 0x9d014d0c OLED_FastText57
+ 0x9d01497c OLED_Fill_RAM
+ 0x9d015cd4 OLED_Init
+ 0x9d015020 OLED_Start_Menu
+ 0x9d014378 OLED_UpdatePrintScreen
+ 0x9d015f18 OLED_Start_Msg
+ 0x9d014a3c OLED_ProgressBar
+ 0x9d014ba4 OLED_BitMapFill_RAM
+ 0x9d015ab4 WriteSPI
+ 0x9d015b90 write_data
+ 0x9d015228 OLED_ToolSetup_Screen
+ 0x9d014b10 OLED_ClearLine
+ 0x9d0147ec OLED_UpdateSetRPM
+ 0x9d0142b4 OLED_Printing_Screen
+ 0x9d01541c OLED_FileEnd_Screen
+ 0x9d01465c OLED_UpdateThermistorReading
+ 0x9d0154a4 OLED_SetCursor
+ 0x9d01453c OLED_Extruder_Screen
+ 0x9d015c14 Fill_RAM
+ 0x9d0150fc OLED_Manual_Screen
+ 0x9d014910 OLED_UpdateSetTemperature
+ .text 0x9d015f88 0x2328 RapMan.o
+ 0x9d0181e4 ShowPrintProgress
+ 0x9d016e04 GetMenuSelection
+ 0x9d0172a8 GetFileToOpen
+ 0x9d016088 Print_Gcode_File
+ 0x9d016fe4 RapMan_MoveTo
+ 0x9d017940 ReadData
+ 0x9d016db4 Start_Menu
+ 0x9d017140 OpenReadSDFile
+ 0x9d0177cc Get_file_Type
+ 0x9d0165e0 ErrorCondition
+ 0x9d017f24 FlushBuffer
+ 0x9d016b7c GetTool_ID
+ 0x9d0164c4 Pause_Print
+ 0x9d015f88 main
+ 0x9d01681c Setup
+ 0x9d017acc GetCodes
+ 0x9d018110 ShowBufferFillState
+ .text 0x9d0182b0 0x280c Stepper.o
+ 0x9d0187c8 RapMan_Home
+ 0x9d0186f4 Axis_Stepper_Motors
+ 0x9d018e98 GoToRest
+ 0x9d0197a4 Stepper_InitIO
+ 0x9d01a7d8 f_to_ul
+ 0x9d019d14 OriginOffset
+ 0x9d01a71c Stepper_SaveValues
+ 0x9d019e64 ResetOrigin
+ 0x9d0182b0 Manual_Mode
+ 0x9d0199b0 Stepper_LoadNewValues
+ 0x9d019b88 Stepper_CalcSteps
+ 0x9d019f74 Bresenham_3D_Line
+ 0x9d018fa8 T4Interrupt
+ 0x9d01a970 AddToStepBuffer
+ 0x9d01a894 f_to_sl
+ 0x9d019f1c Stepper_Run3DLine
+ .text 0x9d01aabc 0x168 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memcpy.o)
+ 0x9d01aabc memcpy
+ .text 0x9d01ac24 0xa8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memset.o)
+ 0x9d01ac24 memset
+ .text 0x9d01accc 0x1a0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strcpy.o)
+ 0x9d01accc strcpy
+ .text 0x9d01ae6c 0x168 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strlen.o)
+ 0x9d01ae6c strlen
+ .text.general_exception
+ 0x9d01afd4 0xd0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(general-exception.o)
+ 0x9d01afd4 _general_exception_context
+ .text.strncpy 0x9d01b0a4 0xd0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ 0x9d01b0a4 strncpy
+ .text.strchr 0x9d01b174 0x90 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ 0x9d01b174 strchr
+ .text.exit 0x9d01b204 0x9c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ 0x9d01b204 exit
+ .text.tolower 0x9d01b2a0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b2a0 tolower
+ .text.toupper 0x9d01b2c0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b2c0 toupper
+ .text.isalnum 0x9d01b2e0 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b2e0 isalnum
+ .text.isalpha 0x9d01b2f8 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b2f8 isalpha
+ .text.isascii 0x9d01b310 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b310 isascii
+ .text.iscntrl 0x9d01b318 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b318 iscntrl
+ .text.isdigit 0x9d01b330 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b330 isdigit
+ .text.isgraph 0x9d01b348 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b348 isgraph
+ .text.islower 0x9d01b360 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b360 islower
+ .text.isprint 0x9d01b378 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b378 isprint
+ .text.ispunct 0x9d01b390 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b390 ispunct
+ .text.isspace 0x9d01b3a8 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b3a8 isspace
+ .text.isupper 0x9d01b3c0 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b3c0 isupper
+ .text.isxdigit
+ 0x9d01b3d8 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b3d8 isxdigit
+ .text.toascii 0x9d01b3f0 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b3f0 toascii
+ .text._tolower
+ 0x9d01b3f8 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b3f8 _tolower
+ .text._toupper
+ 0x9d01b400 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x9d01b400 _toupper
+ .text.atof 0x9d01b408 0x1c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ 0x9d01b408 atof
+ .text.atoi 0x9d01b424 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ 0x9d01b424 atoi
+ .text.strtol 0x9d01b444 0x1ec C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ 0x9d01b444 strtol
+ .text.strtod 0x9d01b630 0x1c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ 0x9d01b630 strtod
+ .text._filbuf_simple
+ 0x9d01b64c 0x48 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0x9d01b64c _filbuf_simple
+ .text._fflush_simple
+ 0x9d01b694 0x6c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0x9d01b694 _fflush_simple
+ .text._flsbuf_simple
+ 0x9d01b700 0xdc C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0x9d01b700 _flsbuf_simple
+ .text._fwrite_simple
+ 0x9d01b7dc 0x84 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0x9d01b7dc _fwrite_simple
+ .text._fsync_simple
+ 0x9d01b860 0x34 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0x9d01b860 _fsync_simple
+ .text.__vsnprintf
+ 0x9d01b894 0x60 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ 0x9d01b894 __vsnprintf
+ .text.vsprintf
+ 0x9d01b8f4 0x2c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ 0x9d01b8f4 vsprintf
+ .text.sprintf 0x9d01b920 0x34 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ 0x9d01b920 sprintf
+ .text._weak_pthread_mutex_init
+ 0x9d01b954 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b954 _weak_pthread_mutex_init
+ 0x9d01b954 pthread_mutex_init
+ .text._weak_pthread_mutex_destroy
+ 0x9d01b95c 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b95c _weak_pthread_mutex_destroy
+ 0x9d01b95c pthread_mutex_destroy
+ .text._weak_pthread_mutex_lock
+ 0x9d01b964 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b964 _weak_pthread_mutex_lock
+ 0x9d01b964 pthread_mutex_lock
+ .text._weak_pthread_mutex_trylock
+ 0x9d01b96c 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b96c _weak_pthread_mutex_trylock
+ 0x9d01b96c pthread_mutex_trylock
+ .text._weak_pthread_mutex_unlock
+ 0x9d01b974 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b974 _weak_pthread_mutex_unlock
+ 0x9d01b974 pthread_mutex_unlock
+ .text._weak_pthread_mutex_setname_np
+ 0x9d01b97c 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b97c pthread_mutex_setname_np
+ 0x9d01b97c _weak_pthread_mutex_setname_np
+ .text._weak_pthread_mutexattr_init
+ 0x9d01b984 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b984 _weak_pthread_mutexattr_init
+ 0x9d01b984 pthread_mutexattr_init
+ .text._weak_pthread_mutexattr_destroy
+ 0x9d01b98c 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b98c pthread_mutexattr_destroy
+ 0x9d01b98c _weak_pthread_mutexattr_destroy
+ .text._weak_pthread_mutexattr_setname_np
+ 0x9d01b994 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b994 _weak_pthread_mutexattr_setname_np
+ 0x9d01b994 pthread_mutexattr_setname_np
+ .text._weak_pthread_mutexattr_settype_np
+ 0x9d01b99c 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b99c _weak_pthread_mutexattr_settype_np
+ 0x9d01b99c pthread_mutexattr_settype_np
+ .text._weak_pthread_sysconf_np
+ 0x9d01b9a4 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9a4 _weak_pthread_sysconf_np
+ 0x9d01b9a4 pthread_sysconf_np
+ .text._weak_pthread_sigdisable_np
+ 0x9d01b9ac 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9ac _weak_pthread_sigdisable_np
+ 0x9d01b9ac pthread_sigdisable_np
+ .text._weak_pthread_sigrestore_np
+ 0x9d01b9b4 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9b4 pthread_sigrestore_np
+ 0x9d01b9b4 _weak_pthread_sigrestore_np
+ .text._weak__pthread_cleanup_push
+ 0x9d01b9bc 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9bc _weak__pthread_cleanup_push
+ 0x9d01b9bc _pthread_cleanup_push
+ .text._weak__pthread_cleanup_pop
+ 0x9d01b9c4 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9c4 _pthread_cleanup_pop
+ 0x9d01b9c4 _weak__pthread_cleanup_pop
+ .text._weak__pthread_cleanup_push_defer
+ 0x9d01b9cc 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9cc _weak__pthread_cleanup_push_defer
+ 0x9d01b9cc _pthread_cleanup_push_defer
+ .text._weak__pthread_cleanup_pop_restore
+ 0x9d01b9d4 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9d4 _pthread_cleanup_pop_restore
+ 0x9d01b9d4 _weak__pthread_cleanup_pop_restore
+ .text._weak_pthread_once
+ 0x9d01b9dc 0x2c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01b9dc _weak_pthread_once
+ 0x9d01b9dc pthread_once
+ 0x9d01b9dc _pthread_once
+ .text._weak_pthread_key_create
+ 0x9d01ba08 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01ba08 pthread_key_create
+ 0x9d01ba08 _weak_pthread_key_create
+ .text._weak_pthread_setspecific
+ 0x9d01ba10 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01ba10 _weak_pthread_setspecific
+ 0x9d01ba10 pthread_setspecific
+ .text._weak_pthread_getspecific
+ 0x9d01ba18 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01ba18 pthread_getspecific
+ 0x9d01ba18 _weak_pthread_getspecific
+ .text._weak__libc_private_storage
+ 0x9d01ba20 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x9d01ba20 _libc_private_storage
+ 0x9d01ba20 _weak__libc_private_storage
+ .text._general_exception_handler
+ 0x9d01ba28 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ 0x9d01ba28 _general_exception_handler
+ .text._bootstrap_exception_handler
+ 0x9d01ba30 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ 0x9d01ba30 _bootstrap_exception_handler
+ .text._on_reset
+ 0x9d01ba38 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ 0x9d01ba38 _on_reset
+ .text._on_bootstrap
+ 0x9d01ba40 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ 0x9d01ba40 _on_bootstrap
+ .text 0x9d01ba48 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-nmi-handler.o)
+ 0x9d01ba48 _nmi_handler
+ .text._mon_getc
+ 0x9d01ba60 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ 0x9d01ba60 _mon_getc
+ .text._mon_write
+ 0x9d01ba68 0x4c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ 0x9d01ba68 _mon_write
+ .text._exit 0x9d01bab4 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ 0x9d01bab4 _exit
+ .text.__sputn 0x9d01babc 0x6c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .text.repl 0x9d01bb28 0x74 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .text._outcnvrt
+ 0x9d01bb9c 0xe4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .text.rounded 0x9d01bc80 0x134 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .text.vfprintf
+ 0x9d01bdb4 0x1554 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ 0x9d01bdb4 vfprintf
+ .text.vprintf 0x9d01d308 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ 0x9d01d308 vprintf
+ .text._filbuf_string
+ 0x9d01d338 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .text._flsbuf_string
+ 0x9d01d340 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .text._fflush_string
+ 0x9d01d348 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .text._fwrite_string
+ 0x9d01d350 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .text._fsync_string
+ 0x9d01d358 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .text.fputc 0x9d01d360 0xac C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ 0x9d01d360 fputc
+ .text.putc 0x9d01d40c 0x1c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ 0x9d01d40c putc
+ .text.putchar 0x9d01d428 0x24 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ 0x9d01d428 putchar
+ .text._mon_putc
+ 0x9d01d44c 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ 0x9d01d44c _mon_putc
+ .text 0x9d01d474 0x5c8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(mod32.o)
+ 0x9d01d7b8 __mchp_ldexp
+ 0x9d01d474 dpfmod
+ 0x9d01d920 modf
+ 0x9d01d474 fmod
+ 0x9d01d7b8 dpldexp
+ 0x9d01d920 dpmodf
+ 0x9d01d714 dpfrexp
+ 0x9d01d714 frexp
+ .text 0x9d01da3c 0xfc C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(ceil32.o)
+ 0x9d01da3c ceil
+ 0x9d01da3c dpceil
+ .text 0x9d01db38 0x1128 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(dp32.o)
+ 0x9d01ebe8 fabs
+ 0x9d01eaac __eqdf2
+ 0x9d01eaac __gtdf2
+ 0x9d01db38 dpsub
+ 0x9d01e740 __floatsidf
+ 0x9d01eaac __ltdf2
+ 0x9d01e7b4 ultodp
+ 0x9d01df64 dpmul
+ 0x9d01e8a8 dptofp
+ 0x9d01ea28 __fixunsdfsi
+ 0x9d01eaac dpcmp
+ 0x9d01e804 __extendsfdf2
+ 0x9d01db40 __adddf3
+ 0x9d01ea28 dptoul
+ 0x9d01e28c dpdiv
+ 0x9d01e740 litodp
+ 0x9d01e9a0 __fixdfsi
+ 0x9d01eaac __ledf2
+ 0x9d01e804 fptodp
+ 0x9d01ebd0 __negdf2
+ 0x9d01db40 dpadd
+ 0x9d01e28c __divdf3
+ 0x9d01df64 __muldf3
+ 0x9d01e8a8 __truncdfsf2
+ 0x9d01eaac __nedf2
+ 0x9d01e9a0 dptoli
+ 0x9d01ec04 nan
+ 0x9d01ebe8 dpfabs
+ 0x9d01eaac __gedf2
+ 0x9d01ec04 dpnan
+ 0x9d01db38 __subdf3
+ .text 0x9d01ec60 0x8ec C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libm.a(fp32.o)
+ 0x9d01f08c __divsf3
+ 0x9d01f2b8 sitofp
+ 0x9d01f360 __fixsfsi
+ 0x9d01f08c fpdiv
+ 0x9d01ec60 __subsf3
+ 0x9d01f360 fptoli
+ 0x9d01f44c __lesf2
+ 0x9d01f4e0 fabsf
+ 0x9d01f44c __nesf2
+ 0x9d01f314 uitofp
+ 0x9d01f44c __gtsf2
+ 0x9d01f3d8 fptoui
+ 0x9d01f4e0 fpfabs
+ 0x9d01f2b8 __floatsisf
+ 0x9d01f360 fptosi
+ 0x9d01f500 fpnan
+ 0x9d01f44c __eqsf2
+ 0x9d01ec68 fpadd
+ 0x9d01f4f0 __negsf2
+ 0x9d01f44c __ltsf2
+ 0x9d01ec60 fpsub
+ 0x9d01f44c fpcmp
+ 0x9d01eed4 __mulsf3
+ 0x9d01f44c __gesf2
+ 0x9d01f500 nanf
+ 0x9d01f2b8 litofp
+ 0x9d01eed4 fpmul
+ 0x9d01f3d8 __fixunssfsi
+ 0x9d01ec68 __addsf3
+ 0x9d01f3d8 fptoul
+ 0x9d01f314 ultofp
+ .text.__strtod
+ 0x9d01f54c 0x444 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ 0x9d01f54c __strtod
+ .text.__ldexp 0x9d01f990 0x220 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ 0x9d01f990 __ldexp
+ .text.getcSPI2
+ 0x9d01fbb0 0x24 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ 0x9d01fbb0 getcSPI2
+ .text.OpenSPI2
+ 0x9d01fbd4 0x64 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ 0x9d01fbd4 OpenSPI2
+ .text.INTDisableInterrupts
+ 0x9d01fc38 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ 0x9d01fc38 INTDisableInterrupts
+ .text.INTEnableSystemMultiVectoredInt
+ 0x9d01fc40 0x34 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ 0x9d01fc40 INTEnableSystemMultiVectoredInt
+ .text.INTRestoreInterrupts
+ 0x9d01fc74 0x1c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ 0x9d01fc74 INTRestoreInterrupts
+ .text.INTEnableInterrupts
+ 0x9d01fc90 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+ 0x9d01fc90 INTEnableInterrupts
+ .text 0x9d01fc98 0x47c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_udivdi3.o)
+ 0x9d01fc98 __udivdi3
+ .text 0x9d020114 0x48c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_umoddi3.o)
+ 0x9d020114 __umoddi3
+ *(.text.*personality*)
+ *(.gnu.warning)
+ *(.mips16.fn.*)
+ *(.mips16.call.*)
+ 0x9d0205a0 _text_end = .
+
+.rodata 0x9d0205a0 0x1870
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ .rodata 0x9d0205a0 0xb8 Extruder.o
+ 0x9d0205a0 Therm_Table
+ .rodata 0x9d020658 0xf0 FSIO.o
+ .rodata 0x9d020748 0xcc SD-SPI.o
+ 0x9d020748 sdmmc_cmdtable
+ .rodata 0x9d020814 0x14 G_Code.o
+ .rodata 0x9d020828 0xfe0 OLED.o
+ 0x9d021528 TEXT2
+ 0x9d020c28 BfB_LOGO
+ 0x9d021028 EXTRUDER_SCREEN
+ 0x9d020828 RAPMAN_LOGO
+ 0x9d021428 TEXT
+ .rodata 0x9d021808 0x1c4 RapMan.o
+ *fill* 0x9d0219cc 0x4 00
+ .rodata 0x9d0219d0 0xc8 Stepper.o
+ .rodata 0x9d021a98 0x14 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ 0x9d021a98 _io_funcs
+ .rodata 0x9d021aac 0x104 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctype.o)
+ 0x9d021aac _ctype
+ .rodata 0x9d021bb0 0x114 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ *fill* 0x9d021cc4 0x4 00
+ .rodata.cst8 0x9d021cc8 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ 0x30 (size before relaxing)
+ .rodata.str1.4
+ 0x9d021cf0 0x1b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ 0x1c (size before relaxing)
+ *fill* 0x9d021d0b 0x1 00
+ .rodata 0x9d021d0c 0x14 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ 0x9d021d0c _io_strfuncs
+ .rodata 0x9d021d20 0x48 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .rodata.cst8 0x9d021d68 0x10 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ 0x18 (size before relaxing)
+ .rodata.cst8 0x9d021d78 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .rodata 0x9d021d90 0x80 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_brg_tbl_lib.o)
+ 0x9d021d90 SpiBrgConvTbl
+ *(.rodata1)
+ 0x9d021e10 . = ALIGN (0x4)
+
+.sdata2 0x9d021e10 0x0
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ 0x9d021e10 . = ALIGN (0x4)
+
+.sbss2 0x9d021e10 0x0
+ *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+ 0x9d021e10 . = ALIGN (0x4)
+
+.eh_frame_hdr
+ *(.eh_frame_hdr)
+
+.eh_frame 0x9d021e10 0x50
+ *(.eh_frame)
+ .eh_frame 0x9d021e10 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_udivdi3.o)
+ .eh_frame 0x9d021e30 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_umoddi3.o)
+
+.dbg_data 0xa0000000 0x0
+ 0xa0000000 . = (. + DEFINED (_DEBUGGER)?0x200:0x0)
+
+.data 0xa0000000 0xf4 load address 0x9d021e60
+ 0xa0000000 _data_begin = .
+ *(.data .data.* .gnu.linkonce.d.*)
+ .data 0xa0000000 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ 0xa0000000 __exfun_mx
+ .data 0xa0000020 0xd4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ *(.gnu.linkonce.d.*personality*)
+ *(.data1)
+ 0x9d021e60 _data_image_begin = LOADADDR (.data)
+
+.eh_frame
+ *(.eh_frame)
+ 0xa00080f0 _gp = (ALIGN (0x10) + 0x7ff0)
+
+.got
+ *(.got.plt)
+ *(.got)
+
+.sdata 0xa00000f4 0x2c load address 0x9d021f54
+ 0xa00000f4 _sdata_begin = .
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ .sdata 0xa00000f4 0xc Extruder.o
+ 0xa00000fc Direction
+ 0xa00000f8 PR3_Setting
+ 0xa00000f4 RPM_Setting
+ .sdata 0xa0000100 0xc FSIO.o
+ 0xa0000100 gLastFATSectorRead
+ 0xa0000108 cwdptr
+ 0xa0000104 gLastDataSectorRead
+ .sdata 0xa000010c 0x10 Stepper.o
+ 0xa000010c BufferEmpty
+ 0xa0000110 StepRPM_Setting
+ 0xa0000118 FirstPass
+ 0xa0000114 PR4_Setting
+ .sdata 0xa000011c 0x4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ 0xa000011c _libc_data
+ 0xa0000120 _sdata_end = .
+
+.lit8
+ *(.lit8)
+
+.lit4
+ *(.lit4)
+ 0xa0000120 . = ALIGN (0x4)
+ 0xa0000120 _data_end = .
+ 0xa0000120 _bss_begin = .
+
+.sbss 0xa0000120 0x25c
+ 0xa0000120 _sbss_begin = .
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ .sbss 0xa0000120 0x34 Extruder.o
+ 0xa000014c UART_Counter
+ 0xa0000144 RPM_Setting_Old
+ 0xa0000134 temperature_OK
+ 0xa000012c AveSamplesThermistor
+ 0xa000013c SetTemperature
+ 0xa0000124 ADC_reading
+ 0xa0000128 SampleCountThermistor
+ 0xa0000130 HeaterON
+ 0xa0000148 New_Data
+ 0xa0000150 Temperature_Cycle
+ 0xa0000138 update_temp
+ 0xa0000140 Step_Cycle
+ 0xa0000120 Thermistor_Failure_Counter
+ .sbss 0xa0000154 0xc FSIO.o
+ 0xa0000154 gNeedFATWrite
+ 0xa0000158 gBufferOwner
+ 0xa000015c gNeedDataWrite
+ 0xa000015f recache
+ 0xa000015d nextClusterIsLast
+ 0xa000015e gBufferZeroed
+ .sbss 0xa0000160 0x1c G_Code.o
+ 0xa0000170 GZ_On
+ 0xa0000164 Inch_mm
+ 0xa0000178 GJ_On
+ 0xa000016c GY_On
+ 0xa0000160 F_Code
+ 0xa0000174 GI_On
+ 0xa0000168 GX_On
+ .sbss 0xa000017c 0x40 RapMan.o
+ 0xa0000190 ADC_readingToolID
+ 0xa00001a0 ToolType
+ 0xa000018c ItemsRead
+ 0xa0000198 AveSamplesToolID
+ 0xa0000194 SampleCountToolID
+ 0xa00001b0 FileType
+ 0xa000019c Operation_Mode
+ 0xa00001a8 SetRPM
+ 0xa00001ac GoToRestSpeed
+ 0xa0000188 EOF_Flag
+ 0xa00001a4 SetTemp
+ 0xa0000184 Word_Count
+ 0xa000017c PosInFile
+ 0xa0000180 LineNumber
+ .sbss 0xa00001bc 0x48 Stepper.o
+ 0xa00001d8 Save2_Z
+ 0xa00001c0 ZFeed_Rate
+ 0xa00001ec ManualStepperInt_Cycle
+ 0xa00001bc xyrate
+ 0xa00001e8 StepperInt_Cycle
+ 0xa00001c8 Save_Y
+ 0xa00001f1 moveY
+ 0xa00001dc Save3_X
+ 0xa00001cc Save_Z
+ 0xa00001d4 Save2_Y
+ 0xa00001f4 Manual_Mode_Set
+ 0xa00001d0 Save2_X
+ 0xa00001e4 Save3_Z
+ 0xa00001f0 moveX
+ 0xa00001f2 moveZ
+ 0xa00001e0 Save3_Y
+ 0xa00001c4 Save_X
+ .sbss 0xa0000204 0x4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(errno.o)
+ 0xa0000204 errno
+ *(.scommon)
+ .scommon 0xa0000208 0x5c Extruder.o
+ 0xa0000208 S_F_Code
+ 0xa000020c LowValue
+ 0xa0000210 Fraction
+ 0xa0000214 temperature1
+ 0xa0000218 Reverse_Steps
+ 0xa000021c FeedRate_ManualChange
+ 0xa0000220 StepReady
+ 0xa0000224 FastMoveMotorEnable
+ 0xa0000228 G_CodeRapidZMove
+ 0xa000022c EnableFanControl
+ 0xa0000230 G_CodeRapidXYMove
+ 0xa0000234 Ex_Reverse
+ 0xa0000238 Change_M104
+ 0xa0000239 RPM_Change
+ 0xa000023c Feed_Rate
+ 0xa0000240 Range
+ 0xa0000244 Prime_Steps
+ 0xa0000248 Reverse_Step_Count
+ 0xa000024c DataVal
+ 0xa0000250 HighValue
+ 0xa0000254 raw_temperature
+ 0xa0000258 TempVal
+ 0xa000025c Temp_Change
+ 0xa0000260 Prime_Step_Count
+ .scommon 0xa0000264 0x1c FSIO.o
+ 0xa0000264 gFileSlotOpen
+ 0xa0000267 gTimeCrtMS
+ 0xa0000268 gTimeCrtTime
+ 0xa000026c FatRootDirClusterValue
+ 0xa0000270 gTimeWrtDate
+ 0xa0000272 gTimeCrtDate
+ 0xa0000274 TempClusterCalc
+ 0xa0000278 dirCleared
+ 0xa000027a gTimeAccDate
+ 0xa000027c FSerrno
+ 0xa000027e gTimeWrtTime
+ .scommon 0xa0000280 0x4 SD-SPI.o
+ 0xa0000280 MDD_SDSPI_finalLBA
+ .scommon 0xa0000284 0x24 G_Code.o
+ 0xa0000284 M_Code
+ 0xa0000288 G_Code
+ 0xa000028c GY
+ 0xa0000290 GI_Val
+ 0xa0000294 GJ_Val
+ 0xa0000298 GZ
+ 0xa000029c GP_Val
+ 0xa00002a0 GS_Val
+ 0xa00002a4 GX
+ .scommon 0xa00002a8 0x4 OLED.o
+ 0xa00002a8 ExtrusionRate
+ .scommon 0xa00002ac 0x70 RapMan.o
+ 0xa00002ac fDim_1
+ 0xa00002b0 Dim_4
+ 0xa00002b8 X_Rest_mm
+ 0xa00002bc iInst_Code
+ 0xa00002c0 FilePointer
+ 0xa00002c4 Inst_Code
+ 0xa00002cc fDim_4
+ 0xa00002d0 fDim_2
+ 0xa00002d4 SaveFileSize
+ 0xa00002d8 Inst_Code_Letter
+ 0xa00002d9 Dim_4_Letter
+ 0xa00002dc Ops_mode
+ 0xa00002e0 pointer
+ 0xa00002e4 Y_Rest_mm
+ 0xa00002e8 Dim_2_Letter
+ 0xa00002ec ManualChange
+ 0xa00002f0 Dim_2
+ 0xa00002f8 Dim_3_Letter
+ 0xa00002f9 ExtruderStatus
+ 0xa00002fc Z_Rest_mm
+ 0xa0000300 Dim_3
+ 0xa0000308 CharBuffer
+ 0xa0000309 Dim_1_Letter
+ 0xa000030c fDim_3
+ 0xa0000310 PauseFlag
+ 0xa0000314 Dim_1
+ .scommon 0xa000031c 0x60 Stepper.o
+ 0xa000031c SBReady
+ 0xa0000320 lX_Steps
+ 0xa0000324 lSaveSteps_X
+ 0xa0000328 lHomeStepsX
+ 0xa000032c lSaveSteps_Z
+ 0xa0000330 Delta_Z
+ 0xa0000334 Delta_Y
+ 0xa0000338 SBR
+ 0xa000033c SBCode
+ 0xa0000340 lHomeStepsY
+ 0xa0000344 Y_Steps
+ 0xa0000348 lZ_Steps
+ 0xa000034c lHomeStepsZ
+ 0xa0000350 X_Steps
+ 0xa0000354 Set_Y_Dir
+ 0xa0000358 lSaveSteps_Y
+ 0xa000035c SBW
+ 0xa0000360 Set_Z_Dir
+ 0xa0000364 S_M_Code
+ 0xa0000368 SBuf
+ 0xa000036c Delta_X
+ 0xa0000370 lY_Steps
+ 0xa0000374 Set_X_Dir
+ 0xa0000378 Z_Steps
+ 0xa000037c _sbss_end = .
+
+.bss 0xa000037c 0xf04
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ .bss 0xa000037c 0x88 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ .bss 0xa0000404 0x80 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .bss 0xa0000484 0x4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0xa0000484 __isthreaded
+ *(COMMON)
+ COMMON 0xa0000488 0x14 Extruder.o
+ 0xa0000488 Message
+ COMMON 0xa000049c 0x5a2 FSIO.o
+ 0xa000049c gDataBuffer
+ 0xa000069c cwd
+ 0xa00006d8 defaultString
+ 0xa00006e8 tempCWDobj
+ 0xa0000724 gFATBuffer
+ 0xa0000924 gFileArray
+ 0xa00009d8 gDiskData
+ 0xa00009f8 gFileTemp
+ 0xa0000a34 defaultArray
+ *fill* 0xa0000a3e 0x2 00
+ COMMON 0xa0000a40 0x40 RapMan.o
+ 0xa0000a40 LineBuffer
+ 0xa0000a74 SaveFileName
+ COMMON 0xa0000a80 0x800 Stepper.o
+ 0xa0000a80 SCB
+ 0xa0001280 . = ALIGN (0x4)
+ 0xa0001280 . = ALIGN (0x4)
+ 0xa0001280 _end = .
+ 0xa0001280 _bss_end = .
+
+.heap 0xa0001280 0x0
+ 0xa0001280 _heap = .
+ 0xa0001280 . = (. + _min_heap_size)
+
+.stack 0xa0001280 0x400
+ 0xa0001680 . = (. + _min_stack_size)
+ *fill* 0xa0001280 0x400 00
+
+.ramfunc 0xa0001800 0x0 load address 0x9d021f80
+ 0xa0001800 _ramfunc_begin = .
+ *(.ramfunc .ramfunc.*)
+ 0xa0001800 . = ALIGN (0x4)
+ 0xa0001800 _ramfunc_end = .
+ 0x9d021f80 _ramfunc_image_begin = LOADADDR (.ramfunc)
+ 0x00000000 _ramfunc_length = SIZEOF (.ramfunc)
+ 0x00001800 _bmxdkpba_address = (_ramfunc_begin - 0xa0000000)
+ 0x00008000 _bmxdudba_address = 0x8000
+ 0x00008000 _bmxdupba_address = 0x8000
+ 0xa0008000 _stack = (_ramfunc_length > 0x0)?(_ramfunc_begin - 0x4):0xa0008000
+ 0x00000001 ASSERT (((_min_stack_size + _min_heap_size) <= (_stack - _heap)), Not enough space to allocate both stack and heap. Reduce heap and/or stack size.)
+
+.pdr 0x00000000 0x2240
+ *(.pdr)
+ .pdr 0x00000000 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+ .pdr 0x000000a0 0x1e0 Extruder.o
+ .pdr 0x00000280 0x7a0 FSIO.o
+ .pdr 0x00000a20 0x1e0 SD-SPI.o
+ .pdr 0x00000c00 0x360 G_Code.o
+ .pdr 0x00000f60 0x320 OLED.o
+ .pdr 0x00001280 0x220 RapMan.o
+ .pdr 0x000014a0 0x220 Stepper.o
+ .pdr 0x000016c0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memcpy.o)
+ .pdr 0x000016e0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memset.o)
+ .pdr 0x00001700 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strcpy.o)
+ .pdr 0x00001720 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strlen.o)
+ .pdr 0x00001740 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(general-exception.o)
+ .pdr 0x00001760 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .pdr 0x00001780 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .pdr 0x000017a0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .pdr 0x000017c0 0x220 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .pdr 0x000019e0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .pdr 0x00001a00 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .pdr 0x00001a20 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .pdr 0x00001a40 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .pdr 0x00001a60 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .pdr 0x00001b00 0x60 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .pdr 0x00001b60 0x2c0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .pdr 0x00001e20 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .pdr 0x00001e40 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .pdr 0x00001e60 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .pdr 0x00001e80 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .pdr 0x00001ea0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-nmi-handler.o)
+ .pdr 0x00001ec0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .pdr 0x00001ee0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .pdr 0x00001f00 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .pdr 0x00001f20 0xc0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .pdr 0x00001fe0 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .pdr 0x00002080 0x60 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .pdr 0x000020e0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .pdr 0x00002100 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .pdr 0x00002120 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .pdr 0x00002140 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .pdr 0x00002160 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .pdr 0x00002180 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .pdr 0x000021a0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .pdr 0x000021c0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .pdr 0x000021e0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+ .pdr 0x00002200 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_udivdi3.o)
+ .pdr 0x00002220 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_umoddi3.o)
+
+.reginfo 0x00000000 0x18
+ *(.reginfo)
+ .reginfo 0x00000000 0x18 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib/crt0.o
+
+.stab
+ *(.stab)
+
+.stabstr
+ *(.stabstr)
+
+.stab.excl
+ *(.stab.excl)
+
+.stab.exclstr
+ *(.stab.exclstr)
+
+.stab.index
+ *(.stab.index)
+
+.stab.indexstr
+ *(.stab.indexstr)
+
+.comment 0x00000000 0x1479
+ *(.comment)
+ .comment 0x00000000 0x4d Extruder.o
+ .comment 0x0000004d 0x4d FSIO.o
+ .comment 0x0000009a 0x4d SD-SPI.o
+ .comment 0x000000e7 0x4d G_Code.o
+ .comment 0x00000134 0x4d OLED.o
+ .comment 0x00000181 0x4d RapMan.o
+ .comment 0x000001ce 0x4d Stepper.o
+ .comment 0x0000021b 0x56 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(memset.o)
+ .comment 0x00000271 0x56 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strcpy.o)
+ .comment 0x000002c7 0x56 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strlen.o)
+ .comment 0x0000031d 0x9d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .comment 0x000003ba 0x9c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .comment 0x00000456 0x9a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .comment 0x000004f0 0x9c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .comment 0x0000058c 0x9a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .comment 0x00000626 0x9a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .comment 0x000006c0 0x9c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .comment 0x0000075c 0x9c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .comment 0x000007f8 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ .comment 0x00000898 0xa1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .comment 0x00000939 0x9f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .comment 0x000009d8 0x9b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .comment 0x00000a73 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .comment 0x00000ac0 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .comment 0x00000b0d 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .comment 0x00000b5a 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .comment 0x00000ba7 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .comment 0x00000bf4 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .comment 0x00000c41 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .comment 0x00000c8e 0x9b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctype.o)
+ .comment 0x00000d29 0x9b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(errno.o)
+ .comment 0x00000dc4 0x9f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .comment 0x00000e63 0xa2 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .comment 0x00000f05 0x9d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .comment 0x00000fa2 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .comment 0x00000fef 0xea C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .comment 0x000010d9 0xeb C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .comment 0x000011c4 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .comment 0x00001211 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .comment 0x0000125e 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .comment 0x000012ab 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .comment 0x000012f8 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .comment 0x00001345 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_brg_tbl_lib.o)
+ .comment 0x00001392 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+ .comment 0x000013df 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_udivdi3.o)
+ .comment 0x0000142c 0x4d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4\libgcc.a(_umoddi3.o)
+
+.debug
+ *(.debug)
+
+.line
+ *(.line)
+
+.debug_srcinfo
+ *(.debug_srcinfo)
+
+.debug_sfnames
+ *(.debug_sfnames)
+
+.debug_aranges 0x00000000 0x740
+ *(.debug_aranges)
+ .debug_aranges
+ 0x00000000 0x20 Extruder.o
+ .debug_aranges
+ 0x00000020 0x20 FSIO.o
+ .debug_aranges
+ 0x00000040 0x20 SD-SPI.o
+ .debug_aranges
+ 0x00000060 0x20 G_Code.o
+ .debug_aranges
+ 0x00000080 0x20 OLED.o
+ .debug_aranges
+ 0x000000a0 0x20 RapMan.o
+ .debug_aranges
+ 0x000000c0 0x20 Stepper.o
+ .debug_aranges
+ 0x000000e0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_aranges
+ 0x00000108 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_aranges
+ 0x00000130 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_aranges
+ 0x00000158 0xa8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_aranges
+ 0x00000200 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_aranges
+ 0x00000228 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_aranges
+ 0x00000250 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_aranges
+ 0x00000278 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_aranges
+ 0x000002a0 0x48 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_aranges
+ 0x000002e8 0x38 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_aranges
+ 0x00000320 0xd0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_aranges
+ 0x000003f0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_aranges
+ 0x00000418 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_aranges
+ 0x00000440 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_aranges
+ 0x00000468 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_aranges
+ 0x00000490 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_aranges
+ 0x000004b8 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_aranges
+ 0x000004e0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_aranges
+ 0x00000508 0x50 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_aranges
+ 0x00000558 0x48 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .debug_aranges
+ 0x000005a0 0x38 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_aranges
+ 0x000005d8 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_aranges
+ 0x00000600 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_aranges
+ 0x00000628 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_aranges
+ 0x00000650 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_aranges
+ 0x00000678 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_aranges
+ 0x000006a0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_aranges
+ 0x000006c8 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_aranges
+ 0x000006f0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_aranges
+ 0x00000718 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_pubnames
+ 0x00000000 0x21eb
+ *(.debug_pubnames)
+ .debug_pubnames
+ 0x00000000 0x3ef Extruder.o
+ .debug_pubnames
+ 0x000003ef 0x5d9 FSIO.o
+ .debug_pubnames
+ 0x000009c8 0x18c SD-SPI.o
+ .debug_pubnames
+ 0x00000b54 0x31b G_Code.o
+ .debug_pubnames
+ 0x00000e6f 0x30a OLED.o
+ .debug_pubnames
+ 0x00001179 0x469 RapMan.o
+ .debug_pubnames
+ 0x000015e2 0x42b Stepper.o
+ .debug_pubnames
+ 0x00001a0d 0x1e C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_pubnames
+ 0x00001a2b 0x1d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_pubnames
+ 0x00001a48 0x1b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_pubnames
+ 0x00001a63 0xe1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_pubnames
+ 0x00001b44 0x1b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_pubnames
+ 0x00001b5f 0x1b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_pubnames
+ 0x00001b7a 0x1d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_pubnames
+ 0x00001b97 0x1d C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_pubnames
+ 0x00001bb4 0x70 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_pubnames
+ 0x00001c24 0x3b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_pubnames
+ 0x00001c5f 0x2da C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_pubnames
+ 0x00001f39 0x31 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_pubnames
+ 0x00001f6a 0x33 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_pubnames
+ 0x00001f9d 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_pubnames
+ 0x00001fbd 0x24 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_pubnames
+ 0x00001fe1 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_pubnames
+ 0x00002001 0x21 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_pubnames
+ 0x00002022 0x1c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_pubnames
+ 0x0000203e 0x2b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_pubnames
+ 0x00002069 0x31 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_pubnames
+ 0x0000209a 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_pubnames
+ 0x000020ba 0x1f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_pubnames
+ 0x000020d9 0x1e C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_pubnames
+ 0x000020f7 0x1f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_pubnames
+ 0x00002116 0x1f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_pubnames
+ 0x00002135 0x2b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_pubnames
+ 0x00002160 0x36 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_pubnames
+ 0x00002196 0x2b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_pubnames
+ 0x000021c1 0x2a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_info 0x00000000 0x9d30
+ *(.debug_info .gnu.linkonce.wi.*)
+ .debug_info 0x00000000 0xe49 Extruder.o
+ .debug_info 0x00000e49 0x382b FSIO.o
+ .debug_info 0x00004674 0xc3f SD-SPI.o
+ .debug_info 0x000052b3 0xa9e G_Code.o
+ .debug_info 0x00005d51 0xc7f OLED.o
+ .debug_info 0x000069d0 0x15cf RapMan.o
+ .debug_info 0x00007f9f 0x140e Stepper.o
+ .debug_info 0x000093ad 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_info 0x000093dd 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_info 0x0000940d 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_info 0x0000943d 0x150 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_info 0x0000958d 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_info 0x000095bd 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_info 0x000095ed 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_info 0x0000961d 0x3a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_info 0x00009657 0x78 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_info 0x000096cf 0x54 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_info 0x00009723 0x1aa C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_info 0x000098cd 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_info 0x000098fd 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_info 0x0000992d 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_info 0x0000995d 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_info 0x0000998d 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_info 0x000099bd 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_info 0x000099ed 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_info 0x00009a1d 0x8a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_info 0x00009aa7 0x73 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .debug_info 0x00009b1a 0x54 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_info 0x00009b6e 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_info 0x00009b9e 0x42 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_info 0x00009be0 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_info 0x00009c10 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_info 0x00009c40 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_info 0x00009c70 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_info 0x00009ca0 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_info 0x00009cd0 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_info 0x00009d00 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_abbrev 0x00000000 0x133d
+ *(.debug_abbrev)
+ .debug_abbrev 0x00000000 0x20a Extruder.o
+ .debug_abbrev 0x0000020a 0x2ad FSIO.o
+ .debug_abbrev 0x000004b7 0x268 SD-SPI.o
+ .debug_abbrev 0x0000071f 0x170 G_Code.o
+ .debug_abbrev 0x0000088f 0x239 OLED.o
+ .debug_abbrev 0x00000ac8 0x21f RapMan.o
+ .debug_abbrev 0x00000ce7 0x1e0 Stepper.o
+ .debug_abbrev 0x00000ec7 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_abbrev 0x00000eea 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_abbrev 0x00000f0d 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_abbrev 0x00000f30 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_abbrev 0x00000f53 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_abbrev 0x00000f76 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_abbrev 0x00000f99 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_abbrev 0x00000fbc 0x32 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_abbrev 0x00000fee 0x1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobdata.o)
+ .debug_abbrev 0x00000fef 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_abbrev 0x00001012 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_abbrev 0x00001035 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_abbrev 0x00001058 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_abbrev 0x0000107b 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_abbrev 0x0000109e 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_abbrev 0x000010c1 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_abbrev 0x000010e4 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_abbrev 0x00001107 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_abbrev 0x0000112a 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_abbrev 0x0000114d 0x1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctype.o)
+ .debug_abbrev 0x0000114e 0x1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(errno.o)
+ .debug_abbrev 0x0000114f 0x58 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_abbrev 0x000011a7 0x21 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .debug_abbrev 0x000011c8 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_abbrev 0x000011eb 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_abbrev 0x0000120e 0x39 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_abbrev 0x00001247 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_abbrev 0x0000126a 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_abbrev 0x0000128d 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_abbrev 0x000012b0 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_abbrev 0x000012d3 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_abbrev 0x000012f6 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_abbrev 0x00001319 0x1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_brg_tbl_lib.o)
+ .debug_abbrev 0x0000131a 0x23 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_line 0x00000000 0x3164
+ *(.debug_line)
+ .debug_line 0x00000000 0x271 Extruder.o
+ .debug_line 0x00000271 0xf44 FSIO.o
+ .debug_line 0x000011b5 0x241 SD-SPI.o
+ .debug_line 0x000013f6 0x214 G_Code.o
+ .debug_line 0x0000160a 0x2eb OLED.o
+ .debug_line 0x000018f5 0x3d5 RapMan.o
+ .debug_line 0x00001cca 0x3bd Stepper.o
+ .debug_line 0x00002087 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_line 0x0000210d 0x85 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_line 0x00002192 0x83 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_line 0x00002215 0x85 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_line 0x0000229a 0x83 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_line 0x0000231d 0x83 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_line 0x000023a0 0x85 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_line 0x00002425 0x85 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_line 0x000024aa 0x8a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_line 0x00002534 0x88 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_line 0x000025bc 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_line 0x00002642 0xa2 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_line 0x000026e4 0xa4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_line 0x00002788 0x91 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_line 0x00002819 0x95 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_line 0x000028ae 0x8a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_line 0x00002938 0x8b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_line 0x000029c3 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_line 0x00002a49 0x88 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_line 0x00002ad1 0x8b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .debug_line 0x00002b5c 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_line 0x00002be2 0x8a C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_line 0x00002c6c 0x94 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_line 0x00002d00 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_line 0x00002d86 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_line 0x00002e26 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_line 0x00002ec6 0xa9 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_line 0x00002f6f 0xa4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_line 0x00003013 0xa9 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_line 0x000030bc 0xa8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_frame 0x00000000 0x1e28
+ *(.debug_frame)
+ .debug_frame 0x00000000 0x1b0 Extruder.o
+ .debug_frame 0x000001b0 0x790 FSIO.o
+ .debug_frame 0x00000940 0x1d0 SD-SPI.o
+ .debug_frame 0x00000b10 0x340 G_Code.o
+ .debug_frame 0x00000e50 0x32c OLED.o
+ .debug_frame 0x0000117c 0x228 RapMan.o
+ .debug_frame 0x000013a4 0x1fc Stepper.o
+ .debug_frame 0x000015a0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_frame 0x000015c0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ .debug_frame 0x000015e0 0x34 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ .debug_frame 0x00001614 0x120 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ .debug_frame 0x00001734 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ .debug_frame 0x0000175c 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ .debug_frame 0x00001784 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ .debug_frame 0x000017a4 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ .debug_frame 0x000017cc 0x98 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ .debug_frame 0x00001864 0x58 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ .debug_frame 0x000018bc 0x178 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ .debug_frame 0x00001a34 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ .debug_frame 0x00001a54 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ .debug_frame 0x00001a74 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ .debug_frame 0x00001a94 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ .debug_frame 0x00001ab4 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ .debug_frame 0x00001ad4 0x30 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ .debug_frame 0x00001b04 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ .debug_frame 0x00001b24 0xf8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ .debug_frame 0x00001c1c 0x60 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ .debug_frame 0x00001c7c 0x60 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ .debug_frame 0x00001cdc 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ .debug_frame 0x00001cfc 0x44 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ .debug_frame 0x00001d40 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ .debug_frame 0x00001d60 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ .debug_frame 0x00001d80 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ .debug_frame 0x00001da0 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ .debug_frame 0x00001dc0 0x28 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ .debug_frame 0x00001de8 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ .debug_frame 0x00001e08 0x20 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+
+.debug_str 0x00000000 0x1617
+ *(.debug_str)
+ .debug_str 0x00000000 0x2e Extruder.o
+ .debug_str 0x0000002e 0x277 FSIO.o
+ .debug_str 0x000002a5 0x2e SD-SPI.o
+ .debug_str 0x000002d3 0x2c G_Code.o
+ .debug_str 0x000002ff 0x4f OLED.o
+ .debug_str 0x0000034e 0x49 RapMan.o
+ .debug_str 0x00000397 0x43 Stepper.o
+ .debug_str 0x000003da 0xb8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strncpy.o)
+ .debug_str 0x00000492 0x6f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strchr.o)
+ 0xb6 (size before relaxing)
+ .debug_str 0x00000501 0x66 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(exit.o)
+ 0xb2 (size before relaxing)
+ .debug_str 0x00000567 0xe3 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(ctypef.o)
+ 0x13a (size before relaxing)
+ .debug_str 0x0000064a 0x6b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atof.o)
+ 0xb2 (size before relaxing)
+ .debug_str 0x000006b5 0x6b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(atoi.o)
+ 0xb2 (size before relaxing)
+ .debug_str 0x00000720 0x6f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtol.o)
+ 0xb6 (size before relaxing)
+ .debug_str 0x0000078f 0x71 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(strtod.o)
+ 0xbf (size before relaxing)
+ .debug_str 0x00000800 0xb7 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobfuncs.o)
+ 0xfe (size before relaxing)
+ .debug_str 0x000008b7 0x80 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(sprintf.o)
+ 0xcf (size before relaxing)
+ .debug_str 0x00000937 0x2d9 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(stubs.o)
+ 0x320 (size before relaxing)
+ .debug_str 0x00000c10 0xa0 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-general-exception-handler.o)
+ 0xe7 (size before relaxing)
+ .debug_str 0x00000cb0 0xa4 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-bootstrap-exception-handler.o)
+ 0xeb (size before relaxing)
+ .debug_str 0x00000d54 0x7e C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-reset.o)
+ 0xc5 (size before relaxing)
+ .debug_str 0x00000dd2 0x86 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(default-on-bootstrap.o)
+ 0xcd (size before relaxing)
+ .debug_str 0x00000e58 0x77 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_getc.o)
+ 0xbe (size before relaxing)
+ .debug_str 0x00000ecf 0x79 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_write.o)
+ 0xc0 (size before relaxing)
+ .debug_str 0x00000f48 0x6f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_exit.o)
+ 0xb6 (size before relaxing)
+ .debug_str 0x00000fb7 0x9b C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_doprnt.o)
+ 0xe2 (size before relaxing)
+ .debug_str 0x00001052 0xb8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_iobstring.o)
+ 0xff (size before relaxing)
+ .debug_str 0x0000110a 0x77 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(fputc.o)
+ 0xc3 (size before relaxing)
+ .debug_str 0x00001181 0x77 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libc.a(_mon_putc.o)
+ 0xbe (size before relaxing)
+ .debug_str 0x000011f8 0x77 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_strtod.o)
+ 0xc7 (size before relaxing)
+ .debug_str 0x0000126f 0x8 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libe.a(_ldexp.o)
+ 0xb6 (size before relaxing)
+ .debug_str 0x00001277 0x8c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_getc_spi2_lib.o)
+ 0xd3 (size before relaxing)
+ .debug_str 0x00001303 0x8c C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(spi_open_spi2_lib.o)
+ 0xd3 (size before relaxing)
+ .debug_str 0x0000138f 0xa1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_disable_interrupts_lib.o)
+ 0xe8 (size before relaxing)
+ .debug_str 0x00001430 0xa7 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_mv_int_lib.o)
+ 0xee (size before relaxing)
+ .debug_str 0x000014d7 0xa1 C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_restore_interrupts_lib.o)
+ 0xe8 (size before relaxing)
+ .debug_str 0x00001578 0x9f C:/Program Files/Microchip/MPLAB C32 Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/lib\libmchp_peripheral.a(int_enable_interrupts_lib.o)
+ 0xe6 (size before relaxing)
+
+.debug_loc
+ *(.debug_loc)
+
+.debug_macinfo
+ *(.debug_macinfo)
+
+.debug_weaknames
+ *(.debug_weaknames)
+
+.debug_funcnames
+ *(.debug_funcnames)
+
+.debug_typenames
+ *(.debug_typenames)
+
+.debug_varnames
+ *(.debug_varnames)
+
+/DISCARD/
+ *(.note.GNU-stack)
+OUTPUT(bfb-firmware-dev.elf elf32-tradlittlemips)
+
+.mdebug.abi32 0x9d021f80 0x0
+
+.rel.dyn 0x9d021f80 0x0
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.mcp b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.mcp new file mode 100644 index 00000000..23e03a46 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.mcp @@ -0,0 +1,114 @@ +[HEADER]
+magic_cookie={66E99B07-E706-4689-9E80-9B2582898A13}
+file_version=1.0
+device=PIC32MX440F256H
+[PATH_INFO]
+BuildDirPolicy=BuildDirIsProjectDir
+dir_src=
+dir_bin=
+dir_tmp=
+dir_sin=
+dir_inc=C:\Documents and Settings\erik\My Documents\bfb-firmware-dev;C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral;C:\Program Files\Microchip\MPLAB C32\pic32mx\include;C:\Microchip Solutions\Microchip\Include
+dir_lib=
+dir_lkr=
+[CAT_FILTERS]
+filter_src=*.s;*.c
+filter_inc=*.h;*.inc
+filter_obj=*.o
+filter_lib=*.a
+filter_lkr=*.ld
+[CAT_SUBFOLDERS]
+subfolder_src=
+subfolder_inc=
+subfolder_obj=
+subfolder_lib=
+subfolder_lkr=
+[FILE_SUBFOLDERS]
+file_000=.
+file_001=.
+file_002=.
+file_003=.
+file_004=.
+file_005=.
+file_006=.
+file_007=.
+file_008=.
+file_009=.
+file_010=.
+file_011=.
+file_012=.
+file_013=.
+file_014=.
+file_015=.
+file_016=.
+[GENERATED_FILES]
+file_000=no
+file_001=no
+file_002=no
+file_003=no
+file_004=no
+file_005=no
+file_006=no
+file_007=no
+file_008=no
+file_009=no
+file_010=no
+file_011=no
+file_012=no
+file_013=no
+file_014=no
+file_015=no
+file_016=no
+[OTHER_FILES]
+file_000=no
+file_001=no
+file_002=no
+file_003=no
+file_004=no
+file_005=no
+file_006=no
+file_007=no
+file_008=no
+file_009=no
+file_010=no
+file_011=no
+file_012=no
+file_013=no
+file_014=no
+file_015=no
+file_016=no
+[FILE_INFO]
+file_000=Extruder.c
+file_001=FSIO.c
+file_002=SD-SPI.c
+file_003=G_Code.c
+file_004=OLED.c
+file_005=RapMan.c
+file_006=Stepper.c
+file_007=RapMan.h
+file_008=extruder.h
+file_009=stepper.h
+file_010=Screens.h
+file_011=SD-SPI.h
+file_012=HardwareProfile.h
+file_013=FSIO.h
+file_014=OLED.h
+file_015=G_Code.h
+file_016=Enviroment.h
+[SUITE_INFO]
+suite_guid={14495C23-81F8-43F3-8A44-859C583D7760}
+suite_state=
+[TOOL_SETTINGS]
+TS{CB0AF4B8-4022-429D-8F99-8A56782B2C6D}=-gdwarf-2
+TS{9C698E0A-CBC9-4EFF-AE7D-B569F93E7322}=-g
+TS{77F59DA1-3C53-4677-AC5F-A03EB0125170}=-o"$(BINDIR_)$(TARGETBASE).$(TARGETSUFFIX)" -Map="$(BINDIR_)$(TARGETBASE).map"
+TS{0396C0A1-9052-4E4F-8B84-EF0162B1B4E9}=
+[INSTRUMENTED_TRACE]
+enable=0
+transport=0
+format=0
+[CUSTOM_BUILD]
+Pre-Build=
+Pre-BuildEnabled=1
+Post-Build=
+Post-BuildEnabled=1
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.mcw b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.mcw Binary files differnew file mode 100644 index 00000000..d3184386 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/bfb-firmware-dev.mcw diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/FSIO.c b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/FSIO.c new file mode 100644 index 00000000..6a42c66b --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/FSIO.c @@ -0,0 +1,8874 @@ +/******************************************************************************
+*
+* Microchip Memory Disk Drive File System
+*
+******************************************************************************
+* FileName: FSIO.c
+* Dependencies: GenericTypeDefs.h
+* FSIO.h
+* Physical interface include file (SD-SPI.h, CF-PMP.h, ...)
+* string.h
+* stdlib.h
+* FSDefs.h
+* ctype.h
+* salloc.h
+* Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+* Compiler: C18/C30/C32
+* Company: Microchip Technology, Inc.
+* Version: 1.2.0
+*
+* Software License Agreement
+*
+* The software supplied herewith by Microchip Technology Incorporated
+* (the �Company�) for its PICmicro� Microcontroller is intended and
+* supplied to you, the Company�s customer, for use solely and
+* exclusively on Microchip PICmicro Microcontroller products. The
+* software is owned by the Company and/or its supplier, and is
+* protected under applicable copyright laws. All rights are reserved.
+* Any use in violation of the foregoing restrictions may subject the
+* user to criminal sanctions under applicable laws, as well as to
+* civil liability for the breach of the terms and conditions of this
+* license.
+*
+* THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+*
+*****************************************************************************/
+
+#include "FSIO.h"
+#include "GenericTypeDefs.h"
+#include "string.h"
+#include "stdlib.h"
+#include "ctype.h"
+#include "MDD File System\FSDefs.h"
+
+#ifdef ALLOW_FSFPRINTF
+#include "stdarg.h"
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ #ifdef __18CXX
+ #include "salloc.h"
+ #endif
+#endif
+
+#ifndef ALLOW_WRITES
+ #ifdef ALLOW_FORMATS
+ #error Write functions must be enabled to use the format function
+ #endif
+ #ifdef ALLOW_FSFPRINTF
+ #error Write functions must be enabled to use the FSfprintf function
+ #endif
+#endif
+
+#ifdef USEREALTIMECLOCK
+ #ifdef USERDEFINEDCLOCK
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#elif defined USERDEFINEDCLOCK
+ #ifdef INCREMENTTIMESTAMP
+ #error Please select only one timestamp clocking mode in FSconfig.h
+ #endif
+#endif
+/*****************************************************************************/
+/* Global Variables */
+/*****************************************************************************/
+
+#ifndef FS_DYNAMIC_MEM
+ FSFILE gFileArray[FS_MAX_FILES_OPEN]; // Array that contains file information (static allocation)
+ BYTE gFileSlotOpen[FS_MAX_FILES_OPEN]; // Array that indicates which elements of gFileArray are available for use
+#endif
+
+DWORD gLastFATSectorRead = 0xFFFF; // Global variable indicating which FAT sector was read last
+BYTE gNeedFATWrite = FALSE; // Global variable indicating that there is information that needs to be written to the FAT
+FSFILE * gBufferOwner = NULL; // Global variable indicating which file is using the data buffer
+DWORD gLastDataSectorRead = 0xFFFFFFFF; // Global variable indicating which data sector was read last
+BYTE gNeedDataWrite = FALSE; // Global variable indicating that there is information that needs to be written to the data section
+BYTE nextClusterIsLast = FALSE; // Global variable indicating that the entries in a directory align with a cluster boundary
+
+// Timing variables
+BYTE gTimeCrtMS; // Global time variable (for timestamps) used to indicate create time (milliseconds)
+WORD gTimeCrtTime; // Global time variable (for timestamps) used to indicate create time
+WORD gTimeCrtDate; // Global time variable (for timestamps) used to indicate create date
+WORD gTimeAccDate; // Global time variable (for timestamps) used to indicate last access date
+WORD gTimeWrtTime; // Global time variable (for timestamps) used to indicate last update time
+WORD gTimeWrtDate; // Global time variable (for timestamps) used to indicate last update date
+
+BYTE gBufferZeroed = FALSE; // Global variable indicating that the data buffer contains all zeros
+
+DWORD FatRootDirClusterValue; // Global variable containing the cluster number of the root dir (0 for FAT12/16)
+
+BYTE FSerrno; // Global error variable. Set to one of many error codes after each function call.
+
+DWORD TempClusterCalc; // Global variable used to store the calculated value of the cluster of a specified sector.
+BYTE dirCleared; // Global variable used by the "recursive" FSrmdir function to indicate that all subdirectories and files have been deleted from the target directory.
+BYTE recache = FALSE; // Global variable used by the "recursive" FSrmdir function to indicate that additional cache reads are needed.
+FSFILE tempCWDobj; // Global variable used to preserve the current working directory information.
+FSFILE gFileTemp; // Global variable used for file operations.
+
+#ifdef ALLOW_DIRS
+ FSFILE cwd; // Global current working directory
+ FSFILE * cwdptr = &cwd; // Pointer to the current working directory
+#endif
+
+
+#ifdef __18CXX
+ #pragma udata dataBuffer
+ BYTE gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ #pragma udata FATBuffer
+ BYTE gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE __attribute__ ((aligned(4))) gDataBuffer[MEDIA_SECTOR_SIZE]; // The global data sector buffer
+ BYTE __attribute__ ((aligned(4))) gFATBuffer[MEDIA_SECTOR_SIZE]; // The global FAT sector buffer
+#endif
+
+
+#pragma udata
+
+DISK gDiskData; // Global structure containing device information.
+
+
+
+/************************************************************************/
+/* Structures and defines */
+/************************************************************************/
+
+// Directory entry structure
+typedef struct
+{
+ char DIR_Name[DIR_NAMESIZE]; // File name
+ char DIR_Extension[DIR_EXTENSION]; // File extension
+ BYTE DIR_Attr; // File attributes
+ BYTE DIR_NTRes; // Reserved byte
+ BYTE DIR_CrtTimeTenth; // Create time (millisecond field)
+ WORD DIR_CrtTime; // Create time (second, minute, hour field)
+ WORD DIR_CrtDate; // Create date
+ WORD DIR_LstAccDate; // Last access date
+ WORD DIR_FstClusHI; // High word of the entry's first cluster number
+ WORD DIR_WrtTime; // Last update time
+ WORD DIR_WrtDate; // Last update date
+ WORD DIR_FstClusLO; // Low word of the entry's first cluster number
+ DWORD DIR_FileSize; // The 32-bit file size
+}_DIRENTRY;
+
+typedef _DIRENTRY * DIRENTRY; // A pointer to a directory entry structure
+
+#define DIRECTORY 0x12 // Value indicating that the CreateFileEntry function will be creating a directory
+
+#define DIRENTRIES_PER_SECTOR (MEDIA_SECTOR_SIZE / 32) // The number of directory entries in a sector
+
+// internal errors
+#define CE_FAT_EOF 60 // Error that indicates an attempt to read FAT entries beyond the end of the file
+#define CE_EOF 61 // Error that indicates that the end of the file has been reached
+
+typedef FSFILE * FILEOBJ; // Pointer to an FSFILE object
+
+#ifdef ALLOW_FSFPRINTF
+
+#define _FLAG_MINUS 0x1 // FSfprintf minus flag indicator
+#define _FLAG_PLUS 0x2 // FSfprintf plus flag indicator
+#define _FLAG_SPACE 0x4 // FSfprintf space flag indicator
+#define _FLAG_OCTO 0x8 // FSfprintf octothorpe (hash mark) flag indicator
+#define _FLAG_ZERO 0x10 // FSfprintf zero flag indicator
+#define _FLAG_SIGNED 0x80 // FSfprintf signed flag indicator
+
+#ifdef __18CXX
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONG 1 // FSfprintf 32-bit argument size flag
+ #define _FMT_SHRTLONG 2 // FSfprintf 24-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#else
+ #define _FMT_UNSPECIFIED 0 // FSfprintf unspecified argument size flag
+ #define _FMT_LONGLONG 1 // FSfprintf 64-bit argument size flag
+ #define _FMT_LONG 2 // FSfprintf 32-bit argument size flag
+ #define _FMT_BYTE 3 // FSfprintf 8-bit argument size flag
+#endif
+
+#ifdef __18CXX
+ static const rom char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#else
+ static const char s_digits[] = "0123456789abcdef"; // FSfprintf table of conversion digits
+#endif
+
+#endif
+
+/************************************************************************************/
+/* Prototypes */
+/************************************************************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls);
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead);
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle);
+DWORD Cluster2Sector(DISK * disk, DWORD cluster);
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle);
+#ifdef INCREMENTTIMESTAMP
+ void IncrementTimeStamp(DIRENTRY dir);
+#elif defined USEREALTIMECLOCK
+ void CacheTime (void);
+#endif
+
+#if defined (__C30__) || defined (__C32__)
+ BYTE ReadByte( BYTE* pBuffer, WORD index );
+ WORD ReadWord( BYTE* pBuffer, WORD index );
+ DWORD ReadDWord( BYTE* pBuffer, WORD index );
+#endif
+
+// Function pointer that points to a physical layer's MDD_xxxxx_WriteProtectState function
+extern BYTE MDD_WriteProtectState(void);
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource);
+BYTE ValidateChars (char * FileName, BYTE mode);
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode);
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode);
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n);
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type);
+
+// Write functions
+#ifdef ALLOW_WRITES
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry);
+ BYTE flushData (void);
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters);
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode);
+ BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk);
+ DWORD FATfindEmptyCluster(FILEOBJ fo);
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle);
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode);
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster);
+ BYTE EraseCluster(DISK *disk, DWORD cluster);
+ CETYPE CreateFirstCluster(FILEOBJ fo);
+ DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite);
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode);
+#endif
+
+// Directory functions
+#ifdef ALLOW_DIRS
+ BYTE GetPreviousEntry (FSFILE * fo);
+ BYTE FormatDirName (char * string, BYTE mode);
+ int CreateDIR (char * path);
+ BYTE writeDotEntries (DISK * dsk, DWORD dotAddress, DWORD dotdotAddress);
+ int eraseDir (char * path);
+#ifdef ALLOW_PGMFUNCTIONS
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs);
+ #endif
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+#else
+ #ifdef ALLOW_WRITES
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr);
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs);
+ #endif
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+#endif
+#endif
+
+#ifdef ALLOW_FSFPRINTF
+ #ifdef __18CXX
+ int FSvfprintf (auto FSFILE *handle, auto const rom char *formatString, auto va_list ap);
+ #else
+ int FSvfprintf (FSFILE *handle, const char *formatString, va_list ap);
+ #endif
+ int FSputc (char c, FSFILE * file);
+ unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c);
+#endif
+
+BYTE DISKmount( DISK *dsk);
+BYTE LoadMBR(DISK *dsk);
+BYTE LoadBootSector(DISK *dsk);
+DWORD GetFullClusterNumber(DIRENTRY entry);
+
+
+/*************************************************************************
+ Function:
+ int FSInit(void)
+ Summary:
+ Function to initialize the device.
+ Conditions:
+ The physical device should be connected to the microcontroller.
+ Input:
+ None
+ Return Values:
+ TRUE - Initialization successful
+ FALSE - Initialization unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Initializes the static or dynamic memory slots for holding file
+ structures. Initializes the device with the DISKmount function. Loads
+ MBR and boot sector information. Initializes the current working
+ directory to the root directory for the device if directory support
+ is enabled.
+ Remarks:
+ None
+ *************************************************************************/
+
+int FSInit(void)
+{
+ int fIndex;
+#ifndef FS_DYNAMIC_MEM
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ gFileSlotOpen[fIndex] = TRUE;
+#else
+ #ifdef __18CXX
+ SRAMInitHeap();
+ #endif
+#endif
+
+ gBufferZeroed = FALSE;
+
+ MDD_InitIO();
+
+ if(DISKmount(&gDiskData) == CE_GOOD)
+ {
+ // Initialize the current working directory to the root
+#ifdef ALLOW_DIRS
+ cwdptr->dsk = &gDiskData;
+ cwdptr->sec = 0;
+ cwdptr->pos = 0;
+ cwdptr->seek = 0;
+ cwdptr->size = 0;
+ cwdptr->name[0] = '\\';
+ for (fIndex = 1; fIndex < 11; fIndex++)
+ {
+ cwdptr->name[fIndex] = 0x20;
+ }
+ cwdptr->entry = 0;
+ cwdptr->attributes = ATTR_DIRECTORY;
+ // "FatRootDirClusterValue" indicates the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+#endif
+
+ FSerrno = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/********************************************************************************
+ Function:
+ CETYPE FILEfind (FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+ Summary
+ Finds a file on the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - FSFILE object containing information of the file found
+ foCompareTo - FSFILE object containing the name/attr of the file to be
+ found
+ cmd -
+ - LOOK_FOR_EMPTY_ENTRY: Search for empty entry.
+ - LOOK_FOR_MATCHING_ENTRY: Search for matching entry.
+ mode -
+ - 0: Match file exactly with default attributes.
+ - 1: Match file to user-specified attributes.
+ Return Values:
+ CE_GOOD - File found.
+ CE_FILE_NOT_FOUND - File not found.
+ Side Effects:
+ None.
+ Description:
+ The FILEfind function will sequentially cache directory entries within
+ the current working directory into the foDest FSFILE object. If the cmd
+ parameter is specified as LOOK_FOR_EMPTY_ENTRY the search will continue
+ until an empty directory entry is found. If the cmd parameter is specified
+ as LOOK_FOR_MATCHING_ENTRY these entries will be compared to the foCompareTo
+ object until a match is found or there are no more entries in the current
+ working directory. If the mode is specified a '0' the attributes of the FSFILE
+ entries are irrelevant. If the mode is specified as '1' the attributes of the
+ foDest entry must match the attributes specified in the foCompareTo file and
+ partial string search characters may bypass portions of the comparison.
+ Remarks:
+ None
+ ********************************************************************************/
+
+CETYPE FILEfind( FILEOBJ foDest, FILEOBJ foCompareTo, BYTE cmd, BYTE mode)
+{
+ WORD attrib, compareAttrib;
+ WORD fHandle = foDest->entry; // current entry counter
+ BYTE state,index; // state of the current object
+ CETYPE statusB = CE_FILE_NOT_FOUND;
+ BYTE character,test;
+
+ // reset the cluster
+ foDest->dirccls = foDest->dirclus;
+ compareAttrib = 0xFFFF ^ foCompareTo->attributes; // Attribute to be compared as per application layer request
+
+ if (fHandle == 0)
+ {
+ if (Cache_File_Entry(foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ if ((fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) != 0) // Maximum 16 entries possible
+ {
+ if (Cache_File_Entry (foDest, &fHandle, TRUE) == NULL)
+ {
+ statusB = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ if (statusB != CE_BADCACHEREAD)
+ {
+ // Loop until you reach the end or find the file
+ while(1)
+ {
+ if(statusB!=CE_GOOD) //First time entry always here
+ {
+ state = Fill_File_Object(foDest, &fHandle);
+ if(state == NO_MORE) // Reached the end of available files. Comparision over and file not found so quit.
+ {
+ break;
+ }
+ }
+ else // statusB == CE_GOOD then exit
+ {
+ break; // Code below intializes"statusB = CE_GOOD;" so, if no problem in the filled file, Exit the while loop.
+ }
+
+ if(state == FOUND) // Validate the correct matching of filled file data with the required(to be found) one.
+ {
+ /* We got something */
+ // get the attributes
+ attrib = foDest->attributes;
+
+ attrib &= ATTR_MASK;
+ switch (mode)
+ {
+ case 0:
+ // see if we are a volume id or hidden, ignore
+ if(attrib != ATTR_VOLUME)
+ {
+ statusB = CE_GOOD;
+ character = (BYTE)'m'; // random value
+
+ // search for one. if status = TRUE we found one
+ for(index = 0; index < DIR_NAMECOMP; index++)
+ {
+ // get the source character
+ character = foDest->name[index];
+ // get the destination character
+ test = foCompareTo->name[index];
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // Nope its not a match
+ break;
+ }
+ }// for loop
+ } // not dir nor vol
+ break;
+
+ case 1:
+ // Check for attribute match
+ if (((attrib & compareAttrib) == 0) && (attrib != ATTR_LONG_NAME))
+ {
+ statusB = CE_GOOD; // Indicate the already filled file data is correct and go back
+ character = (BYTE)'m'; // random value
+ if (foCompareTo->name[0] != '*') //If "*" is passed for comparion as 1st char then don't proceed. Go back, file alreay found.
+ {
+ for (index = 0; index < DIR_NAMESIZE; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ // Before calling this "FILEfind" fn, "formatfilename" must be called. Hence, extn always starts from position "8".
+ if ((foCompareTo->name[8] != '*') && (statusB == CE_GOOD))
+ {
+ for (index = 8; index < DIR_NAMECOMP; index++)
+ {
+ // Get the source character
+ character = foDest->name[index];
+ // Get the destination character
+ test = foCompareTo->name[index];
+ if (test == '*')
+ break;
+ if (test != '?')
+ {
+ if(tolower(character) != tolower(test))
+ {
+ statusB = CE_FILE_NOT_FOUND; // it's not a match
+ break;
+ }
+ }
+ }
+ }
+
+ } // Attribute match
+
+ break;
+ }
+ } // not found
+ else
+ {
+ /*** looking for an empty/re-usable entry ***/
+ if ( cmd == LOOK_FOR_EMPTY_ENTRY)
+ statusB = CE_GOOD;
+ } // found or not
+
+ // increment it no matter what happened
+ fHandle++;
+
+ }// while
+ }
+
+ return(statusB);
+} // FILEFind
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+ Summary:
+ Loads file information from the device
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File to be opened
+ fHandle - Location of file
+ type -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ Return Values:
+ CE_GOOD - FILEopen successful
+ CE_NOT_INIT - Device is not yet initialized
+ CE_FILE_NOT_FOUND - Could not find the file on the device
+ CE_BAD_SECTOR_READ - A bad read of a sector occured
+ Side Effects:
+ None
+ Description:
+ This function will cache a directory entry in the directory specified
+ by the dirclus parameter of hte FSFILE object 'fo.' The offset of the
+ entry in the directory is specified by fHandle. Once the directory entry
+ has been loaded, the first sector of the file can be loaded using the
+ cluster value specified in the directory entry. The type argument will
+ specify the mode the files will be opened in. This will allow this
+ function to set the correct read/write flags for the file.
+ Remarks:
+ If the mode the file is being opened in is a plus mode (e.g. READ+) the
+ flags will be modified further in the FSfopen function.
+ **************************************************************************/
+
+CETYPE FILEopen (FILEOBJ fo, WORD *fHandle, char type)
+{
+ DISK *dsk; //Disk structure
+ BYTE r; //Result of search for file
+ DWORD l; //lba of first sector of first cluster
+ CETYPE error = CE_GOOD;
+
+ dsk = (DISK *)(fo->dsk);
+ if (dsk->mount == FALSE)
+ {
+ error = CE_NOT_INIT;
+ }
+ else
+ {
+ // load the sector
+ fo->dirccls = fo->dirclus;
+ // Cache no matter what if it's the first entry
+ if (*fHandle == 0)
+ {
+ if (Cache_File_Entry(fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ else
+ {
+ // If it's not the first, only cache it if it's
+ // not divisible by the number of entries per sector
+ // If it is, Fill_File_Object will cache it
+ if ((*fHandle & 0xf) != 0)
+ {
+ if (Cache_File_Entry (fo, fHandle, TRUE) == NULL)
+ {
+ error = CE_BADCACHEREAD;
+ }
+ }
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ r = Fill_File_Object(fo, fHandle);
+ if (r != FOUND)
+ error = CE_FILE_NOT_FOUND;
+ else
+ {
+ fo->seek = 0; // first byte in file
+ fo->ccls = fo->cluster; // first cluster
+ fo->sec = 0; // first sector in the cluster
+ fo->pos = 0; // first byte in sector/cluster
+
+ if ( r == NOT_FOUND)
+ {
+ error = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Determine the lba of the selected sector and load
+ l = Cluster2Sector(dsk,fo->ccls);
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+#endif
+ gBufferOwner = fo;
+ if (gLastDataSectorRead != l)
+ {
+ gBufferZeroed = FALSE;
+ if ( !MDD_SectorRead( l, dsk->buffer))
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = l;
+ }
+ } // -- found
+
+ fo->flags.FileWriteEOF = FALSE;
+ // Set flag for operation type
+#ifdef ALLOW_WRITES
+ if (type == 'w' || type == 'a')
+ {
+ fo->flags.write = 1; //write or append
+ fo->flags.read = 0;
+ }
+ else
+ {
+#endif
+ fo->flags.write = 0; //read
+ fo->flags.read = 1;
+#ifdef ALLOW_WRITES
+ } // -- flags
+#endif
+ } // -- r = Found
+ } // -- Mounted
+ return (error);
+} // -- FILEopen
+
+
+/*************************************************************************
+ Function:
+ BYTE FILEget_next_cluster(FILEOBJ fo, WORD n)
+ Summary:
+ Step through a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file to get the next cluster of
+ n - Number of links in the FAT cluster chain to jump through
+ Return Values:
+ CE_GOOD - Operation successful
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_INVALID_CLUSTER - Invalid cluster value \> maxcls
+ CE_FAT_EOF - Fat attempt to read beyond EOF
+ Side Effects:
+ None
+ Description:
+ This function will load 'n' proximate clusters for a file from
+ the FAT on the device. It will stop checking for clusters if the
+ ReadFAT function returns an error, if it reaches the last cluster in
+ a file, or if the device tries to read beyond the last cluster used
+ by the device.
+ Remarks:
+ None
+ *************************************************************************/
+
+BYTE FILEget_next_cluster(FILEOBJ fo, DWORD n)
+{
+ DWORD c, c2, ClusterFailValue, LastClustervalue;
+ BYTE error = CE_GOOD;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ LastClustervalue = LAST_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT12:
+ LastClustervalue = LAST_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT16:
+ default:
+ LastClustervalue = LAST_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // loop n times
+ do
+ {
+ // get the next cluster link from FAT
+ c2 = fo->ccls;
+ if ( (c = ReadFAT( disk, c2)) == ClusterFailValue)
+ error = CE_BAD_SECTOR_READ;
+ else
+ {
+ // check if cluster value is valid
+ if ( c >= disk->maxcls)
+ {
+ error = CE_INVALID_CLUSTER;
+ }
+
+ // compare against max value of a cluster in FAT
+ // return if eof
+ if ( c >= LastClustervalue) // check against eof
+ {
+ error = CE_FAT_EOF;
+ }
+ }
+
+ // update the FSFILE structure
+ fo->ccls = c;
+
+ } while (--n > 0 && error == CE_GOOD);// loop end
+
+ return(error);
+} // get next cluster
+
+
+/**************************************************************************
+ Function:
+ BYTE DISKmount ( DISK *dsk)
+ Summary:
+ Initialies the device and loads MBR and boot sector information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure to be initialized.
+ Return Values:
+ CE_GOOD - Disk mounted
+ CE_INIT_ERROR - Initialization error has occured
+ Side Effects:
+ None
+ Description:
+ This function will use the function pointed to by the MDD_MediaInitialize
+ function pointer to initialize the device (if any initialization is
+ required). It then attempts to load the master boot record with the
+ LoadMBR function and the boot sector with the LoadBootSector function.
+ These two functions will be used to initialize a global DISK structure
+ that will be used when accessing file information in the future.
+ Remarks:
+ None
+ **************************************************************************/
+
+BYTE DISKmount( DISK *dsk)
+{
+ BYTE error = CE_GOOD;
+
+ dsk->mount = FALSE; // default invalid
+ dsk->buffer = gDataBuffer; // assign buffer
+
+ // Initialize the device
+ if(MDD_MediaInitialize() != TRUE)
+ {
+ error = CE_INIT_ERROR;
+ FSerrno = CE_INIT_ERROR;
+ }
+ else
+ {
+ // Load the Master Boot Record (partition)
+ if((error = LoadMBR(dsk)) == CE_GOOD)
+ {
+ // Now the boot sector
+ if((error = LoadBootSector(dsk)) == CE_GOOD)
+ dsk->mount = TRUE; // Mark that the DISK mounted successfully
+ }
+ } // -- Load file parameters
+
+ return(error);
+} // -- mount
+
+
+
+/********************************************************************
+ Function:
+ CETYPE LoadMBR ( DISK *dsk)
+ Summary:
+ Loads the MBR and extracts necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the master boot record to be loaded
+ Return Values:
+ CE_GOOD - MBR loaded successfully
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_BAD_PARTITION - The boot record is bad
+ Side Effects:
+ None
+ Description:
+ The LoadMBR function will use the function pointed to by the
+ MDD_SectorRead function pointer to read the 0 sector from the
+ device. If a valid boot signature is obtained, this function
+ will compare fields in that cached sector to the values that
+ would be present if that sector was a boot sector. If all of
+ those values match, it will be assumed that the device does not
+ have a master boot record and the 0 sector is actually the boot
+ sector. Otherwise, data about the partition and the actual
+ location of the boot sector will be loaded from the MBR into
+ the DISK structure pointed to by 'dsk.'
+ Remarks:
+ None
+ ********************************************************************/
+
+BYTE LoadMBR(DISK *dsk)
+{
+ PT_MBR Partition;
+ BYTE error = CE_GOOD;
+ BYTE type;
+ BootSec BSec;
+
+ // Get the partition table from the MBR
+ if ( MDD_SectorRead( FO_MBR, dsk->buffer) != TRUE)
+ {
+ error = CE_BAD_SECTOR_READ;
+ FSerrno = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ // Check if the card has no MBR
+ BSec = (BootSec) dsk->buffer;
+
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( dsk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT16;
+ return CE_GOOD;
+ }
+ else
+ {
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( dsk->buffer, BSI_FAT32_FSTYPE ) == 'F' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 1 ) == 'A' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 2 ) == 'T' && \
+ ReadByte( dsk->buffer, BSI_FAT32_FSTYPE + 3 ) == '3' && \
+ ReadByte( dsk->buffer, BSI_FAT32_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_32.BootSec_FilSysType[0] == 'F' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[1] == 'A' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[2] == 'T' && \
+ BSec->FAT.FAT_32.BootSec_FilSysType[3] == '3' && \
+ BSec->FAT.FAT_32.BootSec_BootSig == 0x29)
+#endif
+ {
+ dsk->firsts = 0;
+ dsk->type = FAT32;
+ return CE_GOOD;
+ }
+ }
+ }
+ // assign it the partition table strucutre
+ Partition = (PT_MBR)dsk->buffer;
+
+ // Ensure its good
+ if((Partition->Signature0 != FAT_GOOD_SIGN_0) || (Partition->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_BAD_PARTITION;
+ error = CE_BAD_PARTITION;
+ }
+ else
+ {
+ /* Valid Master Boot Record Loaded */
+
+ // Get the 32 bit offset to the first partition
+ dsk->firsts = Partition->Partition0.PTE_FrstSect;
+
+ // check if the partition type is acceptable
+ type = Partition->Partition0.PTE_FSDesc;
+
+ switch (type)
+ {
+ case 0x01:
+ dsk->type = FAT12;
+ break;
+
+ case 0x04:
+ case 0x06:
+ case 0x0E:
+ dsk->type = FAT16;
+ break;
+
+ case 0x0B:
+ case 0x0C:
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ dsk->type = FAT32; // FAT32 is supported too
+#else
+ FSerrno = CE_CARDFAT32;
+ error = CE_CARDFAT32;
+#endif
+ break;
+
+ default:
+ FSerrno = CE_UNSUPPORTED_FS;
+ error = CE_UNSUPPORTED_FS;
+ } // switch
+ }
+ }
+
+ return(error);
+}// -- LoadMBR
+
+
+/**************************************************************************
+ Function:
+ BYTE LoadBootSector (DISK *dsk)
+ Summary:
+ Load the boot sector and extract the necessary information
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk containing the boot sector
+ Return Values:
+ CE_GOOD - Boot sector loaded
+ CE_BAD_SECTOR_READ - A bad read occured of a sector
+ CE_NOT_FORMATTED - The disk is of an unsupported format
+ CE_CARDFAT32 - FAT 32 device not supported
+ Side Effects:
+ None
+ Description:
+ LoadBootSector will use the function pointed to by the MDD_SectorWrite
+ function pointer to load the boot sector, whose location was obtained
+ by a previous call of LoadMBR. If the boot sector is loaded successfully,
+ partition information will be calcualted from it and copied into the DISK
+ structure pointed to by 'dsk.'
+ Remarks:
+ None
+ **************************************************************************/
+
+
+BYTE LoadBootSector(DISK *dsk)
+{
+ DWORD RootDirSectors;
+ DWORD TotSec,DataSec;
+ BYTE error = CE_GOOD;
+ BootSec BSec;
+ WORD BytesPerSec;
+ WORD ReservedSectorCount;
+
+ // Get the Boot sector
+ if ( MDD_SectorRead( dsk->firsts, dsk->buffer) != TRUE)
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ }
+ else
+ {
+ BSec = (BootSec)dsk->buffer;
+
+ //Verify the Boot Sector is valid
+ if((BSec->Signature0 != FAT_GOOD_SIGN_0) || (BSec->Signature1 != FAT_GOOD_SIGN_1))
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ error = CE_NOT_FORMATTED;
+ }
+ else
+ {
+ #ifdef __18CXX
+
+ // Load count of sectors per cluster
+ dsk->SecPerClus = BSec->FAT.FAT_16.BootSec_SPC;
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + BSec->FAT.FAT_16.BootSec_ResrvSec;
+ // Load the count of FAT tables
+ dsk->fatcopy = BSec->FAT.FAT_16.BootSec_FATCount;
+ // Load the size of the FATs
+ dsk->fatsize = BSec->FAT.FAT_16.BootSec_SPF;
+ if(dsk->fatsize == 0)
+ dsk->fatsize = BSec->FAT.FAT_32.BootSec_FATSz32;
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = BSec->FAT.FAT_16.BootSec_RootDirEnts;
+
+ // Determine the total number of sectors in the partition
+ if(BSec->FAT.FAT_16.BootSec_TotSec16 != 0)
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec16;
+ }
+ else
+ {
+ TotSec = BSec->FAT.FAT_16.BootSec_TotSec32;
+ }
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = BSec->FAT.FAT_16.BootSec_BPS;
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((BSec->FAT.FAT_16.BootSec_RootDirEnts * 32) + (BSec->FAT.FAT_16.BootSec_BPS - 1)) / BSec->FAT.FAT_16.BootSec_BPS;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (dsk->root + RootDirSectors) + dsk->firsts + 2;
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #else // PIC24/30/33
+
+ // Read the count of reserved sectors
+ ReservedSectorCount = ReadWord( dsk->buffer, BSI_RESRVSEC );
+ // Load the count of sectors per cluster
+ dsk->SecPerClus = ReadByte( dsk->buffer, BSI_SPC );
+ // Load the sector number of the first FAT sector
+ dsk->fat = dsk->firsts + ReservedSectorCount;
+ // Load the count of FAT tables
+ dsk->fatcopy = ReadByte( dsk->buffer, BSI_FATCOUNT );
+ // Load the size of the FATs
+ dsk->fatsize = ReadWord( dsk->buffer, BSI_SPF );
+ if(dsk->fatsize == 0)
+ dsk->fatsize = ReadDWord( dsk->buffer, BSI_FATSZ32 );
+ // Calculate the location of the root sector (for FAT12/16)
+ dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);
+ // Determine the max size of the root (will be 0 for FAT32)
+ dsk->maxroot = ReadWord( dsk->buffer, BSI_ROOTDIRENTS );
+
+ // Determine the total number of sectors in the partition
+ TotSec = ReadWord( dsk->buffer, BSI_TOTSEC16 );
+ if( TotSec == 0 )
+ TotSec = ReadDWord( dsk->buffer, BSI_TOTSEC32 );
+
+ // Calculate the number of bytes in each sector
+ BytesPerSec = ReadWord( dsk->buffer, BSI_BPS );
+ if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 )
+ {
+ FSerrno = CE_NOT_FORMATTED;
+ return( CE_NOT_FORMATTED );
+ }
+
+ // Calculate the number of sectors in the root (will be 0 for FAT32)
+ RootDirSectors = ((dsk->maxroot * NUMBER_OF_BYTES_IN_DIR_ENTRY) + (BytesPerSec - 1)) / BytesPerSec;
+ // Calculate the number of data sectors on the card
+ DataSec = TotSec - (ReservedSectorCount + (dsk->fatcopy * dsk->fatsize ) + RootDirSectors );
+ // Calculate the maximum number of clusters on the card
+ dsk->maxcls = DataSec / dsk->SecPerClus;
+
+ #endif
+
+ // Determine the file system type based on the number of clusters used
+ if(dsk->maxcls < 4085)
+ {
+ dsk->type = FAT12;
+ }
+ else
+ {
+ if(dsk->maxcls < 65525)
+ {
+ dsk->type = FAT16;
+ }
+ else
+ {
+ #ifdef SUPPORT_FAT32
+ dsk->type = FAT32;
+ #else
+ error = CE_CARDFAT32;
+ FSerrno = CE_CARDFAT32;
+ #endif
+ }
+ }
+
+ #ifdef SUPPORT_FAT32
+ if (dsk->type == FAT32)
+ {
+ #ifdef __18CXX
+ FatRootDirClusterValue = BSec->FAT.FAT_32.BootSec_RootClus;
+ #else
+ FatRootDirClusterValue = ReadDWord( dsk->buffer, BSI_ROOTCLUS );
+ #endif
+ dsk->data = dsk->root + RootDirSectors;
+ }
+ else
+ #endif
+ {
+ FatRootDirClusterValue = 0;
+ dsk->data = dsk->root + ( dsk->maxroot >> 4);
+ }
+
+ #ifdef __18CXX
+ if(BSec->FAT.FAT_16.BootSec_BPS != MEDIA_SECTOR_SIZE)
+ #else
+ if(BytesPerSec != MEDIA_SECTOR_SIZE)
+ #endif
+ {
+ error = CE_NOT_FORMATTED;
+ FSerrno = CE_NOT_FORMATTED;
+ }
+ }
+ }
+ return(error);
+}
+
+
+
+/*************************************************************************
+ Function:
+ DWORD GetFullClusterNumber (DIRENTRY entry)
+ Summary:
+ Gets the cluster number from a directory entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ entry - The cached directory entry to get the cluster number from
+ Returns:
+ The cluster value from the passed directory entry
+ Side Effects:
+ None.
+ Description:
+ This function will load both the high and low 16-bit first cluster
+ values of a file from a directory entry and copy them into a 32-bit
+ cluster number variable, which will be returned.
+ Remarks:
+ None
+ *************************************************************************/
+
+DWORD GetFullClusterNumber(DIRENTRY entry)
+{
+
+ DWORD TempFullClusterCalc = 0;
+
+#ifndef SUPPORT_FAT32 // If FAT32 Not supported.
+ entry->DIR_FstClusHI = 0; // If FAT32 is not supported then Higher Word of the address is "0"
+#endif
+
+ // Get the cluster
+ TempFullClusterCalc = (entry->DIR_FstClusHI);
+ TempFullClusterCalc = TempFullClusterCalc << 16;
+ TempFullClusterCalc |= entry->DIR_FstClusLO;
+
+ return TempFullClusterCalc;
+}
+
+
+#ifdef ALLOW_FORMATS
+#ifdef ALLOW_WRITES
+
+
+/*********************************************************************************
+ Function:
+ int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+ Summary:
+ Creates a master boot record
+ Conditions:
+ The I/O pins for the device have been initialized by the InitIO function.
+ Input:
+ firstSector - The first sector of the partition on the device (cannot
+ be 0; that's the MBR)
+ numSectors - The number of sectors available in memory (including the
+ MBR)
+ Return Values:
+ 0 - MBR was created successfully
+ EOF - MBR could not be created
+ Side Effects:
+ None
+ Description:
+ This function can be used to create a master boot record for a device. Note
+ that this function should not be used on a device that is already formatted
+ with a master boot record (i.e. most SD cards, CF cards, USB keys). This
+ function will fill the global data buffer with appropriate partition information
+ for a FAT partition with a type determined by the number of sectors available
+ to the partition. It will then write the MBR information to the first sector
+ on the device. This function should be followed by a call to FSformat, which
+ will create a boot sector, root dir, and FAT appropriate the the information
+ contained in the new master boot record. Note that FSformat only supports
+ FAT12 and FAT16 formatting at this time, and so cannot be used to format a
+ device with more than 0x3FFD5F sectors.
+ Remarks:
+ This function can damage the device being used, and should not be called
+ unless the user is sure about the size of the device and the first sector value.
+ *********************************************************************************/
+
+int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+{
+ PT_MBR Partition;
+ DWORD CyHdSc = 0x00000000;
+ DWORD tempSector;
+
+ if ((firstSector == 0) || (numSectors <= 1))
+ return EOF;
+
+ if (firstSector > (numSectors - 1))
+ return EOF;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ return EOF;
+
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ Partition = (PT_MBR) gDataBuffer;
+
+ // Set Cylinder-head-sector address of the first sector
+ tempSector = firstSector;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[447] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[448] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[449] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the count of sectors
+ Partition->Partition0.PTE_NumSect = numSectors - firstSector;
+
+ // Set the partition type
+ // We only support creating FAT12 and FAT16 MBRs at this time
+ if (Partition->Partition0.PTE_NumSect < 0x1039)
+ {
+ // FAT12
+ Partition->Partition0.PTE_FSDesc = 0x01;
+ }
+ else if (Partition->Partition0.PTE_NumSect <= 0x3FFD5F)
+ {
+ // FAT16
+ Partition->Partition0.PTE_FSDesc = 0x06;
+ }
+ else
+ return EOF;
+
+ // Set the LBA of the first sector
+ Partition->Partition0.PTE_FrstSect = firstSector;
+
+ // Set the Cylinder-head-sector address of the last sector
+ tempSector = firstSector + numSectors - 1;
+ CyHdSc = (tempSector / (unsigned int)16065 ) << 14;
+ tempSector %= 16065;
+ CyHdSc |= (tempSector / 63) << 6;
+ tempSector %= 63;
+ CyHdSc |= tempSector + 1;
+ gDataBuffer[451] = (BYTE)((CyHdSc >> 16) & 0xFF);
+ gDataBuffer[452] = (BYTE)((CyHdSc >> 8) & 0xFF);
+ gDataBuffer[453] = (BYTE)((CyHdSc) & 0xFF);
+
+ // Set the boot descriptor. This will be 0, since we won't
+ // be booting anything from our device probably
+ Partition->Partition0.PTE_BootDes = 0x00;
+
+ // Set the signature codes
+ Partition->Signature0 = 0x55;
+ Partition->Signature1 = 0xAA;
+
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) != TRUE)
+ return EOF;
+ else
+ return 0;
+
+}
+
+
+
+/*******************************************************************
+ Function:
+ int FSformat (char mode, long int serialNumber, char * volumeID)
+ Summary:
+ Formats a device
+ Conditions:
+ The device must possess a valid master boot record.
+ Input:
+ mode - - 0 - Just erase the FAT and root
+ - 1 - Create a new boot sector
+ serialNumber - Serial number to write to the card
+ volumeID - Name of the card
+ Return Values:
+ 0 - Format was successful
+ EOF - Format was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSformat function can be used to create a new boot sector
+ on a device, based on the information in the master boot record.
+ This function will first initialize the I/O pins and the device,
+ and then attempts to read the master boot record. If the MBR
+ cannot be loaded successfully, the function will fail. Next, if
+ the 'mode' argument is specified as '0' the existing boot sector
+ information will be loaded. If the 'mode' argument is '1' an
+ entirely new boot sector will be constructed using the disk
+ values from the master boot record. Once the boot sector has
+ been successfully loaded/created, the locations of the FAT and
+ root will be loaded from it, and they will be completely
+ erased. If the user has specified a volumeID parameter, a
+ VOLUME attribute entry will be created in the root directory
+ to name the device.
+ Remarks:
+ FAT12 and FAT16 formatting is supported.
+ *******************************************************************/
+
+int FSformat (char mode, long int serialNumber, char * volumeID)
+{
+ PT_MBR masterBootRecord;
+ DWORD secCount, FAT16DataClusters, RootDirSectors;
+ BootSec BSec;
+ DISK d;
+ DISK * disk = &d;
+ WORD j;
+ DWORD fatsize, test;
+ BYTE Index;
+#ifdef __18CXX
+ // This is here because of a C18 compiler feature
+ BYTE * dataBufferPointer = gDataBuffer;
+#endif
+
+ FSerrno = CE_GOOD;
+
+ disk->buffer = gDataBuffer;
+
+ MDD_InitIO();
+
+ if (MDD_MediaInitialize() != TRUE)
+ {
+ FSerrno = CE_INIT_ERROR;
+ return EOF;
+ }
+
+ if (MDD_SectorRead (0x00, gDataBuffer) == FALSE)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+
+ // Check if the card has no MBR
+ BSec = (BootSec) disk->buffer;
+ if((BSec->Signature0 == FAT_GOOD_SIGN_0) && (BSec->Signature1 == FAT_GOOD_SIGN_1))
+ {
+ // Technically, the OEM name is not for indication
+ // The alternative is to read the CIS from attribute
+ // memory. See the PCMCIA metaformat for more details
+#if defined (__C30__) || defined (__C32__)
+ if (ReadByte( disk->buffer, BSI_FSTYPE ) == 'F' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 1 ) == 'A' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 2 ) == 'T' && \
+ ReadByte( disk->buffer, BSI_FSTYPE + 3 ) == '1' && \
+ ReadByte( disk->buffer, BSI_BOOTSIG) == 0x29)
+#else
+ if (BSec->FAT.FAT_16.BootSec_FSType[0] == 'F' && \
+ BSec->FAT.FAT_16.BootSec_FSType[1] == 'A' && \
+ BSec->FAT.FAT_16.BootSec_FSType[2] == 'T' && \
+ BSec->FAT.FAT_16.BootSec_FSType[3] == '1' && \
+ BSec->FAT.FAT_16.BootSec_BootSig == 0x29)
+#endif
+ {
+ switch (mode)
+ {
+ case 1:
+ // not enough info to construct our own boot sector
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ case 0:
+ // We have to determine the operating system, and the
+ // locations and sizes of the root dir and FAT, and the
+ // count of FATs
+ disk->firsts = 0;
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ default:
+ break;
+ }
+ }
+ else
+ {
+ masterBootRecord = (PT_MBR) &gDataBuffer;
+ disk->firsts = masterBootRecord->Partition0.PTE_FrstSect;
+ }
+ }
+
+ switch (mode)
+ {
+ // True: Rewrite the whole boot sector
+ case 1:
+ secCount = masterBootRecord->Partition0.PTE_NumSect;
+
+ if (secCount < 0x1039)
+ {
+ disk->type = FAT12;
+ // Format to FAT12 only if there are too few sectors to format
+ // as FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x01;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ if (secCount >= 0x1028)
+ {
+ // More than 0x18 sectors for FATs, 0x20 for root dir,
+ // 0x8 reserved, and 0xFED for data
+ // So double the number of sectors in a cluster to reduce
+ // the number of data clusters used
+ disk->SecPerClus = 2;
+ }
+ else
+ {
+ // One sector per cluster
+ disk->SecPerClus = 1;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT12 )
+ gDataBuffer[58] = '2';
+ }
+ else if (secCount <= 0x3FFD5F)
+ {
+ disk->type = FAT16;
+ // Format to FAT16
+ masterBootRecord->Partition0.PTE_FSDesc = 0x06;
+ if (MDD_SectorWrite (0x00, gDataBuffer, TRUE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ FAT16DataClusters = secCount - 0x218;
+ // Figure out how many sectors per cluster we need
+ disk->SecPerClus = 1;
+ while (FAT16DataClusters > 0xFFED)
+ {
+ disk->SecPerClus *= 2;
+ FAT16DataClusters /= 2;
+ }
+ // This shouldnt happen
+ if (disk->SecPerClus > 128)
+ {
+ FSerrno = CE_BAD_PARTITION;
+ return EOF;
+ }
+
+ // Prepare a boot sector
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ // Last digit of file system name (FAT16 )
+ gDataBuffer[58] = '6';
+ }
+ else
+ {
+ // Cannot format; too many sectors
+ FSerrno = CE_NONSUPPORTED_SIZE;
+ return EOF;
+ }
+
+ // Calculate the size of the FAT
+ fatsize = (secCount - 0x21 + (2*disk->SecPerClus));
+ if (disk->type == FAT12)
+ test = (341 * disk->SecPerClus) + 2;
+ else
+ test = (256 * disk->SecPerClus) + 2;
+ fatsize = (fatsize + (test-1)) / test;
+ // Non-file system specific values
+ gDataBuffer[0] = 0xEB; //Jump instruction
+ gDataBuffer[1] = 0x3C;
+ gDataBuffer[2] = 0x90;
+ gDataBuffer[3] = 'M'; //OEM Name "MCHP FAT"
+ gDataBuffer[4] = 'C';
+ gDataBuffer[5] = 'H';
+ gDataBuffer[6] = 'P';
+ gDataBuffer[7] = ' ';
+ gDataBuffer[8] = 'F';
+ gDataBuffer[9] = 'A';
+ gDataBuffer[10] = 'T';
+ gDataBuffer[11] = 0x00; //Bytes per sector - 512
+ gDataBuffer[12] = 0x02;
+ gDataBuffer[13] = disk->SecPerClus; //Sectors per cluster
+ gDataBuffer[14] = 0x08; //Reserved sector count
+ gDataBuffer[15] = 0x00;
+ disk->fat = 0x08 + disk->firsts;
+ gDataBuffer[16] = 0x02; //number of FATs
+ disk->fatcopy = 0x02;
+ gDataBuffer[17] = 0x00; //Max number of root directory entries - 512 files allowed
+ gDataBuffer[18] = 0x02;
+ disk->maxroot = 0x200;
+ gDataBuffer[19] = 0x00; //total sectors
+ gDataBuffer[20] = 0x00;
+ gDataBuffer[21] = 0xF8; //Media Descriptor
+ gDataBuffer[22] = fatsize & 0xFF; //Sectors per FAT
+ gDataBuffer[23] = (fatsize >> 8) & 0xFF;
+ disk->fatsize = fatsize;
+ gDataBuffer[24] = 0x3F; //Sectors per track
+ gDataBuffer[25] = 0x00;
+ gDataBuffer[26] = 0xFF; //Number of heads
+ gDataBuffer[27] = 0x00;
+ // Hidden sectors = sectors between the MBR and the boot sector
+ gDataBuffer[28] = (BYTE)(disk->firsts & 0xFF);
+ gDataBuffer[29] = (BYTE)((disk->firsts / 0x100) & 0xFF);
+ gDataBuffer[30] = (BYTE)((disk->firsts / 0x10000) & 0xFF);
+ gDataBuffer[31] = (BYTE)((disk->firsts / 0x1000000) & 0xFF);
+ // Total Sectors = same as sectors in the partition from MBR
+ gDataBuffer[32] = (BYTE)(secCount & 0xFF);
+ gDataBuffer[33] = (BYTE)((secCount / 0x100) & 0xFF);
+ gDataBuffer[34] = (BYTE)((secCount / 0x10000) & 0xFF);
+ gDataBuffer[35] = (BYTE)((secCount / 0x1000000) & 0xFF);
+ gDataBuffer[36] = 0x00; // Physical drive number
+ gDataBuffer[37] = 0x00; // Reserved (current head)
+ gDataBuffer[38] = 0x29; // Signature code
+ gDataBuffer[39] = (BYTE)(serialNumber & 0xFF);
+ gDataBuffer[40] = (BYTE)((serialNumber / 0x100) & 0xFF);
+ gDataBuffer[41] = (BYTE)((serialNumber / 0x10000) & 0xFF);
+ gDataBuffer[42] = (BYTE)((serialNumber / 0x1000000) & 0xFF);
+ // Volume ID
+ if (volumeID != NULL)
+ {
+ for (Index = 0; (*(volumeID + Index) != 0) && (Index < 11); Index++)
+ {
+ gDataBuffer[Index + 43] = *(volumeID + Index);
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[43 + Index++] = 0x20;
+ }
+ }
+ else
+ {
+ for (Index = 0; Index < 11; Index++)
+ {
+ gDataBuffer[Index+43] = 0;
+ }
+ }
+ gDataBuffer[54] = 'F';
+ gDataBuffer[55] = 'A';
+ gDataBuffer[56] = 'T';
+ gDataBuffer[57] = '1';
+ gDataBuffer[59] = ' ';
+ gDataBuffer[60] = ' ';
+ gDataBuffer[61] = ' ';
+#ifdef __18CXX
+ // C18 can't reference a value greater than 256
+ // using an array name pointer
+ *(dataBufferPointer + 510) = 0x55;
+ *(dataBufferPointer + 511) = 0xAA;
+#else
+ gDataBuffer[510] = 0x55;
+ gDataBuffer[511] = 0xAA;
+#endif
+
+ disk->root = disk->fat + (disk->fatcopy * disk->fatsize);
+
+ if (MDD_SectorWrite (disk->firsts, gDataBuffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ break;
+ case 0:
+ if (LoadBootSector (disk) != CE_GOOD)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return EOF;
+ }
+ break;
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ return EOF;
+ }
+
+ // Erase the FAT
+ memset (gDataBuffer, 0x00, MEDIA_SECTOR_SIZE);
+ gDataBuffer[0] = 0xF8;
+ gDataBuffer[1] = 0xFF;
+ gDataBuffer[2] = 0xFF;
+ if (disk->type == FAT16)
+ gDataBuffer[3] = 0xFF;
+
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (disk->fat + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ memset (gDataBuffer, 0x00, 4);
+
+ for (Index = disk->fat + 1; Index < (disk->fat + disk->fatsize); Index++)
+ {
+ for (j = disk->fatcopy - 1; j != 0xFFFF; j--)
+ {
+ if (MDD_SectorWrite (Index + (j * disk->fatsize), gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ }
+
+ // Erase the root directory
+ RootDirSectors = ((disk->maxroot * 32) + (0x200 - 1)) / 0x200;
+
+ for (Index = 1; Index < RootDirSectors; Index++)
+ {
+ if (MDD_SectorWrite (disk->root + Index, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ if (volumeID != NULL)
+ {
+ // Create a drive name entry in the root dir
+ Index = 0;
+ while ((*(volumeID + Index) != 0) && (Index < 11))
+ {
+ gDataBuffer[Index] = *(volumeID + Index);
+ Index++;
+ }
+ while (Index < 11)
+ {
+ gDataBuffer[Index++] = ' ';
+ }
+ gDataBuffer[11] = 0x08;
+ gDataBuffer[17] = 0x11;
+ gDataBuffer[19] = 0x11;
+ gDataBuffer[23] = 0x11;
+
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+ else
+ {
+ if (MDD_SectorWrite (disk->root, gDataBuffer, FALSE) == FALSE)
+ return EOF;
+ }
+
+ return 0;
+}
+#endif
+#endif
+
+
+/*******************************************************
+ Function:
+ BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+ Summary:
+ Write dir entry info into a specified entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - \File structure
+ curEntry - Write destination
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will calculate the sector of the
+ directory (whose base sector is pointed to by the
+ dirccls value in the FSFILE object 'fo') that contains
+ a directory entry whose offset is indicated by the
+ curEntry parameter. It will then write the data
+ in the global data buffer (which should already
+ contain the entries for that sector) to the device.
+ Remarks:
+ None
+ *******************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
+{
+ DISK *dsk;
+ BYTE status;
+ BYTE offset2;
+ DWORD sector;
+ DWORD ccls;
+
+ dsk = fo->dsk;
+
+ // get the cluster of this entry
+ ccls = fo->dirccls;
+
+ // if its not the root, it's cluster based
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // Root is always cluster-based in FAT32
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ if(ccls != FatRootDirClusterValue)
+ offset2 = offset2 % (dsk->SecPerClus);
+ break;
+ }
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ // Now write it
+ // "Offset" ensures writing of data belonging to a file entry only. Hence it doesn't change other file entries.
+ if ( !MDD_SectorWrite( sector + offset2, dsk->buffer, FALSE))
+ status = FALSE;
+ else
+ status = TRUE;
+
+ return(status);
+} // Write_File_Entry
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE FAT_erase_cluster_chain (WORD cluster, DISK * dsk)
+ Summary:
+ Erase a chain of clusters
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ cluster - The cluster number
+ dsk - The disk structure
+ Return Values:
+ TRUE - Operation successful
+ FALSE - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will parse through a cluster chain
+ starting with the cluster pointed to by 'cluster' and
+ mark all of the FAT entries as empty until the end of
+ the chain has been reached or an error occurs.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FAT_erase_cluster_chain (DWORD cluster, DISK * dsk)
+{
+ DWORD c,c2,ClusterFailValue;
+ enum _status {Good, Fail, Exit}status;
+
+ status = Good;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ c2 = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT16:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ c2 = LAST_CLUSTER_FAT16;
+ break;
+
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16; // FAT16 value itself
+ c2 = LAST_CLUSTER_FAT12;
+ break;
+ }
+
+ // Make sure there is actually a cluster assigned
+ if(cluster == 0 || cluster == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ while(status == Good)
+ {
+ // Get the FAT entry
+ if((c = ReadFAT( dsk, cluster)) == ClusterFailValue)
+ status = Fail;
+ else
+ {
+ if(c == 0 || c == 1) // Cluster assigned can't be "0" and "1"
+ {
+ status = Exit;
+ }
+ else
+ {
+ // compare against max value of a cluster in FATxx
+ // look for the last cluster in the chain
+ if ( c >= c2)
+ status = Exit;
+
+ // Now erase this FAT entry
+ if(WriteFAT(dsk, cluster, CLUSTER_EMPTY, FALSE) == ClusterFailValue)
+ status = Fail;
+
+ // now update what the current cluster is
+ cluster = c;
+ }
+ }
+ }// while status
+ }// cluster == 0
+
+ WriteFAT (dsk, 0, 0, TRUE);
+
+ if(status == Exit)
+ return(TRUE);
+ else
+ return(FALSE);
+} // Erase cluster
+#endif
+
+/**************************************************************************
+ Function:
+ DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+ Summary:
+ Load a file entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - File information
+ curEntry - Offset of the directory entry to load.
+ ForceRead - Forces loading of a new sector of the directory.
+ Return:
+ DIRENTRY - Pointer to the directory entry that was loaded.
+ Side Effects:
+ Any unwritten data in the data buffer will be written to the device.
+ Description:
+ Load the sector containing the file entry pointed to by 'curEntry'
+ from the directory pointed to by the variables in 'fo.'
+ Remarks:
+ Any modification of this function is extremely likely to
+ break something.
+ **************************************************************************/
+
+DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
+{
+ DIRENTRY dir;
+ DISK *dsk;
+ DWORD sector;
+ DWORD cluster, LastClusterLimit;
+ DWORD ccls;
+ BYTE offset2;
+ BYTE numofclus;
+
+ dsk = fo->dsk;
+
+ // get the base sector of this directory
+ cluster = fo->dirclus;
+ ccls = fo->dirccls;
+
+ // figure out the offset from the base sector
+ offset2 = (*curEntry >> VALUE_BASED_ON_ENTRIES_PER_CLUSTER); // 2^4 = 16 entries per sector.
+ /* There are 16 entries per sector. SECTOR size is 512 bytes. Each entry in ROOT takes 32 bytes.
+ So, 512/32 = 16. So 16 file entries can be made in each sector. */
+
+ offset2 = offset2; // emulator issue
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ // the ROOT is always cluster based in FAT32
+ /* In FAT32: There is no ROOT region. Root etries are made in DATA region only.
+ Every cluster of DATA which is accupied by ROOT is tracked by FAT table/entry so the ROOT can grow
+ to an amount which is restricted only by available free DATA region. */
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // if its the root its not cluster based
+ if(cluster != 0)
+ offset2 = offset2 % (dsk->SecPerClus); // figure out the offset
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ // check if a new sector of the root must be loaded
+ if (ForceRead || (*curEntry & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) // only 16 entries per sector
+ {
+ // see if we have to load a new cluster
+ if((offset2 == 0 && (*curEntry) >= DIRENTRIES_PER_SECTOR) || ForceRead)
+ {
+ if(cluster == 0)
+ {
+ ccls = 0;
+ }
+ else
+ {
+ // If ForceRead, read the number of sectors from 0
+ if(ForceRead)
+ numofclus = ((WORD)(*curEntry) / (WORD)(((WORD)DIRENTRIES_PER_SECTOR) * (WORD)dsk->SecPerClus));
+ // Otherwise just read the next sector
+ else
+ numofclus = 1;
+
+ // move to the correct cluster
+ while(numofclus)
+ {
+ ccls = ReadFAT(dsk, ccls);
+
+ if(ccls >= LastClusterLimit)
+ break;
+ else
+ numofclus--;
+ }
+ }
+ }
+
+ // see if that we have a valid cluster number
+ if(ccls < LastClusterLimit)
+ {
+ fo->dirccls = ccls; // write it back
+
+ sector = Cluster2Sector(dsk,ccls);
+
+ /* see if we are root and about to go pass our boundaries
+ FAT32 stores the root directory in the Data Region along with files and other directories,
+ allowing it to grow without such a restraint */
+ if((ccls == FatRootDirClusterValue) && ((sector + offset2) >= dsk->data) && (FAT32 != dsk->type))
+ {
+ dir = ((DIRENTRY)NULL); // reached the end of the root
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ return NULL;
+#endif
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+
+ if ( MDD_SectorRead( sector + offset2, dsk->buffer) != TRUE) // if FALSE: sector could not be read.
+ {
+ dir = ((DIRENTRY)NULL);
+ }
+ else // Sector has been read properly, Copy the root entry info of the file searched.
+ {
+ if(ForceRead) // Buffer holds all 16 root entry info. Point to the one required.
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+ else
+ dir = (DIRENTRY)dsk->buffer;
+ }
+ gLastDataSectorRead = 0xFFFFFFFF;
+ }
+ }
+ else
+ {
+ nextClusterIsLast = TRUE;
+ dir = ((DIRENTRY)NULL);
+ }
+ }
+ else
+ dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
+
+ return(dir);
+} // Cache_File_Entry
+
+
+/*************************************************************************
+ Function:
+ CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Create a new file entry
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location to create file
+ Return Values:
+ CE_GOOD - File Creation successful
+ CE_DIR_FULL - All root directory entries are taken
+ CE_WRITE_ERROR - The head cluster of the file could not be created.
+ Side Effects:
+ Modifies the FSerrno variable.
+ Description:
+ With the data passed within fo, create a new file entry in the current
+ directory. This function will first search for empty file entries.
+ Once an empty entry is found, the entry will be populated with data
+ for a file or directory entry. Finally, the first cluster of the
+ new file will be located and allocated, and its value will be
+ written into the file entry.
+ Remarks:
+ None
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFileEntry(FILEOBJ fo, WORD *fHandle, BYTE mode)
+{
+ BYTE index;
+ CETYPE error = CE_GOOD;
+ char name[11];
+
+ FSerrno = CE_GOOD;
+
+ for (index = 0; index < FILE_NAME_SIZE; index ++)
+ {
+ name[index] = fo->name[index];
+ }
+
+ *fHandle = 0;
+
+ // figure out where to put this file in the directory stucture
+ if(FindEmptyEntries(fo, fHandle))
+ {
+ // found the entry, now populate it
+ if((error = PopulateEntries(fo, name ,fHandle, mode)) == CE_GOOD)
+ {
+ // if everything is ok, create a first cluster
+ error = CreateFirstCluster(fo);
+ }
+ }
+ else
+ {
+ error = CE_DIR_FULL;
+ }
+
+ FSerrno = error;
+
+ return(error);
+}
+#endif
+
+/******************************************************
+ Function:
+ CETYPE CreateFirstCluster(FILEOBJ fo)
+ Summary:
+ Create the first cluster for a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - The file that contains the first cluster
+ Return Values:
+ CE_GOOD - First cluster created successfully
+ CE_WRITE_ERROR - Cluster creation failed
+ Side Effects:
+ None
+ Description:
+ This function will find an unused cluster, link it to
+ a file's directory entry, and write the entry back
+ to the device.
+ Remarks:
+ None.
+ ******************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE CreateFirstCluster(FILEOBJ fo)
+{
+ CETYPE error;
+ DWORD cluster,TempMsbCluster;
+ WORD fHandle;
+ DIRENTRY dir;
+ fHandle = fo->entry;
+
+ // Now create the first cluster (head cluster)
+ if((error = FILECreateHeadCluster(fo,&cluster)) == CE_GOOD)
+ {
+ // load the file entry so the new cluster can be linked to it
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ // Now update the new cluster
+ dir->DIR_FstClusLO = (cluster & 0x0000FFFF);
+
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ // Get the higher part of cluster and store it in directory entry.
+ TempMsbCluster = (cluster & 0x0FFF0000); // Since only 28 bits usedin FAT32. Mask the higher MSB nibble.
+ TempMsbCluster = TempMsbCluster >> 16; // Get the date into Lsb place.
+ dir->DIR_FstClusHI = TempMsbCluster;
+#else // If FAT32 support not enabled
+ TempMsbCluster = 0; // Just to avoid compiler warnigng.
+ dir->DIR_FstClusHI = 0;
+#endif
+
+ // now write it
+ if(Write_File_Entry(fo, &fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+ } // Create Cluster
+
+ return(error);
+}// End of CreateFirstCluster
+#endif
+
+/**********************************************************
+ Function:
+ BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Find an empty dir entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Start of entries
+ Return Values:
+ TRUE - One found
+ FALSE - None found
+ Side Effects:
+ None
+ Description:
+ This function will cache directory entries, starting
+ with the one pointed to by the fHandle argument. It will
+ then search through the entries until an unused one
+ is found. If the end of the cluster chain for the
+ directory is reached, a new cluster will be allocated
+ to the directory (unless it's a FAT12 or FAT16 root)
+ and the first entry of the new cluster will be used.
+ Remarks:
+ None.
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FindEmptyEntries(FILEOBJ fo, WORD *fHandle)
+{
+ BYTE status = NOT_FOUND;
+ BYTE amountfound;
+ BYTE a;
+ WORD bHandle;
+ DWORD b;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ if((dir = Cache_File_Entry( fo, fHandle, TRUE)) == NULL)
+ {
+ status = CE_BADCACHEREAD;
+ }
+ else
+ {
+ // while its still not found
+ while(status == NOT_FOUND)
+ {
+ amountfound = 0;
+ bHandle = *fHandle;
+
+ // find (number) continuous entries
+ do
+ {
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // increase number
+ (*fHandle)++;
+ }while((a == DIR_DEL || a == DIR_EMPTY) && (dir != (DIRENTRY)NULL) && (++amountfound < 1));
+
+ // --- now why did we exit?
+ if(dir == NULL) // Last entry of the cluster
+ {
+ //setup the current cluster
+ b = fo->dirccls; // write it back
+
+ // make sure we are not the root directory
+ if(b == FatRootDirClusterValue)
+ {
+ if (fo->dsk->type != FAT32)
+ status = NO_MORE;
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ fo->ccls = b;
+
+ if(FILEallocate_new_cluster(fo, 1) == CE_DISK_FULL)
+ status = NO_MORE;
+ else
+ {
+ *fHandle = bHandle;
+ status = FOUND; // a new cluster will surely hold a new file name
+ }
+ }
+ }
+ else
+ {
+ if(amountfound == 1)
+ {
+ status = FOUND;
+ *fHandle = bHandle;
+ }
+ }
+ }// while
+
+ // copy the base handle over
+ *fHandle = bHandle;
+ }
+
+ if(status == FOUND)
+ return(TRUE);
+ else
+ return(FALSE);
+}
+#endif
+
+/**************************************************************************
+ Function:
+ BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle)
+ Summary:
+ Populate a dir entry with data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ name - Name of the file
+ fHandle - Location of the file
+ Return Values:
+ CE_GOOD - Population successful
+ Side Effects:
+ None
+ Description:
+ This function will write data into a new file entry. It will also
+ load timestamp data (based on the method selected by the user) and
+ update the timestamp variables.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE PopulateEntries(FILEOBJ fo, char *name , WORD *fHandle, BYTE mode)
+{
+ BYTE error = CE_GOOD;
+ DIRENTRY dir;
+
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+
+ if (dir == NULL)
+ return CE_BADCACHEREAD;
+
+ // copy the contents over
+ strncpy(dir->DIR_Name,name,DIR_NAMECOMP);
+
+ // setup no attributes
+ if (mode == DIRECTORY)
+ dir->DIR_Attr = ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = ATTR_ARCHIVE;
+
+ dir->DIR_NTRes = 0x00; // nt reserved
+ dir->DIR_FstClusHI = 0x0000; // high word of this enty's first cluster number
+ dir->DIR_FstClusLO = 0x0000; // low word of this entry's first cluster number
+ dir->DIR_FileSize = 0x0; // file size in DWORD
+
+ // Timing information for uncontrolled clock mode
+#ifdef INCREMENTTIMESTAMP
+ dir->DIR_CrtTimeTenth = 0xB2; // millisecond stamp
+ dir->DIR_CrtTime = 0x7278; // time created
+ dir->DIR_CrtDate = 0x32B0; // date created
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = 0x32B0; // Last Access date
+ dir->DIR_WrtTime = 0x7279; // last update time
+ dir->DIR_WrtDate = 0x32B0; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ dir->DIR_CrtTime = gTimeCrtTime; // time created //
+ dir->DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate; // Last Access date
+ dir->DIR_WrtTime = gTimeWrtTime; // last update time
+ dir->DIR_WrtDate = gTimeWrtDate; // last update date
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ // The user will have set the time before this funciton is called
+ dir->DIR_CrtTimeTenth = gTimeCrtMS;
+ dir->DIR_CrtTime = gTimeCrtTime;
+ dir->DIR_CrtDate = gTimeCrtDate;
+ if (mode != DIRECTORY)
+ {
+ dir->DIR_LstAccDate = gTimeAccDate;
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+ }
+ else
+ {
+ dir->DIR_LstAccDate = 0x0000; // Last Access date
+ dir->DIR_WrtTime = 0x0000; // last update time
+ dir->DIR_WrtDate = 0x0000; // last update date
+ }
+#endif
+
+ fo->size = dir->DIR_FileSize;
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ fo->attributes = dir->DIR_Attr;
+ fo->entry = *fHandle;
+
+ // just write the last entry in
+ if (Write_File_Entry(fo,fHandle) != TRUE)
+ error = CE_WRITE_ERROR;
+
+ return(error);
+}
+
+#ifdef USEREALTIMECLOCK
+
+/*************************************************************************
+ Function:
+ void CacheTime (void)
+ Summary:
+ Automatically store timestamp information from the RTCC
+ Conditions:
+ RTCC module enabled. Should not be called by the user.
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ This function will automatically load information from an RTCC
+ module and use it to update the global timing variables. These can
+ then be used to update file timestamps.
+ Remarks:
+ None.
+ *************************************************************************/
+
+void CacheTime (void)
+{
+#ifdef __C30__
+ WORD year, monthday, weekhour, minsec, c, result;
+ BYTE ptr1, ptr0;
+
+ if(RCFGCALbits.RTCPTR0)
+ ptr0 = 1;
+ else
+ ptr0 = 0;
+ if (RCFGCALbits.RTCPTR1)
+ ptr1 = 1;
+ else
+ ptr1 = 0;
+
+ RCFGCALbits.RTCPTR0 = 1;
+ RCFGCALbits.RTCPTR1 = 1;
+ year = RTCVAL;
+ monthday = RTCVAL;
+ weekhour = RTCVAL;
+ minsec = RTCVAL;
+
+ if (ptr0 == 1)
+ RCFGCALbits.RTCPTR0 = 1;
+
+ if (ptr1 == 1)
+ RCFGCALbits.RTCPTR1 = 1;
+
+ c = 0;
+ c += (year & 0x0F);
+ c += ((year & 0xF0) >> 4) * 10;
+ // c equals the last 2 digits of the year from 2000 to 2099
+ // Add 20 to adjust it to FAT time (from 1980 to 2107)
+ c += 20;
+ // shift the result to bits
+ result = c << 9;
+
+ if ((monthday & 0x1000) == 0x1000)
+ {
+ c = 10;
+ }
+ else
+ {
+ c = 0;
+ }
+ c += ((monthday & 0x0F00) >> 8);
+ c <<= 5;
+ result |= c;
+
+ c = (monthday & 0x00F0) >> 4;
+ c *= 10;
+ c += (monthday & 0x000F);
+
+ result |= c;
+
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+ gTimeAccDate = result;
+
+ c = ((weekhour & 0x00F0) >> 4) * 10;
+ c += (weekhour & 0x000F);
+ result = c << 11;
+ c = ((minsec & 0xF000) >> 12) * 10;
+ c += (minsec & 0x0F00) >> 8;
+ result |= (c << 5);
+ c = ((minsec & 0x00F0) >> 4) * 10;
+ c += (minsec & 0x000F);
+
+ // If seconds mod 2 is 1, add 1000 ms
+ if (c % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ c >>= 1;
+ result |= c;
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+#elif defined __C32__
+ rtccTime tm; // time structure
+ rtccDate dt; // date structure
+ RtccGetTimeDate(&tm, &dt);
+ gTimeCrtTime = tm.w[1] | tm.w[0];
+ gTimeWrtDate = dt.w[1] | tm.w[0];
+#endif
+}
+#endif
+
+#ifdef USERDEFINEDCLOCK
+
+/***********************************************************************************************************
+ Function:
+ int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+ Summary:
+ Manually set timestamp variables
+ Conditions:
+ USERDEFINEDCLOCK macro defined in FSconfig.h.
+ Input:
+ year - The year (1980\-2107)
+ month - The month (1\-12)
+ day - The day of the month (1\-31)
+ hour - The hour (0\-23)
+ minute - The minute (0\-59)
+ second - The second (0\-59)
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ Lets the user manually set the timing variables. The values passed in will be converted to the format
+ used by the FAT timestamps.
+ Remarks:
+ Call this before creating a file or directory (set create time) and
+ before closing a file (set last access time, last modified time)
+ ***********************************************************************************************************/
+
+int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+{
+ unsigned int result;
+
+ if ((year < 1980) || (year > 2107) || (month < 1) || (month > 12) ||
+ (day < 1) || (day > 31) || (hour > 23) || (minute > 59) || (second > 59))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ result = (year - 1980) << 9;
+ result |= (unsigned int)((unsigned int)month << 5);
+ result |= (day);
+
+ gTimeAccDate = result;
+ gTimeCrtDate = result;
+ gTimeWrtDate = result;
+
+ result = ((unsigned int)hour << 11);
+ result |= (unsigned int)((unsigned int)minute << 5);
+ result |= (second/2);
+
+ gTimeCrtTime = result;
+ gTimeWrtTime = result;
+
+ if (second % 2)
+ gTimeCrtMS = 100;
+ else
+ gTimeCrtMS = 0;
+
+ FSerrno = CE_GOOD;
+ return 0;
+}
+#endif
+
+#endif
+
+/***********************************************************************
+ Function:
+ BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+ Summary;
+ Allocate a new cluster to a file
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ mode -
+ - 0 - Allocate a cluster to a file
+ - 1 - Allocate a cluster to a directory
+ Return Values:
+ CE_GOOD - Cluster allocated
+ CE_DISK_FULL - No clusters available
+ Side Effects:
+ None
+ Description:
+ This function will find an empty cluster on the device using the
+ FATfindEmptyCluster function. It will then mark it as the last
+ cluster in the file in the FAT chain, and link the current last
+ cluster of the passed file to the new cluster. If the new
+ cluster is a directory cluster, it will be erased (so there are no
+ extraneous directory entries). If it's allocated to a non-directory
+ file, it doesn't need to be erased; extraneous data in the cluster
+ will be unviewable because of the file size parameter.
+ Remarks:
+ None.
+ ***********************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE FILEallocate_new_cluster( FILEOBJ fo, BYTE mode)
+{
+ DISK * dsk;
+ DWORD c,curcls;
+
+ dsk = fo->dsk;
+ c = fo->ccls;
+
+ // find the next empty cluster
+ c = FATfindEmptyCluster(fo);
+ if (c == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ return CE_DISK_FULL;
+
+
+ // mark the cluster as taken, and last in chain
+ if(dsk->type == FAT12)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT12, FALSE);
+ else if (dsk->type == FAT16)
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT16, FALSE);
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ WriteFAT( dsk, c, LAST_CLUSTER_FAT32, FALSE);
+#endif
+
+ // link current cluster to the new one
+ curcls = fo->ccls;
+
+ WriteFAT( dsk, curcls, c, FALSE);
+
+ // update the FILE structure
+ fo->ccls = c;
+
+ // IF this is a dir, we need to erase the cluster
+ // If it's a file, we can leave it- the file size
+ // will limit the data we see to the data that's been
+ // written
+ if (mode == 1)
+ return (EraseCluster(dsk, c));
+ else
+ return CE_GOOD;
+
+} // allocate new cluster
+#endif
+
+/***********************************************
+ Function:
+ DWORD FATfindEmptyCluster(FILEOBJ fo)
+ Summary:
+ Find the next available cluster on the device
+ Conditions:
+ This function should not be called by the
+ user.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ DWORD - Address of empty cluster
+ 0 - Could not find empty cluster
+ Side Effects:
+ None
+ Description:
+ This function will search through the FAT to
+ find the next available cluster on the device.
+ Remarks:
+ Should not be called by user
+ ***********************************************/
+
+#ifdef ALLOW_WRITES
+DWORD FATfindEmptyCluster(FILEOBJ fo)
+{
+ DISK * disk;
+ DWORD value = 0x0;
+ DWORD c,curcls, EndClusterLimit, ClusterFailValue;
+
+ disk = fo->dsk;
+ c = fo->ccls;
+
+ /* Settings based on FAT type */
+ switch (disk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ EndClusterLimit = END_CLUSTER_FAT32;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ EndClusterLimit = END_CLUSTER_FAT16;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ case FAT12:
+ EndClusterLimit = END_CLUSTER_FAT12;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ // just in case
+ if(c < 2)
+ c = 2;
+
+ curcls = c;
+ ReadFAT(disk, c);
+
+ // sequentially scan through the FAT looking for an empty cluster
+ while(c)
+ {
+ // look at its value
+ if ( (value = ReadFAT(disk, c)) == ClusterFailValue)
+ {
+ c = 0;
+ break;
+ }
+
+ // check if empty cluster found
+ if (value == CLUSTER_EMPTY)
+ break;
+
+ c++; // check next cluster in FAT
+ // check if reached last cluster in FAT, re-start from top
+ if (value == EndClusterLimit || c >= disk->maxcls)
+ c = 2;
+
+ // check if full circle done, disk full
+ if ( c == curcls)
+ {
+ c = 0;
+ break;
+ }
+ } // scanning for an empty cluster
+
+ return(c);
+}
+#endif
+
+/************************************************************
+ Function:
+ int FSfclose(FSFILE *fo)
+ Summary:
+ Update file information and free FSFILE objects
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to the file to close
+ Return Values:
+ 0 - File closed successfully
+ EOF - Error closing the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will update the directory entry for the
+ file pointed to by 'fo' with the information contained
+ in 'fo,' including the new file size and attributes.
+ Timestamp information will also be loaded based on the
+ method selected by the user and written to the entry
+ as the last modified time and date. The file entry will
+ then be written to the device. Finally, the memory
+ used for the specified file object will be freed from
+ the dynamic heap or the array of FSFILE objects.
+ Remarks:
+ A function to flush data to the device without closing the
+ file can be created by removing the portion of this
+ function that frees the memory and the line that clears
+ the write flag.
+ ************************************************************/
+
+int FSfclose(FSFILE *fo)
+{
+ WORD fHandle;
+#ifndef FS_DYNAMIC_MEM
+ WORD fIndex;
+#endif
+ int error = 72;
+#ifdef ALLOW_WRITES
+ DIRENTRY dir;
+#endif
+
+ FSerrno = CE_GOOD;
+ fHandle = fo->entry;
+
+#ifdef ALLOW_WRITES
+ if(fo->flags.write)
+ {
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ // Write the current FAT sector to the disk
+ WriteFAT (fo->dsk, 0, 0, TRUE);
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = EOF;
+ return error;
+ }
+
+ // update the time
+#ifdef INCREMENTTIMESTAMP
+ IncrementTimeStamp(dir);
+#elif defined USERDEFINEDCLOCK
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#elif defined USEREALTIMECLOCK
+ CacheTime();
+ dir->DIR_WrtTime = gTimeWrtTime;
+ dir->DIR_WrtDate = gTimeWrtDate;
+#endif
+
+ Nop();
+
+ dir->DIR_FileSize = fo->size;
+
+ dir->DIR_Attr = fo->attributes;
+
+ // just write the last entry in
+ if(Write_File_Entry(fo,&fHandle))
+ error = 0;
+ else
+ {
+ FSerrno = CE_WRITE_ERROR;
+ error = EOF;
+ }
+
+ // it's now closed
+ fo->flags.write = FALSE;
+ }
+#endif
+
+#ifdef FS_DYNAMIC_MEM
+ FS_free((unsigned char *)fo);
+#else
+
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( fo == &gFileArray[fIndex] )
+ {
+ gFileSlotOpen[fIndex] = TRUE;
+ break;
+ }
+ }
+#endif
+
+ // File opened in read mode
+ if (error == 72)
+ error = 0;
+
+ return(error);
+} // FSfclose
+
+
+
+
+/*******************************************************
+ Function:
+ void IncrementTimeStamp(DIRENTRY dir)
+ Summary:
+ Automatically set the timestamp to "don't care" data
+ Conditions:
+ Should not be called by the user.
+ Input:
+ dir - Pointer to directory structure
+ Return Values:
+ None
+ Side Effects:
+ None
+ Description:
+ This function will increment the timestamp variable in
+ the 'dir' directory entry. This is used for the
+ don't-care timing method.
+ Remarks:
+ None
+ *******************************************************/
+#ifdef INCREMENTTIMESTAMP
+void IncrementTimeStamp(DIRENTRY dir)
+{
+ BYTE seconds;
+ BYTE minutes;
+ BYTE hours;
+
+ BYTE day;
+ BYTE month;
+ BYTE year;
+
+ seconds = (dir->DIR_WrtTime & 0x1f);
+ minutes = ((dir->DIR_WrtTime & 0x07E0) >> 5);
+ hours = ((dir->DIR_WrtTime & 0xF800) >> 11);
+
+ day = (dir->DIR_WrtDate & 0x1f);
+ month = ((dir->DIR_WrtDate & 0x01E0) >> 5);
+ year = ((dir->DIR_WrtDate & 0xFE00) >> 9);
+
+ if(seconds < 29)
+ {
+ // Increment number of seconds by 2
+ // This clock method isn't intended to be accurate anyway
+ seconds++;
+ }
+ else
+ {
+ seconds = 0x00;
+
+ if(minutes < 59)
+ {
+ minutes++;
+ }
+ else
+ {
+ minutes = 0;
+
+ if(hours < 23)
+ {
+ hours++;
+ }
+ else
+ {
+ hours = 0;
+ if(day < 30)
+ {
+ day++;
+ }
+ else
+ {
+ day = 1;
+
+ if(month < 12)
+ {
+ month++;
+ }
+ else
+ {
+ month = 1;
+ // new year
+ year++;
+ // This is only valid until 2107
+ }
+ }
+ }
+ }
+ }
+
+ dir->DIR_WrtTime = (WORD)(seconds);
+ dir->DIR_WrtTime |= ((WORD)(minutes) << 5);
+ dir->DIR_WrtTime |= ((WORD)(hours) << 11);
+
+ dir->DIR_WrtDate = (WORD)(day);
+ dir->DIR_WrtDate |= ((WORD)(month) << 5);
+ dir->DIR_WrtDate |= ((WORD)(year) << 9);
+}
+#endif
+
+/*****************************************************************
+ Function:
+ BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Fill a file object with specified dir entry data
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Passed member's location
+ Return Values:
+ FOUND - Operation successful
+ NOT_FOUND - Operation failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then copy
+ the file information for that entry into the 'fo' FSFILE
+ object.
+ Remarks:
+ None.
+ *****************************************************************/
+
+BYTE Fill_File_Object(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE index, a;
+ BYTE character;
+ BYTE status;
+ BYTE test = 0;
+
+ // Get the entry
+ if (((*fHandle & MASK_MAX_FILE_ENTRY_LIMIT_BITS) == 0) && (*fHandle != 0)) // 4-bit mask because 16-root entries max per sector
+ {
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ }
+ else
+ {
+ dir = Cache_File_Entry (fo, fHandle, FALSE);
+ }
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Make sure there is a directory left
+ if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
+ {
+ status = NO_MORE;
+ }
+ else
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ status = NOT_FOUND;
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // print the file name and extension
+ for (index=0; index < DIR_NAMESIZE; index++)
+ {
+ character = dir->DIR_Name[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // its possible to have an extension in a directory
+ character = dir->DIR_Extension[0];
+
+ // Get the file extension if its there
+ for (index=0; index < DIR_EXTENSION; index++)
+ {
+ character = dir->DIR_Extension[index];
+ character = (BYTE)toupper(character);
+ fo->name[test++] = character;
+ }
+
+ // done and done with the name
+ // fo->name[++test] = (BYTE)'\0';
+
+ // Now store the identifier
+ fo->entry = *fHandle;
+
+ // see if we are still a good file
+ a = dir->DIR_Name[0];
+
+ if(a == DIR_DEL)
+ status = NOT_FOUND;
+ else
+ status = FOUND;
+
+ // Now store the size
+ fo->size = (dir->DIR_FileSize);
+
+ fo->cluster = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ /// -Get and store the attributes
+ a = dir->DIR_Attr;
+ fo->attributes = a;
+
+ // get the date and time
+ if ((a & ATTR_DIRECTORY) != 0)
+ {
+ fo->time = dir->DIR_CrtTime;
+ fo->date = dir->DIR_CrtDate;
+ }
+ else
+ {
+ fo->time = dir->DIR_WrtTime;
+ fo->date = dir->DIR_WrtDate;
+ }
+
+ }// deleted directory
+ }// Ensure we are still good
+ return(status);
+} // Fill_File_Object
+
+
+/************************************************************************
+ Function:
+ DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+ Summary:
+ Load file information from a directory entry and cache the entry
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Information location
+ Return Values:
+ DIRENTRY - Pointer to the directory entry
+ NULL - Directory entry could not be loaded
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries
+ in the directory pointed to by the dirclus value in
+ the FSFILE object 'fo' that contains the entry that
+ corresponds to the fHandle offset. It will then return a pointer
+ to the directory entry in the global data buffer.
+ Remarks:
+ None.
+ ************************************************************************/
+
+DIRENTRY LoadDirAttrib(FILEOBJ fo, WORD *fHandle)
+{
+ DIRENTRY dir;
+ BYTE a;
+
+ fo->dirccls = fo->dirclus;
+ // Get the entry
+ dir = Cache_File_Entry( fo, fHandle, TRUE);
+ if (dir == NULL)
+ return NULL;
+
+ // Read the first char of the file name
+ a = dir->DIR_Name[0];
+
+ // Make sure there is a directory left
+ if(a == DIR_EMPTY)
+ dir = (DIRENTRY)NULL;
+
+ if(dir != (DIRENTRY)NULL)
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ dir = (DIRENTRY)NULL;
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ // scan through all the long dir entries
+ while(a == ATTR_LONG_NAME)
+ {
+ (*fHandle)++;
+ dir = Cache_File_Entry( fo, fHandle, FALSE);
+ if (dir == NULL)
+ return NULL;
+ a = dir->DIR_Attr;
+ } // long file name while loop
+ } // deleted dir
+ }// Ensure we are still good
+
+ return(dir);
+} // LoadDirAttrib
+
+
+/**************************************************************************
+ Function:
+ CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+ Summary:
+ Erase a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ fHandle - Location of file information
+ EraseClusters - Remove cluster allocation from FAT?
+ Return Values:
+ CE_GOOD - File erased successfully
+ CE_FILE_NOT_FOUND - Could not find the file on the card
+ CE_ERASE_FAIL - Internal Card erase failed
+ Side Effects:
+ None
+ Description:
+ This function will cache the sector of directory entries in the directory
+ pointed to by the dirclus value in the FSFILE object 'fo' that contains
+ the entry that corresponds to the fHandle offset. It will then mark that
+ entry as deleted. If the EraseClusters argument is TRUE, the chain of
+ clusters for that file will be marked as unused in the FAT by the
+ FAT_erase_cluster_chain function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILEerase( FILEOBJ fo, WORD *fHandle, BYTE EraseClusters)
+{
+ DIRENTRY dir;
+ BYTE a;
+ CETYPE status = CE_GOOD;
+ DWORD clus;
+ DISK * disk;
+
+ disk = fo->dsk;
+
+ // reset the cluster
+ clus = fo->dirclus;
+ fo->dirccls = clus;
+
+ // load the sector
+ dir = Cache_File_Entry(fo, fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return CE_BADCACHEREAD;
+ }
+
+ // Fill up the File Object with the information pointed to by fHandle
+ a = dir->DIR_Name[0];
+
+ // see if there is something in the dir
+ if(dir == (DIRENTRY)NULL || a == DIR_EMPTY)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Check for empty or deleted directory
+ if ( a == DIR_DEL)
+ {
+ status = CE_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // Get the attributes
+ a = dir->DIR_Attr;
+
+ /* 8.3 File Name - entry*/
+ dir->DIR_Name[0] = DIR_DEL; // mark as deleted
+
+ // Get the starting cluster
+ clus = GetFullClusterNumber(dir); // Get Complete Cluster number.
+
+ // Now write it
+ if(status != CE_GOOD || !(Write_File_Entry( fo, fHandle)))
+ {
+ status = CE_ERASE_FAIL;
+ }
+ else
+ {
+ if (clus != FatRootDirClusterValue) //
+ {
+ if(EraseClusters)
+ {
+ /* Now remove the cluster allocation from the FAT */
+ status = ((FAT_erase_cluster_chain(clus, disk)) ? CE_GOOD : CE_ERASE_FAIL);
+ }
+ }
+ }
+ } // Not already deleted
+ }// Not existant
+
+ if (status == CE_GOOD)
+ FSerrno = CE_GOOD;
+ else
+ FSerrno = CE_ERASE_FAIL;
+
+ return (status);
+}
+#endif
+
+/***************************************************************
+ Function:
+ int FSrename (const rom char * fileName, FSFILE * fo)
+ Summary:
+ Change the name of a file or directory
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file
+ fo - The file to rename
+ Return Values:
+ 0 - File was renamed successfully
+ EOF - File was not renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrename function will rename a file. First, it will
+ search through the current working directory to ensure the
+ specified new filename is not already in use. If it isn't,
+ the new filename will be written to the file entry of the
+ file pointed to by 'fo.'
+ Remarks:
+ None
+ ***************************************************************/
+
+#ifdef ALLOW_WRITES
+
+int FSrename (const char * fileName, FSFILE * fo)
+{
+ unsigned char j, k = 0;
+ char string[12];
+ WORD fHandle = 1, goodHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ if (fo == NULL)
+ {
+ FSerrno = CE_FILENOTOPENED;
+ return -1;
+ }
+ // If fo != NULL, rename the file
+ if (FormatFileName (fileName, fo->name, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+ else
+ {
+ for (j = 0; j < 11; j++)
+ {
+ string[j] = fo->name[j];
+ }
+ goodHandle = fo->entry;
+
+ fHandle = 0;
+ fo->dirccls = fo->dirclus;
+ dir = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Check if the file name is already used
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+
+ nextClusterIsLast = FALSE;
+ while (1)
+ {
+ // Look through the entries until we get to the end
+ // to make sure the name isn't taken
+ dir = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dir == NULL)
+ {
+ if (nextClusterIsLast == TRUE)
+ {
+ break;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ if (dir->DIR_Name[0] == 0)
+ break;
+ for (j = 0; j < 11; j++)
+ {
+ if (dir->DIR_Name[j] != string[j])
+ k = 1;
+ }
+ if (k == 0)
+ {
+ FSerrno = CE_FILENAME_EXISTS;
+ return -1;
+ }
+ else
+ k = 0;
+ fHandle++;
+ }
+
+ fHandle = goodHandle;
+ fo->dirccls = fo->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(fo, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ for (j = 0; j < 11; j++)
+ {
+ dir->DIR_Name[j] = fo->name[j];
+ }
+
+ // just write the last entry in
+ if(!Write_File_Entry(fo,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#endif // Allow writes
+
+
+
+/*********************************************************************
+ Function:
+ FSFILE * FSfopen (const char * fileName, const char *mode)
+ Summary:
+ Open a file
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to open
+ mode -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ - WRITEPLUS - Create a new file or replace an existing file (reads also enabled)
+ - READPLUS - Read data from an existing file (writes also enabled)
+ - APPENDPLUS - Append data to an existing file (reads also enabled)
+ Return Values:
+ FSFILE * - The pointer to the file object
+ NULL - The file could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will open a file or directory. First, RAM in the
+ dynamic heap or static array will be allocated to a new FSFILE object.
+ Then, the specified file name will be formatted to ensure that it's
+ in 8.3 format. Next, the FILEfind function will be used to search
+ for the specified file name. If the name is found, one of three
+ things will happen: if the file was opened in read mode, its file
+ info will be loaded using the FILEopen function; if it was opened in
+ write mode, it will be erased, and a new file will be constructed in
+ its place; if it was opened in append mode, its file info will be
+ loaded with FILEopen and the current location will be moved to the
+ end of the file using the FSfseek function. If the file was not
+ found by FILEfind, it will be created if the mode was specified as
+ a write or append mode. In these cases, a pointer to the heap or
+ static FSFILE object array will be returned. If the file was not
+ found and the mode was specified as a read mode, the memory
+ allocated to the file will be freed and the NULL pointer value
+ will be returned.
+ Remarks:
+ None.
+ *********************************************************************/
+
+FSFILE * FSfopen( const char * fileName, const char *mode )
+{
+ FILEOBJ filePtr;
+#ifndef FS_DYNAMIC_MEM
+ int fIndex;
+#endif
+ BYTE ModeC;
+ WORD fHandle;
+ CETYPE final;
+
+#ifdef FS_DYNAMIC_MEM
+ filePtr = (FILEOBJ) FS_malloc(sizeof(FSFILE));
+#else
+
+ filePtr = NULL;
+
+ //Pick available file structure
+ for( fIndex = 0; fIndex < FS_MAX_FILES_OPEN; fIndex++ )
+ {
+ if( gFileSlotOpen[fIndex] ) //this slot is available
+ {
+ gFileSlotOpen[fIndex] = FALSE;
+ filePtr = &gFileArray[fIndex];
+ break;
+ }
+ }
+
+ if( filePtr == NULL )
+ {
+ FSerrno = CE_TOO_MANY_FILES_OPEN;
+ return NULL; //no file structure slot available
+ }
+#endif
+
+ //Format the source string.
+ if( !FormatFileName(fileName, filePtr->name, 0) )
+ {
+#ifdef FS_DYNAMIC_MEM
+ FS_free( (unsigned char *)filePtr );
+#else
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+#endif
+ FSerrno = CE_INVALID_FILENAME;
+ return NULL; //bad filename
+ }
+
+ //Read the mode character
+ ModeC = mode[0];
+
+ filePtr->dsk = &gDiskData;
+ filePtr->cluster = 0;
+ filePtr->ccls = 0;
+ filePtr->entry = 0;
+ filePtr->attributes = ATTR_ARCHIVE;
+
+ // start at the current directory
+#ifdef ALLOW_DIRS
+ filePtr->dirclus = cwdptr->dirclus;
+ filePtr->dirccls = cwdptr->dirccls;
+#else
+ filePtr->dirclus = FatRootDirClusterValue;
+ filePtr->dirccls = FatRootDirClusterValue;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, filePtr);
+
+ // See if the file is found
+ if(FILEfind (filePtr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0) == CE_GOOD)
+ {
+ // File is Found
+ switch(ModeC)
+ {
+#ifdef ALLOW_WRITES
+ case 'w':
+ case 'W':
+ {
+ // File exists, we want to create a new one, remove it first
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ break;
+ }
+
+ case 'A':
+ case 'a':
+ {
+ if(filePtr->size != 0)
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ else
+ {
+ fHandle = filePtr->entry;
+ final = FILEerase(filePtr, &fHandle, TRUE);
+
+ if (final == CE_GOOD)
+ {
+ // now create a new one
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ }
+ break;
+ }
+#endif
+ case 'R':
+ case 'r':
+ {
+ fHandle = filePtr->entry;
+
+ final = FILEopen (filePtr, &fHandle, 'r');
+#ifdef ALLOW_WRITES
+ if ((mode[1] == '+') && !(filePtr->attributes & ATTR_DIRECTORY))
+ filePtr->flags.write = 1;
+#endif
+ break;
+ }
+
+ default:
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;; //indicate error condition
+ break;
+ }
+ }
+ else
+ {
+#ifdef ALLOW_WRITES
+ // the file was not found, reset to the default asked
+ FileObjectCopy(filePtr, &gFileTemp);
+
+ // File is not Found
+ if(ModeC == 'w' || ModeC == 'W' || ModeC == 'a' || ModeC == 'A')
+ {
+ // use the user requested name
+ fHandle = 0;
+ final = CreateFileEntry (filePtr, &fHandle, 0);
+
+ if (final == CE_GOOD)
+ {
+ final = FILEopen (filePtr, &fHandle, 'w');
+ if (filePtr->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ final = 0xFF;
+ }
+
+ if (final == CE_GOOD)
+ {
+ final = FSfseek (filePtr, 0, SEEK_END);
+ if (final != CE_GOOD)
+ FSerrno = CE_SEEK_ERROR;
+ if (mode[1] == '+')
+ filePtr->flags.read = 1;
+ }
+ }
+ }
+ else
+#endif
+ final = CE_FILE_NOT_FOUND;
+ }
+
+ if (MDD_WriteProtectState())
+ {
+ filePtr->flags.write = 0;;
+ }
+
+#ifdef FS_DYNAMIC_MEM
+ if( final != CE_GOOD )
+ {
+ FS_free( (unsigned char *)filePtr );
+ filePtr = NULL;
+ }
+#else
+ if( final != CE_GOOD )
+ {
+ gFileSlotOpen[fIndex] = TRUE; //put this slot back to the pool
+ filePtr = NULL;
+ }
+#endif
+ else
+ {
+ FSerrno = CE_GOOD;
+ }
+
+ return filePtr;
+}
+
+/*******************************************************************
+ Function:
+ long FSftell (FSFILE * fo)
+ Summary:
+ Determine the current location in a file
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to file structure
+ Return: Current location in the file
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSftell function will return the current position in the
+ file pointed to by 'fo' by returning the 'seek' variable in the
+ FSFILE object, which is used to keep track of the absolute
+ location of the current position in the file.
+ Remarks:
+ None
+ *******************************************************************/
+
+long FSftell (FSFILE * fo)
+{
+ FSerrno = CE_GOOD;
+ return (fo->seek);
+}
+
+
+#ifdef ALLOW_WRITES
+
+/*********************************************************************
+ Function:
+ int FSremove (const char * fileName)
+ Summary:
+ Delete a file
+ Conditions:
+ File not opened, file exists
+ Input:
+ fileName - Name of the file to erase
+ Return Values:
+ 0 - File removed
+ EOF - File was not removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremove function will attempt to find the specified file with
+ the FILEfind function. If the file is found, it will be erased
+ using the FILEerase function.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSremove (const char * fileName)
+{
+ FILEOBJ fo = &tempCWDobj;
+ CETYPE result;
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+ //Format the source string
+ if( !FormatFileName(fileName, fo->name, 0) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = ATTR_ARCHIVE;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+
+ if (fo->attributes & ATTR_DIRECTORY)
+ {
+ FSerrno = CE_DELETE_DIR;
+ return -1;
+ }
+
+ result = FILEerase(fo, &fo->entry, TRUE);
+ if( result == CE_GOOD )
+ return 0;
+ else
+ {
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+}
+#endif
+
+/*********************************************************
+ Function:
+ void FSrewind (FSFILE * fo)
+ Summary:
+ Set the current position in a file to the beginning
+ Conditions:
+ File opened.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ None
+ Side Effects:
+ None.
+ Description:
+ The FSrewind funciton will reset the position of the
+ specified file to the beginning of the file. This
+ functionality is faster than using FSfseek to reset
+ the position in the file.
+ Remarks:
+ None.
+ *********************************************************/
+
+void FSrewind (FSFILE * fo)
+{
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ flushData();
+#endif
+ fo->seek = 0;
+ fo->pos = 0;
+ fo->sec = 0;
+ fo->ccls = fo->cluster;
+ gBufferOwner = NULL;
+ return;
+}
+
+/**************************************************************************
+ Function:
+ int FSerror (void)
+ Summary:
+ Return an error code for the last function call
+ Conditions:
+ The return value depends on the last function called.
+ Input:
+ None
+ Side Effects:
+ None.
+ Return Values:
+ FSInit -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The physical media could not be initialized
+ - CE_BAD_SECTOR_READ � The MBR or the boot sector could not be
+ read correctly
+ - CE_BAD_PARITION � The MBR signature code was incorrect.
+ - CE_NOT_FORMATTED � The boot sector signature code was incorrect or
+ indicates an invalid number of bytes per sector.
+ - CE_CARDFAT32 � The physical media is FAT32 type (only an error
+ when FAT32 support is disabled).
+ - CE_UNSUPPORTED_FS � The device is formatted with an unsupported file
+ system (not FAT12 or 16).
+ FSfopen -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The device has not been initialized.
+ - CE_TOO_MANY_FILES_OPEN � The function could not allocate any
+ additional file information to the array
+ of FSFILE structures or the heap.
+ - CE_INVALID_FILENAME � The file name argument was invalid.
+ - CE_INVALID_ARGUMENT � The user attempted to open a directory in a
+ write mode or specified an invalid mode argument.
+ - CE_FILE_NOT_FOUND � The specified file (which was to be opened in read
+ mode) does not exist on the device.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_ERASE_FAIL � The existing file could not be erased (when opening
+ a file in WRITE mode).
+ - CE_DIR_FULL � The directory is full.
+ - CE_DISK_FULL� The data memory section is full.
+ - CE_WRITE_ERROR � A write to the device failed.
+ - CE_SEEK_ERROR � The current position in the file could not be set to
+ the end (when the file was opened in APPEND mode).
+ FSfclose -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer or the new file
+ entry information could not be written to the device.
+ - CE_BADCACHEREAD � The file entry information could not be cached
+ FSfread -
+ - CE_GOOD � No Error
+ - CE_WRITEONLY � The file was opened in a write-only mode.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_BAD_SECTOR_READ � The data sector could not be read.
+ - CE_EOF � The end of the file was reached.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be loaded.
+ FSfwrite -
+ - CE_GOOD � No Error
+ - CE_READONLY � The file was opened in a read-only mode.
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_WRITE_ERROR � There was an error writing data to the device.
+ - CE_BADCACHEREAD � The data sector to be modified could not be read from
+ the device.
+ - CE_DISK_FULL � All data clusters on the device are in use.
+ FSfseek -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_INVALID_ARGUMENT � The specified offset exceeds the size of the file.
+ - CE_BADCACHEREAD � The sector that contains the new current position
+ could not be loaded.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be
+ loaded/allocated.
+ FSftell -
+ - CE_GOOD � No Error
+ FSattrib -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The attribute argument was invalid.
+ - CE_BADCACHEREAD � The existing file entry information could not be
+ loaded.
+ - CE_WRITE_ERROR � The file entry information could not be written to
+ the device.
+ FSrename -
+ - CE_GOOD � No Error
+ - CE_FILENOTOPENED � A null file pointer was passed into the function.
+ - CE_INVALID_FILENAME � The file name passed into the function was invalid.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_FILENAME_EXISTS � A file with the specified name already exists.
+ - CE_WRITE_ERROR � The new file entry data could not be written to the
+ device.
+ FSfeof -
+ - CE_GOOD � No Error
+ FSformat -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The device could not be initialized.
+ - CE_BADCACHEREAD � The master boot record or boot sector could not be
+ loaded successfully.
+ - CE_INVALID_ARGUMENT � The user selected to create their own boot sector on
+ a device that has no master boot record, or the mode
+ argument was invalid.
+ - CE_WRITE_ERROR � The updated MBR/Boot sector could not be written to
+ the device.
+ - CE_BAD_PARTITION � The calculated number of sectors per clusters was
+ invalid.
+ - CE_NONSUPPORTED_SIZE � The card has too many sectors to be formatted as
+ FAT12 or FAT16.
+ FSremove -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � The specified file could not be found.
+ - CE_ERASE_FAIL � The file could not be erased.
+ FSchdir -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The path string was mis-formed or the user tried to
+ change to a non-directory file.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_FOUND � Could not find a directory in the path.
+ FSgetcwd -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The user passed a 0-length buffer into the function.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the current working directory.
+ FSmkdir -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_ARGUMENT � The path string was mis-formed.
+ - CE_BADCACHEREAD � Could not successfully change to a recently created
+ directory to store its dir entry information, or
+ could not cache directory entry information.
+ - CE_INVALID_FILENAME � One or more of the directory names has an invalid
+ format.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device or the dot/dotdot entries could
+ not be written to a newly created directory.
+ - CE_DIR_FULL � There are no available dir entries in the CWD.
+ - CE_DISK_FULL � There are no available clusters in the data region of
+ the device.
+ FSrmdir -
+ - CE_GOOD � No Error
+ - CE_DIR_NOT_FOUND � The directory specified could not be found or the
+ function could not change to a subdirectory within
+ the directory to be deleted (when recursive delete is
+ enabled).
+ - CE_INVALID_ARGUMENT � The user tried to remove the CWD or root directory.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_EMPTY � The directory to be deleted was not empty and
+ recursive subdirectory removal was disabled.
+ - CE_ERASE_FAIL � The directory or one of the directories or files
+ within it could not be deleted.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the CWD.
+ SetClockVars -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The time values passed into the function were
+ invalid.
+ FindFirst -
+ - CE_GOOD � No Error
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ - CE_BADCACHEREAD � The file information for the file that was found
+ could not be cached.
+ FindNext -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The SearchRec object was not initialized by a call to
+ FindFirst.
+ - CE_INVALID_ARGUMENT � The SearchRec object was initialized in a different
+ directory from the CWD.
+ - CE_INVALID_FILENAME � The filename is invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ FSfprintf -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � Characters could not be written to the file.
+ Description:
+ The FSerror function will return the FSerrno variable. This global
+ variable will have been set to an error value during the last call of a
+ library function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSerror (void)
+{
+ return FSerrno;
+}
+
+
+/**************************************************************
+ Function:
+ void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+ Summary:
+ Copy a file object
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ foDest - The destination
+ foSource - the source
+ Return:
+ None
+ Side Effects:
+ None
+ Description:
+ The FileObjectCopy function will make an exacy copy of
+ a specified FSFILE object.
+ Remarks:
+ None
+ **************************************************************/
+
+void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
+{
+ BYTE size;
+ BYTE *dest;
+ BYTE *source;
+ BYTE Index;
+
+ dest = (BYTE *)foDest;
+ source = (BYTE *)foSource;
+
+ size = sizeof(FSFILE);
+
+ for(Index=0;Index< size; Index++)
+ {
+ dest[Index] = source[Index];
+ }
+}
+
+/*************************************************************************
+ Function:
+ CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+ Summary:
+ Create the first cluster of a file
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fo - Pointer to file structure
+ cluster - Cluster location
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ CE_DISK_FULL - All clusters in partition are taken
+ Side Effects:
+ None
+ Description:
+ The FILECreateHeadCluster function will create the first cluster
+ of a file. First, it will find an empty cluster with the
+ FATfindEmptyCluster function and mark it as the last cluster in the
+ file. It will then erase the cluster using the EraseCluster function.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+CETYPE FILECreateHeadCluster( FILEOBJ fo, DWORD *cluster)
+{
+ DISK * disk;
+ CETYPE error = CE_GOOD;
+
+ disk = fo->dsk;
+
+ // find the next empty cluster
+ *cluster = FATfindEmptyCluster(fo);
+
+ if(*cluster == 0) // "0" is just an indication as Disk full in the fn "FATfindEmptyCluster()"
+ {
+ error = CE_DISK_FULL;
+ }
+ else
+ {
+ // mark the cluster as taken, and last in chain
+ if(disk->type == FAT12)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT12, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+ else if(disk->type == FAT16)
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT16, FALSE) == CLUSTER_FAIL_FAT16)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+
+ #ifdef SUPPORT_FAT32 // If FAT32 supported.
+ else
+ {
+ if(WriteFAT( disk, *cluster, LAST_CLUSTER_FAT32, FALSE) == CLUSTER_FAIL_FAT32)
+ {
+ error = CE_WRITE_ERROR;
+ }
+ }
+#endif
+
+ // lets erase this cluster
+ if(error == CE_GOOD)
+ {
+ error = EraseCluster(disk,*cluster);
+ }
+ }
+
+ return(error);
+} // allocate head cluster
+#endif
+
+/*************************************************************************
+ Function:
+ BYTE EraseCluster(DISK *disk, DWORD cluster)
+ Summary:
+ Erase a cluster
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - Disk structure
+ cluster - Cluster to be erased
+ Return Values:
+ CE_GOOD - File closed successfully
+ CE_WRITE_ERROR - Could not write to the sector
+ Side Effects:
+ None
+ Description:
+ The EraseCluster function will write a 0 value into every byte of
+ the specified cluster.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE EraseCluster(DISK *disk, DWORD cluster)
+{
+ BYTE index;
+ DWORD SectorAddress;
+ BYTE error = CE_GOOD;
+
+ SectorAddress = Cluster2Sector(disk,cluster);
+ if (gNeedDataWrite)
+ if (flushData())
+ return CE_WRITE_ERROR;
+
+ gBufferOwner = NULL;
+
+ if (gBufferZeroed == FALSE)
+ {
+ // clear out the memory first
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+ gBufferZeroed = TRUE;
+ }
+
+ // Now clear them out
+ for(index = 0; index < disk->SecPerClus && error == CE_GOOD; index++)
+ {
+ if (MDD_SectorWrite( SectorAddress++, disk->buffer, FALSE) != TRUE)
+ error = CE_WRITE_ERROR;
+ }
+
+ return(error);
+}
+#endif
+
+
+#if defined (__C30__) || defined (__C32__)
+
+/***************************************************
+ Function:
+ BYTE ReadByte(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a byte from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ BYTE - the byte read
+ Side Effects:
+ None
+ Description:
+ Reads a byte from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+BYTE ReadByte( BYTE* pBuffer, WORD index )
+{
+ return( pBuffer[index] );
+}
+
+
+/***************************************************
+ Function:
+ BYTE ReadWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 16-bit word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ WORD - the word read
+ Side Effects:
+ None
+ Description:
+ Reads a 16-bit word from a buffer
+ Remarks:
+ None.
+ ***************************************************/
+
+WORD ReadWord( BYTE* pBuffer, WORD index )
+{
+ BYTE loByte, hiByte;
+ WORD res;
+
+ loByte = pBuffer[index];
+ hiByte = pBuffer[index+1];
+ res = hiByte;
+ res *= 0x100;
+ res |= loByte;
+ return( res );
+}
+
+
+/****************************************************
+ Function:
+ BYTE ReadDWord(BYTE * pBuffer, WORD index)
+ Summary:
+ Read a 32-bit double word from a buffer
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ pBuffer - pointer to a buffer to read from
+ index - index in the buffer to read to
+ Return:
+ DWORD - the double word read
+ Side Effects:
+ None
+ Description:
+ Reads a 32-bit double word from a buffer
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD ReadDWord( BYTE* pBuffer, WORD index )
+{
+ WORD loWord, hiWord;
+ DWORD result;
+
+ loWord = ReadWord( pBuffer, index );
+ hiWord = ReadWord( pBuffer, index+2 );
+
+ result = hiWord;
+ result *= 0x10000;
+ result |= loWord;
+ return result;
+}
+
+#endif
+
+
+
+/****************************************************
+ Function:
+ DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+ Summary:
+ Convert a cluster number to the corresponding sector
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - Disk structure
+ cluster - Cluster to be converted
+ Return:
+ sector - Sector that corresponds to given cluster
+ Side Effects:
+ None
+ Description:
+ The Cluster2Sector function will calculate the
+ sector number that corresponds to the first sector
+ of the cluster whose value was passed into the
+ function.
+ Remarks:
+ None.
+ ****************************************************/
+
+DWORD Cluster2Sector(DISK * dsk, DWORD cluster)
+{
+ DWORD sector;
+
+ /* Rt: Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ /* In FAT32, there is no separate ROOT region. It is as well stored in DATA region */
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+#endif
+ case FAT12:
+ case FAT16:
+ // The root dir takes up cluster 0 and 1
+ if(cluster == 0 ||cluster == 1)
+ sector = dsk->root + cluster;
+ else
+ sector = (((DWORD)cluster-2) * dsk->SecPerClus) + dsk->data;
+ break;
+ }
+
+ return(sector);
+
+}
+
+
+/***************************************************************************
+ Function:
+ int FSattrib (FSFILE * file, unsigned char attributes)
+ Summary:
+ Change the attributes of a file
+ Conditions:
+ File opened
+ Input:
+ file - Pointer to file structure
+ attributes - The attributes to set for the file
+ - Attribute - Value - Indications
+ - ATTR_READ_ONLY - 0x01 - The read-only attribute
+ - ATTR_HIDDEN - 0x02 - The hidden attribute
+ - ATTR_SYSTEM - 0x04 - The system attribute
+ - ATTR_ARCHIVE - 0x20 - The archive attribute
+ Return Values:
+ 0 - Attribute change was successful
+ -1 - Attribute change was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSattrib funciton will set the attributes of the specified file
+ to the attributes passed in by the user. This function will load the
+ file entry, replace the attributes with the ones specified, and write
+ the attributes back. If the specified file is a directory, the
+ directory attribute will be preserved.
+ Remarks:
+ None
+ ***************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSattrib (FSFILE * file, unsigned char attributes)
+{
+ WORD fHandle;
+ DIRENTRY dir;
+
+ FSerrno = CE_GOOD;
+
+ // Check for valid attributes
+ if ((attributes & ~0x27) != 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ fHandle = file->entry;
+
+ file->dirccls = file->dirclus;
+
+ // Get the file entry
+ dir = LoadDirAttrib(file, &fHandle);
+
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Ensure that we aren't trying to change the
+ // attributes of a volume entry
+ if (dir->DIR_Attr & ATTR_VOLUME)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Don't remove the directory attribute from DIR files
+ if (file->attributes & ATTR_DIRECTORY)
+ dir->DIR_Attr = attributes | ATTR_DIRECTORY;
+ else
+ dir->DIR_Attr = attributes;
+
+ // just write the last entry in
+ if(!Write_File_Entry(file,&fHandle))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+
+/*********************************************************************************
+ Function:
+ size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Write data to a file
+ Conditions:
+ File opened in WRITE, APPEND, WRITE+, APPEND+, READ+ mode
+ Input:
+ ptr - Pointer to source buffer
+ size - Size of units in bytes
+ n - Number of units to transfer
+ stream - Pointer to file structure
+ Return:
+ size_t - number of units written
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfwrite function will write data to a file. First, the sector that
+ corresponds to the current position in the file will be loaded (if it hasn't
+ already been cached in the global data buffer). Data will then be written to
+ the device from the specified buffer until the specified amount has been written.
+ If the end of a cluster is reached, the next cluster will be loaded, unless
+ the end-of-file flag for the specified file has been set. If it has, a new
+ cluster will be allocated to the file. Finally, the new position and filezize
+ will be stored in the FSFILE object. The parameters 'size' and 'n' indicate how
+ much data to write. 'Size' refers to the size of one object to write (in bytes),
+ and 'n' will refer to the number of these objects to write. The value returned
+ will be equal to 'n' unless an error occured.
+ Remarks:
+ None.
+ *********************************************************************************/
+
+#ifdef ALLOW_WRITES
+size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD count = size * n;
+ BYTE * src = (BYTE *) ptr;
+ DISK * dsk; // pointer to disk structure
+ CETYPE error = CE_GOOD;
+ WORD pos;
+ DWORD l; // absolute lba of sector to load
+ DWORD seek, filesize;
+ WORD writeCount = 0;
+
+ // see if the file was opened in a write mode
+ if(!(stream->flags.write))
+ {
+ FSerrno = CE_READONLY;
+ error = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ if (count == 0)
+ return 0;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ error = CE_WRITE_PROTECTED;
+ return 0;
+ }
+
+ gBufferZeroed = FALSE;
+ dsk = stream->dsk;
+ // get the stated position
+ pos = stream->pos;
+ seek = stream->seek;
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ // Check if the current stream was the last one to use the
+ // buffer. If not, check if we need to write data from the
+ // old stream
+ if (gBufferOwner != stream)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+ gBufferOwner = stream;
+ }
+ if (gLastDataSectorRead != l)
+ {
+ if (gNeedDataWrite)
+ {
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+ }
+
+ gBufferZeroed = FALSE;
+ if(!MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ }
+ gLastDataSectorRead = l;
+ }
+ // exit loop if EOF reached
+ filesize = stream->size;
+
+ // Loop while writing bytes
+ while (error == CE_GOOD && count > 0)
+ {
+ if( seek == filesize )
+ stream->flags.FileWriteEOF = TRUE;
+
+ // load a new sector if necessary, multiples of sector
+ if (pos == MEDIA_SECTOR_SIZE)
+ {
+ BYTE needRead = TRUE;
+
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+
+ // reset position
+ pos = 0;
+
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if (stream->sec == dsk->SecPerClus)
+ {
+ stream->sec = 0;
+
+ if(stream->flags.FileWriteEOF)
+ {
+ error = FILEallocate_new_cluster(stream, 0); // add new cluster to the file
+ needRead = FALSE;
+ }
+ else
+ error = FILEget_next_cluster( stream, 1);
+ }
+
+ if (error == CE_DISK_FULL)
+ {
+ FSerrno = CE_DISK_FULL;
+ return 0;
+ }
+
+ if(error == CE_GOOD)
+ {
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+ gBufferOwner = stream;
+ // If we just allocated a new cluster, then the cluster will
+ // contain garbage data, so it doesn't matter what we write to it
+ // Whatever is in the buffer will work fine
+ if (needRead)
+ {
+ if( !MDD_SectorRead( l, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ error = CE_BAD_SECTOR_READ;
+ gLastDataSectorRead = 0xFFFFFFFF;
+ return 0;
+ }
+ else
+ {
+ gLastDataSectorRead = l;
+ }
+ }
+ else
+ gLastDataSectorRead = l;
+ }
+ } // load new sector
+
+ if(error == CE_GOOD)
+ {
+ // Write one byte at a time
+ RAMwrite(dsk->buffer, pos++, *(char *)src);
+ src = src + 1; // compiler bug
+ seek++;
+ count--;
+ writeCount++;
+ // now increment the size of the part
+ if(stream->flags.FileWriteEOF)
+ filesize++;
+ gNeedDataWrite = TRUE;
+ }
+ } // while count
+
+ // save off the positon
+ stream->pos = pos;
+
+ // save off the seek
+ stream->seek = seek;
+
+ // now the new size
+ stream->size = filesize;
+
+ return(writeCount / size);
+} // fwrite
+#endif
+
+
+/**********************************************************
+ Function:
+ BYTE flushData (void)
+ Summary:
+ Flush unwritten data to a file
+ Conditions:
+ File opened in a write mode, data needs to be written
+ Return Values:
+ CE_GOOD - Data was updated successfully
+ CE_WRITE_ERROR - Data could not be updated
+ Side Effects:
+ None
+ Description:
+ The flushData function is called when it is necessary to
+ read new data into the global data buffer and the
+ gNeedDataWrite variable indicates that there is data
+ in the buffer that hasn't been written to the device.
+ The flushData function will write the data from the
+ buffer into the current cluster of the FSFILE object
+ that is stored in the gBufferOwner global variable.
+ Remarks:
+ None
+ **********************************************************/
+
+#ifdef ALLOW_WRITES
+BYTE flushData (void)
+{
+ DWORD l;
+ DISK * dsk;
+
+ // This will either be the pointer to the last file, or the handle
+ FILEOBJ stream = gBufferOwner;
+
+ dsk = stream->dsk;
+
+ // figure out the lba
+ l = Cluster2Sector(dsk,stream->ccls);
+ l += (WORD)stream->sec; // add the sector number to it
+
+ if(!MDD_SectorWrite( l, dsk->buffer, FALSE))
+ {
+ return CE_WRITE_ERROR;
+ }
+
+ gNeedDataWrite = FALSE;
+
+ return CE_GOOD;
+}
+#endif
+
+/****************************************************
+ Function:
+ int FSfeof( FSFILE * stream )
+ Summary:
+ Indicate whether the current file position is at the end
+ Conditions:
+ File is open in a read mode
+ Input:
+ stream - Pointer to the target file
+ Return Values:
+ Non-Zero - EOF reached
+ 0 - Not at end of File
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfeof function will indicate that the end-of-
+ file has been reached for the specified file by
+ comparing the absolute location in the file to the
+ size of the file.
+ Remarks:
+ None.
+ ****************************************************/
+
+int FSfeof( FSFILE * stream )
+{
+ FSerrno = CE_GOOD;
+ return( stream->seek == stream->size );
+}
+
+
+/**************************************************************************
+ Function:
+ size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Read data from a file
+ Conditions:
+ File is opened in a read mode
+ Input:
+ ptr - Destination buffer for read bytes
+ size - Size of units in bytes
+ n - Number of units to be read
+ stream - File to be read from
+ Return:
+ size_t - number of units read
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfread function will read data from the specified file. First,
+ the appropriate sector of the file is loaded. Then, data is read into
+ the specified buffer until the specified number of bytes have been read.
+ When a cluster boundary is reached, a new cluster will be loaded. The
+ parameters 'size' and 'n' indicate how much data to read. 'Size'
+ refers to the size of one object to read (in bytes), and 'n' will refer
+ to the number of these objects to read. The value returned will be equal
+ to 'n' unless an error occured or the user tried to read beyond the end
+ of the file.
+ Remarks:
+ None.
+ **************************************************************************/
+
+size_t FSfread (void *ptr, size_t size, size_t n, FSFILE *stream)
+{
+ DWORD len = size * n;
+ BYTE *pointer = (BYTE *) ptr;
+ DISK *dsk; // Disk structure
+ DWORD seek, sec_sel;
+ WORD pos; //position within sector
+ CETYPE error = CE_GOOD;
+ WORD readCount = 0;
+
+ FSerrno = CE_GOOD;
+
+ dsk = (DISK *)stream->dsk;
+ pos = stream->pos;
+ seek = stream->seek;
+
+ if( !stream->flags.read )
+ {
+ FSerrno = CE_WRITEONLY;
+ return 0; // CE_WRITEONLY
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return 0;
+ }
+#endif
+
+ // if it not my buffer, then get it from the disk.
+ if( (gBufferOwner != stream) && (pos != MEDIA_SECTOR_SIZE ))
+ {
+ gBufferOwner = stream;
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ return 0;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ //loop reading (count) bytes
+ while( len )
+ {
+ if( seek == stream->size )
+ {
+ FSerrno = CE_EOF;
+ error = CE_EOF;
+ break;
+ }
+
+ // In fopen, pos is init to 0 and the sect is loaded
+ if( pos == MEDIA_SECTOR_SIZE )
+ {
+ // reset position
+ pos = 0;
+ // point to the next sector
+ stream->sec++;
+
+ // get a new cluster if necessary
+ if( stream->sec == dsk->SecPerClus )
+ {
+ stream->sec = 0;
+ if( (error = FILEget_next_cluster( stream, 1)) != CE_GOOD )
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ break;
+ }
+ }
+
+ sec_sel = Cluster2Sector(dsk,stream->ccls);
+ sec_sel += (WORD)stream->sec; // add the sector number to it
+
+
+ gBufferOwner = stream;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead( sec_sel, dsk->buffer) )
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ error = CE_BAD_SECTOR_READ;
+ break;
+ }
+ gLastDataSectorRead = sec_sel;
+ }
+
+ // copy one byte at a time
+ *pointer = RAMread( dsk->buffer, pos++ );
+ pointer++;
+ seek++;
+ readCount++;
+ len--;
+ }
+
+ // save off the positon
+ stream->pos = pos;
+ // save off the seek
+ stream->seek = seek;
+
+ return(readCount / size);
+} // fread
+
+
+/***************************************************************************
+ Function:
+ BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode )
+ Summary:
+ Format a file name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be formatted
+ fN2 - The location the formatted name will be stored
+ mode - Non-zero if parital string search chars are allowed
+ Return Values:
+ TRUE - Name formatted successfully
+ FALSE - File name could not be formatted
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into FSFILE structure format. If filename is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ filename are valid in this filesystem.
+ Remarks:
+ None.
+ ***************************************************************************/
+BYTE FormatFileName( const char* fileName, char* fN2, BYTE mode)
+{
+ char * pExt;
+ WORD temp;
+ char szName[15];
+ BYTE count;
+
+ for (count = 0; count < 11; count++)
+ {
+ *(fN2 + count) = ' '; // Load destination filename to be space intially.
+ }
+
+ // Make sure we dont have an empty string or a name with only
+ // an extension
+ if (fileName[0] == '.' || fileName[0] == 0)
+ return FALSE;
+
+ temp = strlen( fileName );
+
+ if( temp <= TOTAL_FILE_SIZE ) // 8+3+1
+ strcpy( szName, fileName ); // copy to RAM in case fileName is located in flash
+ else
+ return FALSE; //long file name
+
+ // Make sure the characters are valid
+ if ( !ValidateChars(szName, mode) )
+ return FALSE;
+
+ //Look for '.' in the szName
+ if( (pExt = strchr( szName, '.' )) != 0 )
+ {
+ *pExt = 0; // Assigning NULL here makes the "szName" to be terminated and "pExt" pointer to hold only extn characters.
+ pExt++; // now pointing to extension
+
+ if( strlen( pExt ) > 3 ) // make sure the extension is 3 bytes or fewer
+ return FALSE;
+ }
+
+ if( strlen(szName) > 8 )
+ return FALSE;
+
+ //copy file name
+ for (count = 0; count < strlen(szName); count++)
+ {
+ *(fN2 + count) = * (szName + count); // Destination filename initially filled with SPACE. Now copy only available chars.
+ }
+
+ //copy extension
+ if(pExt && *pExt )
+ {
+ for (count = 0; count < strlen (pExt); count++)
+ {
+ *(fN2 + count + 8) = *(pExt + count); // Copy the extn to 8th position onwards. Ex: "FILE .Tx "
+ }
+ }
+
+ return TRUE;
+}
+
+#ifdef ALLOW_DIRS
+
+/*************************************************************************
+ Function:
+ BYTE FormatDirName (char * string, BYTE mode)
+ Summary:
+ Format a dir name into dir entry format
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ string - The name to be formatted
+ mode -
+ - TRUE - Partial string search characters are allowed
+ - FALSE - Partial string search characters are forbidden
+ Return Values:
+ TRUE - The name was formatted correctly
+ FALSE - The name contained invalid characters
+ Side Effects:
+ None
+ Description:
+ Format an 8.3 filename into directory structure format. If the name is less
+ than 8 chars, then it will be padded with spaces. If the extension name is
+ fewer than 3 chars, then it will also be oadded with spaces. The
+ ValidateChars function is used to ensure the characters in the specified
+ directory name are valid in this filesystem.
+ Remarks:
+ None.
+ *************************************************************************/
+
+BYTE FormatDirName (char * string, BYTE mode)
+{
+ unsigned char i, j;
+ char tempString [12];
+
+ if (ValidateChars (string, mode) == FALSE)
+ return FALSE;
+
+ for (i = 0; (i < 8) && (*(string + i) != '.') && (*(string + i) != 0); i++)
+ {
+ tempString[i] = *(string + i);
+ }
+
+ j = i;
+
+ while (i < 8)
+ {
+ tempString [i++] = 0x20;
+ }
+
+ if (*(string + j) == '.')
+ {
+ j++;
+ while (*(string + j) != 0)
+ {
+ tempString[i++] = *(string + j++);
+ }
+ }
+
+ while (i < 11)
+ {
+ tempString[i++] = 0x20;
+ }
+
+ tempString[11] = 0;
+
+ // Forbidden
+ if (tempString[0] == 0x20)
+ {
+ tempString[0] = '_';
+ }
+
+ for (i = 0; i < 12; i++)
+ {
+ *(string + i) = tempString[i];
+ }
+
+ return TRUE;
+}
+#endif
+
+
+/*************************************************************
+ Function:
+ BYTE ValidateChars( char * FileName, BYTE mode)
+ Summary:
+ Validate the characters in a given file name
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ fileName - The name to be validated
+ mode - Determines if partial string search is allowed
+ Return Values:
+ TRUE - Name was validated
+ FALSE - File name was not valid
+ Side Effects:
+ None
+ Description:
+ The ValidateChars function will compare characters in a
+ specified filename to determine if they're permissable
+ in the FAT file system. Lower-case characters will be
+ converted to upper-case. If the mode argument is specifed
+ to be 'TRUE,' partial string search characters are allowed.
+ Remarks:
+ None.
+ *************************************************************/
+BYTE ValidateChars( char * FileName , BYTE mode)
+{
+ int StrSz, index;
+ unsigned char radix = FALSE;
+
+ StrSz = strlen(FileName);
+
+ for( index = 0; index < StrSz; index++ )
+ {
+ if (((FileName[index] <= 0x20) && (FileName[index] != 0x05)) ||
+ (FileName[index] == 0x22) || (FileName[index] == 0x2B) ||
+ (FileName[index] == 0x2C) || (FileName[index] == 0x2F) ||
+ (FileName[index] == 0x3A) || (FileName[index] == 0x3B) ||
+ (FileName[index] == 0x3C) || (FileName[index] == 0x3D) ||
+ (FileName[index] == 0x3E) || (FileName[index] == 0x5B) ||
+ (FileName[index] == 0x5C) || (FileName[index] == 0x5D) ||
+ (FileName[index] == 0x7C) || ((FileName[index] == 0x2E) && radix == TRUE))
+ {
+ return FALSE;
+ }
+ else
+ {
+ // Check for partial string search chars
+ if (mode == FALSE)
+ {
+ if ((FileName[index] == '*') || (FileName[index] == '?'))
+ return FALSE;
+ }
+ // only one radix ('.') character is allowed
+ if (FileName[index] == 0x2E)
+ {
+ radix = TRUE;
+ }
+ // Convert lower-case to upper-case
+ if ((FileName[index] >= 0x61) && (FileName[index] <= 0x7A))
+ FileName[index] -= 0x20;
+ }
+ }
+ return TRUE;
+}
+
+
+/**********************************************************************
+ Function:
+ int FSfseek(FSFILE *stream, long offset, int whence)
+ Summary:
+ Change the current position in a file
+ Conditions:
+ File opened
+ Input:
+ stream - Pointer to file structure
+ offset - Offset from base location
+ whence -
+ - SEEK_SET - Seek from start of file
+ - SEEK_CUR - Seek from current location
+ - SEEK_END - Seek from end of file (subtract offset)
+ Return Values:
+ 0 - Operation successful
+ -1 - Operation unsuccesful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfseek function will change the current position in the file to
+ one specified by the user. First, an absolute offset is calculated
+ using the offset and base location passed in by the user. Then, the
+ position variables are updated, and the sector number that corresponds
+ to the new location. That sector is then loaded. If the offset
+ falls exactly on a cluster boundary, a new cluster will be allocated
+ to the file and the position will be set to the first byte of that
+ cluster.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSfseek(FSFILE *stream, long offset, int whence)
+{
+ DWORD numsector, temp; // lba of first sector of first cluster
+ DISK* dsk; // pointer to disk structure
+ BYTE test;
+ long offset2 = offset;
+
+ dsk = stream->dsk;
+
+ switch(whence)
+ {
+ case SEEK_CUR:
+ // Apply the offset to the current position
+ offset2 += stream->seek;
+ break;
+ case SEEK_END:
+ // Apply the offset to the end of the file
+ offset2 = stream->size - offset2;
+ break;
+ case SEEK_SET:
+ // automatically there
+ default:
+ break;
+ }
+
+#ifdef ALLOW_WRITES
+ if (gNeedDataWrite)
+ if (flushData())
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+#endif
+
+ // start from the beginning
+ temp = stream->cluster;
+ stream->ccls = temp;
+
+ temp = stream->size;
+
+ if (offset2 > temp)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return (-1); // past the limits
+ }
+ else
+ {
+ // if we are writing we are no longer at the end
+ stream->flags.FileWriteEOF = FALSE;
+
+ // set the new postion
+ stream->seek = offset2;
+
+ // figure out how many sectors
+ numsector = offset2 / MEDIA_SECTOR_SIZE;
+
+ // figure out how many bytes off of the offset
+ offset2 = offset2 - (numsector * MEDIA_SECTOR_SIZE);
+ stream->pos = offset2;
+
+ // figure out how many clusters
+ temp = numsector / dsk->SecPerClus;
+
+ // figure out the stranded sectors
+ numsector = numsector - (dsk->SecPerClus * temp);
+ stream->sec = numsector;
+
+ // if we are in the current cluster stay there
+ if (temp > 0)
+ {
+ test = FILEget_next_cluster(stream, temp);
+ if (test != CE_GOOD)
+ {
+ if (test == CE_FAT_EOF)
+ {
+#ifdef ALLOW_WRITES
+ if (stream->flags.write)
+ {
+ // load the previous cluster
+ stream->ccls = stream->cluster;
+ // Don't perform this operation if there's only one cluster
+ if (temp != 1)
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (FILEallocate_new_cluster(stream, 0) != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return -1;
+ }
+ // sec and pos should already be zero
+ }
+ else
+ {
+#endif
+ stream->ccls = stream->cluster;
+ test = FILEget_next_cluster(stream, temp - 1);
+ if (test != CE_GOOD)
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1);
+ }
+ stream->pos = MEDIA_SECTOR_SIZE;
+ stream->sec = dsk->SecPerClus - 1;
+#ifdef ALLOW_WRITES
+ }
+#endif
+ }
+ else
+ {
+ FSerrno = CE_COULD_NOT_GET_CLUSTER;
+ return (-1); // past the limits
+ }
+ }
+ }
+
+ // Determine the lba of the selected sector and load
+ temp = Cluster2Sector(dsk,stream->ccls);
+
+ // now the extra sectors
+ numsector = stream->sec;
+ temp += numsector;
+
+ gBufferOwner = NULL;
+ gBufferZeroed = FALSE;
+ if( !MDD_SectorRead(temp, dsk->buffer) )
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return (-1); // Bad read
+ }
+ gLastDataSectorRead = temp;
+ }
+
+ FSerrno = CE_GOOD;
+
+ return (0);
+}
+
+
+// FSfopenpgm, FSremovepgm, and FSrenamepgm will only work on PIC18s
+#ifdef __18CXX
+#ifdef ALLOW_PGMFUNCTIONS
+
+#ifdef ALLOW_WRITES
+
+/*****************************************************************
+ Function:
+ int FSrenamepgm(const rom char * fileName, FSFILE * fo)
+ Summary:
+ Rename a file named with a ROM string on PIC18
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file (in ROM)
+ fo - The file to rename
+ Return Values:
+ 0 - File renamed successfully
+ -1 - File could not be renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The Fsrenamepgm function will copy the rom fileName specified
+ by the user into a RAM array and pass that array into the
+ FSrename function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *****************************************************************/
+
+int FSrenamepgm (const rom char * fileName, FSFILE * fo)
+{
+ char F[13];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+
+ return FSrename (F, fo);
+}
+#endif
+
+/******************************************************************************
+ Function:
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+ Summary:
+ Open a file named with a ROM string on PIC18
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to be opened (ROM)
+ mode - The mode the file will be opened in (ROM)
+ Return Values:
+ FSFILE * - A pointer to the file object
+ NULL - File could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfopenpgm function will copy a PIC18 ROM fileName and mode argument
+ into RAM arrays, and then pass those arrays to the FSfopen function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ ******************************************************************************/
+
+
+FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+{
+ char F[13];
+ char M[2];
+ BYTE count;
+
+ for (count = 0; count < 13; count++)
+ {
+ F[count] = *(fileName + count);
+ }
+ for (count = 0; count < 2; count++)
+ {
+ M[count] = *(mode + count);
+ }
+
+ return FSfopen(F, M);
+}
+
+/*************************************************************
+ Function:
+ int FSremovepgm (const rom char * fileName)
+ Summary:
+ Delete a file named with a ROM string on PIC18
+ Conditions:
+ File not opened; file exists
+ Input:
+ fileName - The name of the file to be deleted (ROM)
+ Return Values:
+ 0 - File was removed successfully
+ -1 - File could not be removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremovepgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FSremove function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *************************************************************/
+#ifdef ALLOW_WRITES
+int FSremovepgm (const rom char * fileName)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for(...)
+
+ return FSremove (F);
+}
+#endif
+
+/**************************************************************************************
+ Function:
+ int FindFirstpgm (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Find a file named with a ROM string on PIC18
+ Conditions:
+ None
+ Input:
+ fileName - The name of the file to be found (ROM)
+ attr - The attributes of the file to be found
+ rec - Pointer to a search record to store the file info in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the given parameters was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object will be lost.
+ The FSerrno variable will be changed.
+ Description:
+ The FindFirstpgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FindFirst function.
+ Remarks:
+ Call FindFirstpgm or FindFirst before calling FindNext.
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************************/
+#ifdef ALLOW_FILESEARCH
+int FindFirstpgm (const rom char * fileName, unsigned int attr, SearchRec * rec)
+{
+ char F[13];
+ BYTE count;
+
+ *fileName;
+ for(count = 0; count < sizeof(F); count++)
+ {
+ _asm TBLRDPOSTINC _endasm
+ F[count] = TABLAT;
+ }//end for
+
+ return FindFirst (F,attr,rec);
+}
+#endif
+#endif
+#endif
+
+
+/***********************************************
+ Function:
+ DWORD ReadFAT (DISK *dsk, DWORD ccls)
+ Summary:
+ Read the next entry from the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ Return:
+ DWORD - The next cluster in a file chain
+ Side Effects:
+ None
+ Description:
+ The ReadFAT function will read the FAT and
+ determine the next cluster value after the
+ cluster specified by 'ccls.' Note that the
+ FAT sector that is read is stored in the
+ global FAT cache buffer.
+ Remarks:
+ None.
+ ***********************************************/
+
+DWORD ReadFAT (DISK *dsk, DWORD ccls)
+{
+ BYTE q;
+ DWORD p, l; // "l" is the sector Address
+ DWORD c, d, ClusterFailValue,LastClusterLimit; // ClusterEntries
+
+ gBufferZeroed = FALSE;
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls * 4;
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ LastClusterLimit = LAST_CLUSTER_FAT32;
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls *3; // Mulby1.5 to find cluster pos in FAT
+ q = p&1;
+ p >>= 1;
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT12;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD)ccls *2; // Mulby 2 to find cluster pos in FAT
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ LastClusterLimit = LAST_CLUSTER_FAT16;
+ break;
+ }
+
+ l = dsk->fat + (p >> 9); // FAT buffer has 512 bytes of size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ // Check if the appropriate FAT sector is already loaded
+ if (gLastFATSectorRead == l)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if(dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ // Check if the MSB is across the sector boundry
+ p = (p +1) & 0x1FF;
+ if (p == 0)
+ {
+ // Start by writing the sector we just worked on to the card
+ // if we need to
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+#endif
+ if (!MDD_SectorRead (l+1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l +1;
+ }
+ }
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ else
+ {
+ // If there's a currently open FAT sector,
+ // write it back before reading into the buffer
+#ifdef ALLOW_WRITES
+ if (gNeedFATWrite)
+ {
+ if(WriteFAT (dsk, 0, 0, TRUE))
+ return ClusterFailValue;
+ }
+#endif
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF; // Note: It is Sector not Cluster.
+ return ClusterFailValue;
+ }
+ else
+ {
+ gLastFATSectorRead = l;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32)
+ c = RAMreadD (gFATBuffer, p);
+ else
+#endif
+ if(dsk->type == FAT16)
+ c = RAMreadW (gFATBuffer, p);
+ else if (dsk->type == FAT12)
+ {
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c >>= 4;
+ }
+ p = (p +1) & 0x1FF;
+ d = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c += (d <<4);
+ }
+ else
+ {
+ c += ((d & 0x0F)<<8);
+ }
+ }
+ }
+ }
+
+ // Normalize it so 0xFFFF is an error
+ if (c >= LastClusterLimit)
+ c = LastClusterLimit;
+
+ return c;
+} // ReadFAT
+
+
+
+/****************************************************************************
+ Function:
+ WORD WriteFAT (DISK *dsk, DWORD ccls, WORD value, BYTE forceWrite)
+ Summary:
+ Write an entry to the FAT
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ dsk - The disk structure
+ ccls - The current cluster
+ value - The value to write in
+ forceWrite - Force the function to write the current FAT sector
+ Return:
+ 0 - The FAT write was successful
+ FAIL - The FAT could not be written
+ Side Effects:
+ None
+ Description:
+ The WriteFAT function writes an entry to the FAT. If the function
+ is called and the 'forceWrite' argument is TRUE, the function will
+ write the existing FAT data to the device. Otherwise, the function
+ will replace a single entry in the FAT buffer (indicated by 'ccls')
+ with a new value (indicated by 'value.')
+ Remarks:
+ None.
+ ****************************************************************************/
+
+#ifdef ALLOW_WRITES
+DWORD WriteFAT (DISK *dsk, DWORD ccls, DWORD value, BYTE forceWrite)
+{
+ BYTE i, q, c;
+ DWORD p, li, l, ClusterFailValue;
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type != FAT32 && dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT32;
+#else // If FAT32 support not enabled
+ if (dsk->type != FAT16 && dsk->type != FAT12)
+ return CLUSTER_FAIL_FAT16;
+#endif
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ ClusterFailValue = CLUSTER_FAIL_FAT32;
+ break;
+#endif
+ case FAT16:
+ case FAT12:
+ ClusterFailValue = CLUSTER_FAIL_FAT16;
+ break;
+ }
+
+ gBufferZeroed = FALSE;
+
+ // The only purpose for calling this function with forceWrite
+ // is to write the current FAT sector to the card
+ if (forceWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+
+ return 0;
+ }
+
+ /* Settings based on FAT type */
+ switch (dsk->type)
+ {
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ case FAT32:
+ p = (DWORD)ccls *4; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+#endif
+ case FAT12:
+ p = (DWORD) ccls * 3; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ q = p & 1; // Odd or even?
+ p >>= 1;
+ break;
+ default:
+ case FAT16:
+ p = (DWORD) ccls *2; // "p" is the position in "gFATBuffer" for corresponding cluster.
+ break;
+ }
+
+ l = dsk->fat + (p >>9); // FAt Buffer is 512 bytes size.
+ p &= 0x1FF; // FATbuffer is 512bytes so restrict 'p' within that. (2 ^9) is 512.
+
+ if (gLastFATSectorRead != l)
+ {
+ // If we are loading a new sector then write
+ // the current one to the card if we need to
+ if (gNeedFATWrite)
+ {
+ for (i = 0, li = gLastFATSectorRead; i < dsk->fatcopy; i++, li += dsk->fatsize)
+ if (!MDD_SectorWrite (gLastFATSectorRead, gFATBuffer, FALSE))
+ return ClusterFailValue;
+
+ gNeedFATWrite = FALSE;
+ }
+
+ // Load the new sector
+ if (!MDD_SectorRead (l, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l;
+ }
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ if (dsk->type == FAT32) // Refer page 16 of FAT requirement.
+ {
+ RAMwrite (gFATBuffer, p, ((value&0x000000ff))); // lsb,1st byte of cluster value
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8));
+ RAMwrite (gFATBuffer, p+2, ((value&0x00ff0000) >> 16));
+ RAMwrite (gFATBuffer, p+3, ((value&0x0f000000) >> 24)); // the MSB nibble is supposed to be "0" in FAT32. So mask it.
+ }
+ else
+#endif
+
+ if (dsk->type == FAT16)
+ {
+ RAMwrite (gFATBuffer, p, value); //lsB
+ RAMwrite (gFATBuffer, p+1, ((value&0x0000ff00) >> 8)); // msB
+ }
+ else if (dsk->type == FAT12)
+ {
+ // Get the current byte from the FAT
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = ((value & 0x0F) << 4) | ( c & 0x0F);
+ }
+ else
+ {
+ c = (value & 0xFF);
+ }
+ // Write in those bits
+ RAMwrite (gFATBuffer, p, c);
+
+ // FAT12 entries can cross sector boundaries
+ // Check if we need to load a new sector
+ p = (p+1) & 0x1FF;
+ if (p == 0)
+ {
+ // call this function to update the FAT on the card
+ if (WriteFAT (dsk, 0,0,TRUE))
+ return ClusterFailValue;
+ // Load the next sector
+ if (!MDD_SectorRead (l +1, gFATBuffer))
+ {
+ gLastFATSectorRead = 0xFFFF;
+ return ClusterFailValue;
+ }
+ else
+ gLastFATSectorRead = l + 1;
+ }
+
+ // Get the second byte of the table entry
+ c = RAMread (gFATBuffer, p);
+ if (q)
+ {
+ c = (value >> 4);
+ }
+ else
+ {
+ c = ((value >> 8) & 0x0F) | (c & 0xF0);
+ }
+ RAMwrite (gFATBuffer, p, c);
+ }
+
+ gNeedFATWrite = TRUE;
+
+ return 0;
+}
+#endif
+
+
+#ifdef ALLOW_DIRS
+
+// This string is used by dir functions to hold dir names temporarily
+char defaultString [13];
+
+
+
+/**************************************************************************
+ Function:
+ int FSchdir (char * path)
+ Summary:
+ Change the current working directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to.
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdir function passes a RAM pointer to the path to the
+ chdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSchdir (char * path)
+{
+ return chdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSchdirpgm (const rom char * path)
+ Summary:
+ Changed the CWD with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to (ROM)
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdirpgm function passes a PIC18 ROM path pointer to the
+ chdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSchdirpgm (const rom char * path)
+{
+ return chdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int chdirhelper (BYTE mode, char * ramptr, char * romptr);
+ // PIC18
+ int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr);
+ Summary:
+ Helper function for FSchdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was changed successfully.
+ EOF - Directory could not be changed.
+ Side Effects:
+ The current working directory will be changed. The FSerrno variable
+ will be changed. Any unwritten data in the data buffer will be written
+ to the device.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able to
+ parse it correctly. The function will loop through a switch statement
+ to process the tokens in the path string. Dot or dotdot entries are
+ handled in the first case statement. A backslash character is handled
+ in the second case statement (note that this case statement will only
+ be used if backslash is the first character in the path; backslash
+ token delimiters will automatically be skipped after each token in the
+ path is processed). The third case statement will handle actual
+ directory name strings.
+ Remarks:
+ None.
+ *************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int chdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int chdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ WORD curent = 1;
+ DIRENTRY entry;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ FSFILE tempCWDobj2;
+ char tempArray[12];
+ FILEOBJ tempCWD = &tempCWDobj2;
+ FileObjectCopy (tempCWD, cwdptr);
+
+ FSerrno = CE_GOOD;
+
+ // Check the first char of the path
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+ if (i == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ while(1)
+ {
+ switch (i)
+ {
+ // First case: dot or dotdot entry
+ case '.':
+ // Move past the dot
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if it's a dotdot entry
+ if (i == '.')
+ {
+ // Increment the path variable
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Check if we're in the root
+ if (tempCWD->dirclus == FatRootDirClusterValue)
+ {
+ // Fails if there's a dotdot chdir from the root
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ else
+ {
+ // Cache the dotdot entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ curent = 1;
+ entry = Cache_File_Entry (tempCWD, &curent, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ tempCWD->dirclus = GetFullClusterNumber(entry); // Get Complete Cluster number.
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // If we changed to root, record the name
+ if (tempCWD->dirclus == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT) // "0" is the value of Dotdot entry for Root in both FAT types.
+ {
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+
+ /* While moving to Root, get the Root cluster value */
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Otherwise set the name to ..
+ tempCWD->name[0] = '.';
+ tempCWD->name[1] = '.';
+ for (j = 2; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ // Cache the dot entry
+ curent = 0;
+ if (Cache_File_Entry(tempCWD, &curent, TRUE) == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Move past the next backslash, if necessary
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // Copy and return, if we're at the end
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ // If we ended with a . entry,
+ // just return what we have
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ else
+ {
+ // Anything else after a dot doesn't make sense
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ }
+
+ break;
+
+ // Second case: the first char is the root backslash
+ // We will ONLY switch to this case if the first char
+ // of the path is a backslash
+ case '\\':
+ // Increment pointer to second char
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // Can't start the path with multiple backslashes
+ if (i == '\\')
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == 0)
+ {
+ // The user is changing directory to
+ // the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ cwdptr->name[j] = 0x20;
+ }
+ return 0;
+ }
+ else
+ {
+ // Our first char is the root dir switch
+ tempCWD->dirclus = FatRootDirClusterValue;
+ tempCWD->dirccls = FatRootDirClusterValue;
+ tempCWD->name[0] = '\\';
+ for (j = 1; j < 11; j++)
+ {
+ tempCWD->name[j] = 0x20;
+ }
+ }
+ break;
+
+ default:
+ // We should be at the beginning of a string of letters/numbers
+ j = 0;
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath2);
+ }
+ }
+ else
+ {
+#endif
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ defaultString[j++] = i;
+ i = *(++temppath);
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // We got a whole 12 chars
+ // There could be more- truncate it
+ if (j == 12)
+ {
+ while ((i != 0) && (i != '\\'))
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ i = *(++temppath2);
+ }
+ else
+ {
+#endif
+ i = *(++temppath);
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ }
+
+ defaultString[j] = 0;
+
+ if (FormatDirName (defaultString, 0) == FALSE)
+ return -1;
+
+ for (j = 0; j < 11; j++)
+ {
+ tempArray[j] = tempCWD->name[j];
+ tempCWD->name[j] = defaultString[j];
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, tempCWD);
+
+ // See if the directory is there
+ if(FILEfind (&gFileTemp, tempCWD, LOOK_FOR_MATCHING_ENTRY, 0) != CE_GOOD)
+ {
+ // Couldn't find the DIR
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Found the file
+ // Check to make sure it's actually a directory
+ if (gFileTemp.attributes != ATTR_DIRECTORY)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ // Get the new name
+ for (j = 0; j < 11; j++)
+ {
+ tempCWD->name[j] = gFileTemp.name[j];
+ }
+ tempCWD->dirclus = gFileTemp.cluster;
+ tempCWD->dirccls = tempCWD->dirclus;
+ }
+
+ if (i == 0)
+ {
+ // If we're at the end of the string, we're done
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ else
+ {
+ while (i == '\\')
+ {
+ // If we get to another backslash, increment past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+ break;
+ }
+ } // loop
+}
+
+
+
+// This string is used by FSgetcwd to return the cwd name if the path
+// passed into the function is NULL
+char defaultArray [10];
+
+
+/**************************************************************
+ Function:
+ char * FSgetcwd (char * path, int numchars)
+ Summary:
+ Get the current working directory name
+ Conditions:
+ None
+ Input:
+ path - Pointer to the array to return the cwd name in
+ numchars - Number of chars in the path
+ Return Values:
+ char * - The cwd name string pointer (path or defaultArray)
+ NULL - The current working directory name could not be loaded.
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSgetcwd function will get the name of the current
+ working directory and return it to the user. The name
+ will be copied into the buffer pointed to by 'path,'
+ starting at the root directory and copying as many chars
+ as possible before the end of the buffer. The buffer
+ size is indicated by the 'numchars' argument. The first
+ thing this function will do is load the name of the current
+ working directory, if it isn't already present. This could
+ occur if the user switched to the dotdot entry of a
+ subdirectory immediately before calling this function. The
+ function will then copy the current working directory name
+ into the buffer backwards, and insert a backslash character.
+ Next, the function will continuously switch to the previous
+ directories and copy their names backwards into the buffer
+ until it reaches the root. If the buffer overflows, it
+ will be treated as a circular buffer, and data will be
+ copied over existing characters, starting at the beginning.
+ Once the root directory is reached, the text in the buffer
+ will be swapped, so that the buffer contains as much of the
+ current working directory name as possible, starting at the
+ root.
+ Remarks:
+ None
+ **************************************************************/
+char * FSgetcwd (char * path, int numchars)
+{
+ // If path is passed in as null, set up a default
+ // array with 10 characters
+ char totalchars = (path == NULL) ? 10 : numchars;
+ char * returnPointer;
+ char * bufferEnd;
+ FILEOBJ tempCWD = &gFileTemp;
+ BYTE bufferOverflow = FALSE;
+ signed char j;
+ DWORD curclus;
+ WORD fHandle, tempindex;
+ signed int i, index = 0;
+ char aChar;
+ DIRENTRY entry;
+
+ FSerrno = CE_GOOD;
+
+ // Set up the return value
+ if (path == NULL)
+ returnPointer = defaultArray;
+ else
+ {
+ returnPointer = path;
+ if (numchars == 0)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return NULL;
+ }
+ }
+
+ bufferEnd = returnPointer + totalchars - 1;
+
+ FileObjectCopy (tempCWD, cwdptr);
+
+ if ((tempCWD->name[0] == '.') &&
+ (tempCWD->name[1] == '.'))
+ {
+ // We last changed directory into a dotdot entry
+ // Save the value of the current directory
+ curclus = tempCWD->dirclus;
+ // Put this dir's dotdot entry into the dirclus
+ // Our cwd absolutely is not the root
+ fHandle = 1;
+ tempCWD->dirccls = tempCWD->dirclus;
+ entry = Cache_File_Entry (tempCWD,&fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ // For FAT32, if the .. entry is 0, the cluster won't be 0
+#ifdef SUPPORT_FAT32
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ tempCWD->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ tempCWD->dirclus = TempClusterCalc;
+
+ tempCWD->dirccls = tempCWD->dirclus;
+
+ // Find the direntry for the entry we were just in
+ fHandle = 0;
+ entry = Cache_File_Entry (tempCWD, &fHandle, TRUE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != curclus) ||
+ ((TempClusterCalc == curclus) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME) || (entry->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ fHandle++;
+ entry = Cache_File_Entry (tempCWD, &fHandle, FALSE);
+ if (entry == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return NULL;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // We've found the entry for the dir we were in
+ for (i = 0; i < 11; i++)
+ {
+ tempCWD->name[i] = entry->DIR_Name[i];
+ cwdptr->name[i] = entry->DIR_Name[i];
+ }
+ // Reset our temp dir back to that cluster
+ tempCWD->dirclus = curclus;
+ tempCWD->dirccls = curclus;
+ // This will set us at the cwd, but it will actually
+ // have the name in the name field this time
+ }
+ // There's actually some kind of name value in the cwd
+ if (tempCWD->name[0] == '\\')
+ {
+ // Easy, our CWD is the root
+ *returnPointer = '\\';
+ *(returnPointer + 1) = 0;
+ return returnPointer;
+ }
+ else
+ {
+ // Loop until we get back to the root
+ while (tempCWD->dirclus != FatRootDirClusterValue)
+ {
+ j = 10;
+ while (tempCWD->name[j] == 0x20)
+ j--;
+ if (j >= 8)
+ {
+ while (j >= 8)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+ *(returnPointer + index++) = '.';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ while (tempCWD->name[j] == 0x20)
+ j--;
+
+ while (j >= 0)
+ {
+ *(returnPointer + index++) = tempCWD->name[j--];
+ // This is a circular buffer
+ // Any unnecessary values will be overwritten
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+ }
+
+ // Put a backslash delimiter in front of the dir name
+ *(returnPointer + index++) = '\\';
+ if (index == totalchars)
+ {
+ index = 0;
+ bufferOverflow = TRUE;
+ }
+
+ // Load the previous entry
+ tempCWD->dirccls = tempCWD->dirclus;
+ if (GetPreviousEntry (tempCWD))
+ {
+ FSerrno = CE_BAD_SECTOR_READ;
+ return NULL;
+ }
+ }
+ }
+
+ // Point the index back at the last char in the string
+ index--;
+
+ i = 0;
+ // Swap the chars in the buffer so they are in the right places
+ if (bufferOverflow)
+ {
+ tempindex = index;
+ // Swap the overflowed values in the buffer
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+
+ // Point at the non-overflowed values
+ i = tempindex + 1;
+ index = bufferEnd - returnPointer;
+
+ // Swap the non-overflowed values into the right places
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ // All the values should be in the right place now
+ // Null-terminate the string
+ *(bufferEnd) = 0;
+ }
+ else
+ {
+ // There was no overflow, just do one set of swaps
+ tempindex = index;
+ while ((index - i) > 0)
+ {
+ aChar = *(returnPointer + i);
+ *(returnPointer + i) = * (returnPointer + index);
+ *(returnPointer + index) = aChar;
+ index--;
+ i++;
+ }
+ *(returnPointer + tempindex + 1) = 0;
+ }
+
+ return returnPointer;
+}
+
+
+/**************************************************************************
+ Function:
+ void GetPreviousEntry (FSFILE * fo)
+ Summary:
+ Get the file entry info for the parent dir of the specified dir
+ Conditions:
+ Should not be called by the user.
+ Input:
+ fo - The file to get the previous entry of
+ Return Values:
+ 0 - The previous entry was successfully retrieved
+ -1 - The previous entry could not be retrieved
+ Side Effects:
+ None
+ Description:
+ The GetPreviousEntry function is used by the FSgetcwd function to
+ load the previous (parent) directory. This function will load the
+ parent directory and then search through the file entries in that
+ directory for one that matches the cluster number of the original
+ directory. When the matching entry is found, the name of the
+ original directory is copied into the 'fo' FSFILE object.
+ Remarks:
+ None.
+ **************************************************************************/
+
+BYTE GetPreviousEntry (FSFILE * fo)
+{
+ BYTE i;
+ WORD fHandle = 1;
+ DWORD dirclus;
+ DIRENTRY dirptr;
+
+ // Load the previous entry
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ // The previous directory is the root
+ fo->name[0] = '\\';
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = 0x20;
+ }
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+ }
+ else
+ {
+ // Get the directory name
+ // Save the previous cluster value
+ // Get the cluster
+
+ dirclus = TempClusterCalc;
+ fo->dirclus = TempClusterCalc;
+ fo->dirccls = TempClusterCalc;
+
+
+ // Load the previous previous cluster
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+#ifdef SUPPORT_FAT32
+ // If we're using FAT32 and the previous previous cluster is the root, the
+ // value in the dotdot entry will be 0, but the actual cluster won't
+ if (TempClusterCalc == VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT)
+ {
+ fo->dirclus = FatRootDirClusterValue;
+ }
+ else
+#endif
+ fo->dirclus = TempClusterCalc;
+
+ fo->dirccls = fo->dirclus;
+
+ fHandle = 0;
+ dirptr = Cache_File_Entry (fo, &fHandle, TRUE);
+ if (dirptr == NULL)
+ return -1;
+ // Look through it until we get the name
+ // of the previous cluster
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number.
+ while ((TempClusterCalc != dirclus) ||
+ ((TempClusterCalc == dirclus) &&
+ (((unsigned char)dirptr->DIR_Name[0] == 0xE5) || (dirptr->DIR_Attr == ATTR_VOLUME) || (dirptr->DIR_Attr == ATTR_LONG_NAME))))
+ {
+ // Look through the entries until we get the
+ // right one
+ dirptr = Cache_File_Entry (fo, &fHandle, FALSE);
+ if (dirptr == NULL)
+ return -1;
+ fHandle++;
+
+ TempClusterCalc = GetFullClusterNumber(dirptr); // Get complete cluster number in a loop.
+ }
+
+ // The name should be in the entry now
+ // Copy the actual directory location back
+ for (i = 0; i < 11; i++)
+ {
+ fo->name[i] = dirptr->DIR_Name[i];
+ }
+ fo->dirclus = dirclus;
+ fo->dirccls = dirclus;
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+ Function:
+ int FSmkdir (char * path)
+ Summary:
+ Create a directory
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create.
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdir function passes a RAM pointer to the path to the
+ mkdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_WRITES
+int FSmkdir (char * path)
+{
+ return mkdirhelper (0, path, NULL);
+}
+
+/**************************************************************************
+ Function:
+ int FSmkdirpgm (const rom char * path)
+ Summary:
+ Create a directory with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create (ROM)
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdirpgm function passes a PIC18 ROM path pointer to the
+ mkdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arugments in ROM
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSmkdirpgm (const rom char * path)
+{
+ return mkdirhelper (1, NULL, path);
+}
+#endif
+
+
+/*************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+ // PIC18
+ int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+ Summary:
+ Helper function for FSmkdir
+ Conditions:
+ None
+ Input:
+ mode - Indicates which path pointer to use
+ ramptr - Pointer to the path specified in RAM
+ romptr - Pointer to the path specified in ROM
+ Return Values:
+ 0 - Directory was created
+ -1 - Directory could not be created
+ Side Effects:
+ Will create all non-existant directories in the path.
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSchdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first scan through the path
+ to ensure that any DIR names don't exceed 11 characters. It will then
+ backup the current working directory and begin changing directories
+ through the path until it reaches a directory than can't be changed to.
+ It will then create the specified directory and change directories to
+ the new directory. The function will continue creating and changing to
+ directories until the end of the path is reached. The function will
+ then restore the original current working directory.
+ Remarks:
+ None
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int mkdirhelper (BYTE mode, char * ramptr, const rom char * romptr)
+#else
+int mkdirhelper (BYTE mode, char * ramptr, char * romptr)
+#endif
+{
+ BYTE i, j;
+ char * temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ rom char * temppath2 = romptr;
+#endif
+ char tempArray[13];
+ FILEOBJ tempCWD = &tempCWDobj;
+
+#ifdef __18CXX
+ char dotdotPath[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ if (MDD_WriteProtectState())
+ {
+ FSerrno = CE_WRITE_PROTECTED;
+ return (-1);
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath2 != 0) && (*temppath2 != '.')&& (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath2 == '.')
+ {
+ temppath2++;
+ i = 0;
+ while ((*temppath2 != 0) && (*temppath2 != '\\'))
+ {
+ temppath2++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath2 == '\\')
+ temppath2++;
+ if (*temppath2 == 0)
+ break;
+ }
+ }
+ else
+#endif
+ // Scan for too-long file names
+ while (1)
+ {
+ i = 0;
+ while((*temppath != 0) && (*temppath != '.')&& (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 8)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (*temppath == '.')
+ {
+ temppath++;
+ i = 0;
+ while ((*temppath != 0) && (*temppath != '\\'))
+ {
+ temppath++;
+ i++;
+ }
+ if (i > 3)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ while (*temppath == '\\')
+ temppath++;
+ if (*temppath == 0)
+ break;
+ }
+
+ temppath = ramptr;
+#ifdef ALLOW_PGMFUNCTIONS
+ temppath2 = romptr;
+#endif
+
+ // We're going to be moving the CWD
+ // Back up the CWD
+ FileObjectCopy (tempCWD, cwdptr);
+
+ // get to the target directory
+ while (1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ i = *temppath2;
+ else
+#endif
+ i = *temppath;
+
+ if (i == '.')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ if ((i != '.') && (i != 0) && (i != '\\'))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ if (i == '.')
+ {
+ if (cwdptr->dirclus == FatRootDirClusterValue)
+ {
+ // If we try to change to the .. from the
+ // root, operation fails
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ if ((i != '\\') && (i != 0))
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+// dotdot entry
+#ifndef __18CXX
+ FSchdir ("..");
+#else
+ FSchdir (dotdotPath);
+#endif
+ }
+ // Skip past any backslashes
+ while (i == '\\')
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ if (i == 0)
+ {
+ // No point in creating a dot or dotdot entry directly
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ if (i == '\\')
+ {
+ // Start at the root
+ cwdptr->dirclus = FatRootDirClusterValue;
+ cwdptr->dirccls = FatRootDirClusterValue;
+ cwdptr->name[0] = '\\';
+ for (i = 1; i < 11; i++)
+ {
+ cwdptr->name[i] = 0x20;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ // If we just got two backslashes in a row at the
+ // beginning of the path, the function fails
+ if (i == '\\')
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if (i == 0)
+ {
+ // We can't make the root dir
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ tempArray[12] = 0;
+ while (1)
+ {
+ while(1)
+ {
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Change directories as specified
+ i = *temppath2;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ // Change directories as specified
+ i = *temppath;
+ j = 0;
+ // Parse the next token
+ while ((i != 0) && (i != '\\') && (j < 12))
+ {
+ tempArray[j++] = i;
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ tempArray[j] = 0;
+
+ if (tempArray[0] == '.')
+ {
+ if ((tempArray[1] != 0) && (tempArray[1] != '.'))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ if ((tempArray[1] == '.') && (tempArray[2] != 0))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+
+ // Try to change to it
+ // If you can't we need to create it
+ if (FSchdir (tempArray))
+ {
+ break;
+ }
+ else
+ {
+ // We changed into the directory
+ while (i == '\\')
+ {
+ // Next char is a backslash
+ // Move past it
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ else
+ {
+#endif
+ temppath++;
+ i = *temppath;
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+ }
+ // If it's the last one, return success
+ if (i == 0)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+ }
+
+ // Create a dir here
+ if (!CreateDIR (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ // Try to change to that directory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode == 1)
+ {
+ // Check for another backslash
+ while (*temppath2 == '\\')
+ {
+ temppath2++;
+ i = *temppath2;
+ }
+ }
+ else
+ {
+#endif
+ while (*temppath == '\\')
+ {
+ temppath++;
+ i = *temppath;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Check to see if we're at the end of the path string
+ if (i == 0)
+ {
+ // We already have one
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+ }
+}
+
+
+/**************************************************************************
+ Function:
+ int CreateDIR (char * path)
+ Summary:
+ FSmkdir helper function to create a directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the dir to create
+ Return Values:
+ TRUE - Directory was created successfully
+ FALSE - Directory could not be created.
+ Side Effects:
+ Any unwritten data in the data buffer or the FAT buffer will be written
+ to the device.
+ Description:
+ The CreateDIR function is a helper function for the mkdirhelper
+ function. The CreateDIR function will create a new file entry for
+ a directory and assign a cluster to it. It will erase the cluster
+ and write a dot and dotdot entry to it.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int CreateDIR (char * path)
+{
+ FSFILE * dirEntryPtr = &gFileTemp;
+ DIRENTRY dir;
+ WORD handle = 0;
+ DWORD dot, dotdot;
+ BYTE i;
+
+ for (i = 0; i < 12; i++)
+ {
+ defaultString[i] = *(path + i);
+ }
+
+ if (FormatDirName(defaultString, 0) == FALSE)
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return FALSE;
+ }
+
+ // Copy name into file object
+ for (i = 0; i < 11; i++)
+ {
+ dirEntryPtr->name[i] = defaultString[i];
+ }
+
+ dirEntryPtr->dirclus = cwdptr->dirclus;
+ dirEntryPtr->dirccls = cwdptr->dirccls;
+ dirEntryPtr->cluster = 0;
+ dirEntryPtr->ccls = 0;
+ dirEntryPtr->dsk = cwdptr->dsk;
+
+ // Create a directory entry
+ if(CreateFileEntry(dirEntryPtr, &handle, DIRECTORY) != CE_GOOD)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (gNeedFATWrite)
+ if(WriteFAT (dirEntryPtr->dsk, 0, 0, TRUE))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+ // Zero that cluster
+ if (dirEntryPtr->dirclus == FatRootDirClusterValue)
+ dotdot = 0;
+ else
+ dotdot = dirEntryPtr->dirclus;
+ dirEntryPtr->dirccls = dirEntryPtr->dirclus;
+ dir = Cache_File_Entry(dirEntryPtr, &handle, TRUE);
+ if (dir == NULL)
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return FALSE;
+ }
+
+ // Get the cluster
+ dot = GetFullClusterNumber(dir); // Get complete cluster number.
+
+ if (writeDotEntries (dirEntryPtr->dsk, dot, dotdot))
+ return TRUE;
+ else
+ return FALSE;
+
+ }
+}
+
+
+/***********************************************************************************
+ Function:
+ BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+ Summary:
+ Create dot and dotdot entries in a non-root directory
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ disk - The global disk structure
+ dotAddress - The cluster the current dir is in
+ dotdotAddress - The cluster the previous directory was in
+ Return Values:
+ TRUE - The dot and dotdot entries were created
+ FALSE - The dot and dotdot entries could not be created in the new directory
+ Side Effects:
+ None
+ Description:
+ The writeDotEntries function will create and write dot and dotdot entries
+ to a newly created directory.
+ Remarks:
+ None.
+ ***********************************************************************************/
+
+BYTE writeDotEntries (DISK * disk, DWORD dotAddress, DWORD dotdotAddress)
+{
+ WORD i;
+ WORD size;
+ _DIRENTRY entry;
+ DIRENTRY entryptr = &entry;
+ DWORD sector;
+
+ gBufferOwner = NULL;
+
+ size = sizeof (_DIRENTRY);
+
+ memset(disk->buffer, 0x00, MEDIA_SECTOR_SIZE);
+
+ entry.DIR_Name[0] = '.';
+
+ for (i = 1; i < 11; i++)
+ {
+ entry.DIR_Name[i] = 0x20;
+ }
+ entry.DIR_Attr = ATTR_DIRECTORY;
+ entry.DIR_NTRes = 0x00;
+
+ entry.DIR_FstClusLO = (WORD)(dotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+ entry.DIR_FileSize = 0x00;
+
+// Times need to be the same as the times in the directory entry
+
+// Set dir date for uncontrolled clock source
+#ifdef INCREMENTTIMESTAMP
+ entry.DIR_CrtTimeTenth = 0xB2;
+ entry.DIR_CrtTime = 0x7278;
+ entry.DIR_CrtDate = 0x32B0;
+ entry.DIR_LstAccDate = 0x0000;
+ entry.DIR_WrtTime = 0x0000;
+ entry.DIR_WrtDate = 0x0000;
+#endif
+
+#ifdef USEREALTIMECLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+#ifdef USERDEFINEDCLOCK
+ entry.DIR_CrtTimeTenth = gTimeCrtMS; // millisecond stamp
+ entry.DIR_CrtTime = gTimeCrtTime; // time created //
+ entry.DIR_CrtDate = gTimeCrtDate; // date created (1/1/2004)
+ entry.DIR_LstAccDate = 0x0000; // Last Access date
+ entry.DIR_WrtTime = 0x0000; // last update time
+ entry.DIR_WrtDate = 0x0000; // last update date
+#endif
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i) = *((char *)entryptr + i);
+ }
+ entry.DIR_Name[1] = '.';
+
+ entry.DIR_FstClusLO = (WORD)(dotdotAddress & 0x0000FFFF); // Lower 16 bit address
+
+#ifdef SUPPORT_FAT32 // If FAT32 supported.
+ entry.DIR_FstClusHI = (WORD)((dotdotAddress & 0x0FFF0000)>> 16); // Higher 16 bit address. FAT32 uses only 28 bits. Mask even higher nibble also.
+#else // If FAT32 support not enabled
+ entry.DIR_FstClusHI = 0;
+#endif
+
+
+ for (i = 0; i < size; i++)
+ {
+ *(disk->buffer + i + size) = *((char *)entryptr + i);
+ }
+
+ sector = Cluster2Sector (disk, dotAddress);
+
+ if (MDD_SectorWrite(sector, disk->buffer, FALSE) == FALSE)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// This array is used to prevent a stack frame error
+#ifdef __18CXX
+ char tempArray[13] = " ";
+#endif
+
+
+/**************************************************************************
+ Function:
+ int FSrmdir (char * path)
+ Summary:
+ Delete a directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to remove
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdir function passes a RAM pointer to the path to the
+ rmdirhelper function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int FSrmdir (char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (0, path, NULL, rmsubdirs);
+}
+
+/**************************************************************************
+ Function:
+ int FSrmdirpgm (const rom char * path)
+ Summary:
+ Delete a directory with a path in ROM on PIC18
+ Conditions:
+ None.
+ Input:
+ path - The path of the directory to remove (ROM)
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdirpgm function passes a PIC18 ROM path pointer to the
+ rmdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int FSrmdirpgm (const rom char * path, unsigned char rmsubdirs)
+{
+ return rmdirhelper (1, NULL, path, rmsubdirs);
+}
+#endif
+
+/************************************************************************************************
+ Function:
+ // PIC24/30/33/32
+ int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+ // PIC18
+ int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+ Summary:
+ Helper function for FSrmdir
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The path of the dir to delete
+ rmsubdirs -
+ - TRUE - Remove all sub-directories and files in the directory
+ - FALSE - Non-empty directories can not be removed
+ Return Values:
+ 0 - The specified directory was successfully removed.
+ EOF - The specified directory could not be removed.
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function is used by the FSmkdir function. If the path
+ argument is specified in ROM for PIC18 this function will be able
+ to parse it correctly. This function will first change to the
+ specified directory. If the rmsubdirs argument is FALSE the function
+ will search through the directory to ensure that it is empty and then
+ remove it. If the rmsubdirs argument is TRUE the function will also
+ search through the directory for subdirectories or files. When the
+ function finds a file, the file will be erased. When the function
+ finds a subdirectory, it will switch to the subdirectory and begin
+ removing all of the files in that subdirectory. Once the subdirectory
+ is empty, the function will switch back to the original directory.
+ return to the original position in that directory, and continue removing
+ files. Once the specified directory is empty, the function will
+ change to the parent directory, search through it for the directory
+ to remove, and then erase that directory.
+ Remarks:
+ None.
+ ************************************************************************************************/
+
+#ifdef ALLOW_PGMFUNCTIONS
+int rmdirhelper (BYTE mode, char * ramptr, const rom char * romptr, unsigned char rmsubdirs)
+#else
+int rmdirhelper (BYTE mode, char * ramptr, char * romptr, unsigned char rmsubdirs)
+#endif
+{
+ FILEOBJ tempCWD = &tempCWDobj;
+ FILEOBJ fo = &gFileTemp;
+ DIRENTRY entry;
+ WORD handle = 0;
+ WORD handle2;
+ WORD subDirDepth;
+ BYTE Index, Index2;
+
+#ifndef __18CXX
+ char tempArray[13] = " ";
+#else
+ char dotdotname[] = "..";
+#endif
+
+ FSerrno = CE_GOOD;
+
+ // Back up the current working directory
+ FileObjectCopy (tempCWD, cwdptr);
+
+#ifdef ALLOW_PGMFUNCTIONS
+ if (mode)
+ {
+ if (chdirhelper (1, NULL, romptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ }
+ else
+ {
+#endif
+ if (FSchdir (ramptr))
+ {
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+#ifdef ALLOW_PGMFUNCTIONS
+ }
+#endif
+
+ // Make sure we aren't trying to remove the root dir or the CWD
+ if ((cwdptr->dirclus == FatRootDirClusterValue) || (cwdptr->dirclus == tempCWD->dirclus))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Don't remove subdirectories and sub-files
+ if (!rmsubdirs)
+ {
+ while (entry->DIR_Name[0] != 0)
+ {
+ if ((unsigned char)entry->DIR_Name[0] != 0xE5)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_EMPTY;
+ return -1;
+ }
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if ((entry == NULL))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ // Do remove subdirectories and sub-files
+ dirCleared = FALSE;
+ subDirDepth = 0;
+
+ while (!dirCleared)
+ {
+ if (entry->DIR_Name[0] != 0)
+ {
+ if (((unsigned char)entry->DIR_Name[0] != 0xE5) && (entry->DIR_Attr != ATTR_VOLUME) && (entry->DIR_Attr != ATTR_LONG_NAME))
+ {
+ if ((entry->DIR_Attr & ATTR_DIRECTORY) == ATTR_DIRECTORY)
+ {
+ // We have a directory
+ subDirDepth++;
+ for (Index = 0; (Index < DIR_NAMESIZE) && (entry->DIR_Name[Index] != 0x20); Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (entry->DIR_Name[8] != 0x20)
+ {
+ tempArray[Index++] = '.';
+ for (Index2 = 0; (Index2 < DIR_EXTENSION) && (entry->DIR_Name[Index2 + DIR_NAMESIZE] != 0x20); Index2++)
+ {
+ tempArray[Index++] = entry->DIR_Name[Index2 + DIR_NAMESIZE];
+ }
+ }
+ tempArray[Index] = 0;
+ // Change to the subdirectory
+ if (FSchdir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ // Make sure we're not trying to delete the CWD
+ if (cwdptr->dirclus == tempCWD->dirclus)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+ }
+ handle = 2;
+ recache = TRUE;
+ }
+ else
+ {
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ fo->name[Index] = entry->DIR_Name[Index];
+ }
+
+ fo->dsk = &gDiskData;
+
+ fo->entry = handle;
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+ fo->cluster = 0;
+ fo->ccls = 0;
+
+ if (FILEerase(fo, &handle, TRUE))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ }
+ } // Check to see if it's a DIR entry
+ }// Check non-dir entry to see if its a valid file
+ else
+ {
+ handle++;
+ }
+ if (recache)
+ {
+ recache = FALSE;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ }
+ else
+ {
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ }
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+ else
+ {
+ // We have reached the end of the directory
+ if (subDirDepth != 0)
+ {
+ handle2 = 0;
+
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle2, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ handle2 = GetFullClusterNumber(entry); // Get complete cluster number.
+
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+ // Return to our previous position in this directory
+ handle = 2;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number.
+
+ while ((TempClusterCalc != handle2) ||
+ ((TempClusterCalc == handle2) &&
+ (((unsigned char)entry->DIR_Name[0] == 0xE5) || (entry->DIR_Attr == ATTR_VOLUME))))
+ {
+ handle++;
+ entry = Cache_File_Entry (cwdptr, &handle, FALSE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ // Get the cluster
+ TempClusterCalc = GetFullClusterNumber(entry); // Get complete cluster number in a loop.
+ }
+ // Erase the directory that we just cleared the subdirectories out of
+ memset (tempArray, 0x00, 12);
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = entry->DIR_Name[Index];
+ }
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ handle++;
+ cwdptr->dirccls = cwdptr->dirclus;
+ entry = Cache_File_Entry (cwdptr, &handle, TRUE);
+ if (entry == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+ }
+
+ // Decrease the subdirectory depth
+ subDirDepth--;
+ }
+ else
+ {
+ dirCleared = TRUE;
+ } // Check subdirectory depth
+ } // Check until we get an empty entry
+ } // Loop until the whole dir is cleared
+ }
+
+ // Cache the current directory name
+ // tempArray is used so we don't disturb the
+ // global getcwd buffer
+ if (FSgetcwd (tempArray, 12) == NULL)
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return -1;
+ }
+
+ memset(tempArray, 0x00, 12);
+
+ for (Index = 0; Index < 11; Index++)
+ {
+ tempArray[Index] = cwdptr->name[Index];
+ }
+
+ // If we're here, this directory is empty
+#ifndef __18CXX
+ if (FSchdir (".."))
+#else
+ if (FSchdir (dotdotname))
+#endif
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_DIR_NOT_FOUND;
+ return -1;
+ }
+
+ if (eraseDir (tempArray))
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ FSerrno = CE_ERASE_FAIL;
+ return -1;
+ }
+ else
+ {
+ FileObjectCopy (cwdptr, tempCWD);
+ return 0;
+ }
+}
+
+
+/****************************************************************
+ Function:
+ int eraseDir (char * path)
+ Summary:
+ FSrmdir helper function to erase dirs
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ path - The name of the directory to delete
+ Return Values:
+ 0 - Dir was deleted successfully
+ -1 - Dir could not be deleted.
+ Side Effects:
+ None
+ Description:
+ The eraseDir function is a helper function for the rmdirhelper
+ function. The eraseDir function will search for the
+ directory that matches the specified path name and then erase
+ it with the FILEerase function.
+ Remarks:
+ None.
+ *****************************************************************/
+
+int eraseDir (char * path)
+{
+ CETYPE result;
+ BYTE Index;
+ FSFILE tempCWDobj2;
+
+ if (MDD_WriteProtectState())
+ {
+ return (-1);
+ }
+
+ // preserve CWD
+ FileObjectCopy(&tempCWDobj2, cwdptr);
+
+ for (Index = 0; Index <11; Index++)
+ {
+ cwdptr->name[Index] = *(path + Index);
+ }
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, cwdptr);
+
+ // See if the file is found
+ result = FILEfind (cwdptr, &gFileTemp, LOOK_FOR_MATCHING_ENTRY, 0);
+
+ if (result != CE_GOOD)
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+ result = FILEerase(cwdptr, &cwdptr->entry, TRUE);
+ if( result == CE_GOOD )
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return 0;
+ }
+ else
+ {
+ FileObjectCopy(cwdptr, &tempCWDobj2);
+ return -1;
+ }
+}
+#endif
+
+
+
+#endif
+
+
+#ifdef ALLOW_FILESEARCH
+
+
+/***********************************************************************************
+ Function:
+ int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Initial search function
+ Conditions:
+ None
+ Input:
+ fileName - The name to search for
+ - Parital string search characters
+ - * - Indicates the rest of the filename or extension can vary (e.g. FILE.*)
+ - ? - Indicates that one character in a filename can vary (e.g. F?LE.T?T)
+ attr - The attributes that a found file may have
+ - ATTR_READ_ONLY - File may be read only
+ - ATTR_HIDDEN - File may be a hidden file
+ - ATTR_SYSTEM - File may be a system file
+ - ATTR_VOLUME - Entry may be a volume label
+ - ATTR_DIRECTORY - File may be a directory
+ - ATTR_ARCHIVE - File may have archive attribute
+ - ATTR_MASK - All attributes
+ rec - pointer to a structure to put the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the specified criteria was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object
+ will be lost. The FSerrno variable will be changed.
+ Description:
+ The FindFirst function will search for a file based on parameters passed in
+ by the user. This function will use the FILEfind function to parse through
+ the current working directory searching for entries that match the specified
+ parameters. If a file is found, its parameters are copied into the SearchRec
+ structure, as are the initial parameters passed in by the user and the position
+ of the file entry in the current working directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling FindNext
+ ***********************************************************************************/
+
+int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ WORD fHandle;
+ BYTE j;
+ BYTE Index;
+
+ FSerrno = CE_GOOD;
+
+ if( !FormatFileName(fileName, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ rec->initialized = FALSE;
+
+ for (Index = 0; (Index < 12) && (fileName[Index] != 0); Index++)
+ {
+ rec->searchname[Index] = fileName[Index];
+ }
+ rec->searchname[Index] = 0;
+ rec->searchattr = attr;
+#ifdef ALLOW_DIRS
+ rec->cwdclus = cwdptr->dirclus;
+#else
+ rec->cwdclus = FatRootDirClusterValue;
+#endif
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = 0;
+ fo->attributes = attr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ fHandle = fo->entry;
+ result = FILEopen (fo, &fHandle, 'r');
+ }
+ if (result == CE_GOOD)
+ {
+ // Copy as much name as there is
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (Index = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[Index++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); Index++, j++)
+ {
+ rec->filename[Index] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[Index] = 0;
+ }
+ else
+ {
+ for (Index = 0; Index < DIR_NAMECOMP; Index++)
+ {
+ rec->filename[Index] = fo->name[Index];
+ }
+ rec->filename[Index] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ rec->initialized = TRUE;
+ return 0;
+ }
+ else
+ {
+ FSerrno = CE_BADCACHEREAD;
+ return -1;
+ }
+}
+
+
+/**********************************************************************
+ Function:
+ int FindNext (SearchRec * rec)
+ Summary:
+ Sequential search function
+ Conditions:
+ None
+ Input:
+ rec - The structure to store the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No additional files matching the specified criteria were found
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FindNext function performs the same function as the FindFirst
+ funciton, except it does not copy any search parameters into the
+ SearchRec structure (only info about found files) and it begins
+ searching at the last directory entry offset at which a file was
+ found, rather than at the beginning of the current working
+ directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling this function
+ **********************************************************************/
+
+int FindNext (SearchRec * rec)
+{
+ FSFILE f;
+ FILEOBJ fo = &f;
+ CETYPE result;
+ BYTE i, j;
+
+ FSerrno = CE_GOOD;
+
+ // Make sure we called FindFirst on this object
+ if (rec->initialized == FALSE)
+ {
+ FSerrno = CE_NOT_INIT;
+ return -1;
+ }
+
+ // Make sure we called FindFirst in the cwd
+#ifdef ALLOW_DIRS
+ if (rec->cwdclus != cwdptr->dirclus)
+ {
+ FSerrno = CE_INVALID_ARGUMENT;
+ return -1;
+ }
+#endif
+
+ if( !FormatFileName(rec->searchname, fo->name, 1) )
+ {
+ FSerrno = CE_INVALID_FILENAME;
+ return -1;
+ }
+
+ /* Brn: Copy the formatted name to "fo" which is necesary before calling "FILEfind" function */
+ //strcpy(fo->name,rec->searchname);
+
+ fo->dsk = &gDiskData;
+ fo->cluster = 0;
+ fo->ccls = 0;
+ fo->entry = rec->entry + 1;
+ fo->attributes = rec->searchattr;
+
+#ifndef ALLOW_DIRS
+ // start at the root directory
+ fo->dirclus = FatRootDirClusterValue;
+ fo->dirccls = FatRootDirClusterValue;
+#else
+ fo->dirclus = cwdptr->dirclus;
+ fo->dirccls = cwdptr->dirccls;
+#endif
+
+ // copy file object over
+ FileObjectCopy(&gFileTemp, fo);
+
+ // See if the file is found
+ result = FILEfind (fo, &gFileTemp,LOOK_FOR_MATCHING_ENTRY, 1);
+
+ if (result != CE_GOOD)
+ {
+ FSerrno = CE_FILE_NOT_FOUND;
+ return -1;
+ }
+ else
+ {
+ if (fo->attributes != ATTR_VOLUME)
+ {
+ for (i = 0, j = 0; (j < 8) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Add the radix if its not a dir
+ if ((fo->name[8] != ' ') || (fo->name[9] != ' ') || (fo->name[10] != ' '))
+ rec->filename[i++] = '.';
+ // Move to the extension, even if there are more space chars
+ for (j = 8; (j < 11) && (fo->name[j] != 0x20); i++, j++)
+ {
+ rec->filename[i] = fo->name[j];
+ }
+ // Null terminate it
+ rec->filename[i] = 0;
+ }
+ else
+ {
+ for (i = 0; i < DIR_NAMECOMP; i++)
+ {
+ rec->filename[i] = fo->name[i];
+ }
+ rec->filename[i] = 0;
+ }
+
+ rec->attributes = fo->attributes;
+ rec->filesize = fo->size;
+ rec->timestamp = (DWORD)((DWORD)fo->date << 16) + fo->time;
+ rec->entry = fo->entry;
+ return 0;
+ }
+}
+
+
+#endif
+
+
+
+#ifdef ALLOW_FSFPRINTF
+
+
+
+/**********************************************************************
+ Function:
+ int FSputc (char c, FSFILE * file)
+ Summary:
+ FSfprintf helper function to write a char
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ c - The character to write to the file.
+ file - The file to write to.
+ Return Values:
+ 0 - The character was written successfully
+ EOF - The character was not written to the file.
+ Side Effects:
+ None
+ Description:
+ This is a helper function for FSfprintf. It will write one
+ character to a file.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSputc (char c, FSFILE * file)
+{
+ if (FSfwrite ((void *)&c, 1, 1, file) != 1)
+ return EOF;
+ else
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ int str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+ Summary:
+ FSfprintf helper function to write a char multiple times
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - The file to write to.
+ n - The number of times to write that character to a file.
+ c - The character to write to the file.
+ Return Values:
+ 0 - The characters were written successfully
+ EOF - The characters were not written to the file.
+ Side Effects:
+ None
+ Description:
+ This funciton is used by the FSfprintf function to write multiple
+ instances of a single character to a file (for example, when
+ padding a format specifier with leading spacez or zeros).
+ Remarks:
+ None.
+ **********************************************************************/
+
+
+unsigned char str_put_n_chars (FSFILE * handle, unsigned char n, char c)
+{
+ while (n--)
+ if (FSputc (c, handle) == EOF)
+ return 1;
+ return 0;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSfprintf (FSFILE * fptr, const char * fmt, ...)
+ // PIC18
+ int FSfpritnf (FSFILE * fptr, const rom char * fmt, ...)
+ Summary:
+ Function to write formatted strings to a file
+ Conditions:
+ For PIC18, integer promotion must be enabled in the project build
+ options menu. File opened in a write mode.
+ Input:
+ fptr - A pointer to the file to write to.
+ fmt - A string of characters and format specifiers to write to
+ the file
+ ... - Additional arguments inserted in the string by format
+ specifiers
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Writes a specially formatted string to a file.
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSfprintf (FSFILE *fptr, const rom char *fmt, ...)
+#else
+int FSfprintf (FSFILE *fptr, const char * fmt, ...)
+#endif
+{
+ va_list ap;
+ int n;
+
+ va_start (ap, fmt);
+ n = FSvfprintf (fptr, fmt, ap);
+ va_end (ap);
+ return n;
+}
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSvfprintf (FSFILE * handle, const char * formatString, va_list ap)
+ // PIC18
+ int FSvfpritnf (auto FSFILE * handle, auto const rom char * formatString, auto va_list ap)
+ Summary:
+ Helper function for FSfprintf
+ Conditions:
+ This function should not be called by the user.
+ Input:
+ handle - A pointer to the file to write to.
+ formatString - A string of characters and format specifiers to write to
+ the file
+ ap - A structure pointing to the arguments on the stack
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This helper function will access the elements passed to FSfprintf
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef __18CXX
+int FSvfprintf (auto FSFILE *handle, auto const rom char * formatString, auto va_list ap)
+#else
+int FSvfprintf (FSFILE *handle, const char * formatString, va_list ap)
+#endif
+{
+ unsigned char c;
+ int count = 0;
+
+ for (c = *formatString; c; c = *++formatString)
+ {
+ if (c == '%')
+ {
+ unsigned char flags = 0;
+ unsigned char width = 0;
+ unsigned char precision = 0;
+ unsigned char have_precision = 0;
+ unsigned char size = 0;
+#ifndef __18CXX
+ unsigned char size2 = 0;
+#endif
+ unsigned char space_cnt;
+ unsigned char cval;
+#ifdef __18CXX
+ unsigned long larg;
+ far rom char * romstring;
+#else
+ unsigned long long larg;
+#endif
+ char * ramstring;
+ int n;
+
+ FSerrno = CE_GOOD;
+
+ c = *++formatString;
+
+ while (c == '-' || c == '+' || c == ' ' || c == '#'
+ || c == '0')
+ {
+ switch (c)
+ {
+ case '-':
+ flags |= _FLAG_MINUS;
+ break;
+ case '+':
+ flags |= _FLAG_PLUS;
+ break;
+ case ' ':
+ flags |= _FLAG_SPACE;
+ break;
+ case '#':
+ flags |= _FLAG_OCTO;
+ break;
+ case '0':
+ flags |= _FLAG_ZERO;
+ break;
+ }
+ c = *++formatString;
+ }
+ /* the optional width field is next */
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n < 0)
+ {
+ flags |= _FLAG_MINUS;
+ width = -n;
+ }
+ else
+ width = n;
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ width = cval;
+ }
+
+ /* if '-' is specified, '0' is ignored */
+ if (flags & _FLAG_MINUS)
+ flags &= ~_FLAG_ZERO;
+
+ /* the optional precision field is next */
+ if (c == '.')
+ {
+ c = *++formatString;
+ if (c == '*')
+ {
+ n = va_arg (ap, int);
+ if (n >= 0)
+ {
+ precision = n;
+ have_precision = 1;
+ }
+ c = *++formatString;
+ }
+ else
+ {
+ cval = 0;
+ while ((unsigned char) isdigit (c))
+ {
+ cval = cval * 10 + c - '0';
+ c = *++formatString;
+ }
+ precision = cval;
+ have_precision = 1;
+ }
+ }
+
+ /* the optional 'h' specifier. since int and short int are
+ the same size for MPLAB C18, this is a NOP for us. */
+ if (c == 'h')
+ {
+ c = *++formatString;
+ /* if 'c' is another 'h' character, this is an 'hh'
+ specifier and the size is 8 bits */
+ if (c == 'h')
+ {
+ size = _FMT_BYTE;
+ c = *++formatString;
+ }
+ }
+ else if (c == 't' || c == 'z')
+ c = *++formatString;
+#ifdef __18CXX
+ else if (c == 'H' || c == 'T' || c == 'Z')
+ {
+ size = _FMT_SHRTLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l' || c == 'j')
+#else
+ else if (c == 'q' || c == 'j')
+ {
+ size = _FMT_LONGLONG;
+ c = *++formatString;
+ }
+ else if (c == 'l')
+#endif
+ {
+ size = _FMT_LONG;
+ c = *++formatString;
+ }
+
+ switch (c)
+ {
+ case '\0':
+ /* this is undefined behaviour. we have a trailing '%' character
+ in the string, perhaps with some flags, width, precision
+ stuff as well, but no format specifier. We'll, arbitrarily,
+ back up a character so that the loop will terminate
+ properly when it loops back and we'll output a '%'
+ character. */
+ --formatString;
+ /* fallthrough */
+ case '%':
+ if (FSputc ('%', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ break;
+ case 'c':
+ space_cnt = 0;
+ if (width > 1)
+ {
+ space_cnt = width - 1;
+ count += space_cnt;
+ }
+ if (space_cnt && !(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ c = va_arg (ap, int);
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'S':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ romstring = va_arg (ap, rom far char *);
+ else
+ romstring = (far rom char*)va_arg (ap, rom near char *);
+ n = strlenpgm (romstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the
+ string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *romstring; c && cval < width; c = *++romstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+#endif
+ case 's':
+ ramstring = va_arg (ap, char *);
+ n = strlen (ramstring);
+ /* Normalize the width based on the length of the actual
+ string and the precision. */
+ if (have_precision && precision < (unsigned char) n)
+ n = precision;
+ if (width < (unsigned char) n)
+ width = n;
+ space_cnt = width - (unsigned char) n;
+ count += space_cnt;
+ /* we've already calculated the space count that the width
+ will require. now we want the width field to have the
+ number of character to display from the string itself,
+ limited by the length of the actual string and the
+ specified precision. */
+ if (have_precision && precision < width)
+ width = precision;
+ /* if right justified, we print the spaces before the string */
+ if (!(flags & _FLAG_MINUS))
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ space_cnt = 0;
+ }
+ cval = 0;
+ for (c = *ramstring; c && cval < width; c = *++ramstring)
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ ++cval;
+ }
+ /* If there are spaces left, it's left justified.
+ Either way, calling the function unconditionally
+ is smaller code. */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ break;
+ case 'd':
+ case 'i':
+ flags |= _FLAG_SIGNED;
+ /* fall through */
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'b':
+ case 'B':
+ /* This is a bit of a trick. The 'l' and 'hh' size
+ specifiers are valid only for the integer conversions,
+ not the 'p' or 'P' conversions, and are ignored for the
+ latter. By jumping over the additional size specifier
+ checks here we get the best code size since we can
+ limit the size checks in the remaining code. */
+ if (size == _FMT_LONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, long int);
+ else
+ larg = va_arg (ap, unsigned long int);
+ goto _do_integer_conversion;
+ }
+ else if (size == _FMT_BYTE)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed char) va_arg (ap, int);
+ else
+ larg = (unsigned char) va_arg (ap, unsigned int);
+ goto _do_integer_conversion;
+ }
+#ifndef __18CXX
+ else if (size == _FMT_LONGLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = (signed long long)va_arg (ap, long long);
+ else
+ larg = (unsigned long long) va_arg (ap, unsigned long long);
+ goto _do_integer_conversion;
+ }
+#endif
+ /* fall trough */
+ case 'p':
+ case 'P':
+#ifdef __18CXX
+ if (size == _FMT_SHRTLONG)
+ {
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, short long int);
+ else
+ larg = va_arg (ap, unsigned short long int);
+ }
+ else
+#endif
+ if (flags & _FLAG_SIGNED)
+ larg = va_arg (ap, int);
+ else
+ larg = va_arg (ap, unsigned int);
+ _do_integer_conversion:
+ /* default precision is 1 */
+ if (!have_precision)
+ precision = 1;
+ {
+ unsigned char digit_cnt = 0;
+ unsigned char prefix_cnt = 0;
+ unsigned char sign_char;
+ /* A 32 bit number will require at most 32 digits in the
+ string representation (binary format). */
+#ifdef __18CXX
+ char buf[33];
+ /* Start storing digits least-significant first */
+ char *q = &buf[31];
+ /* null terminate the string */
+ buf[32] = '\0';
+#else
+ char buf[65];
+ char *q = &buf[63];
+ buf[64] = '\0';
+#endif
+ space_cnt = 0;
+ size = 10;
+
+ switch (c)
+ {
+ case 'b':
+ case 'B':
+ size = 2;
+#ifndef __18CXX
+ size2 = 1;
+#endif
+ break;
+ case 'o':
+ size = 8;
+#ifndef __18CXX
+ size2 = 3;
+#endif
+ break;
+ case 'p':
+ case 'P':
+ /* from here on out, treat 'p' conversions just
+ like 'x' conversions. */
+ c += 'x' - 'p';
+ /* fall through */
+ case 'x':
+ case 'X':
+ size = 16;
+#ifndef __18CXX
+ size2 = 4;
+#endif
+ break;
+ }// switch (c)
+
+ /* if it's an unsigned conversion, we should ignore the
+ ' ' and '+' flags */
+ if (!(flags & _FLAG_SIGNED))
+ flags &= ~(_FLAG_PLUS | _FLAG_SPACE);
+
+ /* if it's a negative value, we need to negate the
+ unsigned version before we convert to text. Using
+ unsigned for this allows us to (ab)use the 2's
+ complement system to avoid overflow and be able to
+ adequately handle LONG_MIN.
+
+ We'll figure out what sign character to print, if
+ any, here as well. */
+#ifdef __18CXX
+ if (flags & _FLAG_SIGNED && ((long) larg < 0))
+ {
+ larg = -(long) larg;
+#else
+ if (flags & _FLAG_SIGNED && ((long long) larg < 0))
+ {
+ larg = -(long long) larg;
+#endif
+ sign_char = '-';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_PLUS)
+ {
+ sign_char = '+';
+ ++digit_cnt;
+ }
+ else if (flags & _FLAG_SPACE)
+ {
+ sign_char = ' ';
+ ++digit_cnt;
+ }
+ else
+ sign_char = '\0';
+ /* get the digits for the actual number. If the
+ precision is zero and the value is zero, the result
+ is no characters. */
+ if (precision || larg)
+ {
+ do
+ {
+#ifdef __18CXX
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ larg /= size;
+#else
+ // larg is congruent mod size2 to its lower 16 bits
+ // for size2 = 2^n, 0 <= n <= 4
+ if (size2 != 0)
+ cval = s_digits[(unsigned int) larg % size];
+ else
+ cval = s_digits[larg % size];
+ if (c == 'X' && cval >= 'a')
+ cval -= 'a' - 'A';
+ if (size2 != 0)
+ larg = larg >> size2;
+ else
+ larg /= size;
+#endif
+ *q-- = cval;
+ ++digit_cnt;
+ } while (larg);
+ /* if the '#' flag was specified and we're dealing
+ with an 'o', 'b', 'B', 'x', or 'X' conversion,
+ we need a bit more. */
+ if (flags & _FLAG_OCTO)
+ {
+ if (c == 'o')
+ {
+ /* per the standard, for octal, the '#' flag
+ makes the precision be at least one more
+ than the number of digits in the number */
+ if (precision <= digit_cnt)
+ precision = digit_cnt + 1;
+ }
+ else if (c == 'x' || c == 'X' || c == 'b' || c == 'B')
+ prefix_cnt = 2;
+ }
+ }
+ else
+ digit_cnt = 0;
+
+ /* The leading zero count depends on whether the '0'
+ flag was specified or not. If it was not, then the
+ count is the difference between the specified
+ precision and the number of digits (including the
+ sign character, if any) to be printed; otherwise,
+ it's as if the precision were equal to the max of
+ the specified precision and the field width. If a
+ precision was specified, the '0' flag is ignored,
+ however. */
+ if ((flags & _FLAG_ZERO) && (width > precision)
+ && !have_precision)
+ precision = width;
+ /* for the rest of the processing, precision contains
+ the leading zero count for the conversion. */
+ if (precision > digit_cnt)
+ precision -= digit_cnt;
+ else
+ precision = 0;
+ /* the space count is the difference between the field
+ width and the digit count plus the leading zero
+ count. If the width is less than the digit count
+ plus the leading zero count, the space count is
+ zero. */
+ if (width > precision + digit_cnt + prefix_cnt)
+ space_cnt = width - precision - digit_cnt - prefix_cnt;
+
+ /* for output, we check the justification, if it's
+ right justified and the space count is positive, we
+ emit the space characters first. */
+ if (!(flags & _FLAG_MINUS) && space_cnt)
+ {
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ count += space_cnt;
+ space_cnt = 0;
+ }
+ /* if we have a sign character to print, that comes
+ next */
+ if (sign_char)
+ if (FSputc (sign_char, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if we have a prefix (0b, 0B, 0x or 0X), that's next */
+ if (prefix_cnt)
+ {
+ if (FSputc ('0', handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ }
+ /* if we have leading zeros, they follow. the prefix, if any
+ is included in the number of digits when determining how
+ many leading zeroes are needed. */
+// if (precision > prefix_cnt)
+ // precision -= prefix_cnt;
+ if (str_put_n_chars (handle, precision, '0'))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* print the actual number */
+ for (cval = *++q; cval; cval = *++q)
+ if (FSputc (cval, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ /* if there are any spaces left, they go to right-pad
+ the field */
+ if (str_put_n_chars (handle, space_cnt, ' '))
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+
+ count += precision + digit_cnt + space_cnt + prefix_cnt;
+ }
+ break;
+ case 'n':
+ switch (size)
+ {
+ case _FMT_LONG:
+ *(long *) va_arg (ap, long *) = count;
+ break;
+#ifdef __18CXX
+ case _FMT_SHRTLONG:
+ *(short long *) va_arg (ap, short long *) = count;
+ break;
+#else
+ case _FMT_LONGLONG:
+ *(long long *) va_arg (ap, long long *) = count;
+ break;
+#endif
+ case _FMT_BYTE:
+ *(signed char *) va_arg (ap, signed char *) = count;
+ break;
+ default:
+ *(int *) va_arg (ap, int *) = count;
+ break;
+ }
+ break;
+ default:
+ /* undefined behaviour. we do nothing */
+ break;
+ }
+ }
+ else
+ {
+ if (FSputc (c, handle) == EOF)
+ {
+ FSerrno = CE_WRITE_ERROR;
+ return EOF;
+ }
+ ++count;
+ }
+ }
+ return count;
+}
+
+
+
+#endif
+
+
+
+
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/FSIO.d b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/FSIO.d new file mode 100644 index 00000000..1af7e8ce --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/FSIO.d @@ -0,0 +1,61 @@ +FSIO.o: FSIO.c FSIO.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h FSconfig.h \
+ C:/Microchip\ Solutions/Microchip/Include/Compiler.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/string.h \
+ HardwareProfile.h \
+ C:/Microchip\ Solutions/Microchip/Include/MDD\ File\ System\FSDefs.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h SD-SPI.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/ctype.h
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/FSIO.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/FSIO.h new file mode 100644 index 00000000..2a69957f --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/FSIO.h @@ -0,0 +1,1392 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: FSIO.h
+ * Dependencies: GenericTypeDefs.h
+ * FSconfig.h
+ * FSDefs.h
+ * stddef.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#ifndef FS_DOT_H
+#define FS_DOT_H
+
+#include "GenericTypeDefs.h"
+#include "FSconfig.h"
+#include "MDD File System\FSDefs.h"
+#include "stddef.h"
+
+#ifdef USE_SD_INTERFACE_WITH_SPI
+ #include "SD-SPI.h"
+#endif
+#ifdef USE_CF_INTERFACE_WITH_PMP
+ #include "MDD File System\CF-PMP.h"
+#endif
+#ifdef USE_MANUAL_CF_INTERFACE
+ #include "MDD File System\CF- Bit transaction.h"
+#endif
+#ifdef USE_USB_INTERFACE
+ #include "USB\usb_host_msd_scsi.h"
+#endif
+
+
+//#ifndef __C30__
+ #ifdef USE_MANUAL_CF_INTERFACE
+ #ifdef USE_SD_INTERFACE_WITH_SPI
+ #error This library only supports one physical layer
+ #endif
+ #ifdef USE_CF_INTERFACE_WITH_PMP
+ #error This library only supports one physical layer
+ #endif
+ #ifdef USE_USB_INTERFACE
+ #error This library only supports one physical layer
+ #endif
+ #endif
+ #ifdef USE_SD_INTERFACE_WITH_SPI
+ #ifdef USE_CF_INTERFACE_WITH_PMP
+ #error This library only supports one physical layer
+ #endif
+ #ifdef USE_USB_INTERFACE
+ #error This library only supports one physical layer
+ #endif
+ #endif
+ #ifdef USE_CF_INTERFACE_WITH_PMP
+ #ifdef USE_USB_INTERFACE
+ #error This library only supports one physical layer
+ #endif
+ #endif
+//#endif
+
+
+/*******************************************************************/
+/* Strunctures and defines */
+/*******************************************************************/
+
+#ifndef FALSE
+ // Summary: False value
+ // Description: This macro will indicate that a condition is false.
+ #define FALSE 0
+#endif
+#ifndef TRUE
+ // Summary: True value
+ // Description: This macro will indicate that a condition is true.
+ #define TRUE !FALSE // True value
+#endif
+
+
+
+
+#ifndef SEEK_SET
+ // Summary: Macro for the FSfseek SEEK_SET base location.
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the beginning of the file.
+ #define SEEK_SET 0
+
+#endif
+#ifndef SEEK_CUR
+
+ // Summary: Macro for the FSfseek SEEK_CUR base location.
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the current location of the file
+ #define SEEK_CUR 1
+
+#endif
+#ifndef SEEK_END
+
+ // Summary: Macro for the FSfseek SEEK_END base location
+ // Description: Functions as an input for FSfseek that specifies that the position in the file will be changed
+ // relative to the end of the file. For this macro, the offset value will be subtracted from
+ // the end location of the file by default.
+ #define SEEK_END 2
+
+#endif
+
+
+
+
+// Summary: Macro for the FSfopen APPEND mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it's file information will be loaded and the
+// current location in the file will be set to the end. The user will then be able to write to the file.
+#define APPEND "a"
+
+// Summary: Macro for the FSfopen WRITE mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it will be erased and replaced by an empty file
+// of the same name. The user will then be able to write to the file.
+#define WRITE "w"
+
+// Summary: Macro for the FSfopen READ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file information for the
+// specified file will be loaded. If the file does not exist, the FSfopen function will fail. The user
+// will then be able to read from the file.
+#define READ "r"
+
+// Summary: Macro for the FSfopen APPEND+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it's file information will be loaded and the
+// current location in the file will be set to the end. The user will then be able to write to the file
+// or read from the file.
+#define APPENDPLUS "a+"
+
+// Summary: Macro for the FSfopen WRITE+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file being opened will
+// be created if it doesn't exist. If it does exist, it will be erased and replaced by an empty file
+// of the same name. The user will then be able to write to the file or read from the file.
+#define WRITEPLUS "w+"
+
+// Summary: Macro for the FSfopen READ+ mode
+// Description: If this macro is specified as the mode argument in a call of FSfopen, the file information for the
+// specified file will be loaded. If the file does not exist, the FSfopen function will fail. The user
+// will then be able to read from the file or write to the file.
+#define READPLUS "r+"
+
+
+
+#ifndef intmax_t
+ #ifdef __PIC24F__
+ // Summary: A data type indicating the maximum integer size in an architecture
+ // Description: The intmax_t data type refers to the maximum-sized data type on any given architecture. This
+ // data type can be specified as a format specifier size specification for the FSfprintf function.
+ #define intmax_t long long
+ #elif defined __PIC24H__
+ #define intmax_t long long
+ #elif defined __dsPIC30F__
+ #define intmax_t long long
+ #elif defined __dsPIC33F__
+ #define intmax_t long long
+ #endif
+#endif
+
+
+
+// Summary: Indicates flag conditions for a file object
+// Description: The FILEFLAGS structure is used to indicate conditions in a file. It contains three flags: 'write' indicates
+// that the file was opened in a mode that allows writes, 'read' indicates that the file was opened in a mode
+// that allows reads, and 'FileWriteEOF' indicates that additional data that is written to the file will increase
+// the file size.
+typedef struct
+{
+ unsigned write :1; // Indicates a file was opened in a mode that allows writes
+ unsigned read :1; // Indicates a file was opened in a mode that allows reads
+ unsigned FileWriteEOF :1; // Indicates the current position in a file is at the end of the file
+}FILEFLAGS;
+
+
+
+// Summary: Indicates how to search for file entries in the FILEfind function
+// Description: The values in the SEARCH_TYPE enumeration are used internally by the library to indicate how the FILEfind function
+// how to perform a search. The 'LOOK_FOR_EMPTY_ENTRY' value indicates that FILEfind should search for an empty file entry.
+// The 'LOOK_FOR_MATCHING_ENTRY' value indicates that FILEfind should search for an entry that matches the FSFILE object
+// that was passed into the FILEfind function.
+typedef enum{
+ LOOK_FOR_EMPTY_ENTRY = 0,
+ LOOK_FOR_MATCHING_ENTRY
+} SEARCH_TYPE;
+
+
+
+// Summary: Macro indicating the length of a 8.3 file name
+// Description: The TOTAL_FILE_SIZE macro indicates the maximum number of characters in an 8.3 file name. This value includes
+// 8 characters for the name, three for the extentsion, and 1 for the radix ('.')
+#define TOTAL_FILE_SIZE 8+3+1
+
+// Summary: A mask that indicates the limit of directory entries in a sector
+// Description: The MASK_MAX_FILE_ENTRY_LIMIT_BITS is used to indicate to the Cache_File_Entry function that a new sector needs to
+// be loaded.
+#define MASK_MAX_FILE_ENTRY_LIMIT_BITS 0x0f
+
+// Summary: Value used for shift operations to calculate the sector offset in a directory
+// Description: The VALUE_BASED_ON_ENTRIES_PER_CLUSTER macro is used to calculate sector offsets for directories. The position of the
+// entry is shifted by 4 bits (divided by 16, since there are 16 entries in a sector) to calculate how many sectors a
+// specified entry is offset from the beginning of the directory.
+#define VALUE_BASED_ON_ENTRIES_PER_CLUSTER 4
+
+// Summary: A value that will indicate that a dotdot directory entry points to the root.
+// Description: The VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT macro is used as an absolute address when writing information to a dotdot entry
+// in a newly created directory. If a dotdot entry points to the root directory, it's cluster value must be set to 0,
+// regardless of the actual cluster number of the root directory.
+#define VALUE_DOTDOT_CLUSTER_VALUE_FOR_ROOT 0
+
+// Summary: MAcro indicating the length of an 8.3 file name in a directory entry
+// Description: The FILE_NAME_SIZE macro indicates the number of characters that an 8.3 file name will take up when packed in
+// a directory entry. This value includes 8 characters for the name and 3 for the extension. Note that the radix is not
+// stored in the directory entry.
+#define FILE_NAME_SIZE 11
+
+
+
+// Summary: Contains file information and is used to indicate which file to access.
+// Description: The FSFILE structure is used to hold file information for an open file as it's being modified or accessed. A pointer to
+// an open file's FSFILE structure will be passeed to any library function that will modify that file.
+typedef struct
+{
+ DISK * dsk; // Pointer to a DISK structure
+ DWORD cluster; // The first cluster of the file
+ DWORD ccls; // The current cluster of the file
+ WORD sec; // The current sector in the current cluster of the file
+ WORD pos; // The position in the current sector
+ DWORD seek; // The absolute position in the file
+ DWORD size; // The size of the file
+ FILEFLAGS flags; // A structure containing file flags
+ WORD time; // The file's last update time
+ WORD date; // The file's last update date
+ char name[FILE_NAME_SIZE]; // The name of the file
+ WORD entry; // The position of the file's directory entry in it's directory
+ WORD chk; // File structure checksum
+ WORD attributes; // The file attributes
+ DWORD dirclus; // The base cluster of the file's directory
+ DWORD dirccls; // The current cluster of the file's directory
+} FSFILE;
+
+
+
+// Summary: A structure used for searching for files on a device.
+// Description: The SearchRec structure is used when searching for file on a device. It contains parameters that will be loaded with
+// file information when a file is found. It also contains the parameters that the user searched for, allowing further
+// searches to be perfomed in the same directory for additional files that meet the specified criteria.
+typedef struct
+{
+ char filename[FILE_NAME_SIZE + 2]; // The name of the file that has been found
+ unsigned char attributes; // The attributes of the file that has been found
+ unsigned long filesize; // The size of the file that has been found
+ unsigned long timestamp; // The last modified time of the file that has been found (create time for directories)
+
+ unsigned int entry; // The directory entry of the last file found that matches the specified attributes. (Internal use only)
+ char searchname[FILE_NAME_SIZE + 2]; // The name specified when the user began the search. (Internal use only)
+ unsigned char searchattr; // The attributes specified when the user began the search. (Internal use only)
+ unsigned int cwdclus; // The directory that this search was performed in. (Internal use only)
+ unsigned char initialized; // Check to determine if the structure was initialized by FindFirst (Internal use only)
+} SearchRec;
+
+
+/***************************************************************************
+* Prototypes *
+***************************************************************************/
+
+
+
+
+/*************************************************************************
+ Function:
+ int FSInit(void)
+ Summary:
+ Function to initialize the device.
+ Conditions:
+ The physical device should be connected to the microcontroller.
+ Input:
+ None
+ Return Values:
+ TRUE - Initialization successful
+ FALSE - Initialization unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Initializes the static or dynamic memory slots for holding file
+ structures. Initializes the device with the DISKmount function. Loads
+ MBR and boot sector information. Initializes the current working
+ directory to the root directory for the device if directory support
+ is enabled.
+ Remarks:
+ None
+ *************************************************************************/
+
+int FSInit(void);
+
+
+/*********************************************************************
+ Function:
+ FSFILE * FSfopen (const char * fileName, const char *mode)
+ Summary:
+ Open a file
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to open
+ mode -
+ - WRITE - Create a new file or replace an existing file
+ - READ - Read data from an existing file
+ - APPEND - Append data to an existing file
+ - WRITEPLUS - Create a new file or replace an existing file (reads also enabled)
+ - READPLUS - Read data from an existing file (writes also enabled)
+ - APPENDPLUS - Append data to an existing file (reads also enabled)
+ Return Values:
+ FSFILE * - The pointer to the file object
+ NULL - The file could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will open a file or directory. First, RAM in the
+ dynamic heap or static array will be allocated to a new FSFILE object.
+ Then, the specified file name will be formatted to ensure that it's
+ in 8.3 format. Next, the FILEfind function will be used to search
+ for the specified file name. If the name is found, one of three
+ things will happen: if the file was opened in read mode, its file
+ info will be loaded using the FILEopen function; if it was opened in
+ write mode, it will be erased, and a new file will be constructed in
+ its place; if it was opened in append mode, its file info will be
+ loaded with FILEopen and the current location will be moved to the
+ end of the file using the FSfseek function. If the file was not
+ found by FILEfind, it will be created if the mode was specified as
+ a write or append mode. In these cases, a pointer to the heap or
+ static FSFILE object array will be returned. If the file was not
+ found and the mode was specified as a read mode, the memory
+ allocated to the file will be freed and the NULL pointer value
+ will be returned.
+ Remarks:
+ None.
+ *********************************************************************/
+
+FSFILE * FSfopen(const char * fileName, const char *mode);
+
+
+
+#ifdef ALLOW_PGMFUNCTIONS
+
+/******************************************************************************
+ Function:
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode)
+ Summary:
+ Open a file named with a ROM string on PIC18
+ Conditions:
+ For read modes, file exists; FSInit performed
+ Input:
+ fileName - The name of the file to be opened (ROM)
+ mode - The mode the file will be opened in (ROM)
+ Return Values:
+ FSFILE * - A pointer to the file object
+ NULL - File could not be opened
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfopenpgm function will copy a PIC18 ROM fileName and mode argument
+ into RAM arrays, and then pass those arrays to the FSfopen function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ ******************************************************************************/
+
+ FSFILE * FSfopenpgm(const rom char * fileName, const rom char *mode);
+
+
+/**************************************************************************************
+ Function:
+ int FindFirstpgm (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Find a file named with a ROM string on PIC18
+ Conditions:
+ None
+ Input:
+ fileName - The name of the file to be found (ROM)
+ attr - The attributes of the file to be found
+ rec - Pointer to a search record to store the file info in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the given parameters was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object will be lost.
+ The FSerrno variable will be changed.
+ Description:
+ The FindFirstpgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FindFirst function.
+ Remarks:
+ Call FindFirstpgm or FindFirst before calling FindNext.
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************************/
+
+ int FindFirstpgm (const rom char * fileName, unsigned int attr, SearchRec * rec);
+
+
+/**************************************************************************
+ Function:
+ int FSchdirpgm (const rom char * path)
+ Summary:
+ Changed the CWD with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to (ROM)
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdirpgm function passes a PIC18 ROM path pointer to the
+ chdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM
+ **************************************************************************/
+
+ int FSchdirpgm (const rom char * path);
+
+ #ifdef ALLOW_WRITES
+
+
+/*************************************************************
+ Function:
+ int FSremovepgm (const rom char * fileName)
+ Summary:
+ Delete a file named with a ROM string on PIC18
+ Conditions:
+ File not opened; file exists
+ Input:
+ fileName - The name of the file to be deleted (ROM)
+ Return Values:
+ 0 - File was removed successfully
+ -1 - File could not be removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremovepgm function will copy a PIC18 ROM fileName argument
+ into a RAM array, and then pass that array to the FSremove function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *************************************************************/
+
+ int FSremovepgm (const rom char * fileName);
+
+
+/**************************************************************************
+ Function:
+ int FSmkdirpgm (const rom char * path)
+ Summary:
+ Create a directory with a path in ROM on PIC18
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create (ROM)
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdirpgm function passes a PIC18 ROM path pointer to the
+ mkdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arugments in ROM
+ **************************************************************************/
+
+ int FSmkdirpgm (const rom char * path);
+
+
+/**************************************************************************
+ Function:
+ int FSrmdirpgm (const rom char * path)
+ Summary:
+ Delete a directory with a path in ROM on PIC18
+ Conditions:
+ None.
+ Input:
+ path - The path of the directory to remove (ROM)
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdirpgm function passes a PIC18 ROM path pointer to the
+ rmdirhelper function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ **************************************************************************/
+
+ int FSrmdirpgm (const rom char * path, unsigned char rmsubdirs);
+
+
+/*****************************************************************
+ Function:
+ int FSrenamepgm(const rom char * fileName, FSFILE * fo)
+ Summary:
+ Rename a file named with a ROM string on PIC18
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file (in ROM)
+ fo - The file to rename
+ Return Values:
+ 0 - File renamed successfully
+ -1 - File could not be renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The Fsrenamepgm function will copy the rom fileName specified
+ by the user into a RAM array and pass that array into the
+ FSrename function.
+ Remarks:
+ This function is for use with PIC18 when passing arguments in ROM.
+ *****************************************************************/
+
+ int FSrenamepgm (const rom char * fileName, FSFILE * fo);
+ #endif
+#endif
+
+
+/************************************************************
+ Function:
+ int FSfclose(FSFILE *fo)
+ Summary:
+ Update file information and free FSFILE objects
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to the file to close
+ Return Values:
+ 0 - File closed successfully
+ EOF - Error closing the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ This function will update the directory entry for the
+ file pointed to by 'fo' with the information contained
+ in 'fo,' including the new file size and attributes.
+ Timestamp information will also be loaded based on the
+ method selected by the user and written to the entry
+ as the last modified time and date. The file entry will
+ then be written to the device. Finally, the memory
+ used for the specified file object will be freed from
+ the dynamic heap or the array of FSFILE objects.
+ Remarks:
+ A function to flush data to the device without closing the
+ file can be created by removing the portion of this
+ function that frees the memory and the line that clears
+ the write flag.
+ ************************************************************/
+
+int FSfclose(FSFILE *fo);
+
+
+/*********************************************************
+ Function:
+ void FSrewind (FSFILE * fo)
+ Summary:
+ Set the current position in a file to the beginning
+ Conditions:
+ File opened.
+ Input:
+ fo - Pointer to file structure
+ Return Values:
+ None
+ Side Effects:
+ None.
+ Description:
+ The FSrewind funciton will reset the position of the
+ specified file to the beginning of the file. This
+ functionality is faster than using FSfseek to reset
+ the position in the file.
+ Remarks:
+ None.
+ *********************************************************/
+
+void FSrewind (FSFILE *fo);
+
+
+/**************************************************************************
+ Function:
+ size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Read data from a file
+ Conditions:
+ File is opened in a read mode
+ Input:
+ ptr - Destination buffer for read bytes
+ size - Size of units in bytes
+ n - Number of units to be read
+ stream - File to be read from
+ Return:
+ size_t - number of units read
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfread function will read data from the specified file. First,
+ the appropriate sector of the file is loaded. Then, data is read into
+ the specified buffer until the specified number of bytes have been read.
+ When a cluster boundary is reached, a new cluster will be loaded. The
+ parameters 'size' and 'n' indicate how much data to read. 'Size'
+ refers to the size of one object to read (in bytes), and 'n' will refer
+ to the number of these objects to read. The value returned will be equal
+ to 'n' unless an error occured or the user tried to read beyond the end
+ of the file.
+ Remarks:
+ None.
+ **************************************************************************/
+
+size_t FSfread(void *ptr, size_t size, size_t n, FSFILE *stream);
+
+
+/**********************************************************************
+ Function:
+ int FSfseek(FSFILE *stream, long offset, int whence)
+ Summary:
+ Change the current position in a file
+ Conditions:
+ File opened
+ Input:
+ stream - Pointer to file structure
+ offset - Offset from base location
+ whence -
+ - SEEK_SET - Seek from start of file
+ - SEEK_CUR - Seek from current location
+ - SEEK_END - Seek from end of file (subtract offset)
+ Return Values:
+ 0 - Operation successful
+ -1 - Operation unsuccesful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfseek function will change the current position in the file to
+ one specified by the user. First, an absolute offset is calculated
+ using the offset and base location passed in by the user. Then, the
+ position variables are updated, and the sector number that corresponds
+ to the new location. That sector is then loaded. If the offset
+ falls exactly on a cluster boundary, a new cluster will be allocated
+ to the file and the position will be set to the first byte of that
+ cluster.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSfseek(FSFILE *stream, long offset, int whence);
+
+
+/*******************************************************************
+ Function:
+ long FSftell (FSFILE * fo)
+ Summary:
+ Determine the current location in a file
+ Conditions:
+ File opened
+ Input:
+ fo - Pointer to file structure
+ Return: Current location in the file
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSftell function will return the current position in the
+ file pointed to by 'fo' by returning the 'seek' variable in the
+ FSFILE object, which is used to keep track of the absolute
+ location of the current position in the file.
+ Remarks:
+ None
+ *******************************************************************/
+
+long FSftell(FSFILE *fo);
+
+
+/****************************************************
+ Function:
+ int FSfeof( FSFILE * stream )
+ Summary:
+ Indicate whether the current file position is at the end
+ Conditions:
+ File is open in a read mode
+ Input:
+ stream - Pointer to the target file
+ Return Values:
+ Non-Zero - EOF reached
+ 0 - Not at end of File
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfeof function will indicate that the end-of-
+ file has been reached for the specified file by
+ comparing the absolute location in the file to the
+ size of the file.
+ Remarks:
+ None.
+ ****************************************************/
+
+int FSfeof( FSFILE * stream );
+
+
+#ifdef ALLOW_FORMATS
+/*******************************************************************
+ Function:
+ int FSformat (char mode, long int serialNumber, char * volumeID)
+ Summary:
+ Formats a device
+ Conditions:
+ The device must possess a valid master boot record.
+ Input:
+ mode - - 0 - Just erase the FAT and root
+ - 1 - Create a new boot sector
+ serialNumber - Serial number to write to the card
+ volumeID - Name of the card
+ Return Values:
+ 0 - Format was successful
+ EOF - Format was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSformat function can be used to create a new boot sector
+ on a device, based on the information in the master boot record.
+ This function will first initialize the I/O pins and the device,
+ and then attempts to read the master boot record. If the MBR
+ cannot be loaded successfully, the function will fail. Next, if
+ the 'mode' argument is specified as '0' the existing boot sector
+ information will be loaded. If the 'mode' argument is '1' an
+ entirely new boot sector will be constructed using the disk
+ values from the master boot record. Once the boot sector has
+ been successfully loaded/created, the locations of the FAT and
+ root will be loaded from it, and they will be completely
+ erased. If the user has specified a volumeID parameter, a
+ VOLUME attribute entry will be created in the root directory
+ to name the device.
+ Remarks:
+ FAT12 and FAT16 formatting is supported.
+ *******************************************************************/
+
+int FSformat (char mode, long int serialNumber, char * volumeID);
+#endif
+
+
+#ifdef ALLOW_WRITES
+/***************************************************************************
+ Function:
+ int FSattrib (FSFILE * file, unsigned char attributes)
+ Summary:
+ Change the attributes of a file
+ Conditions:
+ File opened
+ Input:
+ file - Pointer to file structure
+ attributes - The attributes to set for the file
+ - Attribute - Value - Indications
+ - ATTR_READ_ONLY - 0x01 - The read-only attribute
+ - ATTR_HIDDEN - 0x02 - The hidden attribute
+ - ATTR_SYSTEM - 0x04 - The system attribute
+ - ATTR_ARCHIVE - 0x20 - The archive attribute
+ Return Values:
+ 0 - Attribute change was successful
+ -1 - Attribute change was unsuccessful
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSattrib funciton will set the attributes of the specified file
+ to the attributes passed in by the user. This function will load the
+ file entry, replace the attributes with the ones specified, and write
+ the attributes back. If the specified file is a directory, the
+ directory attribute will be preserved.
+ Remarks:
+ None
+ ***************************************************************************/
+
+int FSattrib (FSFILE * file, unsigned char attributes);
+
+
+/***************************************************************
+ Function:
+ int FSrename (const rom char * fileName, FSFILE * fo)
+ Summary:
+ Change the name of a file or directory
+ Conditions:
+ File opened.
+ Input:
+ fileName - The new name of the file
+ fo - The file to rename
+ Return Values:
+ 0 - File was renamed successfully
+ EOF - File was not renamed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrename function will rename a file. First, it will
+ search through the current working directory to ensure the
+ specified new filename is not already in use. If it isn't,
+ the new filename will be written to the file entry of the
+ file pointed to by 'fo.'
+ Remarks:
+ None
+ ***************************************************************/
+
+int FSrename (const char * fileName, FSFILE * fo);
+
+
+/*********************************************************************
+ Function:
+ int FSremove (const char * fileName)
+ Summary:
+ Delete a file
+ Conditions:
+ File not opened, file exists
+ Input:
+ fileName - Name of the file to erase
+ Return Values:
+ 0 - File removed
+ EOF - File was not removed
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSremove function will attempt to find the specified file with
+ the FILEfind function. If the file is found, it will be erased
+ using the FILEerase function.
+ Remarks:
+ None
+ **********************************************************************/
+
+int FSremove (const char * fileName);
+
+
+/*********************************************************************************
+ Function:
+ size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream)
+ Summary:
+ Write data to a file
+ Conditions:
+ File opened in WRITE, APPEND, WRITE+, APPEND+, READ+ mode
+ Input:
+ ptr - Pointer to source buffer
+ size - Size of units in bytes
+ n - Number of units to transfer
+ stream - Pointer to file structure
+ Return:
+ size_t - number of units written
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSfwrite function will write data to a file. First, the sector that
+ corresponds to the current position in the file will be loaded (if it hasn't
+ already been cached in the global data buffer). Data will then be written to
+ the device from the specified buffer until the specified amount has been written.
+ If the end of a cluster is reached, the next cluster will be loaded, unless
+ the end-of-file flag for the specified file has been set. If it has, a new
+ cluster will be allocated to the file. Finally, the new position and filezize
+ will be stored in the FSFILE object. The parameters 'size' and 'n' indicate how
+ much data to write. 'Size' refers to the size of one object to write (in bytes),
+ and 'n' will refer to the number of these objects to write. The value returned
+ will be equal to 'n' unless an error occured.
+ Remarks:
+ None.
+ *********************************************************************************/
+
+size_t FSfwrite(const void *ptr, size_t size, size_t n, FSFILE *stream);
+
+#endif
+
+#ifdef ALLOW_DIRS
+
+
+/**************************************************************************
+ Function:
+ int FSchdir (char * path)
+ Summary:
+ Change the current working directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to change to.
+ Return Values:
+ 0 - The current working directory was changed successfully
+ EOF - The current working directory could not be changed
+ Side Effects:
+ The current working directory may be changed. The FSerrno variable will
+ be changed.
+ Description:
+ The FSchdir function passes a RAM pointer to the path to the
+ chdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSchdir (char * path);
+
+
+/**************************************************************
+ Function:
+ char * FSgetcwd (char * path, int numchars)
+ Summary:
+ Get the current working directory name
+ Conditions:
+ None
+ Input:
+ path - Pointer to the array to return the cwd name in
+ numchars - Number of chars in the path
+ Return Values:
+ char * - The cwd name string pointer (path or defaultArray)
+ NULL - The current working directory name could not be loaded.
+ Side Effects:
+ The FSerrno variable will be changed
+ Description:
+ The FSgetcwd function will get the name of the current
+ working directory and return it to the user. The name
+ will be copied into the buffer pointed to by 'path,'
+ starting at the root directory and copying as many chars
+ as possible before the end of the buffer. The buffer
+ size is indicated by the 'numchars' argument. The first
+ thing this function will do is load the name of the current
+ working directory, if it isn't already present. This could
+ occur if the user switched to the dotdot entry of a
+ subdirectory immediately before calling this function. The
+ function will then copy the current working directory name
+ into the buffer backwards, and insert a backslash character.
+ Next, the function will continuously switch to the previous
+ directories and copy their names backwards into the buffer
+ until it reaches the root. If the buffer overflows, it
+ will be treated as a circular buffer, and data will be
+ copied over existing characters, starting at the beginning.
+ Once the root directory is reached, the text in the buffer
+ will be swapped, so that the buffer contains as much of the
+ current working directory name as possible, starting at the
+ root.
+ Remarks:
+ None
+ **************************************************************/
+
+char * FSgetcwd (char * path, int numbchars);
+
+
+#ifdef ALLOW_WRITES
+
+/**************************************************************************
+ Function:
+ int FSmkdir (char * path)
+ Summary:
+ Create a directory
+ Conditions:
+ None
+ Input:
+ path - The path of directories to create.
+ Return Values:
+ 0 - The specified directory was created successfully
+ EOF - The specified directory could not be created
+ Side Effects:
+ Will create all non-existent directories in the path. The FSerrno
+ variable will be changed.
+ Description:
+ The FSmkdir function passes a RAM pointer to the path to the
+ mkdirhelper function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSmkdir (char * path);
+
+
+/**************************************************************************
+ Function:
+ int FSrmdir (char * path)
+ Summary:
+ Delete a directory
+ Conditions:
+ None
+ Input:
+ path - The path of the directory to remove
+ rmsubdirs -
+ - TRUE - All sub-dirs and files in the target dir will be removed
+ - FALSE - FSrmdir will not remove non-empty directories
+ Return Values:
+ 0 - The specified directory was deleted successfully
+ EOF - The specified directory could not be deleted
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FSrmdir function passes a RAM pointer to the path to the
+ rmdirhelper function.
+ Remarks:
+ None.
+ **************************************************************************/
+
+int FSrmdir (char * path, unsigned char rmsubdirs);
+#endif
+
+#endif
+
+#ifdef USERDEFINEDCLOCK
+
+
+/***********************************************************************************************************
+ Function:
+ int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second)
+ Summary:
+ Manually set timestamp variables
+ Conditions:
+ USERDEFINEDCLOCK macro defined in FSconfig.h.
+ Input:
+ year - The year (1980\-2107)
+ month - The month (1\-12)
+ day - The day of the month (1\-31)
+ hour - The hour (0\-23)
+ minute - The minute (0\-59)
+ second - The second (0\-59)
+ Return Values:
+ None
+ Side Effects:
+ Modifies global timing variables
+ Description:
+ Lets the user manually set the timing variables. The values passed in will be converted to the format
+ used by the FAT timestamps.
+ Remarks:
+ Call this before creating a file or directory (set create time) and
+ before closing a file (set last access time, last modified time)
+ ***********************************************************************************************************/
+
+int SetClockVars (unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second);
+#endif
+
+
+#ifdef ALLOW_FILESEARCH
+
+/***********************************************************************************
+ Function:
+ int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec)
+ Summary:
+ Initial search function
+ Conditions:
+ None
+ Input:
+ fileName - The name to search for
+ - Parital string search characters
+ - * - Indicates the rest of the filename or extension can vary (e.g. FILE.*)
+ - ? - Indicates that one character in a filename can vary (e.g. F?LE.T?T)
+ attr - The attributes that a found file may have
+ - ATTR_READ_ONLY - File may be read only
+ - ATTR_HIDDEN - File may be a hidden file
+ - ATTR_SYSTEM - File may be a system file
+ - ATTR_VOLUME - Entry may be a volume label
+ - ATTR_DIRECTORY - File may be a directory
+ - ATTR_ARCHIVE - File may have archive attribute
+ - ATTR_MASK - All attributes
+ rec - pointer to a structure to put the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No file matching the specified criteria was found
+ Side Effects:
+ Search criteria from previous FindFirst call on passed SearchRec object
+ will be lost. The FSerrno variable will be changed.
+ Description:
+ The FindFirst function will search for a file based on parameters passed in
+ by the user. This function will use the FILEfind function to parse through
+ the current working directory searching for entries that match the specified
+ parameters. If a file is found, its parameters are copied into the SearchRec
+ structure, as are the initial parameters passed in by the user and the position
+ of the file entry in the current working directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling FindNext
+ ***********************************************************************************/
+
+int FindFirst (const char * fileName, unsigned int attr, SearchRec * rec);
+
+
+/**********************************************************************
+ Function:
+ int FindNext (SearchRec * rec)
+ Summary:
+ Sequential search function
+ Conditions:
+ None
+ Input:
+ rec - The structure to store the file information in
+ Return Values:
+ 0 - File was found
+ -1 - No additional files matching the specified criteria were found
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ The FindNext function performs the same function as the FindFirst
+ funciton, except it does not copy any search parameters into the
+ SearchRec structure (only info about found files) and it begins
+ searching at the last directory entry offset at which a file was
+ found, rather than at the beginning of the current working
+ directory.
+ Remarks:
+ Call FindFirst or FindFirstpgm before calling this function
+ **********************************************************************/
+
+int FindNext (SearchRec * rec);
+#endif
+
+
+/**********************************************************************
+ Function:
+ // PIC24/30/33/32
+ int FSfprintf (FSFILE * fptr, const char * fmt, ...)
+ // PIC18
+ int FSfpritnf (FSFILE * fptr, const rom char * fmt, ...)
+ Summary:
+ Function to write formatted strings to a file
+ Conditions:
+ For PIC18, integer promotion must be enabled in the project build
+ options menu. File opened in a write mode.
+ Input:
+ fptr - A pointer to the file to write to.
+ fmt - A string of characters and format specifiers to write to
+ the file
+ ... - Additional arguments inserted in the string by format
+ specifiers
+ Returns:
+ The number of characters written to the file
+ Side Effects:
+ The FSerrno variable will be changed.
+ Description:
+ Writes a specially formatted string to a file.
+ Remarks:
+ Consult AN1045 for a full description of how to use format
+ specifiers.
+ **********************************************************************/
+
+#ifdef ALLOW_FSFPRINTF
+ #ifdef __18CXX
+ int FSfprintf (FSFILE *fptr, const rom char *fmt, ...);
+ #else
+ int FSfprintf (FSFILE *fptr, const char * fmt, ...);
+ #endif
+#endif
+
+
+/**************************************************************************
+ Function:
+ int FSerror (void)
+ Summary:
+ Return an error code for the last function call
+ Conditions:
+ The return value depends on the last function called.
+ Input:
+ None
+ Side Effects:
+ None.
+ Return Values:
+ FSInit -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The physical media could not be initialized
+ - CE_BAD_SECTOR_READ � The MBR or the boot sector could not be
+ read correctly
+ - CE_BAD_PARITION � The MBR signature code was incorrect.
+ - CE_NOT_FORMATTED � The boot sector signature code was incorrect or
+ indicates an invalid number of bytes per sector.
+ - CE_CARDFAT32 � The physical media is FAT32 type (only an error
+ when FAT32 support is disabled).
+ - CE_UNSUPPORTED_FS � The device is formatted with an unsupported file
+ system (not FAT12 or 16).
+ FSfopen -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The device has not been initialized.
+ - CE_TOO_MANY_FILES_OPEN � The function could not allocate any
+ additional file information to the array
+ of FSFILE structures or the heap.
+ - CE_INVALID_FILENAME � The file name argument was invalid.
+ - CE_INVALID_ARGUMENT � The user attempted to open a directory in a
+ write mode or specified an invalid mode argument.
+ - CE_FILE_NOT_FOUND � The specified file (which was to be opened in read
+ mode) does not exist on the device.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_ERASE_FAIL � The existing file could not be erased (when opening
+ a file in WRITE mode).
+ - CE_DIR_FULL � The directory is full.
+ - CE_DISK_FULL� The data memory section is full.
+ - CE_WRITE_ERROR � A write to the device failed.
+ - CE_SEEK_ERROR � The current position in the file could not be set to
+ the end (when the file was opened in APPEND mode).
+ FSfclose -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer or the new file
+ entry information could not be written to the device.
+ - CE_BADCACHEREAD � The file entry information could not be cached
+ FSfread -
+ - CE_GOOD � No Error
+ - CE_WRITEONLY � The file was opened in a write-only mode.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_BAD_SECTOR_READ � The data sector could not be read.
+ - CE_EOF � The end of the file was reached.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be loaded.
+ FSfwrite -
+ - CE_GOOD � No Error
+ - CE_READONLY � The file was opened in a read-only mode.
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_WRITE_ERROR � There was an error writing data to the device.
+ - CE_BADCACHEREAD � The data sector to be modified could not be read from
+ the device.
+ - CE_DISK_FULL � All data clusters on the device are in use.
+ FSfseek -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device.
+ - CE_INVALID_ARGUMENT � The specified offset exceeds the size of the file.
+ - CE_BADCACHEREAD � The sector that contains the new current position
+ could not be loaded.
+ - CE_COULD_NOT_GET_CLUSTER � Additional clusters in the file could not be
+ loaded/allocated.
+ FSftell -
+ - CE_GOOD � No Error
+ FSattrib -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The attribute argument was invalid.
+ - CE_BADCACHEREAD � The existing file entry information could not be
+ loaded.
+ - CE_WRITE_ERROR � The file entry information could not be written to
+ the device.
+ FSrename -
+ - CE_GOOD � No Error
+ - CE_FILENOTOPENED � A null file pointer was passed into the function.
+ - CE_INVALID_FILENAME � The file name passed into the function was invalid.
+ - CE_BADCACHEREAD � A read from the device failed.
+ - CE_FILENAME_EXISTS � A file with the specified name already exists.
+ - CE_WRITE_ERROR � The new file entry data could not be written to the
+ device.
+ FSfeof -
+ - CE_GOOD � No Error
+ FSformat -
+ - CE_GOOD � No Error
+ - CE_INIT_ERROR � The device could not be initialized.
+ - CE_BADCACHEREAD � The master boot record or boot sector could not be
+ loaded successfully.
+ - CE_INVALID_ARGUMENT � The user selected to create their own boot sector on
+ a device that has no master boot record, or the mode
+ argument was invalid.
+ - CE_WRITE_ERROR � The updated MBR/Boot sector could not be written to
+ the device.
+ - CE_BAD_PARTITION � The calculated number of sectors per clusters was
+ invalid.
+ - CE_NONSUPPORTED_SIZE � The card has too many sectors to be formatted as
+ FAT12 or FAT16.
+ FSremove -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � The specified file could not be found.
+ - CE_ERASE_FAIL � The file could not be erased.
+ FSchdir -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The path string was mis-formed or the user tried to
+ change to a non-directory file.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_FOUND � Could not find a directory in the path.
+ FSgetcwd -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The user passed a 0-length buffer into the function.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the current working directory.
+ FSmkdir -
+ - CE_GOOD � No Error
+ - CE_WRITE_PROTECTED � The device write-protect check function indicated
+ that the device has been write-protected.
+ - CE_INVALID_ARGUMENT � The path string was mis-formed.
+ - CE_BADCACHEREAD � Could not successfully change to a recently created
+ directory to store its dir entry information, or
+ could not cache directory entry information.
+ - CE_INVALID_FILENAME � One or more of the directory names has an invalid
+ format.
+ - CE_WRITE_ERROR � The existing data in the data buffer could not be
+ written to the device or the dot/dotdot entries could
+ not be written to a newly created directory.
+ - CE_DIR_FULL � There are no available dir entries in the CWD.
+ - CE_DISK_FULL � There are no available clusters in the data region of
+ the device.
+ FSrmdir -
+ - CE_GOOD � No Error
+ - CE_DIR_NOT_FOUND � The directory specified could not be found or the
+ function could not change to a subdirectory within
+ the directory to be deleted (when recursive delete is
+ enabled).
+ - CE_INVALID_ARGUMENT � The user tried to remove the CWD or root directory.
+ - CE_BADCACHEREAD � A directory entry could not be cached.
+ - CE_DIR_NOT_EMPTY � The directory to be deleted was not empty and
+ recursive subdirectory removal was disabled.
+ - CE_ERASE_FAIL � The directory or one of the directories or files
+ within it could not be deleted.
+ - CE_BAD_SECTOR_READ � The function could not determine a previous directory
+ of the CWD.
+ SetClockVars -
+ - CE_GOOD � No Error
+ - CE_INVALID_ARGUMENT � The time values passed into the function were
+ invalid.
+ FindFirst -
+ - CE_GOOD � No Error
+ - CE_INVALID_FILENAME � The specified filename was invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ - CE_BADCACHEREAD � The file information for the file that was found
+ could not be cached.
+ FindNext -
+ - CE_GOOD � No Error
+ - CE_NOT_INIT � The SearchRec object was not initialized by a call to
+ FindFirst.
+ - CE_INVALID_ARGUMENT � The SearchRec object was initialized in a different
+ directory from the CWD.
+ - CE_INVALID_FILENAME � The filename is invalid.
+ - CE_FILE_NOT_FOUND � No file matching the specified criteria was found.
+ FSfprintf -
+ - CE_GOOD � No Error
+ - CE_WRITE_ERROR � Characters could not be written to the file.
+ Description:
+ The FSerror function will return the FSerrno variable. This global
+ variable will have been set to an error value during the last call of a
+ library function.
+ Remarks:
+ None
+ **************************************************************************/
+
+int FSerror (void);
+
+
+/*********************************************************************************
+ Function:
+ int FSCreateMBR (unsigned long firstSector, unsigned long numSectors)
+ Summary:
+ Creates a master boot record
+ Conditions:
+ The I/O pins for the device have been initialized by the InitIO function.
+ Input:
+ firstSector - The first sector of the partition on the device (cannot
+ be 0; that's the MBR)
+ numSectors - The number of sectors available in memory (including the
+ MBR)
+ Return Values:
+ 0 - MBR was created successfully
+ EOF - MBR could not be created
+ Side Effects:
+ None
+ Description:
+ This function can be used to create a master boot record for a device. Note
+ that this function should not be used on a device that is already formatted
+ with a master boot record (i.e. most SD cards, CF cards, USB keys). This
+ function will fill the global data buffer with appropriate partition information
+ for a FAT partition with a type determined by the number of sectors available
+ to the partition. It will then write the MBR information to the first sector
+ on the device. This function should be followed by a call to FSformat, which
+ will create a boot sector, root dir, and FAT appropriate the the information
+ contained in the new master boot record. Note that FSformat only supports
+ FAT12 and FAT16 formatting at this time, and so cannot be used to format a
+ device with more than 0x3FFD5F sectors.
+ Remarks:
+ This function can damage the device being used, and should not be called
+ unless the user is sure about the size of the device and the first sector value.
+ *********************************************************************************/
+
+int FSCreateMBR (unsigned long firstSector, unsigned long numSectors);
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/HardwareProfile-BfB.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/HardwareProfile-BfB.h new file mode 100644 index 00000000..01653540 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/HardwareProfile-BfB.h @@ -0,0 +1,622 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: HardwareProfile.h
+ * Dependencies: None
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+
+#ifndef _HARDWAREPROFILE_H_
+#define _HARDWAREPROFILE_H_
+
+// Define your clock speed here
+
+// Sample clock speed for PIC18
+#if defined (__18CXX)
+
+ #define GetSystemClock() 40000000 // System clock frequency (Hz)
+ #define GetPeripheralClock() GetSystemClock() // Peripheral clock freq.
+ #define GetInstructionClock() (GetSystemClock() / 4) // Instruction clock freq.
+
+// Sample clock speed for a 16-bit processor
+#elif defined (__C30__)
+
+ #define GetSystemClock() 32000000
+ #define GetPeripheralClock() GetSystemClock()
+ #define GetInstructionClock() (GetSystemClock() / 2)
+
+ // Clock values
+ #define MILLISECONDS_PER_TICK 10 // Definition for use with a tick timer
+ #define TIMER_PRESCALER TIMER_PRESCALER_8 // Definition for use with a tick timer
+ #define TIMER_PERIOD 20000 // Definition for use with a tick timer
+
+// Sample clock speed for a 32-bit processor
+#elif defined (__PIC32MX__)
+
+ // Indicates that the PIC32 clock is running at 48 MHz
+ //#define RUN_AT_48MHZ
+ // Indicates that the PIC32 clock is running at 24 MHz
+ //#define RUN_AT_24MHZ
+ // Indicates that the PIC32 clock is running at 60 MHz
+ //#define RUN_AT_60MHZ
+ // Indicates that the PIC32 clock is running at 60 MHz
+ #define RUN_AT_80MHZ
+
+ // Various clock values
+
+ #if defined(RUN_AT_48MHZ)
+ #define GetSystemClock() 48000000UL // System clock frequency (Hz)
+ #define GetPeripheralClock() 48000000UL // Peripheral clock frequency
+ #define GetInstructionClock() (GetSystemClock()) // Instruction clock frequency
+ #elif defined(RUN_AT_24MHZ)
+ #define GetSystemClock() 24000000UL
+ #define GetPeripheralClock() 24000000UL
+ #define GetInstructionClock() (GetSystemClock())
+ #elif defined(RUN_AT_60MHZ)
+ #define GetSystemClock() (60000000ul)
+ #define GetPeripheralClock() (GetSystemClock())
+ #define GetInstructionClock() (GetSystemClock())
+ #elif defined(RUN_AT_80MHZ)
+ #define GetSystemClock() (80000000ul)
+ #define GetPeripheralClock() (GetSystemClock()/8)
+ #define GetInstructionClock() (GetSystemClock())
+ #else
+ #error Choose a speed
+ #endif
+
+ // Clock values
+
+ #define MILLISECONDS_PER_TICK 10 // Definition for use with a tick timer
+ #define TIMER_PRESCALER TIMER_PRESCALER_8 // Definition for use with a tick timer
+ #define TIMER_PERIOD 37500 // Definition for use with a tick timer
+#endif
+
+
+
+
+
+// Select your interface type
+// This library currently only supports a single physical interface layer at a time
+
+
+// Description: Macro used to enable the SD-SPI physical layer (SD-SPI.c and .h)
+#define USE_SD_INTERFACE_WITH_SPI
+
+// Description: Macro used to enable the CF-PMP physical layer (CF-PMP.c and .h)
+//#define USE_CF_INTERFACE_WITH_PMP
+
+// Description: Macro used to enable the CF-Manual physical layer (CF-Bit transaction.c and .h)
+//#define USE_MANUAL_CF_INTERFACE
+
+// Description: Macro used to enable the USB Host physical layer (USB host MSD library)
+//#define USE_USB_INTERFACE
+
+
+/*********************************************************************/
+/******************* Pin and Register Definitions ********************/
+/*********************************************************************/
+
+/* SD Card definitions: Change these to fit your application when using
+ an SD-card-based physical layer */
+
+#ifdef USE_SD_INTERFACE_WITH_SPI
+ #ifdef __18CXX
+
+ // Sample definition for PIC18 (modify to fit your own project)
+
+ // Description: SD-SPI Chip Select Output bit
+ #define SD_CS PORTBbits.RB3
+ // Description: SD-SPI Chip Select TRIS bit
+ #define SD_CS_TRIS TRISBbits.TRISB3
+
+ // Description: SD-SPI Card Detect Input bit
+ #define SD_CD PORTBbits.RB4
+ // Description: SD-SPI Card Detect TRIS bit
+ #define SD_CD_TRIS TRISBbits.TRISB4
+
+ // Description: SD-SPI Write Protect Check Input bit
+ #define SD_WE PORTAbits.RA4
+ // Description: SD-SPI Write Protect Check TRIS bit
+ #define SD_WE_TRIS TRISAbits.TRISA4
+
+ // Registers for the SPI module you want to use
+
+ // Description: The main SPI control register
+ #define SPICON1 SSP1CON1
+ // Description: The SPI status register
+ #define SPISTAT SSP1STAT
+ // Description: The SPI buffer
+ #define SPIBUF SSP1BUF
+ // Description: The receive buffer full bit in the SPI status register
+ #define SPISTAT_RBF SSP1STATbits.BF
+ // Description: The bitwise define for the SPI control register (i.e. _____bits)
+ #define SPICON1bits SSP1CON1bits
+ // Description: The bitwise define for the SPI status register (i.e. _____bits)
+ #define SPISTATbits SSP1STATbits
+
+ // Description: The interrupt flag for the SPI module
+ #define SPI_INTERRUPT_FLAG PIR1bits.SSPIF
+ // Description: The enable bit for the SPI module
+ #define SPIENABLE SPICON1bits.SSPEN
+
+/*
+ // Defines for the FS-USB demo board
+
+ // Tris pins for SCK/SDI/SDO lines
+ #define SPICLOCK TRISBbits.TRISB1
+ #define SPIIN TRISBbits.TRISB0
+ #define SPIOUT TRISCbits.TRISC7
+
+ // Latch pins for SCK/SDI/SDO lines
+ #define SPICLOCKLAT LATBbits.LATB1
+ #define SPIINLAT LATBbits.LATB0
+ #define SPIOUTLAT LATCbits.LATC7
+
+ // Port pins for SCK/SDI/SDO lines
+ #define SPICLOCKPORT PORTBbits.RB1
+ #define SPIINPORT PORTBbits.RB0
+ #define SPIOUTPORT PORTCbits.RC7
+*/
+
+ // Defines for the HPC Explorer board
+
+ // Description: The TRIS bit for the SCK pin
+ #define SPICLOCK TRISCbits.TRISC3
+ // Description: The TRIS bit for the SDI pin
+ #define SPIIN TRISCbits.TRISC4
+ // Description: The TRIS bit for the SDO pin
+ #define SPIOUT TRISCbits.TRISC5
+
+ // Description: The output latch for the SCK pin
+ #define SPICLOCKLAT LATCbits.LATC3
+ // Description: The output latch for the SDI pin
+ #define SPIINLAT LATCbits.LATC4
+ // Description: The output latch for the SDO pin
+ #define SPIOUTLAT LATCbits.LATC5
+
+ // Description: The port for the SCK pin
+ #define SPICLOCKPORT PORTCbits.RC3
+ // Description: The port for the SDI pin
+ #define SPIINPORT PORTCbits.RC4
+ // Description: The port for the SDO pin
+ #define SPIOUTPORT PORTCbits.RC5
+
+
+ // Will generate an error if the clock speed is too low to interface to the card
+ #if (GetSystemClock() < 400000)
+ #error System clock speed must exceed 400 kHz
+ #endif
+
+ #elif defined __PIC24F__
+
+ // Description: SD-SPI Chip Select Output bit
+ #define SD_CS PORTBbits.RB1
+ // Description: SD-SPI Chip Select TRIS bit
+ #define SD_CS_TRIS TRISBbits.TRISB1
+
+ // Description: SD-SPI Card Detect Input bit
+ #define SD_CD PORTFbits.RF0
+ // Description: SD-SPI Card Detect TRIS bit
+ #define SD_CD_TRIS TRISFbits.TRISF0
+
+ // Description: SD-SPI Write Protect Check Input bit
+ #define SD_WE PORTFbits.RF1
+ // Description: SD-SPI Write Protect Check TRIS bit
+ #define SD_WE_TRIS TRISFbits.TRISF1
+
+ // Registers for the SPI module you want to use
+ // Description: The main SPI control register
+ #define SPICON1 SPI1CON1
+ // Description: The SPI status register
+ #define SPISTAT SPI1STAT
+ // Description: The SPI Buffer
+ #define SPIBUF SPI1BUF
+ // Description: The receive buffer full bit in the SPI status register
+ #define SPISTAT_RBF SPI1STATbits.SPIRBF
+ // Description: The bitwise define for the SPI control register (i.e. _____bits)
+ #define SPICON1bits SPI1CON1bits
+ // Description: The bitwise define for the SPI status register (i.e. _____bits)
+ #define SPISTATbits SPI1STATbits
+ // Description: The enable bit for the SPI module
+ #define SPIENABLE SPISTATbits.SPIEN
+
+ // Tris pins for SCK/SDI/SDO lines
+
+ // Description: The TRIS bit for the SCK pin
+ #define SPICLOCK TRISFbits.TRISF6
+ // Description: The TRIS bit for the SDI pin
+ #define SPIIN TRISFbits.TRISF7
+ // Description: The TRIS bit for the SDO pin
+ #define SPIOUT TRISFbits.TRISF8
+
+ // Will generate an error if the clock speed is too low to interface to the card
+ #if (GetSystemClock() < 100000)
+ #error Clock speed must exceed 100 kHz
+ #endif
+
+ #elif defined (__PIC32MX__)
+
+ // Description: SD-SPI Chip Select Output bit
+ #define SD_CS PORTBbits.RB1
+ // Description: SD-SPI Chip Select TRIS bit
+ #define SD_CS_TRIS TRISBbits.TRISB1
+
+ // Description: SD-SPI Card Detect Input bit
+ #define SD_CD PORTEbits.RE4
+ // Description: SD-SPI Card Detect TRIS bit
+ #define SD_CD_TRIS TRISEbits.TRISE4
+
+ // Description: SD-SPI Write Protect Check Input bit
+ #define SD_WE PORTEbits.RE3
+ // Description: SD-SPI Write Protect Check TRIS bit
+ #define SD_WE_TRIS TRISEbits.TRISE3
+
+ // Registers for the SPI module you want to use
+
+ // Description: The main SPI 1 control register
+ //#define SPICON1 SPI1CON
+ // Description: The SPI status register
+ //#define SPISTAT SPI1STAT
+ // Description: The SPI Buffer
+ //#define SPIBUF SPI1BUF
+ // Description: The receive buffer full bit in the SPI status register
+ //#define SPISTAT_RBF SPI1STATbits.SPIRBF
+ // Description: The bitwise define for the SPI control register (i.e. _____bits)
+ //#define SPICON1bits SPI1CONbits
+ // Description: The bitwise define for the SPI status register (i.e. _____bits)
+ //#define SPISTATbits SPI1STATbits
+ // Description: The enable bit for the SPI module
+ //#define SPIENABLE SPICON1bits.ON
+ // Description: The definition for the SPI baud rate generator register (PIC32)
+ //#define SPIBRG SPI1BRG
+
+ // Description: The main SPI 2 control register
+ #define SPICON2 SPI2CON
+ // Description: The SPI status register
+ #define SPISTAT SPI2STAT
+ // Description: The SPI Buffer
+ #define SPIBUF SPI2BUF
+ // Description: The receive buffer full bit in the SPI status register
+ #define SPISTAT_RBF SPI2STATbits.SPIRBF
+ // Description: The bitwise define for the SPI control register (i.e. _____bits)
+ #define SPICON2bits SPI2CONbits
+ // Description: The bitwise define for the SPI status register (i.e. _____bits)
+ #define SPISTATbits SPI2STATbits
+ // Description: The enable bit for the SPI module
+ #define SPIENABLE SPICON2bits.ON
+ // Description: The definition for the SPI baud rate generator register (PIC32)
+ #define SPIBRG SPI2BRG
+
+ // Tris pins for SCK/SDI/SDO lines
+
+ // Description: The TRIS bit for the SCK pin
+ #define SPICLOCK TRISGbits.TRISG6
+ // Description: The TRIS bit for the SDI pin
+ #define SPIIN TRISGbits.TRISG7
+ // Description: The TRIS bit for the SDO pin
+ #define SPIOUT TRISGbits.TRISG8
+
+ // Will generate an error if the clock speed is too low to interface to the card
+ #if (GetSystemClock() < 100000)
+ #error Clock speed must exceed 100 kHz
+ #endif
+
+ #endif
+
+#endif
+
+
+#ifdef USE_CF_INTERFACE_WITH_PMP
+
+ /* CompactFlash-PMP card definitions: change these to fit your application when
+ using the PMP module to interface with CF cards */
+
+ #ifdef __18CXX
+ #error The PIC18 architecture does not currently support PMP interface to CF cards
+ #elif defined __dsPIC30F__
+
+ // Sample dsPIC30 defines
+
+ // Description: The output latch for the CF Reset signal
+ #define CF_PMP_RST _RD0
+ // Description: The TRIS bit for the CF Reset signal
+ #define CF_PMP_RESETDIR _TRISD0
+ // Description: The input port for the CF Ready signal
+ #define CF_PMP_RDY _RD12
+ // Description: The TRIS bit for the CF Ready signal
+ #define CF_PMP_READYDIR _TRISD12
+ // Description: The input port for the CF card detect signal
+ #define CF_PMP_CD1 _RC4
+ // Description: The TRIS bit for the CF card detect signal
+ #define CF_PMP_CD1DIR _TRISC4
+
+ #elif defined __dsPIC33F__
+
+ // Sample dsPIC33 defines
+
+ // Description: The output latch for the CF Reset signal
+ #define CF_PMP_RST _RD0
+ // Description: The TRIS bit for the CF Reset signal
+ #define CF_PMP_RESETDIR _TRISD0
+ // Description: The input port for the CF Ready signal
+ #define CF_PMP_RDY _RD12
+ // Description: The TRIS bit for the CF Ready signal
+ #define CF_PMP_READYDIR _TRISD12
+ // Description: The input port for the CF card detect signal
+ #define CF_PMP_CD1 _RC4
+ // Description: The TRIS bit for the CF card detect signal
+ #define CF_PMP_CD1DIR _TRISC4
+
+ #elif defined __PIC24F__
+
+ // Default case for PIC24F
+
+ // Description: The output latch for the CF Reset signal
+ #define CF_PMP_RST PORTDbits.RD0
+ // Description: The TRIS bit for the CF Reset signal
+ #define CF_PMP_RESETDIR TRISDbits.TRISD0
+ // Description: The input port for the CF Ready signal
+ #define CF_PMP_RDY PORTDbits.RD12
+ // Description: The TRIS bit for the CF Ready signal
+ #define CF_PMP_READYDIR TRISDbits.TRISD12
+ // Description: The input port for the CF card detect signal
+ #define CF_PMP_CD1 PORTCbits.RC4
+ // Description: The TRIS bit for the CF card detect signal
+ #define CF_PMP_CD1DIR TRISCbits.TRISC4
+
+ #endif
+
+ // Description: Defines the PMP data bus direction register
+ #define MDD_CFPMP_DATADIR TRISE
+#endif
+
+
+#ifdef USE_MANUAL_CF_INTERFACE
+ // Use these definitions with CF-Bit transaction.c and .h
+ // This will manually perform parallel port transactions
+
+ #ifdef __18CXX
+
+ // Address lines
+
+ // Description: The CF address bus output latch register (for PIC18)
+ #define ADDBL LATA
+ // Description: The CF address bus TRIS register (for PIC18)
+ #define ADDDIR TRISA
+
+ // Data bus
+
+ // Description: The Manual CF data bus port register
+ #define MDD_CFBT_DATABIN PORTD
+ // Description: The Manual CF data bus output latch register
+ #define MDD_CFBT_DATABOUT LATD
+ // Description: The Manual CF data bus TRIS register
+ #define MDD_CFBT_DATADIR TRISD
+
+ // control bus lines
+
+ // Description: The CF card chip select output latch bit
+ #define CF_CE LATEbits.LATE1
+ // Description: The CF card chip select TRIS bit
+ #define CF_CEDIR TRISEbits.TRISE1
+ // Description: The CF card output enable strobe latch bit
+ #define CF_OE LATAbits.LATA5
+ // Description: The CF card output enable strobe TRIS bit
+ #define CF_OEDIR TRISAbits.TRISA5
+ // Description: The CF card write enable strobe latch bit
+ #define CF_WE LATAbits.LATA4
+ // Description: The CF card write enable strobe TRIS bit
+ #define CF_WEDIR TRISAbits.TRISA4
+ // Description: The CF card reset signal latch bit
+ #define CF_BT_RST LATEbits.LATE0
+ // Description: The CF card reset signal TRIS bit
+ #define CF_BT_RESETDIR TRISEbits.TRISE0
+ // Description: The CF card ready signal port bit
+ #define CF_BT_RDY PORTEbits.RE2
+ // Description: The CF card ready signal TRIS bit
+ #define CF_BT_READYDIR TRISEbits.TRISE2
+ // Description: The CF card detect signal port bit
+ #define CF_BT_CD1 PORTCbits.RC2
+ // Description: The CF card detect signal TRIS bit
+ #define CF_BT_CD1DIR TRISCbits.TRISC2
+
+ #elif defined __dsPIC30F__
+
+ // Address lines
+
+ // Description: The CF address bus bit 0 output latch definition (for PIC24/30/33/32)
+ #define ADDR0 _LATB15
+ // Description: The CF address bus bit 1 output latch definition (for PIC24/30/33/32)
+ #define ADDR1 _LATB14
+ // Description: The CF address bus bit 2 output latch definition (for PIC24/30/33/32)
+ #define ADDR2 _LATG9
+ // Description: The CF address bus bit 3 output latch definition (for PIC24/30/33/32)
+ #define ADDR3 _LATG8
+ // Description: The CF address bus bit 0 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS0 _TRISB15
+ // Description: The CF address bus bit 1 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS1 _TRISB14
+ // Description: The CF address bus bit 2 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS2 _TRISG9
+ // Description: The CF address bus bit 3 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS3 _TRISG8
+
+ // Data bus
+
+ // Description: The Manual CF data bus port register
+ #define MDD_CFBT_DATABIN PORTE
+ // Description: The Manual CF data bus output latch register
+ #define MDD_CFBT_DATABOUT PORTE
+ // Description: The Manual CF data bus TRIS register
+ #define MDD_CFBT_DATADIR TRISE
+
+ // control bus lines
+
+ // Description: The CF card chip select output latch bit
+ #define CF_CE _RD11
+ // Description: The CF card chip select TRIS bit
+ #define CF_CEDIR _TRISD11
+ // Description: The CF card output enable strobe latch bit
+ #define CF_OE _RD5
+ // Description: The CF card output enable strobe TRIS bit
+ #define CF_OEDIR _TRISD5
+ // Description: The CF card write enable strobe latch bit
+ #define CF_WE _RD4
+ // Description: The CF card write enable strobe TRIS bit
+ #define CF_WEDIR _TRISD4
+ // Description: The CF card reset signal latch bit
+ #define CF_BT_RST _RD0
+ // Description: The CF card reset signal TRIS bit
+ #define CF_BT_RESETDIR _TRISD0
+ // Description: The CF card ready signal port bit
+ #define CF_BT_RDY _RD12
+ // Description: The CF card ready signal TRIS bit
+ #define CF_BT_READYDIR _TRISD12
+ // Description: The CF card detect signal port bit
+ #define CF_BT_CD1 _RC4
+ // Description: The CF card detect signal TRIS bit
+ #define CF_BT_CD1DIR _TRISC4
+
+ #elif defined __dsPIC33F__
+
+ // Address lines
+
+ // Description: The CF address bus bit 0 output latch definition (for PIC24/30/33/32)
+ #define ADDR0 _LATB15
+ // Description: The CF address bus bit 1 output latch definition (for PIC24/30/33/32)
+ #define ADDR1 _LATB14
+ // Description: The CF address bus bit 2 output latch definition (for PIC24/30/33/32)
+ #define ADDR2 _LATG9
+ // Description: The CF address bus bit 3 output latch definition (for PIC24/30/33/32)
+ #define ADDR3 _LATG8
+ // Description: The CF address bus bit 0 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS0 _TRISB15
+ // Description: The CF address bus bit 1 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS1 _TRISB14
+ // Description: The CF address bus bit 2 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS2 _TRISG9
+ // Description: The CF address bus bit 3 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS3 _TRISG8
+
+ // Data bus
+
+ // Description: The Manual CF data bus port register
+ #define MDD_CFBT_DATABIN PORTE
+ // Description: The Manual CF data bus output latch register
+ #define MDD_CFBT_DATABOUT PORTE
+ // Description: The Manual CF data bus TRIS register
+ #define MDD_CFBT_DATADIR TRISE
+
+ // control bus lines
+
+ // Description: The CF card chip select output latch bit
+ #define CF_CE _RD11
+ // Description: The CF card chip select TRIS bit
+ #define CF_CEDIR _TRISD11
+ // Description: The CF card output enable strobe latch bit
+ #define CF_OE _RD5
+ // Description: The CF card output enable strobe TRIS bit
+ #define CF_OEDIR _TRISD5
+ // Description: The CF card write enable strobe latch bit
+ #define CF_WE _RD4
+ // Description: The CF card write enable strobe TRIS bit
+ #define CF_WEDIR _TRISD4
+ // Description: The CF card reset signal latch bit
+ #define CF_BT_RST _RD0
+ // Description: The CF card reset signal TRIS bit
+ #define CF_BT_RESETDIR _TRISD0
+ // Description: The CF card ready signal port bit
+ #define CF_BT_RDY _RD12
+ // Description: The CF card ready signal TRIS bit
+ #define CF_BT_READYDIR _TRISD12
+ // Description: The CF card detect signal port bit
+ #define CF_BT_CD1 _RC4
+ // Description: The CF card detect signal TRIS bit
+ #define CF_BT_CD1DIR _TRISC4
+
+ #elif defined __PIC24F__
+
+ // Address lines
+
+ // Description: The CF address bus bit 0 output latch definition (for PIC24/30/33/32)
+ #define ADDR0 LATBbits.LATB15
+ // Description: The CF address bus bit 1 output latch definition (for PIC24/30/33/32)
+ #define ADDR1 LATBbits.LATB14
+ // Description: The CF address bus bit 2 output latch definition (for PIC24/30/33/32)
+ #define ADDR2 LATGbits.LATG9
+ // Description: The CF address bus bit 3 output latch definition (for PIC24/30/33/32)
+ #define ADDR3 LATGbits.LATG8
+ // Description: The CF address bus bit 0 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS0 TRISBbits.TRISB15
+ // Description: The CF address bus bit 1 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS1 TRISBbits.TRISB14
+ // Description: The CF address bus bit 2 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS2 TRISGbits.TRISG9
+ // Description: The CF address bus bit 3 TRIS definition (for PIC24/30/33/32)
+ #define ADRTRIS3 TRISGbits.TRISG8
+
+ // Data bus
+
+ // Description: The Manual CF data bus port register
+ #define MDD_CFBT_DATABIN PORTE
+ // Description: The Manual CF data bus output latch register
+ #define MDD_CFBT_DATABOUT PORTE
+ // Description: The Manual CF data bus TRIS register
+ #define MDD_CFBT_DATADIR TRISE
+
+ // control bus lines
+
+ // Description: The CF card chip select output latch bit
+ #define CF_CE PORTDbits.RD11
+ // Description: The CF card chip select TRIS bit
+ #define CF_CEDIR TRISDbits.TRISD11
+ // Description: The CF card output enable strobe latch bit
+ #define CF_OE PORTDbits.RD5
+ // Description: The CF card output enable strobe TRIS bit
+ #define CF_OEDIR TRISDbits.TRISD5
+ // Description: The CF card write enable strobe latch bit
+ #define CF_WE PORTDbits.RD4
+ // Description: The CF card write enable strobe TRIS bit
+ #define CF_WEDIR TRISDbits.TRISD4
+ // Description: The CF card reset signal latch bit
+ #define CF_BT_RST PORTDbits.RD0
+ // Description: The CF card reset signal TRIS bit
+ #define CF_BT_RESETDIR TRISDbits.TRISD0
+ // Description: The CF card ready signal port bit
+ #define CF_BT_RDY PORTDbits.RD12
+ // Description: The CF card ready signal TRIS bit
+ #define CF_BT_READYDIR TRISDbits.TRISD12
+ // Description: The CF card detect signal port bit
+ #define CF_BT_CD1 PORTCbits.RC4
+ // Description: The CF card detect signal TRIS bit
+ #define CF_BT_CD1DIR TRISCbits.TRISC4
+ #endif
+#endif
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/SD-SPI.d b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/SD-SPI.d new file mode 100644 index 00000000..5556b9b2 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/SD-SPI.d @@ -0,0 +1,61 @@ +SD-SPI.o: SD-SPI.c FSIO.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h FSconfig.h \
+ C:/Microchip\ Solutions/Microchip/Include/Compiler.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/p32xxxx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/p32mx440f256h.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/proc/ppic32mx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/cp0defs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/plib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/adc10.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/int.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/attribs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/bmx.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/cvref.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/dma.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/i2c.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/incap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/nvm.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/kmem.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/outcompare.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pcache.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/pmp.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/ports.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/power.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/reset.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/lock.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/rtcc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/spi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/system.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/osc.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/timer.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/uart.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/peripheral/wdt.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdio.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/posix.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/unistd.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdarg.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stddef.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/ansi.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/int_types.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/endian.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/machine/cdefs.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/swap.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/libc_thread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/signal.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sys/time.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/sched.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/impl.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/pthread/limits.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/stdlib.h \
+ C:/Program\ Files/Microchip/MPLAB\ C32/pic32mx/include/string.h \
+ HardwareProfile.h \
+ C:/Microchip\ Solutions/Microchip/Include/MDD\ File\ System\FSDefs.h \
+ C:/Microchip\ Solutions/Microchip/Include/GenericTypeDefs.h SD-SPI.h \
+ FSConfig.h
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/SD-SPI.h b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/SD-SPI.h new file mode 100644 index 00000000..55084ad4 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/newer_fw/SD-SPI.h @@ -0,0 +1,432 @@ +/******************************************************************************
+ *
+ * Microchip Memory Disk Drive File System
+ *
+ ******************************************************************************
+ * FileName: SD-SPI.h
+ * Dependencies: GenericTypeDefs.h
+ * FSconfig.h
+ * FSDefs.h
+ * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
+ * Compiler: C18/C30/C32
+ * Company: Microchip Technology, Inc.
+ * Version: 1.2.0
+ *
+ * Software License Agreement
+ *
+ * The software supplied herewith by Microchip Technology Incorporated
+ * (the �Company�) for its PICmicro� Microcontroller is intended and
+ * supplied to you, the Company�s customer, for use solely and
+ * exclusively on Microchip PICmicro Microcontroller products. The
+ * software is owned by the Company and/or its supplier, and is
+ * protected under applicable copyright laws. All rights are reserved.
+ * Any use in violation of the foregoing restrictions may subject the
+ * user to criminal sanctions under applicable laws, as well as to
+ * civil liability for the breach of the terms and conditions of this
+ * license.
+ *
+ * THIS SOFTWARE IS PROVIDED IN AN �AS IS� CONDITION. NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
+ * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
+ * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+*****************************************************************************/
+
+#ifndef SDMMC_H
+#define SDMMC_H
+
+#include "GenericTypeDefs.h"
+#include "FSconfig.h"
+#include "MDD File System\FSDefs.h"
+
+
+#ifdef __18CXX
+ // Description: This macro is used to initialize a PIC18 SPI module with a 4x prescale divider
+ #define SYNC_MODE_FAST 0x00
+ // Description: This macro is used to initialize a PIC18 SPI module with a 16x prescale divider
+ #define SYNC_MODE_MED 0x01
+ // Description: This macro is used to initialize a PIC18 SPI module with a 64x prescale divider
+ #define SYNC_MODE_SLOW 0x02
+#elif defined __PIC32MX__
+ // Description: This macro is used to initialize a PIC32 SPI module
+ #define SYNC_MODE_FAST 0x3E
+ // Description: This macro is used to initialize a PIC32 SPI module
+ #define SYNC_MODE_SLOW 0x3C
+#else
+ // Description: This macro indicates the SPI enable bit for 16-bit PICs
+ #define MASTER_ENABLE_ON 0x0020
+
+ // Description: This macro is used to initialize a 16-bit PIC SPI module
+ #define SYNC_MODE_FAST 0x3E
+ // Description: This macro is used to initialize a 16-bit PIC SPI module
+ #define SYNC_MODE_SLOW 0x3C
+
+ // Description: This macro is used to initialize a 16-bit PIC SPI module secondary prescaler
+ #define SEC_PRESCAL_1_1 0x001c
+ // Description: This macro is used to initialize a 16-bit PIC SPI module primary prescaler
+ #define PRI_PRESCAL_1_1 0x0003
+#endif
+
+
+
+/*****************************************************************/
+/* Strcutures and defines */
+/*****************************************************************/
+
+
+// Description: This macro represents an SD card start token
+#define DATA_START_TOKEN 0xFE
+
+// Description: This macro represents an SD card data accepted token
+#define DATA_ACCEPTED 0x05
+
+// Description: This macro indicates that the SD card expects to transmit or receive more data
+#define MOREDATA !0
+
+// Description: This macro indicates that the SD card does not expect to transmit or receive more data
+#define NODATA 0
+
+// Description: This macro represents a floating SPI bus condition
+#define MMC_FLOATING_BUS 0xFF
+
+// Description: This macro represents a bad SD card response byte
+#define MMC_BAD_RESPONSE MMC_FLOATING_BUS
+
+// The SDMMC Commands
+
+// Description: This macro defines the command code to reset the SD card
+#define cmdGO_IDLE_STATE 0
+// Description: This macro defines the command code to initialize the SD card
+#define cmdSEND_OP_COND 1
+// Description: This macro defines the command code to get the Card Specific Data
+#define cmdSEND_CSD 9
+// Description: This macro defines the command code to get the Card Information
+#define cmdSEND_CID 10
+// Description: This macro defines the command code to stop transmission during a multi-block read
+#define cmdSTOP_TRANSMISSION 12
+// Description: This macro defines the command code to get the card status information
+#define cmdSEND_STATUS 13
+// Description: This macro defines the command code to set the block length of the card
+#define cmdSET_BLOCKLEN 16
+// Description: This macro defines the command code to read one block from the card
+#define cmdREAD_SINGLE_BLOCK 17
+// Description: This macro defines the command code to read multiple blocks from the card
+#define cmdREAD_MULTI_BLOCK 18
+// Description: This macro defines the command code to write one block to the card
+#define cmdWRITE_SINGLE_BLOCK 24
+// Description: This macro defines the command code to write multiple blocks to the card
+#define cmdWRITE_MULTI_BLOCK 25
+// Description: This macro defines the command code to set the address of the start of an erase operation
+#define cmdTAG_SECTOR_START 32
+// Description: This macro defines the command code to set the address of the end of an erase operation
+#define cmdTAG_SECTOR_END 33
+// Description: This macro defines the command code to erase all previously selected blocks
+#define cmdERASE 38
+// Description: This macro defines the command code to begin application specific command inputs
+#define cmdAPP_CMD 55
+// Description: This macro defines the command code to get the OCR register information from the card
+#define cmdREAD_OCR 58
+// Description: This macro defines the command code to disable CRC checking
+#define cmdCRC_ON_OFF 59
+
+
+// Description: Enumeration of different SD response types
+typedef enum
+{
+ R1, // R1 type response
+ R1b, // R1b type response
+ R2, // R2 type response
+ R3 // R3 type response
+}RESP;
+
+// Summary: SD card command data structure
+// Description: The typMMC_CMD structure is used to create a command table of information needed for each relevant SD command
+typedef struct
+{
+ BYTE CmdCode; // The command code
+ BYTE CRC; // The CRC value for that command
+ RESP responsetype; // The response type
+ BYTE moredataexpected; // Set to MOREDATA or NODATA, depending on whether more data is expected or not
+} typMMC_CMD;
+
+
+// Summary: An SD command packet
+// Description: This union represents different ways to access an SD card command packet
+typedef union
+{
+ // This structure allows array-style access of command bytes
+ struct
+ {
+ #ifdef __18CXX
+ BYTE field[6]; // BYTE array
+ #else
+ BYTE field[7];
+ #endif
+ };
+ // This structure allows byte-wise access of packet command bytes
+ struct
+ {
+ BYTE crc; // The CRC byte
+ #if defined __C30__
+ BYTE c30filler; // Filler space (since bitwise declarations can't cross a WORD boundary)
+ #elif defined __C32__
+ BYTE c32filler[3]; // Filler space (since bitwise declarations can't cross a DWORD boundary)
+ #endif
+
+ BYTE addr0; // Address byte 0
+ BYTE addr1; // Address byte 1
+ BYTE addr2; // Address byte 2
+ BYTE addr3; // Address byte 3
+ BYTE cmd; // Command code byte
+ };
+ // This structure allows bitwise access to elements of the command bytes
+ struct
+ {
+ BYTE END_BIT:1; // Packet end bit
+ BYTE CRC7:7; // CRC value
+ DWORD address; // Address
+ BYTE CMD_INDEX:6; // Command code
+ BYTE TRANSMIT_BIT:1; // Transmit bit
+ BYTE START_BIT:1; // Packet start bit
+ };
+} CMD_PACKET;
+
+
+// Summary: The format of an R1 type response
+// Description: This union represents different ways to access an SD card R1 type response packet.
+typedef union
+{
+ BYTE _byte; // Byte-wise access
+ // This structure allows bitwise access of the response
+ struct
+ {
+ unsigned IN_IDLE_STATE:1; // Card is in idle state
+ unsigned ERASE_RESET:1; // Erase reset flag
+ unsigned ILLEGAL_CMD:1; // Illegal command flag
+ unsigned CRC_ERR:1; // CRC error flag
+ unsigned ERASE_SEQ_ERR:1; // Erase sequence error flag
+ unsigned ADDRESS_ERR:1; // Address error flag
+ unsigned PARAM_ERR:1; // Parameter flag
+ unsigned B7:1; // Unused bit 7
+ };
+} RESPONSE_1;
+
+// Summary: The format of an R2 type response
+// Description: This union represents different ways to access an SD card R2 type response packet
+typedef union
+{
+ WORD _word;
+ struct
+ {
+ BYTE _byte0;
+ BYTE _byte1;
+ };
+ struct
+ {
+ unsigned IN_IDLE_STATE:1;
+ unsigned ERASE_RESET:1;
+ unsigned ILLEGAL_CMD:1;
+ unsigned CRC_ERR:1;
+ unsigned ERASE_SEQ_ERR:1;
+ unsigned ADDRESS_ERR:1;
+ unsigned PARAM_ERR:1;
+ unsigned B7:1;
+ unsigned CARD_IS_LOCKED:1;
+ unsigned WP_ERASE_SKIP_LK_FAIL:1;
+ unsigned ERROR:1;
+ unsigned CC_ERROR:1;
+ unsigned CARD_ECC_FAIL:1;
+ unsigned WP_VIOLATION:1;
+ unsigned ERASE_PARAM:1;
+ unsigned OUTRANGE_CSD_OVERWRITE:1;
+ };
+} RESPONSE_2;
+
+// Summary: A union of responses from an SD card
+// Description: The MMC_RESPONSE union represents any of the possible responses that an SD card can return after
+// being issued a command.
+typedef union
+{
+ RESPONSE_1 r1;
+ RESPONSE_2 r2;
+}MMC_RESPONSE;
+
+
+// Summary: A description of the card specific data register
+// Description: This union represents different ways to access information in a packet with SD card CSD informaiton. For more
+// information on the CSD register, consult an SD card user's manual.
+typedef union
+{
+ struct
+ {
+ DWORD _u320;
+ DWORD _u321;
+ DWORD _u322;
+ DWORD _u323;
+ };
+ struct
+ {
+ BYTE _byte[16];
+ };
+ struct
+ {
+ unsigned NOT_USED :1;
+ unsigned CRC :7;
+ unsigned ECC :2;
+ unsigned FILE_FORMAT :2;
+ unsigned TMP_WRITE_PROTECT :1;
+ unsigned PERM_WRITE_PROTECT :1;
+ unsigned COPY :1;
+ unsigned FILE_FORMAT_GRP :1;
+ unsigned RESERVED_1 :5;
+ unsigned WRITE_BL_PARTIAL :1;
+ unsigned WRITE_BL_LEN_L :2;
+ unsigned WRITE_BL_LEN_H :2;
+ unsigned R2W_FACTOR :3;
+ unsigned DEFAULT_ECC :2;
+ unsigned WP_GRP_ENABLE :1;
+ unsigned WP_GRP_SIZE :5;
+ unsigned ERASE_GRP_SIZE_L :3;
+ unsigned ERASE_GRP_SIZE_H :2;
+ unsigned SECTOR_SIZE :5;
+ unsigned C_SIZE_MULT_L :1;
+ unsigned C_SIZE_MULT_H :2;
+ unsigned VDD_W_CURR_MAX :3;
+ unsigned VDD_W_CUR_MIN :3;
+ unsigned VDD_R_CURR_MAX :3;
+ unsigned VDD_R_CURR_MIN :3;
+ unsigned C_SIZE_L :2;
+ unsigned C_SIZE_H :8;
+ unsigned C_SIZE_U :2;
+ unsigned RESERVED_2 :2;
+ unsigned DSR_IMP :1;
+ unsigned READ_BLK_MISALIGN :1;
+ unsigned WRITE_BLK_MISALIGN :1;
+ unsigned READ_BL_PARTIAL :1;
+ unsigned READ_BL_LEN :4;
+ unsigned CCC_L :4;
+ unsigned CCC_H :8;
+ unsigned TRAN_SPEED :8;
+ unsigned NSAC :8;
+ unsigned TAAC :8;
+ unsigned RESERVED_3 :2;
+ unsigned SPEC_VERS :4;
+ unsigned CSD_STRUCTURE :2;
+ };
+} CSD;
+
+
+// Summary: A description of the card information register
+// Description: This union represents different ways to access information in a packet with SD card CID register informaiton. For more
+// information on the CID register, consult an SD card user's manual.
+typedef union
+{
+ struct
+ {
+ DWORD _u320;
+ DWORD _u321;
+ DWORD _u322;
+ DWORD _u323;
+ };
+ struct
+ {
+ BYTE _byte[16];
+ };
+ struct
+ {
+ unsigned NOT_USED :1;
+ unsigned CRC :7;
+ unsigned MDT :8;
+ DWORD PSN;
+ unsigned PRV :8;
+ char PNM[6];
+ WORD OID;
+ unsigned MID :8;
+ };
+} CID;
+
+#ifndef FALSE
+ #define FALSE 0
+#endif
+#ifndef TRUE
+ #define TRUE !FALSE
+#endif
+
+#define INPUT 1
+#define OUTPUT 0
+
+
+// Description: A delay prescaler
+#define DELAY_PRESCALER (BYTE) 8 //80MHz
+
+// Description: An approximation of the number of cycles per delay loop of overhead
+#define DELAY_OVERHEAD (BYTE) 5
+
+// Description: An approximate calculation of how many times to loop to delay 1 ms in the Delayms function
+#define MILLISECDELAY (WORD) ((GetInstructionClock()/DELAY_PRESCALER/(WORD)1000) - DELAY_OVERHEAD)
+
+// Summary: An enumeration of SD commands
+// Description: This enumeration corresponds to the position of each command in the sdmmc_cmdtable array
+// These macros indicate to the SendMMCCmd function which element of the sdmmc_cmdtable array
+// to retrieve command code information from.
+typedef enum
+{
+ GO_IDLE_STATE,
+ SEND_OP_COND,
+ SEND_CSD,
+ SEND_CID,
+ STOP_TRANSMISSION,
+ SEND_STATUS,
+ SET_BLOCKLEN,
+ READ_SINGLE_BLOCK,
+ READ_MULTI_BLOCK,
+ WRITE_SINGLE_BLOCK,
+ WRITE_MULTI_BLOCK,
+ TAG_SECTOR_START,
+ TAG_SECTOR_END,
+ ERASE,
+ APP_CMD,
+ READ_OCR,
+ CRC_ON_OFF
+}sdmmc_cmd;
+
+
+
+/***************************************************************************/
+/* Macros */
+/***************************************************************************/
+
+// Description: A macro to send clock cycles to dummy-read the CRC
+#define mReadCRC() WriteSPIM(0xFF);WriteSPIM(0xFF);
+
+// Description: A macro to send clock cycles to dummy-write the CRC
+#define mSendCRC() WriteSPIM(0xFF);WriteSPIM(0xFF);
+
+// Description: A macro to send 8 clock cycles for SD timing requirements
+#define mSend8ClkCycles() WriteSPIM(0xFF);
+
+/*****************************************************************************/
+/* Prototypes */
+/*****************************************************************************/
+
+DWORD MDD_SDSPI_ReadCapacity(void);
+WORD MDD_SDSPI_ReadSectorSize(void);
+void MDD_SDSPI_InitIO(void);
+
+BYTE MDD_SDSPI_MediaDetect(void);
+BYTE MDD_SDSPI_MediaInitialize(void);
+BYTE MDD_SDSPI_SectorRead(DWORD sector_addr, BYTE* buffer);
+BYTE MDD_SDSPI_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero);
+
+BYTE MDD_SDSPI_WriteProtectState(void);
+void MDD_SDSPI_ShutdownMedia(void);
+
+#if defined __C30__ || defined __C32__
+ extern BYTE ReadByte( BYTE* pBuffer, WORD index );
+ extern WORD ReadWord( BYTE* pBuffer, WORD index );
+ extern DWORD ReadDWord( BYTE* pBuffer, WORD index );
+#endif
+
+#endif
diff --git a/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/procdefs.ld b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/procdefs.ld new file mode 100644 index 00000000..7f83fa41 --- /dev/null +++ b/trunk/users/erik/OpenRapMan/bfb-firmware-1.0.8/procdefs.ld @@ -0,0 +1,58 @@ +/* Special procdefs.ld for use with USB HID Bootloader.
+ Just copy to your build area where the .mcw file is located */
+/*************************************************************************
+ * Processor-specific object file. Contains SFR definitions.
+ *************************************************************************/
+INPUT("processor.o")
+
+/*************************************************************************
+ * For interrupt vector handling
+ *************************************************************************/
+PROVIDE(_vector_spacing = 0x00000001);
+_ebase_address = 0x9D005000;
+
+/*************************************************************************
+ * Memory Address Equates
+ *************************************************************************/
+_RESET_ADDR = 0x9D006000;
+_BEV_EXCPT_ADDR = 0x9D006380;
+_DBG_EXCPT_ADDR = 0x9D006480;
+_DBG_CODE_ADDR = 0xBFC02000;
+_GEN_EXCPT_ADDR = _ebase_address + 0x180;
+
+/*************************************************************************
+ * Memory Regions
+ *
+ * Memory regions without attributes cannot be used for orphaned sections.
+ * Only sections specifically assigned to these regions can be allocated
+ * into these regions.
+ *************************************************************************/
+MEMORY
+{
+ kseg0_program_mem (rx) : ORIGIN = 0x9D006A00, LENGTH = 0x7A600
+ kseg0_boot_mem : ORIGIN = 0x9D006490, LENGTH = 0x970
+ exception_mem : ORIGIN = 0x9D005000, LENGTH = 0x1000
+ kseg1_boot_mem : ORIGIN = 0x9D006000, LENGTH = 0x490
+ debug_exec_mem : ORIGIN = 0xBFC02000, LENGTH = 0xFF0
+ config3 : ORIGIN = 0xBFC02FF0, LENGTH = 0x4
+ config2 : ORIGIN = 0xBFC02FF4, LENGTH = 0x4
+ config1 : ORIGIN = 0xBFC02FF8, LENGTH = 0x4
+ config0 : ORIGIN = 0xBFC02FFC, LENGTH = 0x4
+ kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x8000
+ sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000
+}
+SECTIONS
+{
+ .config_BFC02FF0 : {
+ KEEP(*(.config_BFC02FF0))
+ } > config3
+ .config_BFC02FF4 : {
+ KEEP(*(.config_BFC02FF4))
+ } > config2
+ .config_BFC02FF8 : {
+ KEEP(*(.config_BFC02FF8))
+ } > config1
+ .config_BFC02FFC : {
+ KEEP(*(.config_BFC02FFC))
+ } > config0
+}
\ No newline at end of file |