{\rtf1\ansi\ansicpg1251\uc1\deff37\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1026\deflangfe1026{\fonttbl{\f0\froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} {\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f36\froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times;}{\f37\froman\fcharset204\fprq2{\*\panose 00000000000000000000}Garamond;} {\f38\fmodern\fcharset204\fprq1{\*\panose 00000000000000000000}Lucida Console;}{\f39\fnil\fcharset2\fprq2{\*\panose 01010601010101010101}Monotype Sorts;}{\f42\froman\fcharset0\fprq2 Times New Roman;}{\f40\froman\fcharset238\fprq2 Times New Roman CE;} {\f43\froman\fcharset161\fprq2 Times New Roman Greek;}{\f44\froman\fcharset162\fprq2 Times New Roman Tur;}{\f45\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f46\froman\fcharset178\fprq2 Times New Roman (Arabic);} {\f47\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f48\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f402\froman\fcharset0\fprq2 Times;}{\f400\froman\fcharset238\fprq2 Times CE;}{\f403\froman\fcharset161\fprq2 Times Greek;} {\f404\froman\fcharset162\fprq2 Times Tur;}{\f405\froman\fcharset177\fprq2 Times (Hebrew);}{\f406\froman\fcharset178\fprq2 Times (Arabic);}{\f407\froman\fcharset186\fprq2 Times Baltic;}{\f408\froman\fcharset163\fprq2 Times (Vietnamese);} {\f412\froman\fcharset0\fprq2 Garamond;}{\f410\froman\fcharset238\fprq2 Garamond CE;}{\f413\froman\fcharset161\fprq2 Garamond Greek;}{\f414\froman\fcharset162\fprq2 Garamond Tur;}{\f417\froman\fcharset186\fprq2 Garamond Baltic;} {\f422\fmodern\fcharset0\fprq1 Lucida Console;}{\f420\fmodern\fcharset238\fprq1 Lucida Console CE;}{\f423\fmodern\fcharset161\fprq1 Lucida Console Greek;}{\f424\fmodern\fcharset162\fprq1 Lucida Console Tur;}}{\colortbl;\red0\green0\blue0; \red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128; \red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 \snext0 Normal,p;}{\s1\qc \li0\ri0\sb240\sa120\keep\keepn\widctlpar\hyphpar0\faauto\outlinelevel0\adjustright\rin0\lin0\itap0 \b\i\f37\fs28\uldb\lang1033\langfe1026\kerning28\cgrid\langnp1033\langfenp1026 \sbasedon2 \snext0 heading 1,h1;}{ \s2\qj \li0\ri0\sb240\sa120\keep\keepn\widctlpar\hyphpar0\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 \b\f37\fs24\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 \sbasedon0 \snext0 heading 2,h2;}{ \s3\qj \li0\ri0\sb240\sa60\keep\keepn\widctlpar\faauto\outlinelevel2\adjustright\rin0\lin0\itap0 \b\f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 \sbasedon0 \snext0 heading 3,h3;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\* \ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\s15\qj \fi-360\li360\ri0\sb120\sa120\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls3\pnrnot0\pndec }\faauto\ls3\adjustright\rin0\lin360\itap0 \i\f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 \sbasedon0 \snext0 \ssemihidden caption;}{\s16\qj \fi-360\li360\ri0\sb120\sa120\widctlpar{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf36\pnstart1\pnindent360\pnhang {\pntxtb ?}}\faauto\ls2047\ilvl10\adjustright\rin0\lin360\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 \sbasedon0 \snext16 \sautoupd List Bullet,ul;}{ \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 \sbasedon0 \snext17 preformatted,pre;}{ \s18\qj \li0\ri0\sb120\sa120\widctlpar\tqc\tx4320\tqr\tx8640\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 \sbasedon0 \snext18 header;}{\s19\qj \li0\ri0\sb120\sa120\widctlpar \tqc\tx4320\tqr\tx8640\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 \sbasedon0 \snext19 footer;}{\*\cs20 \additive \sbasedon10 page number;}{\s21\qj \fi-360\li360\ri576\sb120\sa120\widctlpar \jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\faauto\ls2\adjustright\rin576\lin360\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 \sbasedon0 \snext21 \sautoupd Example;}{\*\cs22 \additive \fs16 \sbasedon10 \ssemihidden annotation reference;}{\*\cs23 \additive \f38\fs16\lang1024\langfe1024\noproof \sbasedon10 code selection,cs;}{\*\cs24 \additive \cf12 \sbasedon10 highlighted code,hc;}{\*\cs25 \additive \i\cf6 \sbasedon10 Neologism,neo;}{\*\cs26 \additive \cf2 \sbasedon10 new code,nc;}{\s27\qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 \sbasedon0 \snext27 yh2;}}{\*\listtable{\list\listtemplateid-919991388\listsimple{\listlevel \levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \s16\fi-360\li360\jclisttab\tx360\lin360 }{\listname ;}\listid-119}{\list\listtemplateid-489381634 \listsimple{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\'01\u-4051 ?;}{\levelnumbers;}\f39\fbias0 \s21\fi-360\li360\jclisttab\tx360\lin360 }{\listname ;}\listid1282417044} {\list\listtemplateid-1882843058\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'09Figure \'00.;}{\levelnumbers\'08;}\s15\fi-360\li360\jclisttab\tx720\lin360 }{\listname ;}\listid1601571268}}{\*\listoverridetable{\listoverride\listid-119\listoverridecount0\ls1}{\listoverride\listid1282417044\listoverridecount0\ls2}{\listoverride\listid1601571268\listoverridecount0\ls3}}{\*\rsidtbl \rsid412021\rsid13379340} {\*\generator Microsoft Word 10.0.2627;}{\info{\title Refactoring, a simple example}{\author Martin Fowler}{\operator test}{\creatim\yr1997\mo10\dy12\hr15\min22}{\revtim\yr2002\mo11\dy9\hr14\min23}{\version3}{\edmins0}{\nofpages16}{\nofwords6439} {\nofchars36708}{\*\company }{\nofcharsws43061}{\vern16437}}\margl1417\margr1417\margt1417\margb1417 \widowctrl\ftnbj\aenddoc\hyphhotz425\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\formshade\horzdoc\dghspace120\dgvspace120 \dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\nolnhtadjtbl\rsidroot13379340 \fet0\sectd \linex0\headery708\footery708\colsx708\endnhere\sectdefaultcl\sftnbj {\footer \pard\plain \s19\qj \li0\ri0\sb120\sa120\widctlpar\tqc\tx4320\tqr\tx8640\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 \'a9 Martin Fowler }{\field{\*\fldinst {\insrsid412021 TIME \\@ "d-MMM-yy" } }{\fldrslt {\lang1024\langfe1024\noproof\insrsid412021 9-Nov-02}}}{\insrsid412021 \tab \tab Page }{\field{\*\fldinst {\cs20\insrsid412021 PAGE }}{\fldrslt {\cs20\lang1024\langfe1024\noproof\insrsid412021 1}}}{\insrsid412021 \par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}} {\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8 \pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \s1\qc \li0\ri0\sb240\sa120\keep\keepn\widctlpar\hyphpar0\faauto\outlinelevel0\adjustright\rin0\lin0\itap0 \b\i\f37\fs28\uldb\lang1033\langfe1026\kerning28\cgrid\langnp1033\langfenp1026 {\insrsid412021 Refactoring, a first example \par }\pard\plain \qc \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\i\insrsid412021 Martin Fowler\line fowler@acm.org \par }\pard \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 {\insrsid412021 Refactoring is a technique to improve the quality of existing code. It works by applying a series of small steps, each of which changes the internal structure of the code, while maintaining its external behavior. You begin with a program that runs correct ly, but is not well structured, refactoring improves its structure, making it easier to maintain and extend. \par Currently there is not much written on refactoring. I have been making a start at doing something about this with some presentations and other artic les. At some point these may evolve into a book. This document is work in progress, so please be lenient with its inevitable errors! \par When I describe refactoring to people, one of the most difficult things to get over is the rhythm of refactoring. This is t he way you do small step by small step, slowly improving code quality. So it seems that the best way to deal with this is to give an example. As soon as I do this, however, I run into a big problem. If I pick a large program, then describing it and how it is refactored is too complicated for any reader to work through. However if I pick a program that is small enough to be comprehensible, then refactoring does not look like it is worthwhile. \par Thus I\rquote m in the classic bind of anyone who wants to describe techniques that are useful for real world programs. Frankly it is not worth the effort to do the refactoring that I\rquote m going to show you on a small program like the one I\rquote m going to use. But if the code I\rquote m showing you is part of a larger system, then the refactoring soon becomes important. So I have to ask you to look at this and imagine in the context of a much larger system. \par }\pard\plain \s2\qj \li0\ri0\sb240\sa120\keep\keepn\widctlpar\hyphpar0\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 \b\f37\fs24\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 The Starting Point \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 The sample program is quite simple. It is a program to print out a statement of a customer \rquote s charges at a video store. There are several classes that represent various video elements. Here\rquote s a class diagram to show them. \par }{\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\object\objemb\objw8024\objh3704{\*\objclass }{\*\objdata 010500000200000010000000 566973696f2e44726177696e672e3400000000000000000000520000 d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffffdffffff04000000fefffffffefffffffeffffff060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e00 00001f0000002000000021000000220000002300000024000000250000002600000027000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff02000000111a020000000000c000000000000046000000000000000000000000c04c c8d0ea87c20103000000000200000000000001004f006c00650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 0000000000000000000000001400000000000000010043006f006d0070004f0062006a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120002010100000004000000ffffffff0000000000000000000000000000000000000000000000000000 0000000000000000000001000000690000000000000003004f0062006a0049006e0066006f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000201ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 000000000000000000000000030000000600000000000000feffffff02000000fefffffffefffffffeffffff0600000007000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000020800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100feff030a0000ffffffff111a020000000000c0000000000000461000 0000564953494f20342044726177696e670011000000564953494f20342e30205368617065730010000000566973696f2e44726177696e672e3400f439b271000000000000000000000000482100780114003100130100000800000314000003140000000300040000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000feff0000040002000000000000000000000000000000000000000000000008009802140098021400f4ed8f005200000000000000d04921000d00040000010a00feff000004000200000000000000000000000000000000000100 0000e0859ff2f94f6810ab9108002b27b3d9300000008000000006000000040000003800000006000000440000000500000050000000030000005c000000070000006800000002000000740000001e00000001000000000000001e00000001000000000000001e00000001000000000000001e0000000100000000000000 1e00000001000000000000001e00000001000000000000000000000000000000000000000000000056006900730069006f0044006f00630075006d0065006e00740000000000000000000000000000000000000000000000000000000000000000000000000000001c0002000300000005000000ffffffff000000000000 00000000000000000000000000000000000000000000000000000000000005000000b44500000000000056006900730069006f0049006e0066006f0072006d006100740069006f006e00000000000000000000000000000000000000000000000000000000000000000022000201ffffffff06000000ffffffff00000000 0000000000000000000000000000000000000000000000000000000000000000040000001c000000000000000500530075006d006d0061007200790049006e0066006f0072006d006100740069006f006e00000000000000000000000000000000000000000000000000000028000200ffffffffffffffffffffffff0000 0000000000000000000000000000000000000000000000000000000000000000000005000000b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000566973696f2028544d292044726177696e670d0a0000000000000400b445000000840100140052004ccdac00744400004001000000000000ed64eaf10318e9f2ffffff8300fff6f2fff3fbf00701 f8f1008980eaf116048016002000190080ff00c0c0c000e6e6e6ff00cdcdcd00b3b3b3ef009a9a9a2100800066ff6666004d4d4d00337f3333001a1a1a0000000000000004000000000000000400ff1800ffff00d29f007130dcff080fe1fa9f0019ebf0df015400000aebf064007f0020417269616c2900bd012d06e400 00223a0502fa2d021433031254696d65ff73204e657720526f576d616e2900172d02113303fe4f03204e6172726f77ea29001e2d0213330202024dff6f6e6f74797065203f536f727473003554ebf03fe8f3d03ff2ff0406daeaf120e8f359401a06000019012d00310f0000ff1a00ffff00d22c00b914dcffebf02c004a ebf0012f54040020e9f2ff1c0ae0fbf7040068ebf002540000ebcc02e8f3014a00000800bf0200620100fe4f0001f25304025301ebf0307b14aeff47e17a843f0001401ce6f5430101000e50006a065603c9005d0784000375065601046255025502059604069604079601a08001d2034f0a97084f0003960404045304bb 023fe6f50a1f1c16d2018401541c16a10101361a02361a03361708fa0dfaff8001004e0397039507970350f5079703bb0f9703089604099604550a96040b96040c96040d9604550e96040f9604109604119604a512960413761f8e1007500061ab00fe432001472302472303aa472304472305472306472307f04720d21f e4137f1e2600fdff48a623821b4f01609714c02402c024bd03c0213e02fdffba27a7ff009602a3005e0284ff004d02a400ec01a0ff0034018700c40086ff008a0085002100933e37000900a4026981003e017d70dffc10270030552e3283c53f8e10921fa41f96018400054521e8f3f09002c3028400072d36f7fe009437 0001006700896a50003e01a4e5f61c1fa936301d33bc32f3bf30b3362616301fd4421fa8050fa30021bc343f1382a10104c43660321647c002540095be87329c006b00033d021c5cb02dcc020900888732110d0056d2005402150c033f4003dffc85023906dccf364c0f5e0f70010000750c49358c13d6044c32a93fff4f 800570dd3fef3f5a1fb41b87005801309d4605360400c88d3014335040973f8c5fbb3fb056d703c30200364395470d00021100016d4f7f4e010039063a019e4fb04fc24fd44fe64d6a59850367504a3f40da5f7c1ffe5990fc0b6f1d6f001900321cc70d71d360ac3fd26fe4662e15e466542b52fe6a02fe6a03fe678707 34470200840d008830db5401e35f00956f3f007506d6063e3524659025d4087c636234753400c90005110097000096ebf0258100387106aa3f4007370008b77009c9700aaa42200bb6600c0d300dd9700eaadd700fe17010e57011830012aaed7013f17014634015f97016aafd7017f5f01805801909801aaa0d801b1180 1ccf601dedf01eaa1d801f454020258021298022aa2d8023150024073025398026ba3d80274d8028002953804a00c970427f547f667f787f8a7dd20daa79014a42205c8f6e8f808f928f8a7d88310ad60604c28d08d38fe58ff78f099f20897ed850d507b500c48b094b9f5d9fa06f9f819f897e7860d50703c28d0a80c3 9fd59fe79ff99f897ed280d5070702c28d0b3baf4daf5faf71af897eb8700ad50705c28d0cb3afc5afd7afe9af28897e5a80d50706c28d0d2bbf3dbf284fbf61bf897e0ed3090ec28dfcb0a0a5bfb7bfc9bfdbbf8b7c0fd3090f00c28d74c01dcf2fcfff583f008915d80f448f786a06017407e6431f6500053605026b50 4af17094cfa6cf40cf52cf0a8a7d11d30911c28d78d021df33df50b9cfcbcfddcf6d0402f7cf02b401020edd1297dfa9df43df55df897e3aa00ad5070ac28d1323ef35ef47ef59ef28897ea2b0d5070dc28d149befadefa0bfefd1ef897ec290d50709c28d158013ff25ff37ff49ff897e2ab0d5070c02c28d168bff9dff afffc1ff897e4a900ad50708c28d17030f150f270f390f28897eb2a09d770bc28d187b0f8d0fa09f0fb10f897e9ae09d7713c28d1980f30f051f171f291f897e8af09d771502c28d1a6b1f7d1f8f1fa11f897e7a000a9d7717c28d1be31ff51ffd5ac020fccbdfdddf00304f1be8b41f814e6b3f00f6cd1e51b426144036 10d75457201c5b2f6d2f7f2f00912fa32f3366be2fd0203365db2fed22c11df32f053f173f293f3b3fb81e1f85eb51b89e543fce22e53504733fed221e8b3f9d3faf3fc13fd33f10b52fc72fd92f1b441f234f354ffd5f28594f6b4f7d4603fbdf0228a1964faaa84b5c572020bb4003dd520304c54fd748034b4eb06120 2b3e352c63c8e46fbd5f9e7404bb6132775400c9692b50a6613cd9484261102797003272be52c1f560f96107d00b66be61ba6275d0942b923100296ab860a66150d9463f426f8e553b30336662f3bf305d668e5b5506cb62952b92475720215b5f806d5f7f5f915fa35fbe5ffa6e2a540404a671e4596af154406f3d7f64 6f7667122b5306dd328c65693964f85f0a6a08f945176b2d684a3980986faa6fbc6f00ce6fe06ffb6f047f167fec5f967fa87f80ba7f346f437f4c7f5e7f7c6f8e652300d37fe57ff77f098f1b8f368fc75fd95f04638ff382027b8f8d840fe0176b749040a88fc38fcc8fde8ff08f8a69240f9f00219f339f459f579f72 9f3f8f518f9f9f00b19fc39fd59fe79f02af0baf1daf2faf028d66254baf5daf6faf81af93afaeaf00b7afc9af277f3ebf47bf59bf6f7f817f50ebaffdaf0fbfc97626bb4002bf42210291b62ab089c4d84702bfdffcc000f84b2e252a634c3f88c32c542a6214e90ae0a548d94617f242086fbf428dc0a33740d4b6978c 20b33f5720279687bfff26c1c0269fbfe5442c10b9bfcbbf8dc05021014d504cdf5ed0008dcf73db176edc3398d528bf37cf40cf8852cf64cf926128c3cf99bfe7ca9400f5cf07df794f2bdb6ac2365bf2bf49ff2b0102f74205a3c187dda04c5517030084dfa634d34c1ce14af351bc13669cf5a48729572029bb4f09ff d34cdd4c5ce9effbef19dfa9b49507a0e50727220432513ed94e0100ff9c01000048502044ff65736b4a65742038f7373043dcff04370394ff00060103ff800701e900eff0ebf0641f0001002c03010229022003390f4b0fdefd200181036b043409f2ff970fa90fe4f74c07505431b40fdb0fed0fff0f111ff8231f5e0f e6f5e40cf60901870004002e015b1f6d1fe6f52c03012c5a10fd38ebf0080011002100ff010057494e53504fff4f4c004850204465ff736b4a6574203837ff3043004c5054313a00dcffff4600ffff00d60300c520ebf002eff0fcf3dcff0000f7030068ebf001540000ede8e7f44904e9f2f03f49aee8f3e83f3fe8f3c0 3b06bffc33043106f03f0400041028060f750feaf101eaf10ef9f02a0625fe91000133069e01023c069e01fd034506fe0800020662bb0400c801076200cf02085ecd04096210009e01044e067a9e0105ed07009200048b00a7df00658b001e0114e7f405eb0047e9f28307120a00c914f9f01e012a8902251d103f1f511f eb0201eaf120f3f00000f4fee9f2ff00010090888fdfff82f88e77080b0170ff8c000407f8f8708cfd771e02857701708677fd0b1f017000700007703a290005310284008229001e09ba1c0b862b0085770a310500bf77837083770d310300050772007076004a0a500f21013002ff7777000777700785fb7706ad038300 0b70079639007777910a031f000a0d8e7f8801f88fff01f80000b562e9f204e9f2e0bfe8f3d8f53ff4f43ffcf4bfa8703dff0ad7a3e0bf48e17adf14ae47d93f14043f4c561d03bf02e9f2f0fbf4ecfbf40bc0bc44043fff4700ffff00d60400d520ebf004ebf0fffef22600dc0401e0fb040068ebf00154af00007401e8 f340faf1006f00e03f40e8f3d83f2a0425f03205e83b05310850e3f82300570e00022907fe6f00013306d27c01023c067c01034506fe46af000302066b0001aa03009907ac02b7020008ac02c30200bd05ac0104050003b6000568ebf0d901b5010570000700a700a903ab02f00301b70203b702012ac30203c30201cf02 05d5021410f0dd0014121f11e90001120002cf04750260f6f12e0205fe4e331005750339196f00066006bffe0800020762621308f26914096911ddfe840057017d9bf9f00200660165ac01ba1f002ce7f4060048e9f20772ab1408edf0eaf1830012c110750ac11004d6001a0071d600da1e01f8e7f440102c0be83fad01 c310020037110c3c1901f24917f04210e2170b59c842cf16b290bff41f0627642186242196bf1820e6f533062c27f806fef2df3c062d411133044306622ff9ef052e41119900ac0099ab0074c5203cc52004f9f0e40100ff4800ffff00d606009d22ebf0110005eff0fef126ef00260027e1fa010006fa15006813015400 00140276e8f34004e9f2e03f40e8f3bdd83405f03f4001e9f2d0b8340533004803c03f500b0a00ff1400020274026005f70020f8fef2ef3f05fe6e710003740377015755900145d5820300750351058302018903dea30752000302180101045506fbf007170000ce0201ce025502ce0203ce0204ce0206ce025507ce0208 ce0209ce020ace02fd0bce001200020475025560b60b03c50205cb0201d102003410d9003410df003410e5003410eb00003410f1003410f7003410fd0034100310d03410091034100f100113100575bd0319190e0002066206fe5f08000207629413089b14f1099b11090c971002804c40deae10321cc771c910ac3ff8c8 1fda16c70000fefffdffe9fef3100a0b21ae00601928ff4329205368617065ff7761726520436f72ff706f726174696f6efead10a300c80187009ebf01840087019bea0004ef00ff016cc601550000e95848031401079a006100fe0a4f2001532302532035042a000e077a1310001717000005fe131049017b1786210ae4 00cb010a081009033410a220013e076e2f3f05882f010563254508c22fd42d0a316427f22f68802f163f6c290b9a0072010810cb00fe6c30017031ee1000007f8b0010018b00d88330fda0833068008a001c007d89ea0006003a01699a003a200108e5f604006ae400a43d0971ea002001d825055106ba2fa30704d62fe8 2dc0f92ffb3ea901500d303f00fa3f1c3f1e4f403f424f8c4f664fb046427b03df4f079247f145fc37fefef3027d41fc7c04350692472955fc37fef331f7553f375ae8f3c0bc4c5f0e4035f0fef2cff84f60209955145f122656e7a05f4255e7bb5fcd5afef353cfbfe25ffc37fd7c03bf9659f8126fb45f366799006c02 99fb00347b60fc019900c4aa83608c83605483601c8360e4af009900ac97607497603cfe976004000c00a4020ef4fbf0200117e3f861747472ff69627574653a547907706500ff4800ffff00d606009d22ebf0110005eff0fef126ef00260027e1fa010006fa1500681301540000c001f6e8f34004e9f2e03f40f86efef2 bf3f40e8f3f03f2c0471d03d0533002d03c03f500b0aff0014000202740260f70500203603ef3f05fe6e710003740377015b55900145d5820300750351058302018903f5509002c58200280003025d071500010407ebf007ce005501ce0202ce0203ce0204ce007f12000204750260a2082ac10003c50205cb0201d1020a 10a0d9000a10df000a10e50001e900057b7503ef090e0002066206bffe0800020762401308e24714094711090c431002804cbd405a10321cc7717510acf13f741f8616c70000fefffdd3fffe9f100a0b21ae006019ff2843292053686170ff657761726520436fff72706f726174696ffd6e5910a300740187007f4a0184 0033019be400df0400ab016cc6015500f300582504d2020200610015fed70001ff1302ff103e042a00f40e07e90000ed07000005fed2e90001271732210ade020500250a4f20030a104e20013e071a2f043f05342f050f2545086e2f802db621a010279e2f2c2fc22f18290b9a00722d014f2000fe1830011c319a10ff00 008b0010018b00f5d82f30a02f3068008a00f71c0089e40006003a01e9699a00200108e5f604006a24de00503d71e4002001342505510610662fa307822f942dc0a52fa73ea90100500ddc2fa63fc82fca3fec2fee3f384ffc124fa5059900e400990055ac9f40749f403c9f4004fbf0a71c010efbf0200114e3f86f3b70 65cb13282900ff4700ffff00d603001d20ebf0020005eff0fef1dcffdf0000030068ebf001546f00001801e8f34004e9f2b7e03f40e8f3e43f2a04f0173f4002e9f2d03b0531004603e7c03f50e3f823001400029f0274026005f5f2400205ddfe6f0003740375015855aa8e01d58003007309e0800301d68703abaab601 ea80001600d70302096b0001c20300084ac40104bf0003c302d80301cf02ff0512000204750260dca008eb00057503f1090e00fb02066006fe08000207d5621a13082114092111009b3b00046b000f0165c4011f005d14e7f4090048e9f2833712a70a00c9f9f01e0106690226004d10ff4800ffff00d605009d22ebf00b 0008eff0fef126b9000401e2f9010005150068be1301540000c401e8f340bd04e9f2e03f4002e9f2c0953f2c04f03405d03d05330850fe0b0a00140002027402ef60080020e8f3f03f055dfe7100037403770e007509e5e08203018909a901400003bb02091500010409ebf007a900c501cf0102ce0203ce0204aace0205 ce0206ce0207ce0208fece00120002047502602ab60b03c50205cb0201d102221000d9002210df002210e5002210eb002210a0f1002210f7002210fd00010110057b750307190e0002066206bffe0800020762701308e27714097711090c731002804c7d408a10fefffdfffea710fa0a0b21ae006019284329ff20536861 70657761ff726520436f72706fbf726174696f6e8910a3ff007a01840063019bbee4000300b3016cc60155e70000582504d202020061ab00feff1001032302032040d4e6f5142601001100051700004b05fe011001571736210ade006ae9010a5320033a120a013e07001e2f7b073a2f3e0f722f842d81011427d0a22f30 2fc62f1c290b9a00720156532000fe1c300120310189117f8b0010018b00d83330fda0333068008a001c007d89e40006003a01699a003a200108e5f6040071de002001f92436031c2740284992244f4992c4bfe22f8427257f32d3e4bfce264500948130244995c28538f8fef2ef8328803124a349e2a9373300b633e2bd 3edf06cf3e02c0ce29b63f903fda382d06106a2fa307862f982dc0a92f774ebd02002d0ce02f764fcc2f9a4ff02fbe4f085f74e24fa50599230099008c6f50f5546f501c6f50e400990055ac7f50747f503c7f5004d000a7fc010ee400200113e3f843ff6c617373204e616d0365007dd8ebf01e00270002e9f2ff8e0194 000900ffffe2e4f7010d00f6f3defd0a0046ff00c6004c2faa0074ef090000b2ebf0230042ff00b457ab00260a00fb0096250240002c07aaab00bc4300014704344f00bdaa53042b3b00f44f00be43003dfaebf0472b002c17aa00fbea43007a5600482b00b40aaa3f00750c0000e3f6f08a01ff4c16aa00580f0000f936 f6f07a017c3aaa008ecf110000e8ebf08a0114147faa0076120000751200030024000000280003002a000600f530e9f203ebf0012a5c8fffc2f528164050b81edf85eb510440ebf0240077250026e9f20b002015003f180002002200f52ce9f201f1f12a5c8fc2fff528164050b81e85afeb510440ebf028e9f20bfb001c 1100180002001e0100fd2ce5f6012a5c8fc2f5ff28164050b81e85eb77510440e5f60b001a11003f180002001e00fd2ce7f40100012a5c8fffc2f528164050b81edf85eb510440e7f41e00f70b001a110018000200032000f530e9f202ebf0012a5c8fffc2f528164050b81edf85eb510440ebf02a005d2be7f40b001e15 0018f3f0032200fd7ce1fa070040004200ff7cc6a900a41500005130dcffddfefef1b40300d407007d2b2b04e438aa00ff0700fd252b047c3daa002416f700002a2b04743faa00054e57002d1c00ff4600ffff00d602008520ebf002eff0fcf3dcfff8f168beebf001540000e8e7f441b6e8f308402a0dc03f3c05bfed49 e8f3f03f4e0604000858f6f1660f780f0001eaf10ef9f02a2a06fe910001950a023c069e01fd034506fe0800020662bb0400c801076200cf02087b6208cf02096220009e01e9044e069e0105ed070092009d048b00df00658b001e0114aee7f4050048e9f28307120a0100eb7b01eaf120f3f000006dfeeff2ff00010090 338fffff82f38ebb82f383ffbb01b88378017b86ea0b03b70e008b160182bb06dfb3383333bb150282bbdf83000303bb210208bbdfb30fffff032d0306bbfd8742000787870b8bf3dff3bb7b0ff9440185bbfb0b7b57008b0099900bf3bb8b61005602bbb93bbb5e5f07bb000bbb6d08b07903fd078003b08333018383ef 3382bb078e0486000831037a0065016f01bbbbb6005602f06101c202b90fcb0f8bbb3393fb333be306b00999003b7ed5040a8bb0ff9ff0fe02ff87780870fffff078ee640087bb091510fff03bfdbb2811027bb08300826e0b0087bb04dd008b833e133acf007b481383870147120a01ff8e3301f38fff01f3fd6eebf043 6f6e6e6563ff746f722077697468ff20757020746f2035ff206c6567732e20558f73652063f3f60400130420ff73686170657320627f7920706f696e740301f632022c20f9f064796e61ff6d696320676c7565ff206d6574686f6473032e005602006d62e3f8d8bfe8f3e03ff4f4fe0304e0bf6ea0d3063aff6dd8bf38d0 69039d6f36e03f6c15033f371d0310fbf40a060305fbf5bfff4800ffff00d60500d522ebf004ebf0fffef228005c0401e2f90100051500681301d554ebf005e8f340e8f3f63f5a2c04f83405e8bf2c04f04605ddd84605e0bf500b0a000cff000202750c60750aff6004fe0f00020375ff0d60750b60048041bf40fe0e00 02066206fecf110002007800750003e42f6202000699010184008100fea40412000204750260ed205a043f05bb01057503fec2090b000207620000f48801e00008e40408000209bee400fe2e000302180101950425010907100c15020a1005261801090108121f10021d10fe000103021219100a161f1319131313170034 28102907fc34050040470534058ff03f01008c005b178b0101a465168b01026e168b0103a2173ad3000317021603010110000001062f10cc10c91307104a135611ca1282351300ba100113c31fd51fe71a340300031f1004103123092309261c13042811e818012e202f13372f492f5b24bf000008020302640a07967e00 6101f50108a600f503037ab6220ab4214000030b042f20162b802f50132211c8200ccc2fde2ff0f02f90250c09f60002804c4043fe102f22101001101010032a067a570841c405419ff4498c306bcf3f8234d08a35bf3f620cfd1972014c6081012d40ae82368102098a0203b930757f1f60802e40fe449b00b572ea11c0 e03104c0bc200b9ce400e63404000bc00ae030095f00c08016401040724a11840f41db3101e03dd20af337f0330951010f485242bb031fc20e20c209308c0b5e3067340e12040a2d121010e01801110447374731f600016201eab62208cc440acc41321cc7cd71e140ac3fe04ff2460102ff01008700b804a000ff88049c 0046038400ff2003a4006e029d00f732019bf9f00700e0043d6c031155000020faf11301e501a82100ad20a92001610002415102465082342a06140182115056268f1a00fea64053120a875030213a865001505de0bf016750de330eea3002000b0a43f337e033c0004f620a0006164616400a0e45284f502243ea3001b4 5301e538c6544103ce565242dc5152457f540387563830606e00703f0100a8a957f4534ce3330d410f40c0006e60090a43e781015b70617e610b8102831d400a43cc51a7001349e03c091f81021e40728651fc59561122b15106c16fd158ef66fe5460ec5550b353656452406f60037366017d630503846b010c62986718 63a86fba6200fb56c3512811d069707b5b45f267805321048756aa709315476a4b556ef73300b7623061e532e436fa33e8731341cc6200e254cc70ff6cea33e475fb53284c3383040784216c05875668803d674506a45c00d77f2b47cd504c10cf5171611440aa71001b42e958228ff4370e60b6851a70c183245e43768f f0a550f60000c000f501fd01d200fe8b00da038bbb0042379084028b91508bff0060008a001c00894e2152000470bb102001b06d30f828085708649f01030100fda5ff6e0020bd00e03102e5320338ed74c00019716540fe91904042ac999f1a706740415106ad203bc09b00f034b99c9f024981174275666f60756760e4 016940e4010b6440d79101dc9fc951b002fe71a45b4200a76b0ba5e000020a42003adf01034e4200fe1cbb120a1000673383542e6364a01f139f438d543863fd14ec00600c41726d20ff506f736974696f6e18c621669f520d05058a949ca094921e9f95806640fe9ca04042e5a64568cf962fd99ff19600a76a0ba5100c b016ad2ca600a76c46aa4a1157a40e1c1100fe28bb146ca1e4154c110070ad80b0312288a152251e118caf9eaf822c04e246054506ebb8d4afe6a57416efaf8075cf96350dbff19f03a441760ba540c03ebf2eaf05a27746aa38561258a3281100fe1681546ca1003061a873c0c025132f103a61b273d0bff700feaa3d90 aa0050017daaf9f00300a00364f9f0c22001109b2459565956c304104022c304146d17c3047e111f72019f00f8b000760082006660806e40ae03a30503fe58d0035cda674f60806f4000a071d329929c5380788cd178000303a003a103c272d226b29c53c489c301a2806d1f40fe64000335131913152300191028100710 28103516501578a5a873000e18c3bab2733c13c8200d16c0b618ec00688131ef7083c820173f293ffb2a07e80305582d128fefa1efb3efebdffdd73aebf09e11d10005027d98ebf05a00270002e9f2b7d65882ebf0ffffe2f901f7000522dcff00000600ff4600c6009c38aa00dfc21600009bebf02300ff4200bc58ab00 5d17cf00000a0144003b00a41a7faa006718000066ebf0ff0a004000fc12aa00d9cd53004700002b3b00842057aa00ce530034ebf0482b01ff14aa00021900001407060000ff4600ffff00d602008520ebf002eff0fcf3dcfff8f168beebf001540000e8e7f449ff80dbb66ddbb6cd3f774960553501c53f3fe8f36dc03b 06bf49e8f3f03f4e068f04000410060f750feaf10152eaf10ef9f02a06fe9100013306d29e01023c069e01034506fe08bf000206620400c80107eb6200cf0208cd04096210a5009e01044e069e0105ed0700779200048b00df00658b00ba1e0114e7f4050048e9f2830607120a0075bce9f220f3f00000aee9f2ffff0001 0090888fffcf82f88e77080f1a0f82f81f86770170872f0f410f530f2e5d028577825d05005e091e0ffe94088801f88fff01f80000fd62e9f280dbb66ddbb66fbdbf6055fdf1b53ff4f4fd3ffcf4bf4f30d1dfc9ff6ac1bfb81e85eb516fb8be3f5015033fb71d037bbf70f5f2e3bfb0aa3d01ffe2bf20499224499237d8 3fa03d02da3fff4800ffff00d60400d522ebf002ebf0fffef201005d01dffc0100040500681301ef5400000406044080dbffb66ddbb6bd3f4080e5553701b534002e02cd3f40c5603702c53d0533004803b53f4d500b0a000ef9f02c06fe7100490135067e01023e067e01034706bffe0a00030205050001ff0412000204 7502605d20e8f3e03f05a80103ad029d05b300057503b9097100067e6206fe0800020762ec03c508f30409f301090cef000280fb4c4006108400df009bbe17000200f6006cae0155770000500605010007f9f0576100fe3f100143130243105940e6f554160100b30000b7072f000005feb30001d3077611083e075e1fe8 f3f0c2007a1f3e0f9e1f00b01de6115417ce1f701ff21f5c1f162ffe4e298b00fc008b00c4fa6f208c6f2054008a001cfb00891700060034010e6b00031f020ae3f831007d98ebf09600270002e9f2ff9b7e59000300ffffe2e4f7010d00f6f3defd060046ff00c600ec40aa0095ef1f0000a7ebf0230042ff003c5aab00 3c2000fb0043ebf00a004000acaa2f007f4300014704b42f0080fa53042b3b001445aa0081ea43004febf0482b00d455aa0b00d043003a5600ff4600ffff00d602008520ebf002eff0fcf3dcfff8f168beebf001540000e8e7f449ff204992244992cc3fff49e0b66ddbb66dcb6b3f3fe8f3c03b06bf49e8f37bf03f4e06 04000410060f94750feaf101eaf10ef9f02a06fe9291000133069e01023c069e0103fe4506fe0800020662045d00c801076200cf0208cd042f096210009e01044e069e01bd05ed07009200048b00dfd300658b001e0114e7f405003548e9f28307120a0075e0e9f220f3f00000d2e9f2ffff00010090888fffcf82f88e77 080f1a0f82f8bf8677027007862f0984af77067007470184410400f77007004c0285778200870270005e00310f5d09510377e05803440a690f1e0fb8048801f80f8fff01f80000fd62e9f2304992244992ffbcbfe0b66ddbb66debbb3ff4f43ffcf4bf27e7ff3ebb80d8c0bfff9dbfac963746c03f14043fd61c04bf20f5 f2e3fbf4e3bfbdc0fef1dbd83f40f6f12403d93fff4800ffff00d60500d522ebf004ebf0fffef201005d01dffc0100050500681301f954f8f006044000499224ff4992bc3f4000b76d7fdbb66dbb3f40302e025fcc3f40e0b63801cb3d05dc33004803bb3f500b0a000e2b00022b07fe71000135067e01e9023e067e0103 4706fe0a00fb030218010104120002df0475026020e8f3e03fd505a80103ad0205b3000575e903b9097100066206fe080057020762ec0308f30409f301bc090cef0002804c40061084ef00df009bf9f00200f67b006cae015500005006057701000772006100fe3f109501431302431040e6f5541601f500b30000b70700 0005fe82b30001d30776113e075e1fe8f3f000c2007a1f3e0f9e1fb01de6115417ce1fe0701ff21f5c1f162f4e298b00fcaf008b00c46f208c6f2054bf008a001c0089f9f006bf0034016900031f0234fae5f61ee9f21027003055a2a422c5d5107002ba043e1c10233b0094f9f00100297000c2201a21000ae3f85b007d 98ebf01e00760002e9f37f9959000600ffffe4f7f1010d00f6f3defd06004600ffc600dc3daa007d22f70000a9ebf023004200ffdc5dab0026230000fd5febf00a004000fc22d7aa00854300014704042357aa008653042b3b000c5f00d58743004bebf0482b002c2717aa00d24300655600ff4600ffff00d60300c520eb f002eff0fcf3dcff0000f7030068ebf001540000b5e8e7f449e8f3d03f2a063faae8f3c03b06bf2a04f03205f01f3f04000410060f750feaf1a501eaf10ef9f02a06fe910001d2950a023c069e01034506fe08bf000206620400c80107eb6200cf0208cd04096210a5009e01044e069e0105ed0700779200048b00df0065 8b00ba1e0114e7f4050048e9f2834e07120a00c9f9f01e012a8902012b1d103f1f511feb1801eaf120f3f000000afeeff2ff00010090888fdfff82f88e77080b0277ff708a00070777f8f8ff7777078877087077aa210d70270007360605400283ff7701078677017083540b00500c70540007580184510019856d087400 708471038700860aa6830082f878039e05042a00707d85ad0b8677030777770092c40b826b00d807875102080f8e7f8801f88fff01f80000bd62e3f8c0bf5655fdf1c5f53ff4f43ffdf255b5bff2ff342b6d0309c5bfe6ff174b7eb1e4c73ff0fe15033f74da40a70d747bbabfe8f3e4bfa8aa3d01dde23304d83fb03d02 da3fff4800ffff00d60400d522ebf004ebf0fffef22600740401e2f901f9f002006813015f5400009002e8f340e8f3dfc03f4040553701b53f422c04d03d0e330037023b00500b0a53000e19002c06fe7100013506d27e01023e067e010391073400f7030205150001040500510c1500b302ac0207b80002c202d503c202 04c20200c2001200bf020475026020e8f3e0ab3f05a80103ad0205b3020104b302f20207fe00c700fe00cd00fe00e8d300fe00d90001dd000575034b60205a03d5ec007100066206bffe0800020762401308e24714094711090c431002804c21405a10500f3e075a03c54f0f610d92dd0000e10bdd0001271bdd0002aae1 07f0c813032717e5ec000a14aa02b50004dd021fe3090120f2000ab50005231220e309351bdffc6e00fc532443100e620100fefe4ffffdfffe6b200a0b218000ff6019284329205368ff6170657761726520ff436f72706f726174f7696f6e5910a3004002ffa0001f029c004a01df840033019bf9f00500f777026c1900 01550000a91056231401071900615911407f30b91aa2d33cd13d05081401b915d523f1c818e6f5ff12d002350a13300316120a012c073f05f8e627c11fe517401593ab21af3acd93bfdd2f205933b3b1bff82f5630d52f000b1900722d01133000fea43001a83165205f00008b00ccbb3094bb30d75c008a700089b122f6 000971cc00200134c124203de4293c3f26e8f3d53c56302d06533704f63f00c91726433111a114db2fe200a213f62f248c32a21395603f2915b57b3f8d31f8213f2f4f453ffe9900e400579900acff4074ff403cff4006b2211c017d98ebf05a00760002e9f2ff37277a000700ffffe2e4f7010d00f6f3defd060046ff00 c600ac4faa00aaef250000adebf0230042ff00c45eab00572600fb0091ebf00a00400074af23aa00e843000147047cea4f00e953042b3b0134aa00d5ea430048ebf0482b00bc2e7faa0032270000511200f9cadcffe1fa05000a001eff005300640baa00ebef140000abebf0c90040ff00ecbfa900961500fb000eebf03f 0052003cffbba9007b16000047fcebf012013413aa00161ff700007f3f045444aa00df0a220000733f041c2befaa0037255c082eaa001f8329000074fcff900fddfe370300040d000600000000000000000000000000ff1500ffff00d34100f144ebf0f0f0fcff00f0bfccee12012c0640e9f240f43fdcfeffe6f5410046 ebf0015417030020ebf002eff04c032a0fdf000003006847015400f700bc01e8f3492a5c8fffc2f52816404950b87f1e85eb51044041e8f35bc03f8c05bf490a043f9e06287304b60fc80f0073020e49007a069dfee1000149528504ee0102f48c06ee01039506fe080002ef066201001811076200a500ee01049e06ee01 052d1700c3101019031c01491fe6f50404705a1f771f730019100062101f1201019911fd0180160a12a91a6d17361244a9171912041f14e210e10008a91ad509a91a0aa91a0ba91700b7bf00cf009200044900af530165db006e01c8d50647e9f2dd0643220a000b43220400571000484d22115b22126720ee44211a0017 5b222200182e5b222a00195b22326f205c21773a001b5b2242001c5b22974a001d43225277205c215abb00235b226200245b226a2f0083007ac12072c120c0215562c1205ac12052c1204ac1205542c1203ac12032c1202ac1205522c1201ac12012c1200ac1208e58218200c949006e013e010daeb92001002c49202d51 20284a59202e67202f71208021306f205531912032992033a1203eb120493fb920defd47db00420504d90451054b045a0f6c03f07915297c023b064094340140406431a301d68014e83fa634e0ae35d83f0150d10be1019436ee029d36a413a735feb219e83ffe280003023102593149005a300203164221425302041642 2d4202114003154255011542032142012142032d42f5012d4203ca0f008400d15b009b2b22e20032252ce7f491025b2266019243044324f629030a6f2028073436d905e1faa735b035564c05ffff1941032b20055b20141540430022ebf011164248216e3f0425436a05b87915b93e8014ad30730351d0ae35bf307303c0 c93d14fe007f740260010020f84c02efef3f05fe7d5003740356835157559c51d58e53008153845d558f52019553af57cd0f734099ee7744aa006c33215500000988d408801f01ff55ad36106b54557012661d00326f88198b00586360f54463603063601c008a00170700892b2006eb50e1016e01fd15e3f86e616d653a 203f537472696e675b20214042ff4c070f5f215f335c8753bf495840a7335a59a7336c5f7e5f90585b9c5f14ae5f2b70504372c5ca5fdc5fee5f00506f126fb77bfb653a69d97f586f6a6f427c69094c3b2d404306085308b66f92650ac4315fe9f2e4b735ad3002805555b9369483137f25769f058f595858437f557f2b 70abaa0491ea8e50a51012400516421192020d9003ba11920111920300b37742010b00b97f4614e7f4f841a4432d41150a053606d90226f7421190ff44010b32422d81528fc96f748ba6858a8f08a89fae8f277104c58ff39ee881f49600b5581caa747f867f987faa7fa73c80ab80c4953a69a2afff7f118f7c6fe8f344 ff6f6d61696e4f626a976563744320064100f49305d047226a3fd0456a0518730440a8df703d0ad7a3bf304ce11f7a14ae47d9b998b03fc23f40d4374eb5e63357b5f43f064c07164266ceb202081642dab202091642a8e6b23842ceb201ceb203dab2018adab203e6b201e6b2604f39411a6c32422fc2011a05510b2332 416d0241c2032305510c047348a90a312688450791440891440940a14fb34e6091c84fda4f4c0106e5a09d082e800a007167006e01a80a79151073bbe821000d9034c334c4f00d903ac031c7ebc70b59c8422f16b290bf6eafd82100bb7de043d1ffc141c90fd141c9990060aa51a04c51a03851a0042b2094085b20ceb0 ff46065f920e5f909f728f10445f565fd89f2177062c7f18e19b5e0019e0ef8e41ea3daf4faf61af73afbc7f40276f396fbbafcdafdfaf073417e3f8ff7072696365436f640e9760696e745b20dab094dcb56f00b5dfd96feb6ffd6ffddf0fef21ec427e0041ef2be26a7f6aef7cef8eefb4ef470f00d67fe87fe8effaef 1e8f4c3be6b04186009dd3508f628fc9df868fc89fa8ffbaf840c78ec2f0db8eeaff2be2039b0a164288a8121c92a81201a8122c9f3e970a20499f5b9adf11a8106f96095f927e9f405effa29fb49f2d1f3f1f2177095c1f008a2ee8818b26b558b32a0b0f1d0f2f0f00410f85af97afa9af890f9b0fad0f9ac47d0e30b8 4d6f76696582c0a50b14ba0b22bf34be2846b5297f5c8fc2f5280c4056bf8068bf7abf8cb8de359fbfb1bfc3b80ccc49825e42020d49826a42020e5049827642f1b25e42015e42036a4295016a4203764201764219cf3a421e90107792bf420ed03dc11742c296d14203174ec21b7792e34201a91b3cc255c71c60ce0ce0 140d02e0140e82cf94ceb131a9cfbbcfcac1550b63400d91b00fdac6c8e4cf00f6cae3490fd1e3491fdf053f57d5bf4b01030ed0c14747df59d3d1490fd1d149179900807edcb437f05e40a666010bb032a3df272f091fd9dfebdf6f2f0221770bc3ffd86130eed960ef8e017a00d42fe62ff82f0a3f530fbcefceef523f e8643f763f9ac418c0386461797f7352656e74656432f5006a40546c4cff756f70ff82ff94ffbd6f00cf6fe16cd9fe017feb62010f2a7f3c7f004e7f747f089f6d0f7f0fa87fba7fb50f00c70b7640d8065d63e70ff90f896f1d1f005f2f698f7b885e1e8380721eab8f9582429a1b0fa91269a2b31269a20169a204c31f d5170fe01ff21aa0a169a00626010eb032152f1f8f392f4b2fee9f00af02b8f70e1daf4bbeaf214cb64ae874ba00cc8fde8ff08f029f1c3f2e3f403f4a9fc85c9f6e9f9ac40fc038ed71616c8a37f010d600053ff2a5c1ffc10553002978c2deab05eda898d6356528df3206e5384183dfbf18c7224183cfbbc7134c9ec7 08e538de337904e537b7510200700bafb0f90727f014d20100800b402f7a3340fe0fd00113df25d58702701da05033d14ad221d9037849df25d2a690020302021cb37ea1b30d00020b744e8280af7a7340fe8ed00c92d01dc496d297bc1cbc4e3161bf4203ffd7cf40f0c7cd41b265419956f1d2c93fe7d4d0efd5b935ba fec5339c00360184000bff01a400de009d00495eabb205007d01b4b5a023c500d630e7d4069bd6de5bef6def7fefe8b624b4ce2ac16c2bcf3dc4073c603955412e70c2eeeffb32d0504542bf6757171000647c54444bed2bf64eb44300404eb4f0c03efc5d519e89a2273c0070adb18050a48455d6de0a7bff0545e0fedd a4c5cde090acfe6b0505a1f8d0c7cbd43fdbff2ecff9aa0061b1b031b1b033512191a1a0cd4006241cb1112ee2d8affceaab3de5409e4a43ce7dff76f23f40561be8b4ff814ee33f4080dbb67f6ddbb6cd3f4060c3840a6b04bd7305b5124f24405a052f438063053d436c054b43750594bfa6b18102abb492b3bfc5bf0e 936c06131f7307408f793b1f20cfcbef8331e1e911465ea86c057505675711225012a43a1244b23fc43e18d635ea30e83014e53f80f73f094f1b4900252f4f414f534813cc6aa2802202146aa28c220215506aa298228142802201802203922215019222039822019822a94f824190d1421e632e60cd411c89a2f32201a5 1ccc4204a7b0f7450a005e130aa1a414a1a415225f345ed311495f545b5f6b51128520149d20167a5601a8845f965af329af51f329bf5f071f20176ae6242b66e624076f00a9b03d6d1194a1a08020fe7612d212636fe8af20ca9f996fab6f30bf798712848fca4100f06ecb4047aef34ad60fa7bffa0f0c1f80149f7c7f 8e7f13cf661f37cf809f0000a1a09220464c0d8f674f318f438f558f00af4fc14fd34c9a8ef34fdd42c28f1c5f002e5f405f665feb6f2e9f409f9a5fac5ff8be5e98a5e91173746174650d6dee7028293430982099964f4300a89fba9f7b4fde9f20bf4c6f5e681fae20666033ae8e6fdd425bab166aa257824474a25782 01578284af96a716a1af10b3aa8e815780c7a615d212d6af026f20faaf0cbfdc7fee7f12a7150b8f399e0040a13a964da8629aaf6fc16fd36fe56f00ddbfefbf01cf2d7f3f7f517f63749519ff437573746f6d65720a8f801766ca1774cf86cf98c7002301110728a444bbc8fad4cdcfdfc800232912072800231003de12 30d404b20821db04bf41d60b66d43ab257db3abf0477df89d91296d995d3a8dfe02cc9d10e13420300d0b5afe7dff9df0bef001def2fef41ef007ebca84bcf5dcf6fcf20027caaa8bfefd1ef8b1717f3ef00ff027c34171aff2cff3eff50ff62ffaeaf4064df98ff7cdece709cdecffae0ddfe48ccdeffff1109181e0665 2118d610f8d71f410f87f564b5bc31a2fef2a08627abe58d11e2ff3f4030499224499259ccdcd06e016dcb5ae5bc63e501bb342f46204ae5512353e55f235ce5006d2365e5829fe70fa69f3bcf5be703ff4063e781592bff0eafbbcf851d18583e285ce565e5b717188f8019c6125ba182cf1119a5801fef59f19c91de85 ecfe96352d5c8fc2f52806ff4040a70d74da40a701f9acd6020efe80a6628c0f4422f2f5805123fbf55f23eab56d295d00c6ee4cc2a5201ab8b28302820001300c1b4cb8b29502031b9002f32202f322cd03ff220c24b8b2b90203248890020531dbe5de8810153391111910e3cf9c44eab5b71719e4e06470eae0fd70ee e930b91aa2d33ce1d1fe6ffd81eab5dc901593ab0f213acd9391ca281f60ff1ec245588c36e84bfb4216e9113446322085079509a709b909b31001b71fc91f04b909150753200445d01f032e182d26719573d79d1ffd019900bc9790a5a89790942c441fc1d08f801ac256aa1a64a2c9ff7baf43d25ab8ff1e85eb51fa3f 40527ac322f2a535024040fe992291e7a535d120dd23d7239d44d1b45f703d0ad7a38640a60b3213e83ff1f7cb23f8fca5a68123b100343211bb343f31b6e50123b16a3247bb286a3f67bf79b90686b91993bfa5b3988302b613ea1a00f2e52fd7b79f4bf4491140cfe8b81143bffabf000ccf1ecf30cf30186947ef25f4 66ec28008f4fa148da26b54fe121afcfc1cf7bf7111aeb0ff0cf0a141a0adf1cdfa673011447d5f2a02d6548df5adfe62e9b5f130103c1d8dd23f4a358cc5ebfdabe99227ffc3f40fc9922df513ffb5fefdf01e91b56aa1b942f14a62f88a72cf3f2092335d120056313e7bfdc270563d79365f52f7766130c40123f243d 0b8634ec6211bb00ec6f613f733f227f973f79b992b3bb3f609dbb9502fea0e331950900d89d6f00074f194f2b4f3d4f4f4f614f734f854a009e6e478f598892666d8fdb4fed4fcfcb111b135f205f0a141b3a5f4c5f5e5fc0705f825ff4959e6e539fbf5ffff1305b98849ebfda0563edbf0467b49e041f6f01e91c56aa a7b04e6f606f726b190f816809a301c0dc2709a38a9896af6f4016dba214c96f233e12003e74a4a211bda6af1b7f2d7fdcaf517f007bbf757f9fb909228010e331a709f3300056aebf7fd17fe37ff57f078f198f2b8f00854a56aeffbf11c84aa625cf938fa58f22cfcb1ccb8fd88f0a141cf28f049f00169f289f3a9fef b556ae0bdf779a17e1870000f55b983cdebfda033280e1fcbb986cded79f01e747001d08b6f2cdc1bff11dbcf209af15e139e5f528ba252af3f20040404c2e7da0ae47d94cd5f0020589a0083cd31030d423d8260f3800e8d59be3f0f1d55103fad55f09e83ffe286f0003021ed4e0010068e233021f69e274e2022069e2 80e2550264e00368e20168e20374e2550174e20380e20180e20384ce853a8000101022c9e2c8e0b50123acf4c2dbe20123b4010bb902007ab90201c5020b8400d1d004571c0165da042cceb41eb2f0cad6211f1cf420aad0d6218300a51232f00a32f0a5d11a78f636a0b8d4c7ddebc505e3a7f71d6de01faaccc0218e16 c8efb5100debe802fe0010b410ede9a9f0f8e0efe795f77f0b59c84216b29096c002bbcdd8a6f4dbe9b9f1dbe9dfc6e6fca2c9eb03b8f0cbe777234c6a2038ce7a220400b424f068e05403928a2211acd0bbd106c0df023003421ea8b8efb50cee11070333d04315d410300333c01ced1449e07402df601d0020f86f02ef 3fbb05fedc00037403e201578a2622d5ed0300e00378b5ee020190f4030e1786cc0331846a2003f3aa0452c0c7b388fb28bbcfa34600e66f1b80b305a34669d5961ce3b755cf67c3062852c02ce18f510939b94879e15e0c21076e0f800f920ce603bfa8083cd320b9093cd3cb0fdd0fef085bfb0f0d1f0a7e20509622c5 291f3b1f4d1faf1f00711f0a3b4e2599192c3fb71fc91fdb1fa2ceb44785e15e00cdc10266040894092fe3a00320a6c4900fcf42e400f8d812b3b9000ce612b3662f7826e0c562ee0958962fa82f7e20abaa574119eaed00a9f0022169e264423e00eb030364420164420300b35ebcb20100b9000bf514ceb4292124f43b f10138f0c944f44761470100269a4264405e040bccc002bbd109a43f1b2fc63cf935dd3ffb4f04014f7a2120184f465e3b4147561418006f5ac72fd92feb2ffd2ffadcd35b1755a03439f55f523f643f76390d3ab8549761706524f0225c0612b122f0beb2d34fe54bcdb5404da521ffe73e3b054040561bffe8b4814ee3 3f4080ffdbb66ddbb6cd3f402960be24ac64bdb465b51cef2ee0009b6539e3a46547e3ad6555e3b6658f5f0aa1518102f492ae5fc05f0933ad6600547fb46734397c7f1b6f2d6f7631b989a0fb9186cbad65b665e7872224f0230af69a2304a22919820faf21ae3ba353f43ff0d778b4bf9a7dd05c878067af94a6f0d73b a300e0f1d59da41d40a0a0c3a1b582b1abb58fd1a606260040c3a1eb82e7abeb8f07bf19b91d26b9c10633bf45b3dbeb59b1dbe203ff97cf40f07262cf5c8777b799129292c988b89293b99abfacbfbebf00d0bf1739779efc9f0eaf20af1a3c5b88884fcf61cf73c72383cf90cf74f42310aacfbccfefb5cdc408dec5e5 a6efcf0801d8779e1cbf05e69033d6678cdb30344dbe5fdae0789bd43f7cbf8fdf12a1d748c2f00889241582726f2c8f5a91f22de9d203404284f201e8c047c5a00757d5788ffab4eed0a6704f3d0ad7a309e0fbb30602c581f8ad8706216bc4c28d6fcfe484198089c4a3c2f88ba3cf189f2a9f3c9419e0449f5693edeb 3b01c3f20300d85c1ecf88979ff4494ad0cf9998024ad3bfab9fbd9fcf9fe19f2fa8a2d70028c5203625c8c8dfdad813c6eedf1ac18860af72afcc772494afa1af74f424a8bbafcdaf98d314e6a510efa5f0613ff9af0bbf1fced4ef010342bee00ac0deec0bf870ba98d3ee3f4005fcd2b2df16353bf8a0bfb2b7010000 000000f548e9f20febf0012a5c8fffc2f528164050b81edf85eb510440e9f22400ff260028002a002c00ff2d002e002f003000ff3100320033003e00dd3fe9f20b00382d0018000f02003a00fd1ce1fa010040004200ffa4bea900d33e00000149dcf0fd3ee3f8010003001500ffc3007448ad007a2aff000053140000c9 007f4000ccbfa900cdeef0fd06ebf03f00520044a97fa9001c3f000017dcf20000000000000400bd98ebf0b8036802defd01fb0015e9f2fcffe9ffbc7f036c020400ffffe6f577f0bfcc24012c0640e9f28f40f43f01dcff05000401018f00670009360f640fe3f82a1b001405008e00dfe004000034ebf00100ff506167 652d310000fd06f5f0426c61636b207f66696c6c000012f5f05f576869746509040401027d751804010052656409047f0100477265656e0904dd2df5f043796140040100bf59656c6c6f77090347baf5f04df9f06e74613308613d79280531302520780914037f6c696e65000083f5f0fd33850c4c6f6e672064c7617368 31009a032204646125720805a04905cd08ad3906cd0781c06508cd072e030c195804cd0801ab0035850c37850c39850c314770786c9903a2006d18396d18ef486169727113010053ef686f7274b80a010041bf7269616c20636b00653f7265640000909910b013ff746f70206c656674e700009cc119f5f054696d0b6573 b518bc9910e413de19ca17fde19910426f78000102ff01004f7065726174ff696f6e730000f001bf0200636c6173e8106f9f6d70617274f5f0302a2edf32360002022f006374ef616e676c7411436f6efd6e55206f72000200553f6e6976657273b311612679211d206c202d6469725520de2620616c0039512053757f62 74797065006c1d202154b11059221d20402b369f22402b9b3131ac2f3138d4216c2f723f2e3233000078e92ffb23cf3600008e053ffb233700f300a2213ffb23380000aec6ad2e323969202f206e33556e667237537576338835636c3e3f7efc2133350000bd03963fdca8321d30d30333af30330055a2cd309ecd309acd 3096cd305592cd308ecd308acd3086cd305582cd307ecd307bcd3065cd30d549cd302dcd3011cd30f702573300e31140ce1140bb114055ae1140a211408e1140781140556c11405f11404c1140391140552a114021114010114001114077f0013313203300cd514055bc5140a751409c5140905140558451407851406851 40585140554751403451402451400e51405ff9003300e58d40d38d4055c08d40ad8d40a08d40908d4055838d40728d40648d40558d4055478d403c8d402d8d401d8d40fd0d8d4004004000d903ff0604000003000a00ff05003f00ffffb07487a90009eff0030f150fe6f5ff01ff1e0f430f550f670f790f8b0f9d0ff701 000ef1f022002400ff2d002e0025003300ff2c0027000f00060007090010cb062e01d90feb0f3001770f001df5f02a00319e0ffedffc0500020004000bf8f3f0351fe0fb03001a000dbf001100080023ebf026eb00122f101b07101f0020ff0021002b002900288e2d100b0013d70f901f98140afef3f017000c00180014 ff001500160019001c13001e0310b00725c504981fe51f00a415ff1f112fac03292f3b2f4d2f5f2f40e4f86a2f8e2fa02fb22fe3f807be2f10e22ff42f063fe3f808123f363fe7f4f732003ef7f03a003b00053c791407cf2febf0d21ffa05defd1d0a6d1a2f0030091050335c3730c2337e3fdd3fe4331000fd7ce9f225 000400012aff5c8fc2f5281640507fb81e85eb510440ebf0df0100020003f5f00500ff0600070008000900ff0a000b000c000d00ff0e000f0010001100ff1200130014001500ff1600170018001900ff1a001b001c001d00ff1e001f00200021007f22002300270029e9f2ba0c0117ebf00b00641f0018060d006e00056c e1fa06dcff0e0f200f320fe5f6ff4000420034cbac001fb7430000813c0000001500000000001c000000942c2f00000000000000000000000000bbc401e0fb010003fff209e30067fcf10c0f1e0f000028ffa5443943ad62e1409f28325f377a3802340e3c7371a90a02eff8ac75a9e7f4ff1400160052006c7857a90038 ebf054ebf017e7f4d58cebf0088308948f0418007fd2000480a9009cebf0fd7bebf0260042000cc857ac0017eff021ebf01aa700f9d47b01eff0900700001bff0046002cc24f00c8f49200b2011cd700ecc14f005f4309000031ebf01d7700ff9c77a900f7290000f577ebf024e7f46e2a0000f50cebf027770074a8a900 1f333f00003aebf0c201eaf1e96d1f10920129b70064c2a9eb00751f1049a301016000d74415aae5f632d7000460f7ad00be1f10d1020000fdcad700ac1aac008f42f43100eff03f770094c7ac00df3844000020ebf03c007f40001cbda900587f10550aebf043e7f4627f1006ebf0ff3d00500014cfac0001687f101211 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001050000050000000d0000004d45544146494c455049435400483700007ce6ffffd01200000800483784190000 0100090000036409000008003a0000000000050000000b0200000000050000000c0203038706050000000902ffffff000500000001020000000007000000fc020100000000000000040000002d01000009000000fa02000003000000000000002200040000002d01010004000000020101000e00000025030500ae02a100 da03a100da035600ae025600ae02a10009000000fa02000000000000000000002200040000002d01020004000000f001010013000000fb02d6ff0f000000000090010000000000000022417269616c204e6172726f770000040000002d01010010000000fb021400090000000000bc02000000000102022253797374656d 006e040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000c00000021050c006e616d653a20537472696e678800bf02040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000 fa02000003000000000000002200040000002d01040004000000020101000e00000025030500ae02ec00da03ec00da03a100ae02a100ae02ec00040000002d01020004000000f0010400040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e0118000500 0000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01040004000000020101000e00000025030500ae025600da035600da030b00ae020b00ae025600040000002d01020004000000f001040013000000 fb02d6ff100000000000bc020000000000000022417269616c204e6172726f770000040000002d010400040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0104000c00000021050c00446f6d61696e4f626a6563743d00cf02 040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01050004000000020101000e000000250305000b00ae023701ae02370163020b0063020b00ae02040000002d01020004000000f0010500040000002d01010004000000 2d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000d00000021050e007072696365436f64653a20696e7495021c00040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000 03000000000000002200040000002d01050004000000020101000e000000250305000b00f9023701f9023701ae020b00ae020b00f902040000002d01020004000000f0010500040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e011800050000000902 00000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01050004000000020101000e000000250305000b00630237016302370118020b0018020b006302040000002d01020004000000f0010500040000002d010400 040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01040009000000210505004d6f766965004a026f00040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000 000000002200040000002d01050004000000020101000e000000250305008f03ae02bb04ae02bb0463028f0363028f03ae02040000002d01020004000000f0010500040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000 040000002d0101000e00000021050f006461797352656e7465643a20696e74009502a003040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01050004000000020101000e000000250305008f03f902bb04f902bb04ae02 8f03ae028f03f902040000002d01020004000000f0010500040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02 000003000000000000002200040000002d01050004000000020101000e000000250305008f036302bb046302bb0418028f0318028f036302040000002d01020004000000f0010500040000002d010400040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000 090200000000040000002d010400090000002105060052656e74616c4a02f003040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01050004000000020101000a000000250303008f03880244038802f902880204000000 2d01020004000000f0010500040000002d01000009000000fa02000003000000000000002200040000002d01050004000000020101003a00000025031b001a03780218037a0216037c0214037e02110380020f0382020c0383020a038402070386020403870201038702ff028802fc028802f9028802fc028802ff028902 0103890204038a0207038b020a038c020c038d020f038f02110390021403920216039402180396021a039902040000002d01020004000000f0010500050000000902ffffff000500000001020000000010000000fb02ceff16000000000090010000000000000020417269616c004c04040000002d010500040000002d01 03000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0105000700000021050100310059025101040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa0200000300000000000000220004000000 2d01060004000000020101000e000000250305005105ae027d06ae027d066302510563025105ae02040000002d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0103000500 00000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e000000250305005105f9027d06f9027d06ae025105ae025105f902040000002d01020004000000f0010600040000002d010100040000002d010300040000000801 0000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000c00000021050b0073746174656d656e74282900e0026205040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000030000000000000022000400 00002d01060004000000020101000e00000025030500510563027d0663027d0618025105180251056302040000002d01020004000000f0010600040000002d010400040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010400 0a00000021050800437573746f6d65724a029705040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000a000000250303005105880206058802bb048802040000002d01020004000000f0010600 040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101003a00000025031b00dc047802da047a02d8047c02d6047e02d3048002d1048202ce048302cc048402c9048602c6048702c3048702c1048802be048802bb048802be048802c1048902c3048902c6048a02c9048b02 cc048c02ce048d02d1048f02d3049002d6049202d8049402da049602dc049902040000002d01020004000000f0010600050000000902ffffff000500000001020000000014000000fb02ceff250000000000900100000002000000024d6f6e6f7479706520536f7274730000040000002d010600040000002d0103000400 000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01060007000000210501005b006402d304040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d010700 04000000020101000c000000250304006f0337014403ec00180337016f033701040000002d01020004000000f0010700050000000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01070004000000020101000e00000025030500a1001802a100a701 f201a7014403a70144033701040000002d01020004000000f0010700050000000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01070004000000020101000e00000025030500250418022504a701b403a7014403a70144033701040000002d010200 04000000f0010700050000000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01070004000000020101000e00000025030500e7051802e705a7019504a7014403a70144033701040000002d01020004000000f0010700050000000902ffffff000500 0000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01070004000000020101000e00000025030500cd01ae02f902ae02f9026302cd016302cd01ae02040000002d01020004000000f0010700040000002d010100040000002d0103000400000008010000050000000a020000 00000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01070004000000020101000e00000025030500cd01f902f902f902f902ae02cd01ae02cd01f902 040000002d01020004000000f0010700040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000030000000000 00002200040000002d01070004000000020101000e00000025030500cd016302f9026302f9021802cd011802cd016302040000002d01020004000000f0010700040000002d010400040000002d0103000400000008010000050000000a02000000000400000002010100040000002e011800050000000902000000000400 00002d0104000800000021050400546170654a023b02040000002d010300050000000902ffffff0005000000010200000000040000002d010500040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0105000700000021050100 310059021303040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01070004000000020101000a00000025030300cd0188028201880237018802040000002d01020004000000f0010700040000002d01000009000000fa02 000003000000000000002200040000002d01070004000000020101003a00000025031b005801780256017a0254017c0252017e024f0180024d0182024a0183024801840245018602420187023f0187023d0188023a018802370188023a0188023d0189023f01890242018a0245018b0248018c024a018d024d018f024f01 900252019202540194025601960258019902040000002d01020004000000f0010700050000000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01070004000000020101000e00000025030500630218026302a701d302a7014403a701440337010400 00002d01020004000000f0010700030000000000}{\result {\insrsid13379340 {\pict{\*\picprop\shplid1025{\sp{\sn shapeType}{\sv 75}}{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}{\sp{\sn pictureGray}{\sv 0}}{\sp{\sn pictureBiLevel}{\sv 0}} {\sp{\sn pictureActive}{\sv 0}}{\sp{\sn fillColor}{\sv 268435473}}{\sp{\sn fFilled}{\sv 0}}{\sp{\sn fHitTestFill}{\sv 1}}{\sp{\sn fillShape}{\sv 1}}{\sp{\sn fillUseRect}{\sv 0}}{\sp{\sn fNoFillHitTest}{\sv 0}}{\sp{\sn fLine}{\sv 0}} {\sp{\sn fLayoutInCell}{\sv 1}}}\picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0\picw14152\pich6532\picwgoal8023\pichgoal3703\wmetafile8\bliptag-1195057042\blipupi-276{\*\blipuid b8c4e06ea28605cb3f91c137acc80926} 0100090000036409000008003a0000000000050000000b0200000000050000000c0203038706050000000902ffffff000500000001020000000007000000fc02 0100000000000000040000002d01000009000000fa02000003000000000000002200040000002d01010004000000020101000e00000025030500ae02a100da03 a100da035600ae025600ae02a10009000000fa02000000000000000000002200040000002d01020004000000f001010013000000fb02d6ff0f00000000009001 0000000000000022417269616c204e6172726f770000040000002d01010010000000fb021400090000000000bc02000000000102022253797374656d006e0400 00002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000c0000002105 0c006e616d653a20537472696e678800bf02040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa0200000300 0000000000002200040000002d01040004000000020101000e00000025030500ae02ec00da03ec00da03a100ae02a100ae02ec00040000002d01020004000000 f0010400040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000 040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d0104000400 0000020101000e00000025030500ae025600da035600da030b00ae020b00ae025600040000002d01020004000000f001040013000000fb02d6ff100000000000 bc020000000000000022417269616c204e6172726f770000040000002d010400040000002d0103000400000008010000050000000a0200000000040000000201 0100040000002e01180005000000090200000000040000002d0104000c00000021050c00446f6d61696e4f626a6563743d00cf02040000002d01030005000000 0902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01050004000000020101000e0000002503 05000b00ae023701ae02370163020b0063020b00ae02040000002d01020004000000f0010500040000002d010100040000002d01030004000000080100000500 00000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000d00000021050e007072696365436f64653a20696e74 95021c00040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01 050004000000020101000e000000250305000b00f9023701f9023701ae020b00ae020b00f902040000002d01020004000000f0010500040000002d0101000400 00002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902 ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01050004000000020101000e00000025030500 0b00630237016302370118020b0018020b006302040000002d01020004000000f0010500040000002d010400040000002d010300040000000801000005000000 0a02000000000400000002010100040000002e01180005000000090200000000040000002d01040009000000210505004d6f766965004a026f00040000002d01 0300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d0105000400000002010100 0e000000250305008f03ae02bb04ae02bb0463028f0363028f03ae02040000002d01020004000000f0010500040000002d010100040000002d01030004000000 08010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000e00000021050f006461797352656e74 65643a20696e74009502a003040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa0200000300000000000000 2200040000002d01050004000000020101000e000000250305008f03f902bb04f902bb04ae028f03ae028f03f902040000002d01020004000000f00105000400 00002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01 0300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d0105000400000002010100 0e000000250305008f036302bb046302bb0418028f0318028f036302040000002d01020004000000f0010500040000002d010400040000002d01030004000000 08010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010400090000002105060052656e74616c4a02 f003040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d010500 04000000020101000a000000250303008f03880244038802f9028802040000002d01020004000000f0010500040000002d01000009000000fa02000003000000 000000002200040000002d01050004000000020101003a00000025031b001a03780218037a0216037c0214037e02110380020f0382020c0383020a0384020703 86020403870201038702ff028802fc028802f9028802fc028802ff0289020103890204038a0207038b020a038c020c038d020f038f0211039002140392021603 9402180396021a039902040000002d01020004000000f0010500050000000902ffffff000500000001020000000010000000fb02ceff16000000000090010000 000000000020417269616c004c04040000002d010500040000002d0103000400000008010000050000000a02000000000400000002010100040000002e011800 05000000090200000000040000002d0105000700000021050100310059025101040000002d010300050000000902ffffff000500000001020000000004000000 2d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e000000250305005105ae027d06ae027d066302510563025105 ae02040000002d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a0200000000040000000201010004000000 2e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000030000000000 00002200040000002d01060004000000020101000e000000250305005105f9027d06f9027d06ae025105ae025105f902040000002d01020004000000f0010600 040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e0118000500000009020000000004000000 2d0101000c00000021050b0073746174656d656e74282900e0026205040000002d010300050000000902ffffff0005000000010200000000040000002d010000 09000000fa02000003000000000000002200040000002d01060004000000020101000e00000025030500510563027d0663027d06180251051802510563020400 00002d01020004000000f0010600040000002d010400040000002d0103000400000008010000050000000a02000000000400000002010100040000002e011800 05000000090200000000040000002d0104000a00000021050800437573746f6d65724a029705040000002d010300050000000902ffffff000500000001020000 0000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000a000000250303005105880206058802bb048802 040000002d01020004000000f0010600040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101003a0000002503 1b00dc047802da047a02d8047c02d6047e02d3048002d1048202ce048302cc048402c9048602c6048702c3048702c1048802be048802bb048802be048802c104 8902c3048902c6048a02c9048b02cc048c02ce048d02d1048f02d3049002d6049202d8049402da049602dc049902040000002d01020004000000f00106000500 00000902ffffff000500000001020000000014000000fb02ceff250000000000900100000002000000024d6f6e6f7479706520536f7274730000040000002d01 0600040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0106000700 0000210501005b006402d304040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa0200000300000000000000 2200040000002d01070004000000020101000c000000250304006f0337014403ec00180337016f033701040000002d01020004000000f0010700050000000902 ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01070004000000020101000e00000025030500 a1001802a100a701f201a7014403a70144033701040000002d01020004000000f0010700050000000902ffffff0005000000010200000000040000002d010000 09000000fa02000001000000000000002200040000002d01070004000000020101000e00000025030500250418022504a701b403a7014403a701440337010400 00002d01020004000000f0010700050000000902ffffff0005000000010200000000040000002d01000009000000fa0200000100000000000000220004000000 2d01070004000000020101000e00000025030500e7051802e705a7019504a7014403a70144033701040000002d01020004000000f0010700050000000902ffff ff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01070004000000020101000e00000025030500cd01 ae02f902ae02f9026302cd016302cd01ae02040000002d01020004000000f0010700040000002d010100040000002d0103000400000008010000050000000a02 000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01 000009000000fa02000003000000000000002200040000002d01070004000000020101000e00000025030500cd01f902f902f902f902ae02cd01ae02cd01f902 040000002d01020004000000f0010700040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01 180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa0200000300000000000000 2200040000002d01070004000000020101000e00000025030500cd016302f9026302f9021802cd011802cd016302040000002d01020004000000f00107000400 00002d010400040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01 04000800000021050400546170654a023b02040000002d010300050000000902ffffff0005000000010200000000040000002d010500040000002d0103000400 000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0105000700000021050100310059021303 040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d0107000400 0000020101000a00000025030300cd0188028201880237018802040000002d01020004000000f0010700040000002d01000009000000fa020000030000000000 00002200040000002d01070004000000020101003a00000025031b005801780256017a0254017c0252017e024f0180024d0182024a0183024801840245018602 420187023f0187023d0188023a018802370188023a0188023d0189023f01890242018a0245018b0248018c024a018d024d018f024f0190025201920254019402 5601960258019902040000002d01020004000000f0010700050000000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000 000000002200040000002d01070004000000020101000e00000025030500630218026302a701d302a7014403a70144033701040000002d01020004000000f0010700030000000000}}}}}{\insrsid412021 \par {\pntext\pard\plain\s15 \i\f37\fs20\lang1033\langfe1026\langnp1033 \hich\af37\dbch\af0\loch\f37 Figure 1.\tab}}\pard\plain \s15\qj \fi-360\li360\ri0\sb120\sa120\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls3\pnrnot0 \pndec\pnstart1\pnindent360\pnsp120\pnhang {\pntxtb Figure }{\pntxta .}}\faauto\ls3\adjustright\rin0\lin360\itap0 \i\f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 A class diagram of the starting point classes. Only the most important features are shown. The notation is UML [Fowler] \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Here is the code for the classes. DomainObject is a general class that does a few standard things, such as hold a name. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 \par public class DomainObject \{ \par \par \tab public DomainObject (String name)\tab \{ \par \tab \tab _name = name; \par \tab \}; \par \par \tab public DomainObject ()\tab \{\}; \par \par \tab public String name ()\tab \{ \par \tab \tab return _name; \par \tab \}; \par \par \tab public String toString() \{ \par \tab \tab return _name; \par \tab \}; \par \par \tab protected String _name = "no name"; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Movie represents the notion of a film. A video store might have several tapes in stock of the same movie \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public class Movie extends DomainObject \{ \par public static final int CHILDRENS = 2; \par public static final int REGULAR = 0; \par public static final int NEW_RELEASE = 1; \par \par \par \tab private int _priceCode; \par \par \tab public Movie(String name, int priceCode) \{ \par \tab \tab _name = name; \par \tab \tab _priceCode = priceCode; \par \tab \} \par \par \tab public int priceCode() \{ \par \tab \tab return _priceCode; \par \tab \} \par \par \tab public void persist() \{ \par \tab \tab Registrar.add ("Movies", this); \par \tab \} \par \par \tab public static Movie get(String name) \{ \par \tab \tab return (Movie) Registrar.get ("Movies", name); \par \tab \} \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 The movie uses a class called a registrar (not shown) as a class to hold instances of movie. I also do this with other classes. I use the message persist to tell an object to save itself to the registrar. I can then retrieve the object, based on its name, with a get(String) method. \par The tape class represents a physical tape. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 class Tape extends DomainObject \par \{ \par public Movie movie() \{ \par \tab return _movie; \par \} \par public Tape(String serialNumber, Movie movie) \{ \par \tab _serialNumber = serialNumber; \par \tab _movie = movie; \par \} \par private String _serialNumber; \par private Movie _movie; \par \} \par \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 The rental class represents a customer renting a movie. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 \par class Rental extends DomainObject \par \{ \par public int daysRented() \{ \par \tab return _daysRented; \par \} \par public Tape tape() \{ \par \tab return _tape; \par \} \par private Tape _tape; \par public Rental(Tape tape, int daysRented) \{ \par \tab _tape = tape; \par \tab _daysRented = daysRented; \par \} \par private int _daysRented; \par \} \par \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 The customer class represents the customer. So far all the classes have been dumb encapsulated data. Customer holds all the behavior for producing a statement in its }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 statement()}{\insrsid412021 method. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 \par class Customer extends DomainObject \par \{ \par public Customer(String name) \{ \par _name = name; \par \} \par public String statement() \{ \par double totalAmount = 0; \par int frequentRenterPoints = 0; \par Enumeration rentals = _rentals.elements(); \par String result = "Rental Record for " + name() + "\\n"; \par while (rentals.hasMoreElements()) \{ \par double thisAmount = 0; \par Rental each = (Rental) rentals.nextElement(); \par \par //determine amounts for each line \par switch (each.tape().movie().priceCode()) \{ \par case Movie.REGULAR: \par thisAmount += 2; \par if (each.daysRented() > 2) \par thisAmount += (each.daysRented() - 2) * 1.5; \par break; \par case Movie.NEW_RELEASE: \par thisAmount += each.daysRented() * 3; \par break; \par case Movie.CHILDRENS: \par thisAmount += 1.5; \par if (each.daysRented() > 3) \par thisAmount += (each.daysRented() - 3) * 1.5; \par break; \par \par \} \par totalAmount += thisAmount; \par \par // add frequent renter points \par frequentRenterPoints ++; \par // add bonus for a two day new release rental \par if ((each.tape().movie().priceCode() == Movie.NEW_RELEASE) && each.daysRented() > 1) frequentRenterPoints ++; \par \par //show figures for this rental \par result += "\\t" + each.tape().movie().name()+ "\\t" + String.valueOf(thisAmount) + "\\n"; \par \par \} \par //add footer lines \par result += "Amount owed is " + String.valueOf(totalAmount) + "\\n"; \par result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; \par return result; \par \par \} \par public void addRental(Rental arg) \{ \par \tab _rentals.addElement(arg); \par \} \par public static Customer get(String name) \{ \par \tab return (Customer) Registrar.get("Customers", name); \par \} \par public void persist() \{ \par \tab Registrar.add("Customers", this); \par \} \par private Vector _rentals = new Vector(); \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 What are your impressions about the design of this program? I would describe as not well designed, and certainly not object-oriented. For a simple program is this, that does not really matter. There\rquote s nothing wrong with a quick and dirty }{ \i\insrsid412021 simple}{\insrsid412021 program. But if we imagine this as a fragment of a more complex system, then I have some real problems with this program. That long statement routine in the Customer does far to o much. Many of the things that it does should really be done by the other classes. \par This is really brought out by a new requirement, just in from the users, they want a similar statement in }{\scaps\insrsid412021 html}{\insrsid412021 . As you look at the code you can see that it is impossible to reuse any of the behavior of the current } {\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 statement()}{\insrsid412021 method for an }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 htmlStatement()}{\insrsid412021 . Your only recourse is to write a whole new method that duplicates much of the behavior of statement(). Now of course this is not too onerous. You can just copy the statem ent() method and make whatever changes you need. So the lack of design does not do too much to hamper the writing of htmlStatement(), (although it might be tricky to figure out exactly where to do the changes). But what happens when the charging rules cha nge? You have to fix both statement() and htmlStatement(), and ensure the fixes are consistent. The problem from cut and pasting code comes when you have to change it later. Thus if you are writing a program that you don\rquote t expect to change, then cut and paste is fine. If the program is long lived and likely to change, then cut and paste is a menace. \par But you still have to write the htmlStatement() program. You may feel that you should not touch the existing statement() method, after all it works fine. Remember the old engineering adage: \'93if it ain\rquote t broke, don\rquote t fix it\'94 . statement() may not be broke, but it does hurt. It is making your life more difficult to write the htmlStatement() method. \par So this is where refactoring comes in. When you find you have to add a feature to a program, and the program\rquote s code is not structured in a convenient way to add the feature; then first refactor the program to make it easy to add the feature, then add the feature. \par }\pard\plain \s3\qj \li0\ri0\sb240\sa60\keep\keepn\widctlpar\faauto\outlinelevel2\adjustright\rin0\lin0\itap0 \b\f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Extracting the Amount Calculation \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 The obvious first target of my attention is the overly long }{ \cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 statement()}{\insrsid412021 method. When I look at a long method like that, I am looking to take a chunk of the code an }{\cs25\i\cf6\insrsid412021 extract a method}{\insrsid412021 from it. \par Extracting a method is taking the chunk of code and making a method out of it. An obvious piece here is the switch statement (which I'm highlighting below). \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public String statement() \{ \par double totalAmount = 0; \par int frequentRenterPoints = 0; \par Enumeration rentals = _rentals.elements(); \par String result = "Rental Record for " + name() + "\\n"; \par while (rentals.hasMoreElements()) \{ \par double thisAmount = 0; \par Rental each = (Rental) rentals.nextElement(); \par \par //determine amounts for each line \par }{\cs24\cf12\insrsid412021 switch (each.tape().movie().priceCode()) \{ \par case Movie.REGULAR: \par thisAmount += 2; \par if (each.daysRented() > 2) \par thisAmount += (each.daysRented() - 2) * 1.5; \par break; \par case Movie.NEW_RELEASE: \par thisAmount += each.daysRented() * 3; \par break; \par case Movie.CHILDRENS: \par thisAmount += 1.5; \par if (each.daysRented() > 3) \par thisAmount += (each.daysRented() - 3) * 1.5; \par break; \par \par \} \par }{\insrsid412021 totalAmount += thisAmount; \par \par // add frequent renter points \par frequentRenterPoints ++; \par // add bonus for a two day new release rental \par if ((each.tape().movie().priceCode() == Movie.NEW_RELEASE) && each.daysRented() > 1) frequentRenterPoints ++; \par \par //show figures for this rental \par result += "\\t" + each.tape().movie().name()+ "\\t" + String.valueOf(thisAmount) + "\\n"; \par \par \} \par //add footer lines \par result += "Amount owed is " + String.valueOf(totalAmount) + "\\n"; \par result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; \par return result; \par \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 This looks like it would make a good chunk to extract into its own method. When we extract a method, we need to look in the fragment for any variables that are local in scope to the method we are looking at, that local variables and par ameters. This segment of code uses two: }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 each}{\insrsid412021 and }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 thisAmount}{\insrsid412021 . Of these }{ \cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 each}{\insrsid412021 is not modified by the code but }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 thisAmount}{\insrsid412021 is modified. Any non-modified variable we can pass in as a parameter. Modified variables need more care. If there is only one we can retur n it. The temp is initialized to 0 each time round the loop, and not altered until the switch gets its hands on it. So we can just assign the result. The extraction looks like this. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public String statement() \{ \par double totalAmount = 0; \par int frequentRenterPoints = 0; \par Enumeration rentals = _rentals.elements(); \par String result = "Rental Record for " + name() + "\\n"; \par while (rentals.hasMoreElements()) \{ \par double thisAmount = 0; \par Rental each = (Rental) rentals.nextElement(); \par \par //determine amounts for each line \par }{\cs26\cf2\insrsid412021 thisAmount = amountOf(each); \par }{\insrsid412021 totalAmount += thisAmount; \par \par // add frequent renter points \par frequentRenterPoints ++; \par // add bonus for a two day new release rental \par if ((each.tape().movie().priceCode() == Movie.NEW_RELEASE) && each.daysRented() > 1) frequentRenterPoints ++; \par \par //show figures for this rental \par result += "\\t" + each.tape().movie().name()+ "\\t" + String.valueOf(thisAmount) + "\\n"; \par \par \} \par //add footer lines \par result += "Amount owed is " + String.valueOf(totalAmount) + "\\n"; \par result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; \par return result; \par \par \} \par \par private int amountOf(Rental each) \{ \par int thisAmount = 0; \par switch (each.tape().movie().priceCode()) \{ \par case Movie.REGULAR: \par thisAmount += 2; \par if (each.daysRented() > 2) \par thisAmount += (each.daysRented() - 2) * 1.5; \par break; \par case Movie.NEW_RELEASE: \par thisAmount += each.daysRented() * 3; \par break; \par case Movie.CHILDRENS: \par thisAmount += 1.5; \par if (each.daysRented() > 3) \par thisAmount += (each.daysRented() - 3) * 1.5; \par break; \par \par \} \par return thisAmount; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 When I did this the tests blew up. A couple of the test figures gave me the wrong answer. I was puzzled for a few seconds then realized what I had done. Foolishly I had made the return type of }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 amountOf() int}{ \insrsid412021 instead of }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 double}{\insrsid412021 . \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 private double amountOf(Rental each) \{ \par double thisAmount = 0; \par switch (each.tape().movie().priceCode()) \{ \par case Movie.REGULAR: \par thisAmount += 2; \par if (each.daysRented() > 2) \par thisAmount += (each.daysRented() - 2) * 1.5; \par break; \par case Movie.NEW_RELEASE: \par thisAmount += each.daysRented() * 3; \par break; \par case Movie.CHILDRENS: \par thisAmount += 1.5; \par if (each.daysRented() > 3) \par thisAmount += (each.daysRented() - 3) * 1.5; \par break; \par \par \} \par return thisAmount; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 It\rquote s the kind of silly mistake that I often make, and it can be a pain to track down as Java converts ints to doubles withou t complaining (but merrily rounding). Fortunately it was easy to find in this case, because the change was so small. Here is the essence of the refactoring process illustrated by accident. Because each change is so small, any errors are very easy to find. You don't spend long debugging, even if you are as careless as I am. \par This refactoring has taken a large method and broken it down into two much more manageable chunks. We can now consider the chunks a bit better. I don't like some of the variables names in amountOf() and this is a good place to change them. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 private double amountOf(Rental }{ \cs26\cf2\insrsid412021 aRental}{\insrsid412021 ) \{ \par double }{\cs26\cf2\insrsid412021 result }{\insrsid412021 = 0; \par switch (}{\cs26\cf2\insrsid412021 aRental}{\insrsid412021 .tape().movie().priceCode()) \{ \par case Movie.REGULAR: \par }{\cs26\cf2\insrsid412021 result}{\insrsid412021 += 2; \par if (}{\cs26\cf2\insrsid412021 aRental}{\insrsid412021 .daysRented() > 2) \par }{\cs26\cf2\insrsid412021 result}{\insrsid412021 += (}{\cs26\cf2\insrsid412021 aRental}{\insrsid412021 .daysRented() - 2) * 1.5; \par break; \par case Movie.NEW_RELEASE: \par }{\cs26\cf2\insrsid412021 result}{\insrsid412021 += }{\cs26\cf2\insrsid412021 aRental}{\insrsid412021 .daysRented() * 3; \par break; \par case Movie.CHILDRENS: \par }{\cs26\cf2\insrsid412021 result}{\insrsid412021 += 1.5; \par if (}{\cs26\cf2\insrsid412021 aRental}{\insrsid412021 .daysRented() > 3) \par }{\cs26\cf2\insrsid412021 result}{\insrsid412021 += (}{\cs26\cf2\insrsid412021 aRental}{\insrsid412021 .daysRented() - 3) * 1.5; \par break; \par \par \} \par return }{\cs26\cf2\insrsid412021 result}{\insrsid412021 ; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Is that renaming worth the effort? Absolutely. Good code should communicate what it is doing clearly, and variable names are key to clear code. Never be afraid to change the names to things to improve clarity. With good find and replace tools, it is usual ly not difficult. Strong typing and testing will highlight anything you miss. Remember any fool can write code that a computer can understand, good programmers write code that humans can understand. \par }\pard\plain \s3\qj \li0\ri0\sb240\sa60\keep\keepn\widctlpar\faauto\outlinelevel2\adjustright\rin0\lin0\itap0 \b\f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Moving the amount calculation \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 As I look at amountOf, I can see that it uses information from the rental, but does not use information from the customer. This method is thus on the wrong object, it should be moved to the rental. To }{\cs25\i\cf6\insrsid412021 move a method}{\insrsid412021 you first copy the code over to rental, adjust it to fit in its new home and compile. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class Rental\tab \par double charge() \{ \par double result = 0; \par switch (tape().movie().priceCode()) \{ \par case Movie.REGULAR: \par result += 2; \par if (daysRented() > 2) \par result += (daysRented() - 2) * 1.5; \par break; \par case Movie.NEW_RELEASE: \par result += daysRented() * 3; \par break; \par case Movie.CHILDRENS: \par result += 1.5; \par if (daysRented() > 3) \par result += (daysRented() - 3) * 1.5; \par break; \par \par \} \par return result; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 In this case fitting into its new home means removing the parameter. \par The next step is to find every reference to the old method, and adjusting the reference to use the new method. In this case this step is easy as we just created the method and it is in only one place. In general, however, you need to do a find across all the classes that might be using that method. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public String statement() \{ \par double totalAmount = 0; \par int frequentRenterPoints = 0; \par Enumeration rentals = _rentals.elements(); \par String result = "Rental Record for " + name() + "\\n"; \par while (rentals.hasMoreElements()) \{ \par double thisAmount = 0; \par Rental each = (Rental) rentals.nextElement(); \par \par //determine amounts for each line \par }{\cs26\cf2\insrsid412021 thisAmount = each.charge(); \par }{\insrsid412021 totalAmount += thisAmount; \par \par // add frequent renter points \par frequentRenterPoints ++; \par // add bonus for a two day new release rental \par if ((each.tape().movie().priceCode() == Movie.NEW_RELEASE) && each.daysRented() > 1) frequentRenterPoints ++; \par \par //show figures for this rental \par result += "\\t" + each.tape().movie().name()+ "\\t" + String.valueOf(thisAmount) + "\\n"; \par \par \} \par //add footer lines \par result += "Amount owed is " + String.valueOf(totalAmount) + "\\n"; \par result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; \par return result; \par \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 When I've made the change the next thing is to remove the old method. The compiler should then tell me if I missed anything. \par There is certainly some more I would like to do to }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 Rental.charge()}{\insrsid412021 but I will leave it for the moment and return to }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 Customer.statement(). \par }{\insrsid412021 The next thing that strikes me is that }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 thisAmount()}{\insrsid412021 is now pretty redundant. It is set to the result of }{ \cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 each.charge()}{\insrsid412021 and not changed afterwards. Thus I can eliminate }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 thisAmount}{\insrsid412021 by }{\cs25\i\cf6\insrsid412021 replacing a temp with a query}{\insrsid412021 . \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public String statement() \{ \par double totalAmount = 0; \par int frequentRenterPoints = 0; \par Enumeration rentals = _rentals.elements(); \par String result = "Rental Record for " + name() + "\\n"; \par while (rentals.hasMoreElements()) \{ \par Rental each = (Rental) rentals.nextElement(); \par \par //determine amounts for each line \par }{\cs26\cf2\insrsid412021 totalAmount += each.charge(); \par }{\insrsid412021 \par // add frequent renter points \par frequentRenterPoints ++; \par // add bonus for a two day new release rental \par if ((each.tape().movie().priceCode() == Movie.NEW_RELEASE) && each.daysRented() > 1) frequentRenterPoints ++; \par \par //show figures for this rental \par result += "\\t" + each.tape().movie().name()+ "\\t" + String.valueOf(}{\cs26\cf2\insrsid412021 each.charge()}{\insrsid412021 ) + "\\n"; \par \par \} \par //add footer lines \par result += "Amount owed is " + String.valueOf(totalAmount) + "\\n"; \par result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; \par return result; \par \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 I like to get rid of temporary variables like thus as much as possible. Temps are often a problem in that they cause a lot of parameters to get passed around when they don't need to. You can easily lose track of what they are there for. They are particula r ly insidious in long methods. Of course there is a small performance price to pay, here the charge is now calculated twice. But it is easy to optimize that in the rental class, and you can optimize much more effectively when the code is properly refactore d. \par }\pard\plain \s3\qj \li0\ri0\sb240\sa60\keep\keepn\widctlpar\faauto\outlinelevel2\adjustright\rin0\lin0\itap0 \b\f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Extracting Frequent Renter Points \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 The next step is to do a similar thing for the frequent renter points. Again the rules vary with the tape, although there is less variation than with the charging. But it seems reasonable to put the responsibility on the rental. First we need to extract a method from the frequent renter points part of the code (highlighted below). \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public String statement() \{ \par double totalAmount = 0; \par int frequentRenterPoints = 0; \par Enumeration rentals = _rentals.elements(); \par String result = "Rental Record for " + name() + "\\n"; \par while (rentals.hasMoreElements()) \{ \par Rental each = (Rental) rentals.nextElement(); \par \par //determine amounts for each line \par totalAmount += each.charge(); \par \par // add frequent renter points \par }{\cs24\cf12\insrsid412021 frequentRenterPoints ++; \par // add bonus for a two day new release rental \par if ((each.tape().movie().priceCode() == Movie.NEW_RELEASE) && each.daysRented() > 1) frequentRenterPoints ++; \par }{\insrsid412021 \par //show figures for this rental \par result += "\\t" + each.tape().movie().name()+ "\\t" + String.valueOf(each.charge()) + "\\n"; \par \par \} \par //add footer lines \par result += "Amount owed is " + String.valueOf(totalAmount) + "\\n"; \par result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; \par return result; \par \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Again we look at the use of locally scoped variables. Again it uses }{ \cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 each}{\insrsid412021 , which can be passed in as a parameter. The other temp used is }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 frequentRenterPoints}{\insrsid412021 . In this case }{ \cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 frequentRenterPoints}{\insrsid412021 does have a value beforehand. The body of the extracted method doesn't read the value, however, so we don't need to pass it in as a para meter as long as we use an appending assignment. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public String statement() \{ \par double totalAmount = 0; \par int frequentRenterPoints = 0; \par Enumeration rentals = _rentals.elements(); \par String result = "Rental Record for " + name() + "\\n"; \par while (rentals.hasMoreElements()) \{ \par Rental each = (Rental) rentals.nextElement(); \par \par //determine amounts for each line \par totalAmount += each.charge(); \par \par // add frequent renter points \par }{\cs26\cf2\insrsid412021 frequentRenterPoints += frequentRenterPointOf(each); \par }{\insrsid412021 \par //show figures for this rental \par result += "\\t" + each.tape().movie().name()+ "\\t" + String.valueOf(each.charge()) + "\\n"; \par \par \} \par //add footer lines \par result += "Amount owed is " + String.valueOf(totalAmount) + "\\n"; \par result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; \par return result; \par \par \} \par \par int frequentRenterPointOf(Rental each) \{ \par if ((each.tape().movie().priceCode() == Movie.NEW_RELEASE) && each.daysRented() > 1) return 2; \par else return 1; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 I did the extraction, compiled and tested, and then did a move. With refactoring small steps are the best, that way less tends to go wrong. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public String statement() \{ \par double totalAmount = 0; \par int frequentRenterPoints = 0; \par Enumeration rentals = _rentals.elements(); \par String result = "Rental Record for " + name() + "\\n"; \par while (rentals.hasMoreElements()) \{ \par Rental each = (Rental) rentals.nextElement(); \par \par //determine amounts for each line \par totalAmount += each.charge(); \par \par // add frequent renter points \par }{\cs26\cf2\insrsid412021 frequentRenterPoints += each.frequentRenterPoints(); \par }{\insrsid412021 \par //show figures for this rental \par result += "\\t" + each.tape().movie().name()+ "\\t" + String.valueOf(each.charge()) + "\\n"; \par \par \} \par //add footer lines \par result += "Amount owed is " + String.valueOf(totalAmount) + "\\n"; \par result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; \par return result; \par \par \} \par \par int frequentRenterPoints() \{ \par if ((tape().movie().priceCode() == Movie.NEW_RELEASE) && daysRented() > 1) return 2; \par else return 1; \par \} \par }\pard\plain \s3\qj \li0\ri0\sb240\sa60\keep\keepn\widctlpar\faauto\outlinelevel2\adjustright\rin0\lin0\itap0 \b\f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Removing Temps \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 As I suggested before, temporary variables can be a problem. They are only useful within their own routine, and thus they encourage long complex routines. In this case we have two temporary variables, both of whi ch are being used to get a total from the rentals attached to the customer. Both the }{\scaps\insrsid412021 ascii}{\insrsid412021 and }{\scaps\insrsid412021 html}{\insrsid412021 versions will require these totals. I like to }{\cs25\i\cf6\insrsid412021 replace temps with queries}{\insrsid412021 . Queries are accessible to any method in the class, and thus encourage a cleaner design without long complex methods. \par I began by replacing }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 totalAmount}{\insrsid412021 with a }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 charge()}{\insrsid412021 method on customer. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public String statement() \{ \par double totalAmount = 0; \par int frequentRenterPoints = 0; \par Enumeration rentals = _rentals.elements(); \par String result = "Rental Record for " + name() + "\\n"; \par while (rentals.hasMoreElements()) \{ \par Rental each = (Rental) rentals.nextElement(); \par \par // add frequent renter points \par frequentRenterPoints += each.frequentRenterPoints(); \par \par //show figures for this rental \par result += "\\t" + each.tape().movie().name()+ "\\t" + String.valueOf(each.charge()) + "\\n"; \par \par \} \par //add footer lines \par result += "Amount owed is " + String.valueOf(}{\cs26\cf2\insrsid412021 charge()}{\insrsid412021 ) + "\\n"; \par result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; \par return result; \par \par \} \par \par private double charge()\{ \par double result = 0; \par Enumeration rentals = _rentals.elements(); \par while (rentals.hasMoreElements()) \{ \par Rental each = (Rental) rentals.nextElement(); \par result += each.charge(); \par \} \par return result; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 After compiling and testing that refactoring, I then did the same for }{ \cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 frequentRenterPoints}{\insrsid412021 . \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public String statement() \{ \par Enumeration rentals = _rentals.elements(); \par String result = "Rental Record for " + name() + "\\n"; \par while (rentals.hasMoreElements()) \{ \par Rental each = (Rental) rentals.nextElement(); \par //show figures for each rental \par result += "\\t" + each.tape().movie().name()+ "\\t" + \par String.valueOf(each.charge()) + "\\n"; \par \} \par //add footer lines \par result += "Amount owed is " + String.valueOf(charge()) + "\\n"; \par result += "You earned " + String.valueOf(}{\cs26\cf2\insrsid412021 frequentRenterPoints()}{\insrsid412021 ) + \par " frequent renter points"; \par return result; \par \} \par \par private int frequentRenterPoints() \{ \par int result = 0; \par Enumeration rentals = _rentals.elements(); \par while (rentals.hasMoreElements()) \{ \par Rental each = (Rental) rentals.nextElement(); \par result += each.frequentRenterPoints(); \par \} \par return result; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 It is worth stopping and thinking a bit about this refactoring. Most refactoring reduce the amount of code, but this one increases it. That's because Java requires a lot of statements to set up a summing loop. Even a simple summing loop with one line of c ode per element needs six lines of support around it. It\rquote s an idiom that is obvious to any programmer but it is noise that hides what the intent of the loop is. As Java develops and builds up its ability to handle block closures in the style of Smalltalk, I expect that overhead to decrease, probably to the single line that such an expression would take in Smalltalk. \par The other concern with this refactoring lies in performance. The old code executed the while loop once, the new code executes it three times. I f the while loop takes time, this might significantly impair performance. Many programmers would not do this refactoring simply for this reason. But note the words \'93if\'94 and \'93might\'94 . While some loops do cause performance issues, most do not. So while refactoring don\rquote t worry about this. When you optimize you will have to worry about it, but you will then be in a much better position to do something about it, and you will have more options to optimize effectively. (For a good discussion on why it is better to write clearly first and then optimize, see [McConnell, Code Complete]. \par These queries are now available to any code written in the customer class. Indeed they can easily be added to the interface of the class should other parts of the system need this infor mation. Without queries like these, other methods need to deal with knowing about the rentals and building the loops. In a complex system that will lead to much more code to write and maintain. \par You can see the difference immediately with the }{\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 htmlStatement()}{\insrsid412021 . I am now at the point where I take off my refactoring hat and put on my adding function hat. I can write }{ \f38\fs16\lang1024\langfe1024\noproof\insrsid412021 htmlStatement()}{\insrsid412021 like this (and add an appropriate test). \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public String htmlStatement() \{ \par Enumeration rentals = _rentals.elements(); \par String result = "
\\n";
\par while (rentals.hasMoreElements()) \{
\par Rental each = (Rental) rentals.nextElement();
\par //show figures for each rental
\par result += each.tape().movie().name()+ ": " +
\par String.valueOf(each.charge()) + "
\\n";
\par \}
\par //add footer lines
\par result += "
You owe " + String.valueOf(charge()) + "
\\n"; \par result += "On this rental you earned " + String.valueOf(frequentRenterPoints()) + " frequent renter points
"; \par return result; \par \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 There is still some code copied from the }{\scaps\insrsid412021 ascii}{\insrsid412021 version, but that is mainly due to setting up the loop. Further refactoring could clean that up further, extracting methods for header, footer, and detail line are one route I could take. But that isn\rquote t where I want to spend my time, I would like to move onto the methods I\rquote ve moved onto rental. Back on with the refactoring hat. \par }\pard\plain \s2\qj \li0\ri0\sb240\sa120\keep\keepn\widctlpar\hyphpar0\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 \b\f37\fs24\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Moving the Rental Calculations to Movie \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Yes it\rquote s that switch statement that is bugging me. It is a bad idea to do a switch based on an attribute of another object. If you must use a switch statement, it should be on your own data, not on someone else\rquote s. This implies that the charge shou ld move onto movie \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class movie \'85 \par double charge(int daysRented) \{ \par double result = 0; \par switch (priceCode()) \{ \par case REGULAR: \par result += 2; \par if (daysRented > 2) \par result += (daysRented - 2) * 1.5; \par break; \par case NEW_RELEASE: \par result += daysRented * 3; \par break; \par case CHILDRENS: \par result += 1.5; \par if (daysRented > 3) \par result += (daysRented - 3) * 1.5; \par break; \par \par \} \par return result; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 For this to work I have to pass in the length of the rental, which of course is data due of the rental. The method effectively u ses two pieces of data, the length of the rental and the type of the movie. Why do I prefer to pass the length of rental rather than the movie\rquote s type? Its because type information tends to be more volatile. I can easily imagine new types of videos appearing. If I change the movie\rquote s type I want the least ripple effect, so I prefer to calculate the charge within the movie. \par I compiled the method into movie and then adjusted the charge method on rental to use the new method. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class rental\'85 \par double charge() \{ \par return _tape.movie().charge(_daysRented); \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Some people would prefer to remove that chain of calls by having a }{ \cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 charge(int)}{\insrsid412021 message on tape. This would lead to \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class rental \par double charge() \{ \par return _tape.charge(_daysRented); \par \} \par \par Class tape \par double charge() \{ \par return _movie.charge(_daysRented); \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 You can make that change if you like, I don\rquote t tend to worry about message chains providing that they all lie in the same package. If they cross package boundaries, then I\rquote m not so happy, and would add an insulating method. \par Having done this with charge amounts, I\rquote m inclined to do the same with frequent renter points. The need is less pressing, but I think it is more consistent to do them both the same way. And again if t he movie classifications change it makes it easier to update the code. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class rental\'85 \par int frequentRenterPoints() \{ \par return _tape.movie().frequentRenterPoints(_daysRented); \par \} \par \par class movie\'85 \par int frequentRenterPoints(int daysRented)\{ \par if ((priceCode() == NEW_RELEASE) && daysRented > 1) return 2; \par else return 1; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 With these two changes I can hide those constants, which is generally a Good Thing. Even constant data should be private. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 private static final int CHILDRENS = 2; \par private static final int REGULAR = 0; \par private static final int NEW_RELEASE = 1; \par \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 To really do this, however, I need to change a couple of other parts of the class. I need to change how we create a movie. I used to create a movie with a message like \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 new Movie (\'93Ran\'94, Movie.REGULAR); \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 and the constructor \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 class Movie\'85 \par \tab private Movie(String name, int priceCode) \{ \par \tab \tab _name = name; \par \tab \tab _priceCode = priceCode; \par \tab \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 To keep this type code hidden I need some creation methods. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public static Movie newNewRelease(String name)\{ \par return new Movie (name, NEW_RELEASE); \par \} \par public static Movie newRegular(String name)\{ \par return new Movie (name, REGULAR); \par \} \par public static Movie newChildrens(String name) \{ \par return new Movie (name, CHILDRENS); \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Now I create a new movie with \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 \tab Movie.newRegular("Monty Python and the Holy Grail"); \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Movies can change their classification. I change a movie\rquote s classification with \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 aMovie.setPriceCode(Movie.REGULAR); \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 I will need to add a bunch of methods to handle the changes of classification. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public void beRegular() \{ \par _priceCode = REGULAR; \par \} \par \par public void beNewRelease() \{ \par _priceCode = NEW_RELEASE; \par \} \par \par public void beChildrens() \{ \par _priceCode = CHILDRENS; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 It\rquote s a bit of effort to set up these methods, but they are a much more explicit interface then the type codes. Just looking at the name of the method tells you what kind of movie you are getting. This makes the code more understandable. The trade off is that each time I add a price code I have to add a creation and update method. If I had lots of price codes this would hurt (so I wouldn\rquote t do it). If I have a few, however, then it\rquote s quite reasonable. \par }\pard\plain \s3\qj \li0\ri0\sb240\sa60\keep\keepn\widctlpar\faauto\outlinelevel2\adjustright\rin0\lin0\itap0 \b\f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 At last\'85 inheritance \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 So we have several types of movie, which have different ways of answering the same question. This sounds like a job for subclasses. We could have three subclasses of movie, each of which can have its own version of charge. \par }{\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\object\objemb\objw5144\objh3141{\*\objclass }{\*\objdata 010500000200000010000000 566973696f2e44726177696e672e3400000000000000000000440000 d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffffdffffff04000000fefffffffefffffffeffffff060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e00 00001f00000020000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff02000000111a020000000000c000000000000046000000000000000000000000a033 d4d0ea87c20103000000000200000000000001004f006c00650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 0000000000000000000000001400000000000000010043006f006d0070004f0062006a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120002010100000004000000ffffffff0000000000000000000000000000000000000000000000000000 0000000000000000000001000000690000000000000003004f0062006a0049006e0066006f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000201ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 000000000000000000000000030000000600000000000000feffffff02000000fefffffffefffffffeffffff0600000007000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000020800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100feff030a0000ffffffff111a020000000000c0000000000000461000 0000564953494f20342044726177696e670011000000564953494f20342e30205368617065730010000000566973696f2e44726177696e672e3400f439b271000000000000000000000000482100780114003100130100000800000314000003140000000300040000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000feff0000040002000000000000000000000000000000000000000000000008009802140098021400f4ed8f005200000000000000d04921000d00040000010a00feff000004000200000000000000000000000000000000000100 0000e0859ff2f94f6810ab9108002b27b3d9300000008000000006000000040000003800000006000000440000000500000050000000030000005c000000070000006800000002000000740000001e00000001000000000000001e00000001000000000000001e00000001000000000000001e0000000100000000000000 1e00000001000000000000001e00000001000000000000000000000000000000000000000000000056006900730069006f0044006f00630075006d0065006e00740000000000000000000000000000000000000000000000000000000000000000000000000000001c0002000300000005000000ffffffff000000000000 00000000000000000000000000000000000000000000000000000000000005000000f43700000000000056006900730069006f0049006e0066006f0072006d006100740069006f006e00000000000000000000000000000000000000000000000000000000000000000022000201ffffffff06000000ffffffff00000000 0000000000000000000000000000000000000000000000000000000000000000040000001c000000000000000500530075006d006d0061007200790049006e0066006f0072006d006100740069006f006e00000000000000000000000000000000000000000000000000000028000200ffffffffffffffffffffffff0000 0000000000000000000000000000000000000000000000000000000000000000000005000000b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000566973696f2028544d292044726177696e670d0a0000000000000400f43700000084010014005200bc03ad00ae3600004601000000000000ed64eaf10318e9f2ffffff8300fff6f2fff3fbf00701 f8f1008980eaf116048016002000190080ff00c0c0c000e6e6e6ff00cdcdcd00b3b3b3ef009a9a9a2100800066ff6666004d4d4d00337f3333001a1a1a0000000000000004000000000000000400ff1800ffff00d29f007130dcff080fe1fa9f0019ebf0df015400000aebf064007f0020417269616c2900bd012d06e400 00223a0502fa2d021433031254696d65ff73204e657720526f576d616e2900172d02113303fe4f03204e6172726f7701003554ebf03fe8f3d03ff2ff0406daeaf120e8f359401a06000019012d00310f0000ff1a00ffff00d22c00b914dcffebf02c004aebf0012f54040020e9f2ff1c0ae0fbf7040068ebf002540000eb cc02e8f3014a00000800bf0200620100fe4f0001f25304025301ebf0307b14aeff47e17a843f0001401ce6f5430101000e50006a065603c9005d0784000375065601046255025502059604069604079601a08001d2034f0a97084f0003960404045304bb023fe6f50a1f1c16d2018401541c16a10101361a02361a033617 08fa0dfaff8001004e0397039507970350f5079703bb0f9703089604099604550a96040b96040c96040d9604550e96040f9604109604119604a512960413761f8e1007500061ab00fe432001472302472303aa472304472305472306472307f04720d21fe4137f1e2600fdff48a623821b4f01609714c02402c024bd03c0 213e02fdffba27a7ff009602a3005e0284ff004d02a400ec01a0ff0034018700c40086ff008a0085002100933e37000900a4026981003e017d70dffc10270030552e3283c53f8e10921fa41f96018400054521e8f3f09002c3028400072d36f7fe0094370001006700896a50003e01a4e5f61c1fa936301d33bc32f3bf30 b3362616301fd4421fa8050fa30021bc343f1382a10104c43660321647c002540095be87329c006b00033d021c5cb02dcc020900888732110d0056d2005402150c033f4003dffc85023906dccf364c0f5e0f70010000750c49358c13d6044c32a93fff4f800570dd3fef3f5a1fb41b87005801309d4605360400c88d3014 335040973f8c5fbb3fb056d703c30200364395470d00021100016d4f7f4e010039063a019e4fb04fc24fd44fe64d6a59850367504a3f40da5f7c1ffe5990fc0b6f1d6f001900321cc70d71d360ac3fd26fe4662e15e466542b52fe6a02fe6a03fe67870734470200840d008830db5401e35f00956f3f007506d6063e3524 659025d4087c636234753400c90005110097000096ebf0258100387106aa3f4007370008b77009c9700aaa42200bb6600c0d300dd9700eaadd700fe17010e57011830012aaed7013f17014634015f97016aafd7017f5f01805801909801aaa0d801b11801ccf601dedf01eaa1d801f454020258021298022aa2d80231500 24073025398026fb00274b80290028002a024f804ac970427f547f667f787f8a7d04d20daa794a42205c8f6e8f808f928f288a7d8831d60604c28d08d38fe58f80f78f099f897ed850d507b500c48b09804b9f5d9f6f9f819f897e7860d5070302c28d0ac39fd59fe79ff99f897ed2800ad50707c28d0b3baf4daf5faf71 af28897eb870d50705c28d0cb3afc5afa0d7afe9af897e5a80d50706c28d0da02bbf3dbf4fbf61bf897e0ed3090e80c28dfcb0a5bfb7bfc9bfdbbf8b7c0f02d3090fc28d74c01dcf2fcfff583f00108915d80f8f786a06017407e6431f6515000536026b504af17094cfa6cf2840cf52cf8a7d11d30911c28d78d04021df 33dfb9cfcbcfddcf6d0402f7cf0902b4010edd1297dfa9df43df55df28897e3aa0d5070ac28d1323ef35efa047ef59ef897ea2b0d5070dc28d14809befadefbfefd1ef897ec290d5070902c28d1513ff25ff37ff49ff897e2ab00ad5070cc28d168bff9dffafffc1ff28897e4a90d50708c28d17030f150fa0270f390f89 7eb2a09d770bc28d18807b0f8d0f9f0fb10f897e9ae09d771302c28d19f30f051f171f291f897e8af00a9d7715c28d1a6b1f7d1f8f1fa11f28897e7a009d7717c28d1be31ff51ff0fd5ac020cbdfdddf00304f1b7fe8b4814e6b3f00f6cd501e51b426403610d75457201c5b2f006d2f7f2f912fa32f3366be2fd0203365 04db2fed221df32f053f173f293f3b3f7fb81e85eb51b89e543f10ce22e535733fed221e8b3f9d3faf3f40c13fd33fb52fc72fd92f1b441f234fa0354ffd5f594f6b4f7d4603fbdf02a828a1964fa84b5c572020bb400312dd5203c54fd748034b4eb061202b203e352c63e46fbd5f9e7404bb613277275400692b50a661 3cd94842615f1027003272be52c1f56042f961070b66be61ba6275d0942b92a731006ab860a66150d9463fec426f8e5530336662f3bf30545d668e5b06cb62952b9247572001215b5f6d5f7f5f915fa35fbe5ffa6e122a5404a671e4596af154406f3d7f48646f76672b5306dd328c6569396420f85f0a6af945176b2d68 4a3980986f00aa6fbc6fce6fe06ffb6f047f167fec5f00967fa87fba7f346f437f4c7f5e7f7c6f028e6523d37fe57ff77f098f1b8f368f10c75fd95f638ff382027b8f8d840fe000176b7490a88fc38fcc8fde8ff08f8a6901240f9f219f339f459f579f729f3f8f00518f9f9fb19fc39fd59fe79f02af0baf081daf2faf 8d66254baf5daf6faf81af0093afaeafb7afc9af277f3ebf47bf59bf406f7f817febaffdaf0fbfc97626bb408502bf420291b62ab089c4d8470200bfdffcc0f84b2e252a634c3f88c32c54282a6214e9e0a548d94617f242086f8cbf428dc03740d4b6978c20b33f22572027c3cf99bfe7ca94f5cf07dfc0794f2bdb6ac2 365bf2bf35ef0102caf74205a3c187dda04c5503004584dfa634d34c64d136e3bc13665488e5a48729572028a3dffff6e384bcdfe6432cd5dfe7df8dc0502101004d50e0a514265dd18dcf73db89df2b50b53757202987bfff26c1c026009fbfd9ecc0bfd2bb08fd54da25ff37ff001b6adc3398d528bf37cf40cf52cf64 cf034700f530e9f202ebf00154b81ebf85eb510c4050faf131bb0140ebf0250026e7f40b6b001e150018f3f02200f52ce9f201f1f154b81e85dfeb510c4050faf131017540ebf028e9f20b001c11003f180002001e00f530e9f203ebf00154b81ebf85eb510c4050faf131fb0140ebf02b002c002deee9f20b0020150018 000207002200e58ce1fa08dcffdffc400042bf00c407ad00b0fcf02a2a1b04fc2300dafcf0280c0f4c0ffe0f0f002c08ad0002090700002e5c00030025000200280003002b000700ff4600ffff00d60300c520ebf002eff0fcf3dcff0000f7030068ebf001540000b5e8e7f449e8f3d03f2a063faae8f3c03b06bf2a04f0 3205f01f3f04000410060f750feaf1a501eaf10ef9f02a06fe910001d2950a023c069e01034506fe08bf000206620400c80107eb6200cf0208cd04096210a5009e01044e069e0105ed0700779200048b00df00658b00ba1e0114e7f4050048e9f2834e07120a00c9f9f01e012a890201261d103f1f511feb1801eaf120f3 f000000afeeff2ff00010090888fdfff82f88e77080b0277ff708a00070777f8f8ff7777078877087077aa210d70270007360605400283ff7701078677017083540b00500c70540007580184510019856d087400708471038700860aa6830082f878039e05042a00707d85ad0b8677030777770092c40b826b00d8078751 02080f8e7f8801f88fff01f80000bd62e3f8c0bf5655fdf1c5f53ff4f43ffdf255b5bff2ff342b6d0309c5bfe6ff174b7eb1e4c73ff0fe15033f74da40a70d747bbabfe8f3e4bfa8aa3d01dde23304d83fb03d02da3fff4800ffff00d60400d522ebf004ebf0fffef22600740401e2f901f9f002006813015f5400009002 e8f340e8f3dfc03f4040553701b53f422c04d03d0e330037023b00500b0a53000e19002c06fe7100013506d27e01023e067e010391073400f7030205150001040500510c1500b302ac0207b80002c202d503c20204c20200c2001200bf020475026020e8f3e0ab3f05a80103ad0205b3020104b302f20207fe00c700fe00 cd00fe00e8d300fe00d90001dd000575034b60205a03d5ec007100066206bffe0800020762401308e24714094711090c431002804c21405a10500f3e075a03c54f0f610d92dd0000e10bdd0001271bdd0002aae107f0c813032717e5ec000a14aa02b50004dd021fe3090120f2000ab50005231220e309351bdffc6e00fc 532443100e620100fefe4ffffdfffe6b200a0b218000ff6019284329205368ff6170657761726520ff436f72706f726174f7696f6e5910a3004002ffa0001f029c004a01df840033019bf9f00500f777026c190001550000a91056231401071900615911407f30b91aa2d33cd13d05081401b915d523f1c818e6f5ff12d0 02350a13300316120a012c073f05f8e627c11fe517401593ab21af3acd93bfdd2f205933b3b1bff82f5630d52f000b1900722d01133000fea43001a83165205f00008b00ccbb3094bb30d75c008a700089b122f6000971cc00200134c124203de4293c3f26e8f3d53c56302d06533704f63f00c91726433111a114db2fe2 00a213f62f248c32a21395603f2915b57b3f8d31f8213f2f4f453ffe9900e400579900acff4074ff403cff4006b2211c017d98ebf01e00270002e9f2ff37277a000700ffffe2e4f7010d00f6f3defd060046ff00c6004caeac0072af090000adebf02329008cffe6ac001f0a000091feebf00a004400b4a8acab00b04300 014704c44f00b1fa53042b2900d4b5ac00b2ea430048ebf0482b000cbfac0b00fa4300511200ff4600ffff00d602008520ebf002eff0fcf3dcfff8f168beebf001540000e8e7f441b6e8f308402a0dc03f3c05bfed49e8f3f03f4e0604000858f6f1660f780f0001eaf10ef9f02a2a06fe910001950a023c069e01fd0345 06fe0800020662bb0400c801076200cf02087b6208cf02096220009e01e9044e069e0105ed070092009d048b00df00658b001e0114aee7f4050048e9f28307120a0100eb7b01eaf120f3f000006dfeeff2ff00010090338fffff82f38ebb82f383ffbb01b88378017b86ea0b03b70e008b160182bb06dfb3383333bb1502 82bbdf83000303bb210208bbdfb30fffff032d0306bbfd8742000787870b8bf3dff3bb7b0ff9440185bbfb0b7b57008b0099900bf3bb8b61005602bbb93bbb5e5f07bb000bbb6d08b07903fd078003b08333018383ef3382bb078e0486000831037a0065016f01bbbbb6005602f06101c202b90fcb0f8bbb3393fb333be3 06b00999003b7ed5040a8bb0ff9ff0fe02ff87780870fffff078ee640087bb091510fff03bfdbb2811027bb08300826e0b0087bb04dd008b833e133acf007b481383870147120a01ff8e3301f38fff01f3fd6eebf0436f6e6e6563ff746f722077697468ff20757020746f2035ff206c6567732e20558f73652063f3f604 00130420ff73686170657320627f7920706f696e740301f632022c20f9f064796e61ff6d696320676c7565ff206d6574686f6473032e005602006d62e3f8d8bfe8f3e03ff4f4fe0304e0bf6ea0d3063aff6dd8bf38d069039d6f36e03f6c15033f371d0310fbf40a060305fbf5bfff4800ffff00d60500d522ebf004ebf0 fffef227005c0401e2f90100051500681301d554ebf005e8f340e8f3f63f5a2c04f83405e8bf2c04f04605ddd84605e0bf500b0a000cff000202750c60750aff6004fe0f00020375ff0d60750b60048041bf40fe0e0002066206fecf110002007800750003e42f6202000699010184008100fea40412000204750260ed20 5a043f05bb01057503fec2090b000207620000f48801e00008e40408000209bee400fe2e000302180101950425010907100c15020a1005261801090108121f10021d10fe000103021219100a161f131913131317003428102907fc34050040470534058ff03f01008c005b178b0101a465168b01026e168b0103a2173ad3 000317021603010110000001062f10cc10c91307104a135611ca1282351300ba100113c31fd51fe71a340300031f1004103123092309261c13042811e818012e202f13372f492f5b24bf000008020302640a07967e006101f50108a600f503037ab6220ab4214000030b042f20162b802f50132211c8200ccc2fde2ff0f0 2f90250c09f60002804c4043fe102f22101001101010032a067a570841c405419ff4498c306bcf3f8234d08a35bf3f620cfd1972014c6081012d40ae82368102098a0203b930757f1f60802e40fe449b00b572ea11c0e03104c0bc200b9ce400e63404000bc00ae030095f00c08016401040724a11840f41db3101e03dd2 0af337f0330951010f485242bb031fc20e20c209308c0b5e3067340e12040a2d121010e01801110447374731f600016201eab62208cc440acc41321cc7cd71e140ac3fe04ff2460102ff01008700b804a000ff88049c0046038400ff2003a4006e029d00f732019bf9f00700e0043d6c031155000020faf11301e501a821 00ad20a92001610002415102465082342a06140182115056268f1a00fea64053120a875030213a865001505de0bf016750de330eea3002000b0a43f337e033c0004f620a0006164616400a0e45284f502243ea3001b45301e538c6544103ce565242dc5152457f540387563830606e00703f0100a8a957f4534ce3330d41 0f40c0006e60090a43e781015b70617e610b8102831d400a43cc51a7001349e03c091f81021e40728651fc59561122b15106c16fd158ef66fe5460ec5550b353656452406f60037366017d630503846b010c6298671863a86fba6200fb56c3512811d069707b5b45f267805321048756aa709315476a4b556ef73300b762 3061e532e436fa33e8731341cc6200e254cc70ff6cea33e475fb53284c3383040784216c05875668803d674506a45c00d77f2b47cd504c10cf5171611440aa71001b42e958228ff4370e60b6851a70c183245e43768ff0a550f60000c000f501fd01d200fe8b00da038bbb0042379084028b91508bff0060008a001c0089 4e2152000470bb102001b06d30f828085708649f01030100fda5ff6e0020bd00e03102e5320338ed74c00019716540fe91904042ac999f1a706740415106ad203bc09b00f034b99c9f024981174275666f60756760e4016940e4010b6440d79101dc9fc951b002fe71a45b4200a76b0ba5e000020a42003adf01034e4200 fe1cbb120a1000673383542e6364a01f139f438d543863fd14ec00600c41726d20ff506f736974696f6e18c621669f520d05058a949ca094921e9f95806640fe9ca04042e5a64568cf962fd99ff19600a76a0ba5100cb016ad2ca600a76c46aa4a1157a40e1c1100fe28bb146ca1e4154c110070ad80b0312288a152251e 118caf9eaf822c04e246054506ebb8d4afe6a57416efaf8075cf96350dbff19f03a441760ba540c03ebf2eaf05a27746aa38561258a3281100fe1681546ca1003061a873c0c025132f103a61b273d0bff700feaa3d90aa0050017daaf9f00300a00364f9f0c22001109b2459565956c304104022c304146d17c3047e111f 72019f00f8b000760082006660806e40ae03a30503fe58d0035cda674f60806f4000a071d329929c5380788cd178000303a003a103c272d226b29c53c489c301a2806d1f40fe6400033513191315230019102810071028103516501578a5a873000e18c3bab2733c13c8200d16c0b618ec00688131ef7083c820173f293f fb2a07e80305582d128fefa1efb3efebdffdd73aebf09e11d10005027d98ebf05a00270002e9f2b7d65882ebf0ffffe2f901f7000522dcff00000600ff4600c600ecceac005fbe0d00009bebf0232900ff444ead00590e0000f30a01440029002cdfac00df630f000066ebf00a007f4400b4c7ac00c95300f64700002b29 00bceeac00d5ca530034ebf0482b0044fdf7ac00fe530014060000ff4600ffff00d60300c520ebf002eff0fcf3dcff0000f7030068ebf001540000ede8e7f44904e9f2f03f49aee8f3e83f3fe8f3c03b06bffc33043106f03f0400041028060f750feaf101eaf10ef9f02a0625fe91000133069e01023c069e01fd034506 fe0800020662bb0400c801076200cf02085ecd04096210009e01044e067a9e0105ed07009200048b00a7df00658b001e0114e7f405eb0047e9f28307120a00c914f9f01e012a89022c1d103f1f511feb0201eaf120f3f00000f4fee9f2ff00010090888fdfff82f88e77080b0170ff8c000407f8f8708cfd771e02857701 708677fd0b1f017000700007703a290005310284008229001e09ba1c0b862b0085770a310500bf77837083770d310300050772007076004a0a500f21013002ff7777000777700785fb7706ad0383000b70079639007777910a031f000a0d8e7f8801f88fff01f80000b562e9f204e9f2e0bfe8f3d8f53ff4f43ffcf4bfa8 703dff0ad7a3e0bf48e17adf14ae47d93f14043f4c561d03bf02e9f2f0fbf4ecfbf40bc0bc44043fff4700ffff00d60400d520ebf004ebf0fffef22600dc0401e0fb040068ebf00154af00007401e8f340faf1006f00e03f40e8f3d83f2a0425f03205e83b05310850e3f82300570e00022907fe6f00013306d27c01023c 067c01034506fe46af000302066b0001aa03009907ac02b7020008ac02c30200bd05ac0104050003b6000568ebf0d901b5010570000700a700a903ab02f00301b70203b702012ac30203c30201cf0205d5021410f0dd0014121f11e90001120002cf04750260f6f12e0205fe4e331005750339196f00066006bffe080002 0762621308f26914096911ddfe840057017d9bf9f00200660165ac01ba1f002ce7f4060048e9f20772ab1408edf0eaf1830012c110750ac11004d6001a0071d600da1e01f8e7f440102c0be83fad01c310020037110c3c1901f24917f04210e2170b59c842cf16b290bff41f0627642186242196bf1820e6f533062c27f8 06fef2df3c062d411133044306622ff9ef052e41119900ac0099ab0074c5203cc52004f9f0e40100ff4800ffff00d606009d22ebf0110005eff0fef126ef00260029e1fa010006fa1500681301540000140276e8f34004e9f2e03f40e8f3bdd83405f03f4001e9f2d0b8340533004803c03f500b0a00ff14000202740260 05f70020f8fef2ef3f05fe6e710003740377015755900145d5820300750351058302018903dea30752000302180101045506fbf007170000ce0201ce025502ce0203ce0204ce0206ce025507ce0208ce0209ce020ace02fd0bce001200020475025560b60b03c50205cb0201d102003410d9003410df003410e5003410eb 00003410f1003410f7003410fd0034100310d03410091034100f100113100575bd0319190e0002066206fe5f08000207629413089b14f1099b11090c971002804c40deae10321cc771c910ac3ff8c81fda16c70000fefffdffe9fef3100a0b21ae00601928ff4329205368617065ff7761726520436f72ff706f72617469 6f6efead10a300c80187009ebf01840087019bea0004ef00ff016cc601550000e95848031401079a006100fe0a4f2001532302532035042a000e077a1310001717000005fe131049017b1786210ae400cb010a081009033410a220013e076e2f3f05882f010563254508c22fd42d0a316427f22f68802f163f6c290b9a00 72010810cb00fe6c30017031ee1000007f8b0010018b00d88330fda0833068008a001c007d89ea0006003a01699a003a200108e5f604006ae400a43d0971ea002001d825055106ba2fa30704d62fe82dc0f92ffb3ea901500d303f00fa3f1c3f1e4f403f424f8c4f664fb046427b03df4f079247f145fc37fefef3027d41 fc7c04350692472955fc37fef331f7553f375ae8f3c0bc4c5f0e4035f0fef2cff84f60209955145f122656e7a05f4255e7bb5fcd5afef353cfbfe25ffc37fd7c03bf9659f8126fb45f366799006c0299fb00347b60fc019900c4aa83608c83605483601c8360e4af009900ac97607497603cfe976004000c00a4020ef4fb f0200117e3f861747472ff69627574653a547907706500ff4800ffff00d606009d22ebf0110005eff0fef126ef00260029e1fa010006fa1500681301540000c001f6e8f34004e9f2e03f40f86efef2bf3f40e8f3f03f2c0471d03d0533002d03c03f500b0aff0014000202740260f70500203603ef3f05fe6e7100037403 77015b55900145d5820300750351058302018903f5509002c58200280003025d071500010407ebf007ce005501ce0202ce0203ce0204ce007f12000204750260a2082ac10003c50205cb0201d1020a10a0d9000a10df000a10e50001e900057b7503ef090e0002066206bffe0800020762401308e24714094711090c4310 02804cbd405a10321cc7717510acf13f741f8616c70000fefffdd3fffe9f100a0b21ae006019ff2843292053686170ff657761726520436fff72706f726174696ffd6e5910a300740187007f4a01840033019be400df0400ab016cc6015500f300582504d2020200610015fed70001ff1302ff103e042a00f40e07e90000 ed07000005fed2e90001271732210ade020500250a4f20030a104e20013e071a2f043f05342f050f2545086e2f802db621a010279e2f2c2fc22f18290b9a00722d014f2000fe1830011c319a10ff00008b0010018b00f5d82f30a02f3068008a00f71c0089e40006003a01e9699a00200108e5f604006a24de00503d71e4 002001342505510610662fa307822f942dc0a52fa73ea90100500ddc2fa63fc82fca3fec2fee3f384ffc124fa5059900e400990055ac9f40749f403c9f4004fbf0a71c010efbf0200114e3f86f3b7065cb13282900ff4700ffff00d603001d20ebf0020005eff0fef1dcffdf0000030068ebf001546f00001801e8f34004 e9f2b7e03f40e8f3e43f2a04f0173f4002e9f2d03b0531004603e7c03f50e3f823001400029f0274026005f5f2400205ddfe6f0003740375015855aa8e01d58003007309e0800301d68703abaab601ea80001600d70302096b0001c20300084ac40104bf0003c302d80301cf02ff0512000204750260dca008eb00057503 f1090e00fb02066006fe08000207d5621a13082114092111009b3b00046b000f0165c4011f005d14e7f4090048e9f2833712a70a00c9f9f01e010669022d004d10ff4800ffff00d605009d22ebf00b0008eff0fef126b9000401e2f9010005150068be1301540000c401e8f340bd04e9f2e03f4002e9f2c0953f2c04f034 05d03d05330850fe0b0a00140002027402ef60080020e8f3f03f055dfe7100037403770e007509e5e08203018909a901400003bb02091500010409ebf007a900c501cf0102ce0203ce0204aace0205ce0206ce0207ce0208fece00120002047502602ab60b03c50205cb0201d102221000d9002210df002210e5002210eb 002210a0f1002210f7002210fd00010110057b750307190e0002066206bffe0800020762701308e27714097711090c731002804c7d408a10fefffdfffea710fa0a0b21ae006019284329ff2053686170657761ff726520436f72706fbf726174696f6e8910a3ff007a01840063019bbee4000300b3016cc60155e7000058 2504d202020061ab00feff1001032302032040d4e6f5142601001100051700004b05fe011001571736210ade006ae9010a5320033a120a013e07001e2f7b073a2f3e0f722f842d81011427d0a22f302fc62f1c290b9a00720156532000fe1c300120310189117f8b0010018b00d83330fda0333068008a001c007d89e400 06003a01699a003a200108e5f6040071de002001f92436031c2740284992244f4992c4bfe22f8427257f32d3e4bfce264500948130244995c28538f8fef2ef8328803124a349e2a9373300b633e2bd3edf06cf3e02c0ce29b63f903fda382d06106a2fa307862f982dc0a92f774ebd02002d0ce02f764fcc2f9a4ff02fbe 4f085f74e24fa50599230099008c6f50f5546f501c6f50e400990055ac7f50747f503c7f5004d000a7fc010ee400200113e3f843ff6c617373204e616d0365007dd8ebf09600270002e9f2ff8e0194000900ffffe2e4f7010d00f6f3defd0a0046ff00c6008cffac008faf160000b2ebf02329000c9f81ad004117f0f126 0144bf00ccfcac00d7430001aa4704dc4f00d853042b3b015357ad00d943003debf0472b00ff845bad0016180000f57a5600482b001483ad009f90190000e3f6f08a01d4ff87ad00731c000036fcf6f07a010440ad00a91ee70000e8ebf08a010480ad3f00911f0000751200f9cadcffe1fa03000a003fff005200b405ad 0030ef09000034ebf0c90044bf00fc74ac00641b000efeebf01e005300d4a4acbf004b0d0000732f04b4ffc3ac00121600007df0fcff600fdffc3201acfeac009f06220000aa700fddfe02020d0007a002000000000000000000000000ff1500ffff00d31a007144ebf0f0f0fcff00f0bfe8f3771140551a01f51540feff eee6f51a0046ebf00154038b0020ebf002eff04c032a0f00ef000300684701540000fbbc01e8f34954b81e85bfeb510c4049507c0131b701403fe8f3c03f8c05bf85490a043f9e067304b60fc80f005273020e49007a06fee100018306d2ee01028c06ee01039506fe08bf00020662010018110797620000ee01049e06ee 01058e2d170010102106481f210604e1045a1f771f73001910006210021f12019911fd0121060a12a91a6d17883612a9171912041f14e210e10008aaa91a09a91a0aa91a0ba917007fb700cf00920004490087af0165db006e016a01eaf105eb0048e9f20643220a00077243220494104c23090047ebf04912db0064211a 49006421226700be64212a0083003a81203254812080212281201a8120128120390a812058214200c949006e015d2aebf008002edb002f490055306700254120284920315120a53294102b6120e6f547db00012b5404450205d9020741204e0ff456216a0504730440a8703d7f0ad7a3e03f40a01a3125231f3004a00421 04e829351f300ee8f3d83f50d10be1011836ee02f02136a4132b35b219e83ffe288f0003020edd21e000de2002990f9a32a53202109a32b13202aa953003993201993203a53201aaa53203b13201b13203ddfe16cabe30062b20014920fc300106ff001100010b8400d15b009b2b22f80032252ce7f4550e43240f432410 632200952a15033b0028a72436d905f92ca103ac34354c05ffff9d310fb6301153007167006e01887915103e3b05e88c00106700fa39b6400540fc37fea2470b59c84216b290841100801dd88c0021043136fa4199ab006011504c1150381150042a2b2074632002df2a02ed2fff2f0c1135840251fc203f323f443f5639 a063556a3f7c3f8e386821016722013302139a32ef5202149a32fb5254bc32e35201e35203ef5201ef524503fb5201fb52e43ff63107fb32a644620107074f194c1243241312432414394f4b4e025d4f6f4f4c041502672013006015914fa34fb542004469c6414469d64fe84ffa4f0c5f1e57c103df2a02713a5f4c5f7c 122a5cff8fc2f528084040403fe17a14aec7dc7358a6621380eb8558c873db975f5f30ad7548b453b675c25f03c7769432169a32662d8202179a32398202189a32a84582bc322d82012d82033982018a39820345820145822e6ff631084cfb328e820108516f194c1643240517432418836f4b4e788fb86f4c051503f530 174a8019db6fed66c875e0b4438e89c6418e89ec67b390850f2c642193317ada7546798897aa5c7f74432005df2222e52405204900847fda012c216a05d879157b03fe6950a80d74da4067f3da7c55d009aec03f190355b540e17f5f30f995b45302a5a419d0cf5a2864a08320d00b3af73502fa32f9300a9c800c446202 4462436098a18e8271028e828d8098a1840081a38409ccc32034232ee524dbaf0fa10ba5ee7e4705006ca721550000fd70d407074030b91aa207d33cd17c55da011ca70ba52cb0ff1593ab213acd93bfac23b91bbf008bf5f08bbb208baf001c008a5120892b20050b00582596d0791b35b6eaf1953000ff338fa49ca9ae a99530c943afbfc1ba821ca75327a4327026a321b808c695b84ab790bff0a19900a4a59090eaa5907ca590681d520500b8aa432006410005c1920647220350cd9fd902bc906906981135577c02aff23f40527c01117b50faa44c0208a00c0ca5afc3e3b6c5c0be2dad0c000240b41a3bec553ff89753a7c2f2af001b4900 e5707301070cb00fd2010080bf0b407a3340fe0ad0010c0edf20d50270e8212ed145d21cd9f10344df20d2931002030202f4a66673000d1820744e60015f007a7340fe89d00c8dd0c90591d2cf0c1cf73e8ca7ffe3fac0cf41e8f3e03f419ff45549ecd0cfe1d5d0ead5bf2daafee8f39c00360184000bff01a400de009d 00493ea38205007d016c33210bb001a0d505ec20e2d4871a44e7cac52cb040c1ce6aef7ce8b5c690ef3cb38b05b0298b7fb06abf045120804f46d4a1b06ac1ebef82501104f0bf7e47060300642794f6f17c1feaf146017f618d4038f41040487638f408919e22fb323c0db02c206f00a41ff5c1ce6676ff01031e105304 40f64c0299e97ef8a7fe05059cf8afc27fe67b56c83cd6ffcaf9aa0061520500310500de819143200761ca11076fcf81cf93c7556455a6c68d0489bcb7c739f3b06e05d0cfe2c05600645bf4cf06d6a6612ed1c7021cdbc70f203cdf4edffd0f72df84d90291dfa3df00436c9ea724f67f08e2dff4df06ef18ef002aef3c ef4eef60ea790e222f34286d0600482fb6efc8efdaeb2ed0a22ffdef0df2010715ff27ff39ff4bff5dffd72b7f08182e3f9afaed63e8bf7ff75f3ecafa811491534ab5e6f08f3efaff0c0908a261ca08270f390f93c72cae72037940a5c7e8e3f4bf400a0ca5a2e8e3e42645880fe2c02dae75a100a70fb90bf0812ed17f 421cdb7f4ff40f10061fb54f2a1f84d903491f5b1f8d8c06b0a700e43047921fa41fb61fc81f00da1fec1ffe1f102f2cb0415eda5fec58402540fa5f2647722f842f962708a62f04b32f0df408cd2fdf2ff12f033f153f208f65415ee66f9afab8c3ea3847167f6ccafae8e280f04ab5c43c467f5cb23f0c07470009d130 03a762a20291097310e23fab6103fb36f042f19e50b9026d4002959664e8d375443d90a963d82daf3faecc75fe51804b020a46820b46822782022d8253020c3a87a5b103278201278295032d82012d82033f82668301c859a2029566a9e873a0f28d0140778400d1c3a4e20065cda4a52cfb840ab990ab610bbf840c5c85 70ab61830012d5800ad5800ac8311a9326369372908dd57586852afaa709bd800be0c00db990278012bf941287709671069b7fe192fa3731b88f65e77695c280de09a5acc045f40df2a709a5ed70829397f77dfd14cc40740360090020bdf00df2af3f05feab9000a37402b1915355bd9201af9356aa0cc2e4bc9302c393 f80df2ef76bc90008577ac08008455c012c4a3aa05b0a253880fb9b55f956500ddf63eab82952cb6946060afbc59306f8278b30605b007816af1f28a82b5289095c58b9628ce7f969707c18b9ca7e0f8a771a6f7af1db4f193df3f4095f30df2b707c1fcf294b8f4b1680cba55b8b593cf3fbfffe77bbfc28db1f2839371 6073b7a5b79900d5e055c0cc55c0b845cf0054aa55c04055c02c55c01855c20ca300f4c7802d801b0413359407283d9ff53c5e9ffe0df2cc7798e8e349dd8998e8e3cd9b9fad9559de9229e3bc9fce9c54de92d3e49ff69f0008af1aaf2caf3eaf50ad51c568a92fdfe886af98afaaa911a5786368617f72676528290069 8764ceb685000017b470b6602700ff32721cc7711cc7c1fc01602b500202620200fe4b0094519223c2a068f3808f6b04daaf4cc8cd20ba51c5946900effed944dfbf9a516885703f808b7402359449080ccfad7ac45f9ea963e4d37800ed437600e776ed43404eb6c7bb658cc2caae9458de92d58bcfce9cabaa2a26f1ea 04f01024800d348233f2e5002ff00333f242f30100b30ee0c20100b9ad868f333f11c883e4de813181c99524da3101002d40259233f08b701e01229196710973ef02af800322cf6598c8e5acefcaffd0ef02b9c10ce7ef150e0af11606cf983e0a00cacfdccfeecf00dfd57ca20be6f568a9d0c40f55df67dfaaa90e7de8 4d6f17766965c7800e2b9829813a9f404c9fc2ff709f829f949fa69901b39f00b51111feb610dd9eb610c0c8928cac6000720f840ae10f0edf51af63af652feb0f00fd0fabafbdafdedfe1af1bbf05bf17bf0029bf3bbf4dbf5fbf71bf83bf95bfa7bf10b9bfcbbfddbfefb70ffab83a130bcf001dcf2fcf41cf53cf65cf ac1a84ceca1f00b412accef21f042f162f282f3a2f4c2f0029df3bdf015f942fa62f83df95dfa7d50cb561b3df6200c7dfd9dfe02ffddf200fef21ef33efe23f57e61061e83a130072ef84ef96efa8efeafffcffdee5994640efe8b610fdee994fb41225fb112882523772023ff13772013772034fff0261f6116bff7dfa 6e71377091f66460809dffafff304fd3ffb96fcb6fd9ea1000eb6f198e3a011a86cf98428ace4fe04f00f24f045fa70fb90fcb0fdd0f5e5f705ff88254b05364f34368696c640f72656e732615381031168350803d1f4f1fc57f731f851f971f74ca0200b71fc29111fec390e11ec390c44f6b8f007d8f8f8f205f48af61 2f732fe98ffb8f00a92fbb2fcd2fee5ff12f033f153f9b9f00393f4b3f5d3f6f3f953f8cbfa53fb73f00c93fdb3fed3d0740004647930f4f214f00334f454f574f694fb99a884ed79fc19200b04eff9f11af23af35af47af59af2d5f003f5f0edfa1afb3af875f995fab5fbd5f00cf5fdfaff35f2d6f176f296f3b6f4d6f 025f621465684793766f886f9a6fac6f00ee7f008fe265a6c6f368c390017ea6cf84c192297b15387244f2427244f2010844f2527f6477156f7f817a7bf144f000957618f1a27fb47f3ecfd87fc7efd9ef02de6914f8ef260e1bf12706e0984f0a00dbcfedcfffcf11dfab8fbd8fcf8fe18fe86bdf7ddf8fd4168ee85265 675f756c6172203395163c980103acd04b9f5d9fd3ff819f939fa59ffcb7996860dd1bd6be61ed81ab15f76863dd9b6860d510d310e100c4c76860d1cf780f8a0f9c0f2ddf542f006eaf80aff60f081fb6afc8afdaaffbdf00feaf10bf22bfa71f46bf58bf6abf7cbf80a2bf983fb2bfc4bfd6bfe8bffabd17400bc85313 1ccf2ecf40cf52cd0763cef86e437acfc916e2b0f60d6b51dfe094df1ff116dda242d0012f00132f252f372f492f5b2f6d2d6e458529004c5fa32fb52f8adf9cdfaedfc0dfd2df00e4dff32f654c3feb6e4518591d6f1b6904fc3f69e51872e8531383ef95ef7f1f5700c0e5ecf805ca52d7fef8c2d363c7874fd545faee b240c7da9f37ac7dc3daa84feb1c4ebf09f294204fe93df4191045f250724ff250720150725fff71f741197cff8efa877150704a140c64e0005511b1ff6b1fb16de565c96fe77fed6f02cac118047f328e1bf13386e0985b8a00e74ff94f0b5f1d5fb80fc28803858529d0e18f725f845fc7291a9a684e65ff772052656c 656173e9653e14e025e0019d402c499f92244992cdc9319616988e72902449ca769706608393ea40769766308398acecb3680086c73d31820c8cd7293ad39fd199ec3f656f0900de70010000000000fd40e9f20a0001000154ffb81e85eb510c4050f6faf13101eef325002800ff2b002d002e002f007f30003100320017 ebf0f717000b15000b0018000f02003400fd1ce1fa0100400042007f649bac00d53100fdf0030000fd3ee3f8010003001500ffc30004b0ad001f23ff0000b00e0000c900ff40008c90ac00cf31f7000006ebf03f005200ff8492ac00153200000117dcf200000000000004001918dcffe7f41400dffc03000023ebf00100 ff506167652d310000fd06f5f0426c61636b207f66696c6c000012f5f05f576869746509040401027d751804010052656409047f0100477265656e0904dd2df5f043796140040100bf59656c6c6f77090347baf5f04df9f06e74613308613d79280531302520780914037f6c696e65000083f5f0fd33850c4c6f6e672064 c761736831009a032204646125720805a04905cd08ad3906cd0781c06508cd072e030c195804cd0801ab0035850c37850c39850c314770786c9903a2006d18396d18ef486169727113010053ef686f7274b80a010041bf7269616c20636b00653f7265640000909910b013ff746f70206c656674e700009cc119f5f05469 6d0b6573b518bc9910e413de19ca17fde19910426f78000102f70000430d00436c0200ff5375627479706500f32102e210b1106e676c65fd003120436f6e6e6563ff746f72000200556e1f6976657273b311412630217d463d00204c6162650d00fd3e31204f7065726174ff696f6e7300004a02bf0200636c6173e8106f 9f6d70617274f5f0842a2e1732360081205244203723922d6731007a3120942c0089c52ee733009931204c2f722e37fcf5f0f02f722e38003300ff14033300fa02330055e62530d22530c02530b3253055a025308d25307d25306e2530555825304b25303e2530322530552e25302a2530212530102530dd012530f00133 1320330055cd6d30bc6d30a76d309c6d3055906d30846d30786d30686d3055586d30476d30346d30246d30550e6d30f91d30e51d30d31d3055c01d30ad1d30a01d30901d3055831d30721d30641d30551d3055471d303c1d302d1d301d1d30350d1d30041d302c03ff0604000003000a00ff05003200ffffa8a987a80009 eff0030f150fe6f5ff01ff1e0f430f550f670f790f8b0f9d0ff701000ef1f022002b00ff2e002f002c003000ff27000f000600290007090010cb022a05d90fea0de8f3970f001df5f0259e0fddfe053f00020004000b1a1fddfeff03001a000d0011007708002aebf02d00122f10fd1b07101f0020002100df2600280031 2d100b00d113d70f901f98140af3f01700ff0c001800140015007f160019001c001e03102eb005230024c302097f1fe41f00a316ff1f112fac03292f3b2f4d2f5f2f40e4f86a2f8e2fa02fb22fe3f807be2f10e22ff42f063fe3f808123f363f483f845a3fe3f809663f8a3fe7f46e1932607914d02fd60ff40be2f90b00 fd7ce9f2250004000154ffb81e85eb510c4050eefaf1310140ebf0010002fb0003f5f00500060007ff00080009000a000bff000c000d000e000fff0010001100120013ff0014001500160017ff00180019001a001bff001c001d001e001fff00200021002200274f0029002ae9f20c0117ebf0d70b00641f00180d006e00 056ce1fa06dcff0e0f200f320fe5f6ff400042004406ad001ff43500007e3c000000000000000000000000000000150000000000030000002bad810173c401e6f5eff3010003fff2c7090067f6f5100fdefd28adff5d633ef661e14028cff9d053413802340ebcecb9acf7f20b08b4a2ace7f414ff0016005200dc45aceb 0038ebf054ebf0170040bf00ec40ac008cebf008be8304cc41ac00948f0418ff00d2008415ad009cfaebf061ebf026004200bcaf46ac00fdebf021ebf01abea700540bad001eeff092bf0700001b0044e9f2b0d49201ebf01cd70c1d770084e97fac00b022000063ebf0ff240050002c42ac005f132300000cebf0277700 ff5493ac002c320000fd3cbf024000e44fac00e9681f10920129b700645bacfb00702f14180160000cfc0b10e6f53200460004e0f7ad00781f106a020000fdca57101cd5ad00e234d7000012eff03f77008ca07fac007236000020ebf07d3d0710c401ad00927f10fa12113cd7000c02ad009eaa7f100aebf043d7001c9b 10a8027f1006210000000000000000000000000001050000050000000d0000004d45544146494c455049435400702300005deaffffaa0b000008007023a3150000 010009000003d10500000700130000000000050000000b0200000000050000000c028e022f04050000000902ffffff000500000001020000000007000000fc020100000000000000040000002d01000009000000fa02000003000000000000002200040000002d01010004000000020101000c0000002503040043023701 1802ec00ec0137014302370109000000fa02000000000000000000002200040000002d01020004000000f0010100050000000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01010004000000020101000e00000025030500a1008201a1005c015c01 5c0118025c0118023701040000002d01020004000000f0010100050000000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01010004000000020101000a000000250303001802820118025c0118023701040000002d01020004000000f00101000500 00000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01010004000000020101000e000000250305008f0382018f035c01d3025c0118025c0118023701040000002d01020004000000f0010100050000000902ffffff00050000000102000000000400 00002d01000009000000fa02000003000000000000002200040000002d01010004000000020101000e0000002503050082016400ae026400ae0256008201560082016400040000002d01020004000000f001010013000000fb02d6ff0f000000000090010000000000000022417269616c204e6172726f77000004000000 2d01010010000000fb021400090000000000bc02000000000102022253797374656d006e040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d0100000900 0000fa02000003000000000000002200040000002d01040004000000020101000e000000250305008201ec00ae02ec00ae026400820164008201ec00040000002d01020004000000f001040013000000fb02d6ff0f000000000090010100000000000022417269616c204e6172726f770000040000002d01040004000000 2d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0104000a000000210508006368617267652829b4009301040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000030000000000 00002200040000002d01050004000000020101000e0000002503050082015600ae025600ae020b0082010b0082015600040000002d01020004000000f001050013000000fb02d6ff100000000000bc020000000000000022417269616c204e6172726f770000040000002d010500040000002d0103000400000008010000 050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01050009000000210505004d6f766965003d00e601040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d0106000400 0000020101000e000000250305000b00db013701db013701cd010b00cd010b00db01040000002d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffff ff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e000000250305000b006302370163023701db010b00db010b006302040000002d01020004000000f0010600040000002d010100040000002d010300040000000801000005000000 0a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000a0000002105080063686172676528292b021c00040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000 020101000e000000250305000b00cd013701cd01370182010b0082010b00cd01040000002d01020004000000f0010600040000002d010500040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0105000d00000021050e004368 696c6472656e734d6f766965b4012000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e000000250305008201db01ae02db01ae02cd018201cd018201db01040000002d01020004000000 f0010600040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d010600 04000000020101000e0000002503050082016302ae026302ae02db018201db0182016302040000002d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000a0000002105 080063686172676528292b029301040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e000000250305008201cd01ae02cd01ae028201820182018201cd01040000002d01020004000000f001 0600040000002d010500040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0105000d00000021050d00526567756c6172204d6f76696500b401a101040000002d010300050000000902ffffff00050000000102000000000400 00002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e00000025030500f902fc012504fc012504ee01f902ee01f902fc01040000002d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100 040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e00000025030500f9028402250484022504fc01f902fc01f9028402040000002d0102000400 0000f0010600040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000a0000002105080063686172676528294c020a03040000002d010300050000000902ffffff000500000001020000000004000000 2d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e00000025030500f902ee012504ee0125048201f9028201f902ee01040000002d01020004000000f0010600040000002d010500040000002d0103000400000008010000050000000a020000000004000000020101000400 00002e01180005000000090200000000040000002d0105000c00000021050b004e65772052656c6561736500ab01250309000000210505004d6f76696500dd015d03040000002d010300030000000000}{\result {\insrsid13379340 {\pict{\*\picprop\shplid1026{\sp{\sn shapeType}{\sv 75}}{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}{\sp{\sn fillColor}{\sv 268435473}}{\sp{\sn fFilled}{\sv 0}}{\sp{\sn fLine}{\sv 0}}{\sp{\sn fLayoutInCell}{\sv 1}}} \picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0\picw9072\pich5539\picwgoal5143\pichgoal3140\wmetafile8\bliptag-1976574852\blipupi299{\*\blipuid 8a2fdc7c11b987f69aa7602fe7ed679f} 010009000003d10500000700130000000000050000000b0200000000050000000c028e022f04050000000902ffffff000500000001020000000007000000fc02 0100000000000000040000002d01000009000000fa02000003000000000000002200040000002d01010004000000020101000c00000025030400430237011802 ec00ec0137014302370109000000fa02000000000000000000002200040000002d01020004000000f0010100050000000902ffffff0005000000010200000000 040000002d01000009000000fa02000001000000000000002200040000002d01010004000000020101000e00000025030500a1008201a1005c015c015c011802 5c0118023701040000002d01020004000000f0010100050000000902ffffff0005000000010200000000040000002d01000009000000fa020000010000000000 00002200040000002d01010004000000020101000a000000250303001802820118025c0118023701040000002d01020004000000f0010100050000000902ffff ff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01010004000000020101000e000000250305008f03 82018f035c01d3025c0118025c0118023701040000002d01020004000000f0010100050000000902ffffff0005000000010200000000040000002d0100000900 0000fa02000003000000000000002200040000002d01010004000000020101000e0000002503050082016400ae026400ae025600820156008201640004000000 2d01020004000000f001010013000000fb02d6ff0f000000000090010000000000000022417269616c204e6172726f770000040000002d01010010000000fb02 1400090000000000bc02000000000102022253797374656d006e040000002d0103000400000008010000050000000a0200000000040000000201010004000000 2e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000030000000000 00002200040000002d01040004000000020101000e000000250305008201ec00ae02ec00ae026400820164008201ec00040000002d01020004000000f0010400 13000000fb02d6ff0f000000000090010100000000000022417269616c204e6172726f770000040000002d010400040000002d01030004000000080100000500 00000a02000000000400000002010100040000002e01180005000000090200000000040000002d0104000a000000210508006368617267652829b40093010400 00002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01050004000000 020101000e0000002503050082015600ae025600ae020b0082010b0082015600040000002d01020004000000f001050013000000fb02d6ff100000000000bc02 0000000000000022417269616c204e6172726f770000040000002d010500040000002d0103000400000008010000050000000a02000000000400000002010100 040000002e01180005000000090200000000040000002d01050009000000210505004d6f766965003d00e601040000002d010300050000000902ffffff000500 0000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e000000250305000b00db013701 db013701cd010b00cd010b00db01040000002d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a0200000000 0400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d0100000900 0000fa02000003000000000000002200040000002d01060004000000020101000e000000250305000b006302370163023701db010b00db010b00630204000000 2d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e0118000500 0000090200000000040000002d0101000a0000002105080063686172676528292b021c00040000002d010300050000000902ffffff0005000000010200000000 040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e000000250305000b00cd013701cd01370182010b00 82010b00cd01040000002d01020004000000f0010600040000002d010500040000002d0103000400000008010000050000000a02000000000400000002010100 040000002e01180005000000090200000000040000002d0105000d00000021050e004368696c6472656e734d6f766965b4012000040000002d01030005000000 0902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e0000002503 05008201db01ae02db01ae02cd018201cd018201db01040000002d01020004000000f0010600040000002d010100040000002d01030004000000080100000500 00000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff00050000000102000000000400 00002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e0000002503050082016302ae026302ae02db018201db01 82016302040000002d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a020000000004000000020101000400 00002e01180005000000090200000000040000002d0101000a0000002105080063686172676528292b029301040000002d010300050000000902ffffff000500 0000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e000000250305008201cd01ae02 cd01ae028201820182018201cd01040000002d01020004000000f0010600040000002d010500040000002d0103000400000008010000050000000a0200000000 0400000002010100040000002e01180005000000090200000000040000002d0105000d00000021050d00526567756c6172204d6f76696500b401a10104000000 2d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d010600040000000201 01000e00000025030500f902fc012504fc012504ee01f902ee01f902fc01040000002d01020004000000f0010600040000002d010100040000002d0103000400 000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000 010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e00000025030500f902840225048402 2504fc01f902fc01f9028402040000002d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a02000000000400 000002010100040000002e01180005000000090200000000040000002d0101000a0000002105080063686172676528294c020a03040000002d01030005000000 0902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e0000002503 0500f902ee012504ee0125048201f9028201f902ee01040000002d01020004000000f0010600040000002d010500040000002d01030004000000080100000500 00000a02000000000400000002010100040000002e01180005000000090200000000040000002d0105000c00000021050b004e65772052656c6561736500ab01250309000000210505004d6f76696500dd015d03040000002d010300030000000000}}}}}{\insrsid412021 \par This would allow me to replace the switch statement by using polymorphism. Sadly it has one slight flaw: it doesn\rquote t work. A move can change its classification during its lifetime. An object cannot change its cla ss during its lifetime. There is a solution however, the }{\cs25\i\cf6\insrsid412021 state pattern}{\insrsid412021 [Gang of Four]. With the state pattern the classes look like this. \par }{\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\object\objemb\objw8769\objh3471{\*\objclass }{\*\objdata 010500000200000010000000 566973696f2e44726177696e672e3400000000000000000000560000 d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffffdffffff04000000fefffffffefffffffeffffff060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e00 00001f00000020000000210000002200000023000000240000002500000026000000270000002800000029000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff02000000111a020000000000c000000000000046000000000000000000000000a033 d4d0ea87c20103000000000200000000000001004f006c00650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 0000000000000000000000001400000000000000010043006f006d0070004f0062006a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120002010100000004000000ffffffff0000000000000000000000000000000000000000000000000000 0000000000000000000001000000690000000000000003004f0062006a0049006e0066006f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000201ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 000000000000000000000000030000000600000000000000feffffff02000000fefffffffefffffffeffffff0600000007000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000020800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100feff030a0000ffffffff111a020000000000c0000000000000461000 0000564953494f20342044726177696e670011000000564953494f20342e30205368617065730010000000566973696f2e44726177696e672e3400f439b271000000000000000000000000482100780114003100130100000800000314000003140000000300040000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000feff0000040002000000000000000000000000000000000000000000000008009802140098021400f4ed8f005200000000000000d04921000d00040000010a00feff000004000200000000000000000000000000000000000100 0000e0859ff2f94f6810ab9108002b27b3d9300000008000000006000000040000003800000006000000440000000500000050000000030000005c000000070000006800000002000000740000001e00000001000000000000001e00000001000000000000001e00000001000000000000001e0000000100000000000000 1e00000001000000000000001e00000001000000000000000000000000000000000000000000000056006900730069006f0044006f00630075006d0065006e00740000000000000000000000000000000000000000000000000000000000000000000000000000001c0002000300000005000000ffffffff000000000000 000000000000000000000000000000000000000000000000000000000000050000007b4800000000000056006900730069006f0049006e0066006f0072006d006100740069006f006e00000000000000000000000000000000000000000000000000000000000000000022000201ffffffff06000000ffffffff00000000 0000000000000000000000000000000000000000000000000000000000000000040000001c000000000000000500530075006d006d0061007200790049006e0066006f0072006d006100740069006f006e00000000000000000000000000000000000000000000000000000028000200ffffffffffffffffffffffff0000 0000000000000000000000000000000000000000000000000000000000000000000005000000b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000566973696f2028544d292044726177696e670d0a00000000000004007b4800000084010014005200a4d5ad003c4700003f01000000000000ed64eaf10318e9f2ffffff8300fff6f2fff3fbf00701 f8f1008980eaf116048016002000190080ff00c0c0c000e6e6e6ff00cdcdcd00b3b3b3ef009a9a9a2100800066ff6666004d4d4d00337f3333001a1a1a0000000000000004000000000000000400ff1800ffff00d29f007130dcff080fe1fa9f0019ebf0df015400000aebf064007f0020417269616c2900bd012d06e400 00223a0502fa2d021433031254696d65ff73204e657720526f576d616e2900172d02113303fe4f03204e6172726f7701003554ebf03fe8f3d03ff2ff0406daeaf120e8f359401a06000019012d00310f0000ff1a00ffff00d22c00b914dcffebf02c004aebf0012f54040020e9f2ff1c0ae0fbf7040068ebf002540000eb cc02e8f3014a00000800bf0200620100fe4f0001f25304025301ebf0307b14aeff47e17a843f0001401ce6f5430101000e50006a065603c9005d0784000375065601046255025502059604069604079601a08001d2034f0a97084f0003960404045304bb023fe6f50a1f1c16d2018401541c16a10101361a02361a033617 08fa0dfaff8001004e0397039507970350f5079703bb0f9703089604099604550a96040b96040c96040d9604550e96040f9604109604119604a512960413761f8e1007500061ab00fe432001472302472303aa472304472305472306472307f04720d21fe4137f1e2600fdff48a623821b4f01609714c02402c024bd03c0 213e02fdffba27a7ff009602a3005e0284ff004d02a400ec01a0ff0034018700c40086ff008a0085002100933e37000900a4026981003e017d70dffc10270030552e3283c53f8e10921fa41f96018400054521e8f3f09002c3028400072d36f7fe0094370001006700896a50003e01a4e5f61c1fa936301d33bc32f3bf30 b3362616301fd4421fa8050fa30021bc343f1382a10104c43660321647c002540095be87329c006b00033d021c5cb02dcc020900888732110d0056d2005402150c033f4003dffc85023906dccf364c0f5e0f70010000750c49358c13d6044c32a93fff4f800570dd3fef3f5a1fb41b87005801309d4605360400c88d3014 335040973f8c5fbb3fb056d703c30200364395470d00021100016d4f7f4e010039063a019e4fb04fc24fd44fe64d6a59850367504a3f40da5f7c1ffe5990fc0b6f1d6f001900321cc70d71d360ac3fd26fe4662e15e466542b52fe6a02fe6a03fe67870734470200840d008830db5401e35f00956f3f007506d6063e3524 659025d4087c636234753400c90005110097000096ebf0258100387106aa3f4007370008b77009c9700aaa42200bb6600c0d300dd9700eaadd700fe17010e57011830012aaed7013f17014634015f97016aafd7017f5f01805801909801aaa0d801b11801ccf601dedf01eaa1d801f454020258021298022aa2d80231500 24073025398026fb00274b80290028002a024f804ac970427f547f667f787f8a7d04d20daa794a42205c8f6e8f808f928f288a7d8831d60604c28d08d38fe58f80f78f099f897ed850d507b500c48b09804b9f5d9f6f9f819f897e7860d5070302c28d0ac39fd59fe79ff99f897ed2800ad50707c28d0b3baf4daf5faf71 af28897eb870d50705c28d0cb3afc5afa0d7afe9af897e5a80d50706c28d0da02bbf3dbf4fbf61bf897e0ed3090e80c28dfcb0a5bfb7bfc9bfdbbf8b7c0f02d3090fc28d74c01dcf2fcfff583f00108915d80f8f786a06017407e6431f6515000536026b504af17094cfa6cf2840cf52cf8a7d11d30911c28d78d04021df 33dfb9cfcbcfddcf6d0402f7cf0902b4010edd1297dfa9df43df55df28897e3aa0d5070ac28d1323ef35efa047ef59ef897ea2b0d5070dc28d14809befadefbfefd1ef897ec290d5070902c28d1513ff25ff37ff49ff897e2ab00ad5070cc28d168bff9dffafffc1ff28897e4a90d50708c28d17030f150fa0270f390f89 7eb2a09d770bc28d18807b0f8d0f9f0fb10f897e9ae09d771302c28d19f30f051f171f291f897e8af00a9d7715c28d1a6b1f7d1f8f1fa11f28897e7a009d7717c28d1be31ff51ff0fd5ac020cbdfdddf00304f1b7fe8b4814e6b3f00f6cd501e51b426403610d75457201c5b2f006d2f7f2f912fa32f3366be2fd0203365 04db2fed221df32f053f173f293f3b3f7fb81e85eb51b89e543f10ce22e535733fed221e8b3f9d3faf3f40c13fd33fb52fc72fd92f1b441f234fa0354ffd5f594f6b4f7d4603fbdf02a828a1964fa84b5c572020bb400312dd5203c54fd748034b4eb061202b203e352c63e46fbd5f9e7404bb613277275400692b50a661 3cd94842615f1027003272be52c1f56042f961070b66be61ba6275d0942b92a731006ab860a66150d9463fec426f8e5530336662f3bf30545d668e5b06cb62952b9247572001215b5f6d5f7f5f915fa35fbe5ffa6e122a5404a671e4596af154406f3d7f48646f76672b5306dd328c6569396420f85f0a6af945176b2d68 4a3980986f00aa6fbc6fce6fe06ffb6f047f167fec5f00967fa87fba7f346f437f4c7f5e7f7c6f028e6523d37fe57ff77f098f1b8f368f10c75fd95f638ff382027b8f8d840fe000176b7490a88fc38fcc8fde8ff08f8a6901240f9f219f339f459f579f729f3f8f00518f9f9fb19fc39fd59fe79f02af0baf081daf2faf 8d66254baf5daf6faf81af0093afaeafb7afc9af277f3ebf47bf59bf406f7f817febaffdaf0fbfc97626bb408502bf420291b62ab089c4d8470200bfdffcc0f84b2e252a634c3f88c32c54282a6214e9e0a548d94617f242086f8cbf428dc03740d4b6978c20b33f22572027c3cf99bfe7ca94f5cf07dfc0794f2bdb6ac2 365bf2bf35ef0102caf74205a3c187dda04c5503004584dfa634d34c64d136e3bc13665488e5a48729572028a3dffff6e384bcdfe6432cd5dfe7df8dc0502101004d50e0a514265dd18dcf73db89df2b50b53757202987bfff26c1c026009fbfd9ecc0bfd2bb08fd54da25ff37ff001b6adc3398d528bf37cf40cf52cf64 cf034700f530e9f202ebf0014ea521ffe73e3b1840285c8fdfc2f5080340ebf025005d26e7f40b001e150018f3f0032200f52ce9f201f1f14ea521e7ff3e3b1840285c8fc2aff5080340ebf028e9f20bfb001c1100180002001e0100fd2ce7f40100014ea521ffe73e3b1840285c8fdfc2f5080340e7f41700f70b001a11 0018000200032000f530e9f203ebf0014ea521ffe73e3b1840285c8fdfc2f5080340ebf02b00772c002de9f20b002015003f180002002200fd2ce5f6014ea521e73eff3b1840285c8fc2f577080340e5f60b001a11003f180002001e00e59ce1fa09dcffdffc400042ff009454ad00b00800fb002d1b046c5dad00dde227 002b0c0f0d0f1f00249cadeb0008fcf02a1b04a49badeb0032fcf0301b0454a6ad0b0062fcf0254c00030025000200280003002b000700ff4600ffff00d60300c520ebf002eff0fcf3dcff0000f7030068ebf001540000b5e8e7f449e8f3d03f2a063faae8f3c03b06bf2a04f03205f01f3f04000410060f750feaf1a501 eaf10ef9f02a06fe910001d2950a023c069e01034506fe08bf000206620400c80107eb6200cf0208cd04096210a5009e01044e069e0105ed0700779200048b00df00658b00ba1e0114e7f4050048e9f2834e07120a00c9f9f01e012a890201261d103f1f511feb1801eaf120f3f000000afeeff2ff00010090888fdfff82 f88e77080b0277ff708a00070777f8f8ff7777078877087077aa210d70270007360605400283ff7701078677017083540b00500c70540007580184510019856d087400708471038700860aa6830082f878039e05042a00707d85ad0b8677030777770092c40b826b00d807875102080f8e7f8801f88fff01f80000bd62e3 f8c0bf5655fdf1c5f53ff4f43ffdf255b5bff2ff342b6d0309c5bfe6ff174b7eb1e4c73ff0fe15033f74da40a70d747bbabfe8f3e4bfa8aa3d01dde23304d83fb03d02da3fff4800ffff00d60400d522ebf004ebf0fffef22600740401e2f901f9f002006813015f5400009002e8f340e8f3dfc03f4040553701b53f422c 04d03d0e330037023b00500b0a53000e19002c06fe7100013506d27e01023e067e010391073400f7030205150001040500510c1500b302ac0207b80002c202d503c20204c20200c2001200bf020475026020e8f3e0ab3f05a80103ad0205b3020104b302f20207fe00c700fe00cd00fe00e8d300fe00d90001dd00057503 4b60205a03d5ec007100066206bffe0800020762401308e24714094711090c431002804c21405a10500f3e075a03c54f0f610d92dd0000e10bdd0001271bdd0002aae107f0c813032717e5ec000a14aa02b50004dd021fe3090120f2000ab50005231220e309351bdffc6e00fc532443100e620100fefe4ffffdfffe6b20 0a0b218000ff6019284329205368ff6170657761726520ff436f72706f726174f7696f6e5910a3004002ffa0001f029c004a01df840033019bf9f00500f777026c190001550000a91056231401071900615911407f30b91aa2d33cd13d05081401b915d523f1c818e6f5ff12d002350a13300316120a012c073f05f8e627 c11fe517401593ab21af3acd93bfdd2f205933b3b1bff82f5630d52f000b1900722d01133000fea43001a83165205f00008b00ccbb3094bb30d75c008a700089b122f6000971cc00200134c124203de4293c3f26e8f3d53c56302d06533704f63f00c91726433111a114db2fe200a213f62f248c32a21395603f2915b57b 3f8d31f8213f2f4f453ffe9900e400579900acff4074ff403cff4006b2211c017d98ebf01e00270002e9f2ff37277a000700ffffe2e4f7010d00f6f3defd060046ff00c6009438ad00dfaf090000adebf0232900ccff72ad008c0a000091feebf00a0044006c11ade7001d0b0c0148036414adeb001e53042b29007439ad ab001f530048ebf0482b006c2f2dad00675300511200ff4600ffff00d602008520ebf002eff0fcf3dcfff8f168beebf001540000e8e7f441b6e8f308402a0dc03f3c05bfed49e8f3f03f4e0604000858f6f1660f780f0001eaf10ef9f02a2a06fe910001950a023c069e01fd034506fe0800020662bb0400c801076200cf 02087b6208cf02096220009e01e9044e069e0105ed070092009d048b00df00658b001e0114aee7f4050048e9f28307120a0100eb7b01eaf120f3f000006dfeeff2ff00010090338fffff82f38ebb82f383ffbb01b88378017b86ea0b03b70e008b160182bb06dfb3383333bb150282bbdf83000303bb210208bbdfb30fff ff032d0306bbfd8742000787870b8bf3dff3bb7b0ff9440185bbfb0b7b57008b0099900bf3bb8b61005602bbb93bbb5e5f07bb000bbb6d08b07903fd078003b08333018383ef3382bb078e0486000831037a0065016f01bbbbb6005602f06101c202b90fcb0f8bbb3393fb333be306b00999003b7ed5040a8bb0ff9ff0fe 02ff87780870fffff078ee640087bb091510fff03bfdbb2811027bb08300826e0b0087bb04dd008b833e133acf007b481383870147120a01ff8e3301f38fff01f3fd6eebf0436f6e6e6563ff746f722077697468ff20757020746f2035ff206c6567732e20558f73652063f3f60400130420ff73686170657320627f7920 706f696e740301f632022c20f9f064796e61ff6d696320676c7565ff206d6574686f6473032e005602006d62e3f8d8bfe8f3e03ff4f4fe0304e0bf6ea0d3063aff6dd8bf38d069039d6f36e03f6c15033f371d0310fbf40a060305fbf5bfff4800ffff00d60500d522ebf004ebf0fffef227005c0401e2f9010005150068 1301d554ebf005e8f340e8f3f63f5a2c04f83405e8bf2c04f04605ddd84605e0bf500b0a000cff000202750c60750aff6004fe0f00020375ff0d60750b60048041bf40fe0e0002066206fecf110002007800750003e42f6202000699010184008100fea40412000204750260ed205a043f05bb01057503fec2090b000207 620000f48801e00008e40408000209bee400fe2e000302180101950425010907100c15020a1005261801090108121f10021d10fe000103021219100a161f131913131317003428102907fc34050040470534058ff03f01008c005b178b0101a465168b01026e168b0103a2173ad3000317021603010110000001062f10cc 10c91307104a135611ca1282351300ba100113c31fd51fe71a340300031f1004103123092309261c13042811e818012e202f13372f492f5b24bf000008020302640a07967e006101f50108a600f503037ab6220ab4214000030b042f20162b802f50132211c8200ccc2fde2ff0f02f90250c09f60002804c4043fe102f22 101001101010032a067a570841c405419ff4498c306bcf3f8234d08a35bf3f620cfd1972014c6081012d40ae82368102098a0203b930757f1f60802e40fe449b00b572ea11c0e03104c0bc200b9ce400e63404000bc00ae030095f00c08016401040724a11840f41db3101e03dd20af337f0330951010f485242bb031fc2 0e20c209308c0b5e3067340e12040a2d121010e01801110447374731f600016201eab62208cc440acc41321cc7cd71e140ac3fe04ff2460102ff01008700b804a000ff88049c0046038400ff2003a4006e029d00f732019bf9f00700e0043d6c031155000020faf11301e501a82100ad20a9200161000241510246508234 2a06140182115056268f1a00fea64053120a875030213a865001505de0bf016750de330eea3002000b0a43f337e033c0004f620a0006164616400a0e45284f502243ea3001b45301e538c6544103ce565242dc5152457f540387563830606e00703f0100a8a957f4534ce3330d410f40c0006e60090a43e781015b70617e 610b8102831d400a43cc51a7001349e03c091f81021e40728651fc59561122b15106c16fd158ef66fe5460ec5550b353656452406f60037366017d630503846b010c6298671863a86fba6200fb56c3512811d069707b5b45f267805321048756aa709315476a4b556ef73300b7623061e532e436fa33e8731341cc6200e2 54cc70ff6cea33e475fb53284c3383040784216c05875668803d674506a45c00d77f2b47cd504c10cf5171611440aa71001b42e958228ff4370e60b6851a70c183245e43768ff0a550f60000c000f501fd01d200fe8b00da038bbb0042379084028b91508bff0060008a001c00894e2152000470bb102001b06d30f82808 5708649f01030100fda5ff6e0020bd00e03102e5320338ed74c00019716540fe91904042ac999f1a706740415106ad203bc09b00f034b99c9f024981174275666f60756760e4016940e4010b6440d79101dc9fc951b002fe71a45b4200a76b0ba5e000020a42003adf01034e4200fe1cbb120a1000673383542e6364a01f 139f438d543863fd14ec00600c41726d20ff506f736974696f6e18c621669f520d05058a949ca094921e9f95806640fe9ca04042e5a64568cf962fd99ff19600a76a0ba5100cb016ad2ca600a76c46aa4a1157a40e1c1100fe28bb146ca1e4154c110070ad80b0312288a152251e118caf9eaf822c04e246054506ebb8d4 afe6a57416efaf8075cf96350dbff19f03a441760ba540c03ebf2eaf05a27746aa38561258a3281100fe1681546ca1003061a873c0c025132f103a61b273d0bff700feaa3d90aa0050017daaf9f00300a00364f9f0c22001109b2459565956c304104022c304146d17c3047e111f72019f00f8b000760082006660806e40 ae03a30503fe58d0035cda674f60806f4000a071d329929c5380788cd178000303a003a103c272d226b29c53c489c301a2806d1f40fe6400033513191315230019102810071028103516501578a5a873000e18c3bab2733c13c8200d16c0b618ec00688131ef7083c820173f293ffb2a07e80305582d128fefa1efb3efeb dffdd73aebf09e11d10005027d98ebf05a00270002e9f2b7d65882ebf0ffffe2f901f7000522dcff00000600ff4600c600d452ad005f2c0e00009bebf0232900df1cd3ad00c733000a01fc44003b0154ad00d10f00fb0066ebf00a00440064df11ad0037100e0100007d2b2900f457ad00386300f534ebf0482b006474ad 003d6c630014060000ff4600ffff00d602008520ebf002eff0fcf3dcfff8f168beebf001540000e8e7f449bae7f4402a04f03f3fe8f3c0f23b06bf330633060400041028060f750feaf101eaf10ef9f02a0625fe91000133069e01023c069e01fd034506fe0800020662bb0400c801076200cf02085ecd04096210009e01 04a30abd05a307009200048b00dfd300658b001e0114e7f405003548e9f28307120a0075c8e9f220f3f00000bae9f2ffff00010090888fffcf82f88e77080f12050170ff8c000407f8f8708c71772a0f3c0f4e0f89778329037f897707077700776d04db7077760400077f030001f30783130fa10b8801f88f07ff01f800 006d62e3f8f0bfe8f3e03ff4f4fe0304e0bf52b81e85ebff51f0bfa4703d0ad797a3e03f14043f1c04fbf4f818fbf4faf6fbf40000ff4800ffff00d60900952aebf009ebf0fffef2dcff05fef9f001000200030004fa150068ebf0015400004cb501e8f340e8f3f03f3404e0263c050040340d3b0850e3f82d00290e1b00 5806fe7900013d068601e90246068601037d071200025f04750260203e0505b001a7057503b7097900066a06fe5f0800020762e00308e7047d09e7012200030205190057010405ebf0071500010812a5020812030810fb0003ff0205820512010b122c1013102c1019100123003fe6f5401f5216021900e300ff04620200 fe87000fb3019b1f007b00016c001155e700009c6f050d11020061bb01fe8f10016100951102dc9a104605004055ae12e53f8b0100b10000b5071400b0010104c701ae1505a3183505b61fc8173505ff05fe8b0054008a00f71c00891f0003008c00016c6311811f931fdd1fef1f012fa31589f857075e2de8c003052f17 2c0300272f392f832f952fa72f812aae1f103f04d217bc2f04cf2fe12f2b3f3d3f4f3f02d91840a53fb128c23f643fff00793001502d04843f9e1fe03fc21fd41f6e0700584f1a3b6641460d8c4ff639aa4fdc3fe0ce4f704ffa2fb43fae2dfc008bcb00c45f508c5f50162706002734017173502801f84e2d2d5f08b80b 1d3f490ae0fd4fab5ebf01580df8c44faa5fb0490040892449c7922449d05f66493a6505fe7f9900ac009900746b60753c6b60041f00e4006a0810b028016a07521f97663033aa62f3a3bf30a1666d08e30006e701003d9575310047006967102801f644460017e9f2102700327f721cc7711cc7c14160d47802b80437a1 0207f366fe000d94d16237007d98ebf05a00760002e9f2b78b5fb3f5f0ffffe4f701f80d00f6f3defd06004600c67f005c9bad00fb16ecf3fd2329008cacad009317fef0f100000a00440024af91ad00ed430001470434ea4f00ee53042b290044a0adab00ef430034ebf0482b00dcffdead00231800004d001200ff4600 ffff00d60300c520ebf002eff0fcf3dcff0000f7030068ebf001540000ede8e7f44904e9f2f03f49aee8f3e83f3fe8f3c03b06bffc33043106f03f0400041028060f750feaf101eaf10ef9f02a0625fe91000133069e01023c069e01fd034506fe0800020662bb0400c801076200cf02085ecd04096210009e01044e067a 9e0105ed07009200048b00a7df00658b001e0114e7f405eb0047e9f28307120a00c914f9f01e012a89022c1d103f1f511feb0201eaf120f3f00000f4fee9f2ff00010090888fdfff82f88e77080b0170ff8c000407f8f8708cfd771e02857701708677fd0b1f017000700007703a290005310284008229001e09ba1c0b86 2b0085770a310500bf77837083770d310300050772007076004a0a500f21013002ff7777000777700785fb7706ad0383000b70079639007777910a031f000a0d8e7f8801f88fff01f80000b562e9f204e9f2e0bfe8f3d8f53ff4f43ffcf4bfa8703dff0ad7a3e0bf48e17adf14ae47d93f14043f4c561d03bf02e9f2f0fb f4ecfbf40bc0bc44043fff4700ffff00d60400d520ebf004ebf0fffef22600dc0401e0fb040068ebf00154af00007401e8f340faf1006f00e03f40e8f3d83f2a0425f03205e83b05310850e3f82300570e00022907fe6f00013306d27c01023c067c01034506fe46af000302066b0001aa03009907ac02b7020008ac02c3 0200bd05ac0104050003b6000568ebf0d901b5010570000700a700a903ab02f00301b70203b702012ac30203c30201cf0205d5021410f0dd0014121f11e90001120002cf04750260f6f12e0205fe4e331005750339196f00066006bffe0800020762621308f26914096911ddfe840057017d9bf9f00200660165ac01ba1f 002ce7f4060048e9f20772ab1408edf0eaf1830012c110750ac11004d6001a0071d600da1e01f8e7f440102c0be83fad01c310020037110c3c1901f24917f04210e2170b59c842cf16b290bff41f0627642186242196bf1820e6f533062c27f806fef2df3c062d411133044306622ff9ef052e41119900ac0099ab0074c5 203cc52004f9f0e40100ff4800ffff00d606009d22ebf0110005eff0fef126ef00260029e1fa010006fa1500681301540000140276e8f34004e9f2e03f40e8f3bdd83405f03f4001e9f2d0b8340533004803c03f500b0a00ff1400020274026005f70020f8fef2ef3f05fe6e710003740377015755900145d58203007503 51058302018903dea30752000302180101045506fbf007170000ce0201ce025502ce0203ce0204ce0206ce025507ce0208ce0209ce020ace02fd0bce001200020475025560b60b03c50205cb0201d102003410d9003410df003410e5003410eb00003410f1003410f7003410fd0034100310d03410091034100f10011310 0575bd0319190e0002066206fe5f08000207629413089b14f1099b11090c971002804c40deae10321cc771c910ac3ff8c81fda16c70000fefffdffe9fef3100a0b21ae00601928ff4329205368617065ff7761726520436f72ff706f726174696f6efead10a300c80187009ebf01840087019bea0004ef00ff016cc60155 0000e95848031401079a006100fe0a4f2001532302532035042a000e077a1310001717000005fe131049017b1786210ae400cb010a081009033410a220013e076e2f3f05882f010563254508c22fd42d0a316427f22f68802f163f6c290b9a0072010810cb00fe6c30017031ee1000007f8b0010018b00d88330fda08330 68008a001c007d89ea0006003a01699a003a200108e5f604006ae400a43d0971ea002001d825055106ba2fa30704d62fe82dc0f92ffb3ea901500d303f00fa3f1c3f1e4f403f424f8c4f664fb046427b03df4f079247f145fc37fefef3027d41fc7c04350692472955fc37fef331f7553f375ae8f3c0bc4c5f0e4035f0fe f2cff84f60209955145f122656e7a05f4255e7bb5fcd5afef353cfbfe25ffc37fd7c03bf9659f8126fb45f366799006c0299fb00347b60fc019900c4aa83608c83605483601c8360e4af009900ac97607497603cfe976004000c00a4020ef4fbf0200117e3f861747472ff69627574653a547907706500ff4800ffff00d6 06009d22ebf0110005eff0fef126ef00260029e1fa010006fa1500681301540000c001f6e8f34004e9f2e03f40f86efef2bf3f40e8f3f03f2c0471d03d0533002d03c03f500b0aff0014000202740260f70500203603ef3f05fe6e710003740377015b55900145d5820300750351058302018903f5509002c58200280003 025d071500010407ebf007ce005501ce0202ce0203ce0204ce007f12000204750260a2082ac10003c50205cb0201d1020a10a0d9000a10df000a10e50001e900057b7503ef090e0002066206bffe0800020762401308e24714094711090c431002804cbd405a10321cc7717510acf13f741f8616c70000fefffdd3fffe9f 100a0b21ae006019ff2843292053686170ff657761726520436fff72706f726174696ffd6e5910a300740187007f4a01840033019be400df0400ab016cc6015500f300582504d2020200610015fed70001ff1302ff103e042a00f40e07e90000ed07000005fed2e90001271732210ade020500250a4f20030a104e20013e 071a2f043f05342f050f2545086e2f802db621a010279e2f2c2fc22f18290b9a00722d014f2000fe1830011c319a10ff00008b0010018b00f5d82f30a02f3068008a00f71c0089e40006003a01e9699a00200108e5f604006a24de00503d71e4002001342505510610662fa307822f942dc0a52fa73ea90100500ddc2fa6 3fc82fca3fec2fee3f384ffc124fa5059900e400990055ac9f40749f403c9f4004fbf0a71c010efbf0200114e3f86f3b7065cb13282900ff4700ffff00d603001d20ebf0020005eff0fef1dcffdf0000030068ebf001546f00001801e8f34004e9f2b7e03f40e8f3e43f2a04f0173f4002e9f2d03b0531004603e7c03f50 e3f823001400029f0274026005f5f2400205ddfe6f0003740375015855aa8e01d58003007309e0800301d68703abaab601ea80001600d70302096b0001c20300084ac40104bf0003c302d80301cf02ff0512000204750260dca008eb00057503f1090e00fb02066006fe08000207d5621a13082114092111009b3b00046b 000f0165c4011f005d14e7f4090048e9f2833712a70a00c9f9f01e010669022d004d10ff4800ffff00d605009d22ebf00b0008eff0fef126b9000401e2f9010005150068be1301540000c401e8f340bd04e9f2e03f4002e9f2c0953f2c04f03405d03d05330850fe0b0a00140002027402ef60080020e8f3f03f055dfe71 00037403770e007509e5e08203018909a901400003bb02091500010409ebf007a900c501cf0102ce0203ce0204aace0205ce0206ce0207ce0208fece00120002047502602ab60b03c50205cb0201d102221000d9002210df002210e5002210eb002210a0f1002210f7002210fd00010110057b750307190e0002066206bf fe0800020762701308e27714097711090c731002804c7d408a10fefffdfffea710fa0a0b21ae006019284329ff2053686170657761ff726520436f72706fbf726174696f6e8910a3ff007a01840063019bbee4000300b3016cc60155e70000582504d202020061ab00feff1001032302032040d4e6f51426010011000517 00004b05fe011001571736210ade006ae9010a5320033a120a013e07001e2f7b073a2f3e0f722f842d81011427d0a22f302fc62f1c290b9a00720156532000fe1c300120310189117f8b0010018b00d83330fda0333068008a001c007d89e40006003a01699a003a200108e5f6040071de002001f92436031c2740284992 244f4992c4bfe22f8427257f32d3e4bfce264500948130244995c28538f8fef2ef8328803124a349e2a9373300b633e2bd3edf06cf3e02c0ce29b63f903fda382d06106a2fa307862f982dc0a92f774ebd02002d0ce02f764fcc2f9a4ff02fbe4f085f74e24fa50599230099008c6f50f5546f501c6f50e400990055ac7f 50747f503c7f5004d000a7fc010ee400200113e3f843ff6c617373204e616d0365007dd8ebf09600270002e9f2ff8e0194000900ffffe2e4f7010d00f6f3defd0a0046ff00c600cc82ad00dfaf1a0000b2ebf0232900dc9fcbad00911bf0f12601447f005c80ad00271c0c01aa48036c4f002853042b2900acaf8dad0029 53003debf047be2b003c8fad006653007afa5600482b006c84ad00e0cf1d0000e3f6f08a0134957fad00c320000036f6f0fa7a01a47f00f9220000e8fcebf08a01fc98ad00e123070000751200ff4600ffff00d602008520ebf002eff0fcf3dcfff8f168beebf001540000e8e7f449ff80dbb66ddbb6cd3f774960553501 c53f3fe8f36dc03b06bf49e8f3f03f4e068f04000410060f750feaf10152eaf10ef9f02a06fe9100013306d29e01023c069e01034506fe08bf000206620400c80107eb6200cf0208cd04096210a5009e01044e069e0105ed0700779200048b00df00658b00ba1e0114e7f4050048e9f2830607120a0075bce9f220f3f000 00aee9f2ffff00010090888fffcf82f88e77080f1a0f82f81f86770170872f0f410f530f2e5d028577825d05005e091e0ffe94088801f88fff01f80000fd62e9f280dbb66ddbb66fbdbf6055fdf1b53ff4f4fd3ffcf4bf4f30d1dfc9ff6ac1bfb81e85eb516fb8be3f5015033fb71d037bbf70f5f2e3bfb0aa3d01ffe2bf 20499224499237d83fa03d02da3fff4800ffff00d60400d522ebf002ebf0fffef201005d01dffc0100040500681301ef5400000406044080dbffb66ddbb6bd3f4080e5553701b534002e02cd3f40c5603702c53d0533004803b53f4d500b0a000ef9f02c06fe7100490135067e01023e067e01034706bffe0a0003020505 0001ff04120002047502605d20e8f3e03f05a80103ad029d05b300057503b9097100067e6206fe0800020762ec03c508f30409f301090cef000280fb4c4006108400df009bbe17000200f6006cae0155770000500605010007f9f0576100fe3f100143130243105940e6f554160100b30000b7072f000005feb30001d307 7611083e075e1fe8f3f0c2007a1f3e0f9e1f00b01de6115417ce1f701ff21f5c1f162ffe4e298b00fc008b00c4fa6f208c6f2054008a001cfb00891700060034010e6b00031f020ae3f831007d98ebf01e00760002e9f2ff9b7e59000300ffffe2e4f7010d00f6f3defd060046ff00c600ec73ad00ffaf260000a7ebf023 290034ff9fad00a627000043feebf00a004400dc71adab00e94300014704ec4f00eafa53042b2900ac94ad00ebea43004febf0482b00ac7dad3f003a2800003a5600f9cadcffe1fa05000a003fff005200549cad0087ef0900004aebf0c90044bf008c16ad00d11b000efeebf01e0053008c1dadbf00b80d0000742f04e4 ff1aad00801600007bf8fcffddfe3201bc9aad0070ef1a00006f2f049480adbf0056260000a92f04149f77ad0074293c03defd02ff00030007000800060100000000000000000000000000ff1500ffff00d325007144ebf0f0f0fcff00f0bfe8f3771140551a01f51540feffeee6f5250046ebf00154038b0020ebf002ef f04c032a0f00ef000300684701540000fbbc01e8f3494ea521e7ff3e3b184049285c8fbfc2f508034041e8f3c02d3f8c05bf490a043f9e06730494b60fc80f0073020e49007a06fe92e100018306ee01028c06ee0103fe9506fe080002066201bd00181107620000ee0104749e06ee01052d1700101021060c481f210604 045a1f771f73001910170062101f12019911fd012106400a12a91a6d173612a9171912041f1454e210e10008a91a09a91a0aa91afd0ba91700b700cf00923b00044900af0165db006e0155c8d50648e9f20243220a6700724421042b204c23050047ebf0b9124f2064211a000f632222bb001463222a0019432232dc6f20 44213a001b432242005d1c63224a00214322527720ee44215a00234322620024be43226a0083007ac1207254c120c02162c1205ac12052c120554ac12042c1203ac12032c120552ac12022c1201ac12012c120fd0ac120040010008200a9c949006e012a4d2225db0028aa4900326700332b202b61202eaa4f202f712030 7920349920352aa122014100047720006120da01490261204e0f012b226a05d87915ff3af7d905c4061140ff40a80d74da4067f3b53f2104d08b3ec03f19035507b53f50d10be1017a36ee028336e2a419d00913df37cd0e3a00039b03022b2001020c420b4011cf00010c030d421e4203036c1942582101023042030419 425f840081009b2b22cc17308234232ed9055e4f92308d354c05ffefff01006c0731550000fd70d4084030b91aa2d3833cd18b35da019e378d35ae40157f93ab213acd93bfa549569d4f008bf5f08b2f308b9920df8a000700892b2005002758007167006e01d0791bb74682eaf12805510d481e493049285001082c5f3e 5f9e3753a9347e10a833a348e28a5695cc47125f72419900a42ac75090c7507cc75068c750fe4155b8432002410005433206470249034f3fd90205db006a05987304ff4076eeb30b880d0dff404052b81e85eb114ff03f40fa4c028a300c8e354a3163e33865c0af3d7d11772062ff084040a0703d0ad75723ec3f7a3753 2962f2af002d1b4900700aebf0078e409162ff0100800b407a334065fe8c6001906fa2650270730188b061c7629e6903c66fa262931002d303021140d5070d1820744e7f600a007a7340fe0b70250c0f70011372cf0c1c09452b53e6535affe3426f8c04e03f41579ff4496e70cf9405d06c75f9bfaf3ae8f39c00360184 ff000b01a400de009dfb0049454205007d016c0433218d40a0d50573008c04871ac677004c65ae40436eec7ffe783766128fbe43a58b87408b0150ec4f04f94080d017325245ff66dffce81104f0bf0e7c470200640554f6f17c1feaf16c4601ebf01440ba8410402104abf03fba84f073409e39723c888f402c206f00a4 a185436ef88f0159031e10530440f44c02e9009826299e05051e9831627f2e60e8f373c83c589f4c99aa006187905531879004670091432003e35a0103f15f036f15677b362866db7c933620e178546f7a37706f826c0fad6449a2809e6b49afbe6fd06f7faff46f06790f00137f257f5f53670040711e49a6895c7f006e 7f807f927fa47fb67fc87fda7fae460099bfabbfbdbfe99e3c8f4e8f608707b00824cf7f8f4c0203978fa98fbb8fcd8f00df8f59ce0296cfbf4d9934c40098e1ce044c9ae8f3d8609811de7c9f8e990e40a0e5589291ac9fbe9f5ac43b7c31867513266808e9f2f4bf40ac61449132a1d3e4a8d50aaf5ec03c7c324f1640 40a129af836b14ad640001e29e6b01ef76af88af37efacaf06796114cbafddaf43535722010130490300e4b2d714bf26bf38bf4abf5cbf006ebf80bf92bfae40c3ee5cff6ef8a7d0207cffa8d7f4bf06cf60870428cf35cf024c04044fcf61cf73cf85cf97cf110528c3ee680f1c9a102c02eabad7980f6c4c9aa1d280f0 cc45c43cc80f8434df8e974779d141302a0148310550f94064df68127dd604cf9e50296287fc3f40daf35f96e7c0daf3e0028b35d8af3fc13e4e15da335715e83937e83ffe505002063d31eb50663e300207c612d1120208c612aadd1202505003c51201c512032ad11201d11203dd1201dd1222cf85160940210d422622 25203e43d1ae4544f800654f442c2b1406a88322ae615623087b2200f52a0304f3205e85364534241d4805e3c37c475505eb5007e210090356881105e499036f16e88951cf260b59c84f4216b290f3f0180dd84d0011101d3026290a300126293c06ff2857990060c7502cc75018d752870400745d20c5100d1058d11244 17101811061d1fabe27cd7b811058c6916176280deb8452e602993a7a8b8456f10299397791d14ea3074bf0360050020f0fff2af773f05fed530007402db3154d5e5e73201d933568e52e4e6331502ed33f8fff2efe630e3fc17610984c7503c23aa874024f3c62598420037ff5745e6986a49ac35e0b98a4f3ef944b2ff fa430643408911ec810996e9420455281765b536aa5ea93697895182b53ca722572696215f47541b43df573f40f3fff2b78951fc1c448b40f6fff2b1365a7f58df33cf26695fffe7a55fb751f2ad33f3215c9e56cf579900e03940cc394055b83940a439409039407c3940d568394054394040413a0c0051f45d20d1109d 94135f3407673f9477dc883ffefff2cca138a491009300ddb3387b63cdc53fd73559520842e3e63ff83c540842d30e4f00204f324f444f564f684f357d7b659249d0597fb04fc24fd4491197e86368ff6172676528290069dcbf244c2500001768821027ff0032721cc7711cc7f9c183f0e210020262020097fe00947b32 23bd20ea838008110b045f7668cd4a5a7b6525792a8fc82889096f1cf1680710dd1054038a2902025f3408366fa5927ed5c404893e2b03e455186fe3f89069166fe3a0c2dee0673d05b662d834580842d52cb56ff83cabaa5091ea2e900a30530209c6125d92020a30035d92dd015d920300b319f2010091b9432624e12d 01095d24742101727120c97d247b6101002d9392245d9057340ce2101811099d8f793f408b3cf285d68ff49ffa8fe36108119f003fae349140a6f93868aaf46f067f187f002a7f571cccab10a59249eeaf7f7f917ffad4490e97e8507269636570c37fd5711020dc7f026203f178894771200c190a191f2b1f87d574ffee b30b880d08404001a0e1d26f10571f691f7b1fcab69613c8d4b5a41fb61c0bc6124bc2020c0cc61257c2020dc61263c2e8124bc255014bc20357c20157c20363c2910163c2102f222102df92acc201a50233210b382f4a270b5d240c825d240d652f772eaad38e2fa02fff2bff0a50c00c7ae00ebd2fcf2f000932acc91a 31acc9e22fbaaf3a312a3f8a3c354c9da03849384bc057360a009db2663fdc9f8a3f9c3fae3fc03fd237010add3f61e13b9e62e0074e62e0ea6f0091afa3afb5af467fe7ef874f994f0fbf0021bfcf4fe14ff34f148f175f295f3b5f003aef5f5f715f835f955fbb5f2b0fcb5f00dd5fef5f016f136d57c02666e6d3356f 00476f596f6b6f7d6f8f6f58eaae6e76ef0060e2d66e9eefb0efc2efd4efe6eff8ef00537f657fad1f40ff52ffad7fbf7f63b51c2a606ebf026200f17f038f8cff00278f398f4b8f5d8f8e0f818691c08d8600e6d39c8fae8fc08fd28f14af26af089580451649a862e0279e451f60e24f9b0e1064c2e3326892e33201e3 32789f8a97810e959fa79a1a41e3308d80be910b1068c09eb1ca9f0d2103d20ff39f5b3f086d3f7f3f3ba20d973fc54eba31c64600c868ee4a7a1f8c1f9e1fb01fd1afe3af80f5af07bf0a2f1c2f2e245c23d4c343ff68696c6472656e732e50b347000f91ba0f9fbfb1bffe7cf539f7d905c4061100d2bfe4bff6bf08c9 22651ccf2ecf40c8891064c2a26202bac08590ae6202011264c2ba626ec2a26277d0fb31ae621501ae6203ba6201ba6296cfa8c1410301e20372fd30bacfcccb101b4425111b4412ebcffdce0f0fdf21df2a32d40f67d0114a701343df55df0067d2037978d1037988df405facdfbedf08d0d7a260ddd60ff452ecdffedf 10ef1022ef34ef46ef58e70f63efb8813b9e00b9808deeb980701f175f295f3b5fcc1f003e9f0dff1fff955fa75f55ff67ff79ff009a2f9dffafffc1ff918fe5fff7ff090f001b0f410f82af510f630f750f870f990d001170ac063d83bb0fcd0fdf0ff10f031f00151faf8a341ecd8fb7825c1ef58f079f00199f2b9f3d 9f4f9fd91feb1f04cf979f00a99f332f452f572f692f7b2fd59f9f2f00d92fc32fd52fe72ff92f0b32ba601336003d83223f343f463f583f9a4fac4fbe45809cb69f38b980ad3e9cbfb782d53b1310bb623ae2ee323ae2013ae2fe3f104701131b4f2d4a71e13ae041463b814e4f40604f34bf844fbddfcfdfba4912eedf 001cfeba311df64e1845fad1bfe3bff5bf0007cf575f695f7b5f8d5f61cf73cf5a74fd151bb8526567756c611572df5514e85a14f65f086fd395fd3a236216404040e17a6f14aec7dce2ed80ebf4ed0380db566f6860770573638005816fc90391069d6215bb62f70202160cbb6203120217bb620f12c562f7025501f702 030312010312030f1281010f12ed6fff6129815781db710454107f227c1572e41672e417427f50547e12456d7f7f7f14200016b2c001189a7fe0769205bd735819cf715819fedf77b390852c64219300f07aa405ec9952271b8f2d81f700348601144902438f558f678f798f8b8f9d8ffeaf87140020dd1bd6be0761edab e4470e30c13e0e301430021230e1bab70e30c7bf6eff80ff92ff0023cf933f649f769fecfffeffac9fbe9f00d09ff1cff49f06af18afe62f3caf4eaf0060af72af98afd74fa8afbaafccafdeaf00f0ad031003b6922312bf24bf36bf48bde10759bead5370bf0836e2b0f6470d6bdfd6841e3f3036dde15201d0403f523f 643f763f883f9a3f676d00ad55c4398b6fe23ff43f80cf92cfa4cf00b6cfc8cfdacf324fa45c35dbad555769005c7f5a793b5f5fd50f106ad6922379df9c8bdfbe2f00c0e5e2e84601001300d799081283c7c65f1465f0defe0e30c7da37ac7dc3dafce75f2a3c4e09f294204f85e933e41810128f8245e28f8201088f82 55ef67e71872ef84eac6818f800289240c07704a01a7efaa2ff07d248510088f269f2c8fc0b117438f719e11e1007296a5b89a9a266f386f4a6f5c6faeff8001a84295c43920afb16fc36f064919fe70584e657752656c654f6173650a3403f015e040adff402c4992244992cd744527db2098b0a02449ca4527049850c1 a3ea452ac1a8a2dcf2783f9609c77c414b9cd7684a11bf0fb92b5f8aa47f091d904875a08825421119e8cd704e0f0e9da040a5e2c96aff7963840b40400889ffc36befa9e93f4080ffdbb66ddbb6cd3f40556005e2c5ceb5bdd7b5b5ab0f00bd00beb5c803c7b5d603d0b5e403d9b5a9fecd706f5b08cd90816d14920ed9 9f0100073eafbff0d0b677cf80d7b7c4399fcf46af58af0641ae152ea08cb2441dd0b5d9b5dc1719f5663498451c0e71137271bc1971d96007a842d6ba91267329c7801a82ba1af890bfa2bfb4b715ae47e17affd412404098ad0cfe0313f3cdbfdfbff1bfbc01a6d5c80300afd51dcf2fc9bc9f4dcfe09f71cf83cf40b7 dfa7cfb9cfcbcfddcfefc71afacf840cdfdf141a26df38df4adf5cda1be282ba1b78df8adfb4b7cc1b230f98e8af17addfbfdfd1dfb409008ef5f7df09ef1bef2def3fef51ef63ef40490f9bef99efabefbdefcfef1be2ef14f4efdf141bf5663c18ff2af91d751436ffaf823197101c87229c914291a11c665063ffc813 1695042845507fb81e85eb51f43f7b132311fc3798d415f3add8c2ffecd0807c15dff38515edf303a52bc39715fe65288c801d9082fc12021e9082a60822021f9082142202f81003aafc1201fc1203082201082203a214220114228bb1001b169c8021ecaf825d220121e060010b844b00d1d194f8b586fe651dc784a51e c7841f3e10ca8312cd800a12cd820376d0edc5364c12ca0d03a55497151bd71c01201e1920201e469631054010f5abe87c4106360b3f59c84216b290dcaaa91500414937378b80622362248b8068205f278e3f5d040074c780fc10ed8412845fa04f1106541f0f9ff17fd900dee0a25861457f4f5c9f52811c002042d043 af608713406d8e13405614d201e40f6713401c6fc39fd59f360f786f80984fe0387709c14f950fa70fd56909446f5993a52874153f7fb64e978b7ae0e3358d49525f505a5243df3f40d5f39f32b78b71fc534440f6a29f32b1777ab6581643cfa05fff09e7dc5fee51f2e433b4a1d55606675d999aa09900cc7040b856bf 6468bff380f4c780082054056ed225139634079e3fa68005b43ff2a805fe6e62ccd838de8174718457b26329cdfc3f0e455914d2e31d4f2f4c055414d2d3454f574f694f7b4f8d4f009f4f6c7db2657709907fe74ff94f0b59fd11a6386368617267659328290ef6832500f5800b1572122b12c11a1936142392a075208b 601180b07b3b5fad68cd815ab2655c7928618f5f89406f044a10683e1014202b54037392029634086d6f58f2528665c4c03eba73e4379802bb7209d049981793c0cb6f1975759e1340655814d2d5ec6f2f4cabaa879199eaa490653002201522949202ea65300394920194920300b3ae41720100b97a2614b97420949424 ab2101a820c9be04b2610143002dca929490c4806fd10b1920124f1109d48f432003836ff2a82995000d9f2baf319f1a71f1214b9d77ad6b910077a630489faa2b7f3d7f4f7f617f8e1c8003bb47a5770925bfb67fc87f0b590ebea6384d6f766965942021445b66b26121f800531f7e6dc87415ff4da521e73e1b0640fe 84179624499224c9ffe07a77ddb4b3504db5b11c0c0002ff304f1be8b4814e6b973f000143b603b20049c102df06620700fe1e1004627f0300feff07404e7d12fc8b10851673eeb30b880df50ed3b70150f00200701cfc26c268c40100800b407a973340fe65c00169cf7bc502437005be0089c1a0c277c9039fcf3c7bc2 1c100203020247a3eda3bf0d00020b744e12407a577340fee4c00ce8c005ecc2d0c2ac85c05c2cb330025d2203c9d7ef409cf1bd41ec35419f5bf44947d0cf3f3dd4d045d5f9bfb01a4fb39c00620184ff003701a4000a019dbf007600850049d6a206e700a901dfa585f501010001073dd4657b2cdeb5dfc7dfd9df7e76 24debe55b16c56bfb204073a80d5e9a121ca0e97142a30ab62bf03f7218b0064f80444a5dd85e6a1a4088d40a1a4004085e59fe5d7219e2eb2323c00703484a4c2552cde0ad5ef059fd0fea434efbd0b9006fe2b0505fbeefb7a75d4dcb53cf82e29f9aa0061dca031dca0ad212591942022f09647a1222cc0a1bffc13ad 97d5402a5c8fc2f59b280cd3b5fe3f650ff2f4bd426d05b5b01fc210b4f5cd19feda14486605e9138305fe2cc0a53b08d2a00581d6a492deafa0d085efb540c6f6006d0fcdf79879950f4bbf25ef0b513be9a09131c22bc6f5cff5e12722942023ae421009002af6900af6902300d97089fff7e01650e1a0fc70b9831da3 fdb0c255a8703d0ad7a35aef50a0651123e97a75f77a7511dc7a75ef50bf03cce8ffc210641508cd136d15e919dc12047615bfad5332b30324b232f51201044208a2604e06b3059fd1b3078792aad2b00f288410c50165b703d0006cdf71142f4c3a2eb30340f17d17492f6cfc7100602f862ebb272d27972fd9a0ac2fd2 2e007517d92f5327bbc0e4a81f2f312f7e7c407c16773b5d3d892dc90fdb0706e60651234def425c69e723a71007e602fd2b92f83c3c636f6465ff3e3e0a7265747572ff6e207072696365430a24402ef276712cc120a0e7a5871d41dca950a090fa13fa14a09001f51942751dccbd578e1681ebd5527f984157990060d4 a04cd4a038b68257040074cc9024f090027cf6aa331303fc7003c2ac0218a828ecd8c4631323ec47c491f43f7f403df30a8fe61f0b90f0c156295345f0f9b644beeb92a7e1b6f1a950cea121238075ff0c60750a6004e462bebdc0750d60750b6454032380110402c7152780162ec06b543e5f54801240fe11df7062502a 5f50036651069f51016e506b503aaa541236c0750260a1a8c25027057503c8592dc00726812dc09508ea540926810a9190da4000e30104fe50f4109c9005307bff14ae47e17a843f00687f5747a12bc20239c180ff6317440b03af605441c2af600b03f962c500df3189c1616277cb616f7cc11402496580c31352658950 6a419691026201630600ae600163b76d7b40a691b86c0b63e36ad4e31ff5192276d0f47ed022017985c300d7a1040012024f05b99498d8df706101fe0f4001cb61005371025870673f010002c25000c657f7e0b5138156285f747d9480a1887b8b00c08a64b03733840100010000000000fd48e9f20c000200014effa521 e73e3b1840287f5c8fc2f5080340e9f2ff250028002b002d00ff2e002f00300032005f3300340035e7f417ebf0dd0b1b000b0018f5f03a00fd1ce1fa010040004200ff0440ad00354200000145dcf0fd3ee3f8010003001500ffc3005ccaaf006f2aff0000c0170000c900ff40005c31ad002f42f7000006ebf03f005200 1fdc37ad007a17000b002c0000000000000004001918dcffe7f41400df3c04000023ebf00100ff506167652d310000fd06f5f0426c61636b207f66696c6c000012f5f05f576869746509040401027d751804010052656409047f0100477265656e0904dd2df5f043796140040100bf59656c6c6f77090347baf5f04df9f0 6e74613308613d79280531302520780914037f6c696e65000083f5f0fd33850c4c6f6e672064c761736831009a032204646125720805a04905cd08ad3906cd0781c06508cd072e030c195804cd0801ab0035850c37850c39850c314770786c9903a2006d18396d18ef486169727113010053ef686f7274b80a010041bf72 69616c20636b00653f7265640000909910b013ff746f70206c656674e700009cc119f5f054696d0b6573b518bc9910e413de19ca17fde19910426f78000102f70000430d00436c0200ff5375627479706500f32102e210b1106e676c65fd003120436f6e6e6563ff746f72000200556e1f6976657273b311412630217d46 3d00204c6162650d00fd3e31204f7065726174ff696f6e7300004a02bf0200636c6173e8106f9f6d70617274f5f0842a2e1732360081205244203723922d6731007a3120942c0089c52e773300991d205061014b2fcf6f722e37f5f0f42f722ee538912f383c210c3f722e33ff330000cc02330043af0333003055301855 30feaa5130fa5130e65130d25130c0aa5130b35130a051308d51307daa51306e51305851304b51303eaa51303251302e51302a513021ea5130105130015130f00133ae13203300cdad30bcad30a7aaad309cad3090ad3084ad3078aaad3068ad3058ad3047ad3034eaad3024ad300ead30f90033ab00e5e930d3e930c0e9 30adaae930a0e93090e93083e93072aae93064e93055e93047e9303caae9302de9301de9300de930041f0036005d03ff0604000003000a00ff05003500ffffb0f987a80009eff0030f150fe6f5ff01ff1e0f430f550f670f790f8b0f9d0ff701000ef1f022002b00ff2e002f002c003400ff300027000f0006001f290009 0010cd022c03d90f5ceb0feaf110001df5f0259e0ffeddfe0500020004000bfc1a1fddfe03001a000d00df110008002aebf02d00f5122f101b691025001f007f200021002600282d10470b0013d70f901f98140af3f0ff17000c0018001400ff1500160019001c00b91e0310b005230024c50209007f1fe41fa316ff1f11 2fac03292f3b2f004d2f5f2fe4f86a2f8e2fa02fb22fe3f84107be2fe22ff42f063fe3f808123f10363f483f5a3fe3f809663f8a3fe7f4be7017350032003379140730cf2eec1ff40be4f70c00fd7ce9f225000400014effa521e73e3b1840287f5c8fc2f5080340ebf0df0100020003f5f00500ff0600070008000900ff 0a000b000c000d00ff0e000f0010001100ff1200130014001500ff1600170018001900ff1a001b001c001d00ff1e001f00200021007f2200270029002ae9f2ba0c0117ebf00b00641f0018060d006e00056ce1fa06dcff0e0f200f320fe5f6ff4000420094bcad001f7f460000813c000000000000000000000000000000 150000000000240000003ccfbd00bbc401e0fb010003fff209e30067fcf10c0f1e0f000028ff039d36d00f62e1409f28fc6d8ad13802340e3c73b9ad0a02eff88451ade7f4ff1400160052009411d7ad0038ebf054ebf01700574000447b008cebf0088304f5547b00948f041800d2005f04c0ad009cebf061ebf0ff2600 4200c418ad00d5fdebf021ebf01aa70110affb001eeff0920700001b4b0044e9f2b09201ebf01cd70cfd1d77007c56ad00e829f700007bebf024005000ffec13ad00632a0000f50cebf0277700bc3fad00df914200003bbf024000a5fc0b10cc1f10920129b70064ef1ead00d42f14180160f300cc0b10e6f532004600df 04f0af00dc1f108902f70000ca5710dcd9ad00d36545c400eff03f770044505e6c0047000020ebf03d07109f04b0ad00207f1012113cbed7001cd2ad002c7f100aaaebf043d7002c9b10367f1006002100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001050000050000000d0000004d45544146494c4550494354006a3c000016e8ffff 6e13000008006a3cea170000 010009000003b30900000a003a0000000000050000000b0200000000050000000c02d3022307050000000902ffffff000500000001020000000007000000fc020100000000000000040000002d01000009000000fa02000003000000000000002200040000002d01010004000000020101000c000000250304002d057c01 02053101d6047c012d057c0109000000fa02000000000000000000002200040000002d01020004000000f0010100050000000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01010004000000020101000e000000250305008b03c7018b03a1014604 a1010205a10102057c01040000002d01020004000000f0010100050000000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01010004000000020101000a000000250303000205c7010205a10102057c01040000002d01020004000000f00101000500 00000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01010004000000020101000e000000250305007906c7017906a101bd05a1010205a10102057c01040000002d01020004000000f0010100050000000902ffffff00050000000102000000000400 00002d01000009000000fa02000003000000000000002200040000002d01010004000000020101000e000000250305006c04a9009805a90098059b006c049b006c04a900040000002d01020004000000f001010013000000fb02d6ff0f000000000090010000000000000022417269616c204e6172726f77000004000000 2d01010010000000fb021400090000000000bc02000000000102022253797374656d006e040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d0100000900 0000fa02000003000000000000002200040000002d01040004000000020101000e000000250305006c043101980531019805a9006c04a9006c043101040000002d01020004000000f001040013000000fb02d6ff0f000000000090010100000000000022417269616c204e6172726f770000040000002d01040004000000 2d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0104000a000000210508006368617267652829f9007d04040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000030000000000 00002200040000002d01050004000000020101000e000000250305006c049b0098059b00980550006c0450006c049b00040000002d01020004000000f001050013000000fb02d6ff100000000000bc020100000000000022417269616c204e6172726f770000040000002d010500040000002d0103000400000008010000 050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01050009000000210505005072696365008200d804040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d0106000400 0000020101000e00000025030500f50220022104200221041202f5021202f5022002040000002d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffff ff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e00000025030500f502a8022104a80221042002f5022002f502a802040000002d01020004000000f0010600040000002d010100040000002d010300040000000801000005000000 0a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000a00000021050800636861726765282970020603040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000 020101000e00000025030500f5021202210412022104c701f502c701f5021202040000002d01020004000000f001060013000000fb02d6ff100000000000bc020000000000000022417269616c204e6172726f770000040000002d010600040000002d0103000400000008010000050000000a0200000000040000000201 0100040000002e01180005000000090200000000040000002d0106000d00000021050e004368696c6472656e735072696365f9011103040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01070004000000020101000e00 0000250305006c04200298052002980512026c0412026c042002040000002d01020004000000f0010700040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff00050000000102 00000000040000002d01000009000000fa02000003000000000000002200040000002d01070004000000020101000e000000250305006c04a8029805a802980520026c0420026c04a802040000002d01020004000000f0010700040000002d010100040000002d0103000400000008010000050000000a02000000000400 000002010100040000002e01180005000000090200000000040000002d0101000a00000021050800636861726765282970027d04040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01070004000000020101000e000000 250305006c041202980512029805c7016c04c7016c041202040000002d01020004000000f0010700040000002d010600040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0106000c00000021050c00526567756c6172507269 6365f9019804040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01070004000000020101000e00000025030500e30541020f0741020f073302e3053302e3054102040000002d01020004000000f0010700040000002d01 0100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01070004000000020101000e00 000025030500e305c9020f07c9020f074102e3054102e305c902040000002d01020004000000f0010700040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000a000000210508006368617267652829 9102f405040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01070004000000020101000e00000025030500e30533020f0733020f07c701e305c701e3053302040000002d01020004000000f0010700040000002d010600 040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0106000b00000021050a004e657752656c65617365f0011406090000002105050050726963650022024f06040000002d010300050000000902ffffff000500000001020000 000010000000fb02dfff0f000000000090010000000000000020417269616c00ad81040000002d010700040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01070007000000210501003100e8010404040000002d0103000500 00000902ffffff0005000000010200000000040000002d010700040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01070007000000210501003100e5018005040000002d010300050000000902ffffff000500000001020000 0000040000002d010700040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01070007000000210501003100e501ec06040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02 000003000000000000002200040000002d01080004000000020101000e00000025030500ec00a9001802a90018029b00ec009b00ec00a900040000002d01020004000000f0010800040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000 090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01080004000000020101000e00000025030500ec003101180231011802a900ec00a900ec003101040000002d01020004000000f0010800040000002d01 0100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000a000000210508006368617267652829f900fd00040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000 03000000000000002200040000002d01080004000000020101000e00000025030500ec009b0018029b0018025000ec005000ec009b00040000002d01020004000000f0010800040000002d010600040000002d0103000400000008010000050000000a02000000000400000002010100040000002e011800050000000902 00000000040000002d01060009000000210505004d6f7669650082005001040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01080004000000020101000a000000250303001802c0004203c0006c04c000040000002d01 020004000000f0010800040000002d01000009000000fa02000001000000000000002200040000002d01080004000000020101003a00000025031b004f04cf005004cd005204cb005404c9005604c7005804c6005a04c5005d04c3005f04c2006104c2006404c1006704c1006904c0006c04c0006904c0006704c0006404 bf006104bf005f04be005d04bd005a04bc005804ba005604b9005404b7005204b6005004b4004f04b200040000002d01020004000000f0010800050000000902ffffff000500000001020000000010000000fb02ceff16000000000090010000000000000020417269616c00ae81040000002d010800040000002d010300 0400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01080007000000210501003100aa001704040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01 0900040000000201010008000000250302000b00cd010b00a10108000000250302000b00a1014e01a10108000000250302004e01a1014e01cd0108000000250302004e01cd01ba01cd010e000000250305000b00cd010b002402ba012402ba01cd014e01a101040000002d01020004000000f0010900040000002d010100 040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000a000000210508003c3c636f64653e3ee6010b00130000002105190072657475726e207072696365436f64652e63686172676528290018020b00040000002d010300 050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d0109000400000002010100050000001402a101e2000500000013029e01e3000500000014029101ea000500000013028e01eb000500000014028101f2000500000013027e01f30005000000 14027101fa000500000013026e01fb00050000001402610102010500000013025e01030105000000140251010a010500000013024e010c01050000001402400113010500000013023d01140105000000140230011b010500000013022d011c01050000001402200123010500000013021d01240105000000140210012b01 0500000013020d012c0105000000140200013301050000001302fd003401040000002d01020004000000f0010900030000000000}{\result {\insrsid13379340 {\pict{\*\picprop\shplid1027{\sp{\sn shapeType}{\sv 75}}{\sp{\sn fFlipH}{\sv 0}} {\sp{\sn fFlipV}{\sv 0}}{\sp{\sn fillColor}{\sv 268435473}}{\sp{\sn fFilled}{\sv 0}}{\sp{\sn fLine}{\sv 0}}{\sp{\sn fLayoutInCell}{\sv 1}}}\picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0 \picw15466\pich6122\picwgoal8768\pichgoal3471\wmetafile8\bliptag-1430453870\blipupi-252{\*\blipuid aabd019236d41bcbf3063520e1bb11e3} 010009000003b30900000a003a0000000000050000000b0200000000050000000c02d3022307050000000902ffffff000500000001020000000007000000fc02 0100000000000000040000002d01000009000000fa02000003000000000000002200040000002d01010004000000020101000c000000250304002d057c010205 3101d6047c012d057c0109000000fa02000000000000000000002200040000002d01020004000000f0010100050000000902ffffff0005000000010200000000 040000002d01000009000000fa02000001000000000000002200040000002d01010004000000020101000e000000250305008b03c7018b03a1014604a1010205 a10102057c01040000002d01020004000000f0010100050000000902ffffff0005000000010200000000040000002d01000009000000fa020000010000000000 00002200040000002d01010004000000020101000a000000250303000205c7010205a10102057c01040000002d01020004000000f0010100050000000902ffff ff0005000000010200000000040000002d01000009000000fa02000001000000000000002200040000002d01010004000000020101000e000000250305007906 c7017906a101bd05a1010205a10102057c01040000002d01020004000000f0010100050000000902ffffff0005000000010200000000040000002d0100000900 0000fa02000003000000000000002200040000002d01010004000000020101000e000000250305006c04a9009805a90098059b006c049b006c04a90004000000 2d01020004000000f001010013000000fb02d6ff0f000000000090010000000000000022417269616c204e6172726f770000040000002d01010010000000fb02 1400090000000000bc02000000000102022253797374656d006e040000002d0103000400000008010000050000000a0200000000040000000201010004000000 2e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000030000000000 00002200040000002d01040004000000020101000e000000250305006c043101980531019805a9006c04a9006c043101040000002d01020004000000f0010400 13000000fb02d6ff0f000000000090010100000000000022417269616c204e6172726f770000040000002d010400040000002d01030004000000080100000500 00000a02000000000400000002010100040000002e01180005000000090200000000040000002d0104000a000000210508006368617267652829f9007d040400 00002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01050004000000 020101000e000000250305006c049b0098059b00980550006c0450006c049b00040000002d01020004000000f001050013000000fb02d6ff100000000000bc02 0100000000000022417269616c204e6172726f770000040000002d010500040000002d0103000400000008010000050000000a02000000000400000002010100 040000002e01180005000000090200000000040000002d01050009000000210505005072696365008200d804040000002d010300050000000902ffffff000500 0000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e00000025030500f50220022104 200221041202f5021202f5022002040000002d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a0200000000 0400000002010100040000002e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d0100000900 0000fa02000003000000000000002200040000002d01060004000000020101000e00000025030500f502a8022104a80221042002f5022002f502a80204000000 2d01020004000000f0010600040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e0118000500 0000090200000000040000002d0101000a00000021050800636861726765282970020603040000002d010300050000000902ffffff0005000000010200000000 040000002d01000009000000fa02000003000000000000002200040000002d01060004000000020101000e00000025030500f5021202210412022104c701f502 c701f5021202040000002d01020004000000f001060013000000fb02d6ff100000000000bc020000000000000022417269616c204e6172726f77000004000000 2d010600040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d010600 0d00000021050e004368696c6472656e735072696365f9011103040000002d010300050000000902ffffff0005000000010200000000040000002d0100000900 0000fa02000003000000000000002200040000002d01070004000000020101000e000000250305006c04200298052002980512026c0412026c04200204000000 2d01020004000000f0010700040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e0118000500 0000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000030000000000000022000400 00002d01070004000000020101000e000000250305006c04a8029805a802980520026c0420026c04a802040000002d01020004000000f0010700040000002d01 0100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000a00 000021050800636861726765282970027d04040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa0200000300 0000000000002200040000002d01070004000000020101000e000000250305006c041202980512029805c7016c04c7016c041202040000002d01020004000000 f0010700040000002d010600040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000 040000002d0106000c00000021050c00526567756c61725072696365f9019804040000002d010300050000000902ffffff000500000001020000000004000000 2d01000009000000fa02000003000000000000002200040000002d01070004000000020101000e00000025030500e30541020f0741020f073302e3053302e305 4102040000002d01020004000000f0010700040000002d010100040000002d0103000400000008010000050000000a0200000000040000000201010004000000 2e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000030000000000 00002200040000002d01070004000000020101000e00000025030500e305c9020f07c9020f074102e3054102e305c902040000002d01020004000000f0010700 040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e0118000500000009020000000004000000 2d0101000a0000002105080063686172676528299102f405040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000 fa02000003000000000000002200040000002d01070004000000020101000e00000025030500e30533020f0733020f07c701e305c701e3053302040000002d01 020004000000f0010700040000002d010600040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000 090200000000040000002d0106000b00000021050a004e657752656c65617365f0011406090000002105050050726963650022024f06040000002d0103000500 00000902ffffff000500000001020000000010000000fb02dfff0f000000000090010000000000000020417269616c00ad81040000002d010700040000002d01 03000400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01070007000000210501003100 e8010404040000002d010300050000000902ffffff0005000000010200000000040000002d010700040000002d0103000400000008010000050000000a020000 00000400000002010100040000002e01180005000000090200000000040000002d01070007000000210501003100e5018005040000002d010300050000000902 ffffff0005000000010200000000040000002d010700040000002d0103000400000008010000050000000a02000000000400000002010100040000002e011800 05000000090200000000040000002d01070007000000210501003100e501ec06040000002d010300050000000902ffffff000500000001020000000004000000 2d01000009000000fa02000003000000000000002200040000002d01080004000000020101000e00000025030500ec00a9001802a90018029b00ec009b00ec00 a900040000002d01020004000000f0010800040000002d010100040000002d0103000400000008010000050000000a0200000000040000000201010004000000 2e01180005000000090200000000040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa020000030000000000 00002200040000002d01080004000000020101000e00000025030500ec003101180231011802a900ec00a900ec003101040000002d01020004000000f0010800 040000002d010100040000002d0103000400000008010000050000000a02000000000400000002010100040000002e0118000500000009020000000004000000 2d0101000a000000210508006368617267652829f900fd00040000002d010300050000000902ffffff0005000000010200000000040000002d01000009000000 fa02000003000000000000002200040000002d01080004000000020101000e00000025030500ec009b0018029b0018025000ec005000ec009b00040000002d01 020004000000f0010800040000002d010600040000002d0103000400000008010000050000000a02000000000400000002010100040000002e01180005000000 090200000000040000002d01060009000000210505004d6f7669650082005001040000002d010300050000000902ffffff000500000001020000000004000000 2d01000009000000fa02000001000000000000002200040000002d01080004000000020101000a000000250303001802c0004203c0006c04c000040000002d01 020004000000f0010800040000002d01000009000000fa02000001000000000000002200040000002d01080004000000020101003a00000025031b004f04cf00 5004cd005204cb005404c9005604c7005804c6005a04c5005d04c3005f04c2006104c2006404c1006704c1006904c0006c04c0006904c0006704c0006404bf00 6104bf005f04be005d04bd005a04bc005804ba005604b9005404b7005204b6005004b4004f04b200040000002d01020004000000f0010800050000000902ffff ff000500000001020000000010000000fb02ceff16000000000090010000000000000020417269616c00ae81040000002d010800040000002d01030004000000 08010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d01080007000000210501003100aa0017040400 00002d010300050000000902ffffff0005000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d01090004000000 0201010008000000250302000b00cd010b00a10108000000250302000b00a1014e01a10108000000250302004e01a1014e01cd0108000000250302004e01cd01 ba01cd010e000000250305000b00cd010b002402ba012402ba01cd014e01a101040000002d01020004000000f0010900040000002d010100040000002d010300 0400000008010000050000000a02000000000400000002010100040000002e01180005000000090200000000040000002d0101000a000000210508003c3c636f 64653e3ee6010b00130000002105190072657475726e207072696365436f64652e63686172676528290018020b00040000002d010300050000000902ffffff00 05000000010200000000040000002d01000009000000fa02000003000000000000002200040000002d0109000400000002010100050000001402a101e2000500 000013029e01e3000500000014029101ea000500000013028e01eb000500000014028101f2000500000013027e01f3000500000014027101fa00050000001302 6e01fb00050000001402610102010500000013025e01030105000000140251010a010500000013024e010c01050000001402400113010500000013023d011401 05000000140230011b010500000013022d011c01050000001402200123010500000013021d01240105000000140210012b010500000013020d012c0105000000140200013301050000001302fd003401040000002d01020004000000f0010900030000000000}}}}}{\insrsid412021 By adding the indirection we can do the subclassing from the price code object, changing the price whenever we need to. \par With a complex class you have to move data and methods around in small pieces to avoid errors, it seems slow but it is the quickest because you avoid debugging. For this case I could probabl y move the data and methods in one go as the whole thing is not too complicated. However I\rquote ll do it the bit by bit way, so you can see how it goes. Just remember to do it one small bit at a time if you do this to a complicated class. \par The first step is to create the new classes. Then I need to sort out how they are managed. As the diagram shows they are all singletons. It seems sensible to get hold of them via the superclass with a method like }{ \cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 Price.regular()}{\insrsid412021 . I can do this by getting the superclass to manage the instances of the subclasses. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 abstract class Price \{ \par static Price regular() \{ \par return _regular; \par \} \par \par static Price childrens() \{ \par return _childrens; \par \} \par static Price newRelease() \{ \par return _newRelease; \par \} \par \par private static Price _childrens = new ChildrensPrice(); \par private static Price _newRelease = new NewReleasePrice(); \par private static Price _regular = new RegularPrice(); \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Now I can begin to move the data over. The first piece of data to mov e over is the price code. Of course I\rquote m not actually going to use the price code within the Price object, but I will give it the illusion of doing so. That way the old methods will still work. They key is to modify those methods that access and update the price code value within Movie. My first step is to }{\cs25\i\cf6\insrsid412021 self-encapsulate the type code}{\insrsid412021 , ensuring that all uses of the type code go though getting and setting methods. Since most of the code came from other classes, most methods already use the getting method. H owever the constructors do access the price code, I can use the setting methods instead. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 \tab public static Movie newNewRelease(String name)\{ \par Movie result = new Movie (name); \par result.beNewRelease(); \par return result; \par \tab \} \par \tab public static Movie newRegular(String name)\{ \par Movie result = new Movie (name); \par result.beRegular(); \par return result; \par \tab \} \par \tab public static Movie newChildrens(String name) \{ \par Movie result = new Movie (name); \par result.beChildrens(); \par return result; \par \tab \} \par \par \tab private Movie(String name) \{ \par \tab \tab _name = name; \par \tab \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 After compiling and testing I now change getting and setting methods to use the new class. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 public void beRegular() \{ \par _price = Price.regular(); \par \} \par \par public void beNewRelease() \{ \par _price = Price.newRelease(); \par \} \par \par public void beChildrens() \{ \par _price = Price.childrens(); \par \} \par public int priceCode() \{ \par return _price.priceCode(); \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 And provide the }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 priceCode}{ \insrsid412021 methods on }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 Price}{\insrsid412021 and its subclasses. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class Price\'85 \par abstract int priceCode(); \par \par Class RegularPrice\'85 \par int priceCode()\{ \par return Movie.REGULAR; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 To do this I need to make the constants non-private again. This is fine, I don\rquote t mind them having a little fame before they bite the dust. \par I can now compile and test and the more complex methods don\rquote t realize the world has changed. \par After moving the data I can now start moving methods. My prime target is the }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 charge()}{\insrsid412021 method. It is simple to move. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class Movie\'85 \par double charge(int daysRented) \{ \par return _price.charge(daysRented); \par \} \par \par Class Price\'85 \par double charge(int daysRented) \{ \par double result = 0; \par switch (priceCode()) \{ \par case Movie.REGULAR: \par result += 2; \par if (daysRented > 2) \par result += (daysRented - 2) * 1.5; \par break; \par case Movie.NEW_RELEASE: \par result += daysRented * 3; \par break; \par case Movie.CHILDRENS: \par result += 1.5; \par if (daysRented > 3) \par result += (daysRented - 3) * 1.5; \par break; \par \par \} \par return result; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Once it is moved I can start }{\cs25\i\cf6\insrsid412021 replacing the case statement with inheritance}{\insrsid412021 . I do this by taking one leg of the case statement at a time, and creating an overriding method. I start with }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 RegularPrice}{ \insrsid412021 . \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class RegularPrice\'85 \par double charge(int daysRented)\{ \par double result = 2; \par if (daysRented > 2) \par result += (daysRented - 2) * 1.5; \par return result; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 This will override the parent case statement, which I just leave as it is. I compile and test for this case, then take the next leg, compile and test\'85. (To make sure I\rquote m executing the subclass code, I like to throw in a deliberate bug and run it to ensure the tests blow up. Not that I\rquote m paranoid or anything.) \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class ChildrensPrice \par double charge(int daysRented)\{ \par double result = 1.5; \par if (daysRented > 3) \par result += (daysRented - 3) * 1.5; \par return result; \par \} \par \par Class NewReleasePrice\'85 \par double charge(int daysRented)\{ \par return daysRented * 3; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 When I\rquote ve done that with all the legs, I declare the }{ \cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 Price.charge()}{\insrsid412021 method abstract. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class Price\'85 \par abstract double charge(int daysRented); \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 I can now do the same procedure with }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 frequentRenterPoints()}{\insrsid412021 . First I move the method over to }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 Price}{\insrsid412021 . \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class Movie\'85 \par int frequentRenterPoints(int daysRented)\{ \par return _price.frequentRenterPoints(daysRented); \par \} \par Class Price\'85 \par int frequentRenterPoints(int daysRented)\{ \par if ((priceCode() == Movie.NEW_RELEASE) && daysRented > 1) return 2; \par else return 1; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 In this case, however I won\rquote t make the superclass method abstract. Instead I will create an overriding method for new releases, and leave a defined method (as the default) on the superclass. \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 Class NewReleasePrice \par int frequentRenterPoints(int daysRented)\{ \par return (daysRented > 1) ? \par 2: \par 1; \par \} \par \par Class Price\'85 \par int frequentRenterPoints(int daysRented)\{ \par return 1; \par \} \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Now I have removed all the methods that needed a price code. So I can get rid of the price code methods and data on both }{\cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 Movie}{\insrsid412021 and }{ \cs23\f38\fs16\lang1024\langfe1024\noproof\insrsid412021 Price}{\insrsid412021 . \par Putting in the state pattern was quite an effort, was it worth it? The gain is now that should I change any of price\rquote s behavior, add new prices, or add extra price dependent behavior; it will be much easier to change. The rest of the application d oes not know about the use of the state pattern. For the tiny amount of behavior I currently have it is not a big deal. But in a more complex system with a dozen or so price dependent methods this would make a big difference. All these changes were small steps, it seems slow to write it like this, but not once did I have to open the debugger. So the process actually flowed quite quickly. \par }\pard\plain \s2\qj \li0\ri0\sb240\sa120\keep\keepn\widctlpar\hyphpar0\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 \b\f37\fs24\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 Final Thoughts \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 This is a simple example, yet I hope it gives you the feeling of what refactoring is like. I \rquote ve used sever al refactoring techniques: moving behavior, replacing case statements, method extraction. All these lead to a better distributed responsibilities, and code that is easier to maintain. It does look rather different to procedural style code, and that does t ake some getting used to. But once you are used to it, it is hard to go back to procedural programs. \par The most important lesson from this example is the rhythm of refactoring: test, small change, test, small change, test, small change. It is that rhythm that allows refactoring to move quickly and safely. \par }\pard\plain \s3\qj \li0\ri0\sb240\sa60\keep\keepn\widctlpar\faauto\outlinelevel2\adjustright\rin0\lin0\itap0 \b\f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 References \par }\pard\plain \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1026\cgrid\langnp1033\langfenp1026 {\insrsid412021 [Fowler]\tab \line Fowler M with Scott K, }{\i\insrsid412021 UML Dist illed: Applying the Standard Object Modeling Language}{\insrsid412021 , Addison-Wesley, Reading MA, 1997 \par }\pard \ql \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 {\insrsid412021 [Gang of Four] \line Gamma E, Helm R, Johnson R, and Vlissides J, }{\i\insrsid412021 Design Patterns: Elements of Reusable Object Oriented Software}{ \insrsid412021 , Addison-Wesley, Reading MA, 1995 \par }\pard \qj \li0\ri0\sb120\sa120\widctlpar\faauto\adjustright\rin0\lin0\itap0 {\insrsid412021 [McConnell, Code Complete]\tab \line McConnell Steve, }{\i\insrsid412021 Code Complete: A Practical Handbook of Software Construction}{\insrsid412021 , Microsoft Press, 1993 \par \par }\pard\plain \s17\qj \li144\ri0\widctlpar\tx288\tx576\tx864\tx1080\tx1260\tx1440\tx1620\tx1800\faauto\adjustright\rin0\lin144\itap0 \f38\fs16\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1026 {\insrsid412021 \par \par \par \par \par \par \par }}