home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!paladin.american.edu!howland.reston.ans.net!spool.mu.edu!uwm.edu!ogicse!news.u.washington.edu!serval!wsuaix.csc.wsu.edu!rnelson
- From: rnelson@wsuaix.csc.wsu.edu (roger nelson;S23487)
- Newsgroups: comp.os.msdos.programmer
- Subject: A foreign language translation Pascal unit
- Message-ID: <1993Jan11.034157.14452@serval.net.wsu.edu>
- Date: 11 Jan 93 03:41:57 GMT
- Article-I.D.: serval.1993Jan11.034157.14452
- Sender: news@serval.net.wsu.edu (USENET News System)
- Organization: Washington State University
- Lines: 693
-
-
- Here is the Turbo Pascal Unit for translating phrases to various languages.
- It can be used for both DOS and Windows.
-
- A couple of weeks ago I asked if windows provided facilities for allowing
- an application to switch between one or more foreign languages
- and gave a brief outline of what I was planning on doing.
-
- A number of people replied suggesting windows string tables, however
- this seemed to have a fair amount of overhead.
- Others suggested DLL or making resources files, but this didn't allow the
- user to change the language on the fly.
-
- Thanks to everyone who replied.
-
- This unit allows the user to change the language on the fly and only stores the
- phrases used by the current program for the current language in main memory.
-
- By editing the PHRASES.LNG file, users can also provide localizations
- for other languages (not supplied by the programmer) without having
- to recompile the application program.
-
- I thought others might find this unit useful so I am posting the short
- program listing here.
-
- I am also supplying a sample PHRASES.LNG file which has translations of
- several common user interface strings for ENGLISH, FRENCH, SPANISH and
- ITALIAN. This file is UUENCODED because it uses IBM-PC 8-bit characters
- for accented characters in French,Spanish and Italian.
-
- I hope that other programmers will provide multilingual support for their
- applications.
- _____________________________________________________________________
- ______________
- ____ | ^ | Roger Nelson rnelson@wsuaix.csc.wsu.edu
- \^^ | | ^ | Biological Systems Engineering Department
- |^^// ^^ |
- | ' ^ +|<---Washington State University
- \_ ^ _________| Pullman, WA 99164-6120
- `-----' Work: (509)335-4714 Home: (509)332-8387
- FAX: (509)335-2722
-
- LANGUAG.PAS
- ---Cut Here-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
-
- UNIT languag;
- {
- This TurboPascal unit will help provide translation of text strings
- to different human languages.
-
- Written by Roger Nelson Jan. 1993
- Comments, suggestions, questions and bug reports can be sent to:
-
- Roger Nelson
- Biological Systems Engr. Dept.
- Washington State University
- Pullman, WA 99164-6120
-
- rnelson@wsuaix.csc.wsu.edu
-
- Phone: (509)335-1578
- FAX : (509)335-2722
-
-
- An equivelent module can also be provided for the programming languages:
- C and scheme by request.
- ________________________________________________________________________
-
- Phrases are stored in the phrases file: PHRASES.LNG
- which must be placed in in the same directory as the application
- program executables.
- (The phrases.lng file must also be available to the compiler.)
-
- The phrases files has the following format which allows for the compiler
- to double check the existance of a phrase so you can't inadvertantly
- leave out a phrase from your translations!!!!
-
-
- phraseID,
- ( programlist
- ENGLISH English phrase
- SPANISH Spanish phrase
- ITALIAN Italian phrase
- FRENCH French phrase
- :
- :
- )
- NextphrasesID,
- :
- :
-
- The phraseID must be a unique valid Pascal Identifier and must be
- followed by a comma. The phraseID and comma must be on their own line.
-
- THE ( AND ) CHARACTERS ARE ACTUALLY PASCAL COMMENT CHARACTERS AND MUST
- BE ON THEIR OWN LINES.
-
- After the first comment (on the same line) is a list of all programs in
- which the phrase is used, only those phrases used by the program will
- be loaded. This is useful if your application consists of several programs,
- but where not all phrases are used in all the programs.
-
- Each translation must be on its own line, the name of the language
- must be uppercase with consistent spelling and one word.
-
- There must be only one space or one tab character seperating the
- language from the phrase.
-
- There must not be any blank lines between the ) and the next phrase ID.
-
- The very first phrases in PHRASES.LNG must be the translation for the
- name of the language:
-
- L_LANGUAGE,
- ( PROGRAM1 PROGRAM2
- ENGLISH English phrase
- FRENCH Francais phrase
- SPANISH Espanol phrase
- ITALIAN Italiano phrase
- )
- ^- Pascal comment characters!
-
- If the phrase is to be a null string or a single space, then use
- an underscore character _, Ie: ENGLISH _
-
-
-
- Tips for restarting a TurboVision application with a new application.
-
- You may want to allow the user to change the language within the
- application.
-
- The easiest thing to do is shutdown and restart TurboVision.
-
- 1. Create a boolean variable that will be used to test for the actual exit
- of the application.
-
- 2. Put a while loop using this variable as the test around the application
- init, run and done procedures.
-
- 3. Call the init_language function near the beginning of the program.
- Call the end_language function near the end of the program.
-
- 4. Usually object registration for TurboVision is done in the
- application.init procedure.
- Move these registrations to a point before the exit_application loop
- otherwise TurboVision will complain about stream registration when
- init gets call more than once.
-
- 5. Provide menu options for changing the language.
- This may be a user preferences dialog box or submenus etc...
-
- 6. Provide an application event handler point for each language:
-
- I.e.
-
- cmLanguageDefault :
- BEGIN
- Load_language(getenv('LANGUAGE'),'MYAPP');
- message(@self,evCommand,cmQUIT,NIL);
- END;
- cmLanguageEnglish :
- BEGIN
- Load_language('ENGLISH','MYAPP');
- message(@self,evCommand,cmQUIT,NIL);
- END;
- cmLanguageFrench :
- BEGIN
- Load_language('FRENCH','MYAPP');
- message(@self,evCommand,cmQUIT,NIL);
- END;
- cmLanguageSpanish :
- BEGIN
- Load_language('SPANISH','MYAPP');
- message(@self,evCommand,cmQUIT,NIL);
- END;
- cmLanguageItalian :
- BEGIN
- Load_language('ITALIAN','MYAPP');
- message(@self,evCommand,cmQUIT,NIL);
- END;
-
- 7. When you actually want to exit the program with cmQUIT, set
- exit_application to TRUE:
-
- cmExit_MyApp :
- BEGIN
- exit_application := TRUE;
- message(@self,evCommand,cmQUIT,NIL);
- END;
-
- 8. To use a phrase translation simply call tranlate() with the phrase_Id
- Ie.
- Writeln(translate(L_mouse),' (',translate(L_Not_available),')');
-
- I.e. The main module of the program MYAPP would look something like this:
-
- BEGIN
-
- init_language(getenv('LANGUAGE'),'MYAPP'); <- To get the default language
- From the DOS environment
- variable LANGUAGE, set before
- running the program
-
- RegisterObjects;
- RegisterViews;
- RegisterMenus;
- RegisterDialogs;
- RegisterApp;
- RegisterHelpFile;
-
- exit_application := FALSE; <- global variable
- WHILE NOT exit_application DO
- BEGIN
- theapplication.Init;
- theapplication.Run;
- theapplication.Done;
- END;
-
- end_language;
- END.
-
-
- The function program_path is implemented as follows:
-
- FUNCTION program_path : STRING;
- VAR
- directory : DirStr;
- Name : NameStr;
- ext : ExtStr;
- BEGIN
- FSplit(ParamStr(0),directory,name,ext);
- program_path := directory;
- END;
-
- The function upcase_str is implemented as follows:
-
- FUNCTION upcase_str(the_string : STRING) : STRING;
- VAR i : INTEGER;
- BEGIN
- FOR i := 1 to length(the_string) DO
- the_string[i] := upcase(the_string[i]);
- upcase_str := the_string;
- END;
-
- The function strpos is implemented as follows:
-
- FUNCTION strpos(str1, str2 : STRING) : INTEGER;
- VAR
- I,J : INTEGER;
- BEGIN
- J := 0;
- strpos := 0;
- FOR I := 1 TO LENGTH(str1) DO
- IF str1[i] = str2[j+1] THEN
- BEGIN
- INC(J);
- IF J = LENGTH(STR2) THEN strpos :=i-j;
- END
- ELSE
- BEGIN
- j := 0;
- i := i-j;
- END;
- END;
-
- Please note that the translate function could be enhanced by using
- a search tree (which would also require balancing the phrase list),
- however, since the phrases list is ordered by phraseID,
- the linear search should suffice for a few hundred phrases.
-
- }
-
- INTERFACE
-
- USES DOS,cs_glob,objects;
-
- TYPE
- phrases = ({$I PHRASES.LNG} END_PHRASES);
-
- PROCEDURE init_language(Language_Name : STRING; program_name : STRING);
- PROCEDURE load_language(Language_Name : STRING; program_name : STRING);
- FUNCTION translate(phrase_ID : phrases) : STRING;
- PROCEDURE end_language;
-
- IMPLEMENTATION
-
- TYPE
-
- translation_node_ptr = ^translation_node;
- translation_node = RECORD
- phrase_ID : phrases;
- phrase : Pstring;
- right : translation_node_ptr;
- END;
-
- VAR
- translation_list : translation_node_ptr;
-
- FUNCTION program_path : STRING;
- VAR
- directory : DirStr;
- Name : NameStr;
- ext : ExtStr;
- BEGIN
- FSplit(ParamStr(0),directory,name,ext);
- program_path := directory;
- END;
-
-
-
- PROCEDURE clear_translation_list(node : translation_node_ptr);
- BEGIN
- IF (node <> NIL) THEN
- WITH node^ DO
- BEGIN
- { clear_translation_list(left); }
- clear_translation_list(right);
- DisposeStr(phrase);
- Dispose(node)
- END;
- END;
-
- PROCEDURE load_language(Language_Name: STRING; program_name : STRING);
- VAR
- phrases_file : TEXT;
- phrases_filename : STRING;
- node : translation_node_ptr;
- phrase_ID : phrases;
- last_node : translation_node_ptr;
- phrase : STRING;
- used_by : STRING;
-
- FUNCTION read_phrase : BOOLEAN;
- VAR phrase_ID_str : STRING;
- language_name_in : STRING;
- line_in : STRING;
- read_complete : BOOLEAN;
- phrase_in : STRING;
-
- PROCEDURE split_line(line : STRING; VAR lang : STRING;
- VAR phrase : STRING);
- VAR Line_ndx : INTEGER;
- linelen : INTEGER;
- langlen : INTEGER;
- phraselen: INTEGER;
- BEGIN
-
- Line_ndx := 0;
- linelen := length(line);
- langlen := 0;
- REPEAT
- INC(line_ndx);
- INC(langlen);
- lang[langlen] := line[line_ndx];
- UNTIL (line[line_ndx+1] = ' ') OR (line_ndx = linelen);
- lang[0] := char(langlen);
- INC(line_ndx);
- phraselen := 0;
- REPEAT
- INC(line_ndx);
- INC(phraselen);
- phrase[phraselen] := line[line_ndx];
- UNTIL (line_ndx = linelen);
- phrase[0] := CHAR(phraselen);
- END;
-
- BEGIN
- read_phrase := TRUE;
- IF eof(phrases_file) THEN
- read_phrase := FALSE
- ELSE
- BEGIN
- phrase := '';
- readln(phrases_file,phrase_ID_str); { phrases ID Not used}
- IF (phrase_ID_str = '') OR (eof(phrases_file))
- THEN
- read_phrase := FALSE
- ELSE
- BEGIN
- readln(phrases_file,used_by);
- read_complete := FALSE;
- REPEAT
- readln(phrases_file,line_in);
-
- IF (line_in[1] = '}') THEN
- read_complete := TRUE
- ELSE
- BEGIN
- split_line(line_in,language_name_in,phrase_in);
- IF language_name_in = language_name THEN
- phrase := phrase_in
- ELSE IF (language_name_in = 'ENGLISH') AND
- (phrase = '') THEN
- { Use english if translation not provided}
- phrase := phrase_in;
-
- END
- UNTIL read_complete;
- END;
- END;
- END;
-
- BEGIN
- IF (translation_list <> NIL) THEN
- clear_translation_list(translation_list);
- translation_list := NIL;
- IF language_name = '' THEN
- language_name := 'ENGLISH';
-
- phrase_ID := L_LANGUAGE;
- phrases_filename := program_path + 'PHRASES.LNG';
- ASSIGN(phrases_file,phrases_filename);
- RESET(phrases_file);
- last_node := NIL;
- FOR phrase_ID := L_LANGUAGE TO PRED(END_PHRASES) DO
- BEGIN
- IF NOT read_phrase THEN halt(0);
- IF strpos(upcase_str(used_by),upcase_str(program_name)) <> 0 THEN
- BEGIN
- new(node);
- IF translation_list = NIL THEN
- translation_list := node;
- node^.phrase_ID := phrase_ID;
- node^.phrase := NewStr(phrase);
- node^.right := NIL;
- IF (last_node <> NIL) THEN
- last_node^.right := node;
- last_node := node;
- END;
- END;
- CLOSE(phrases_file);
- END;
-
- FUNCTION translate(phrase_ID : phrases) : STRING;
- VAR
- curr : translation_node_ptr;
- translation : STRING;
- BEGIN
- curr := translation_list;
- WHILE ((curr <> NIL) AND (curr^.phrase_ID <> phrase_ID)) DO
- curr := curr^.right;
- IF (curr <> NIL) THEN
- translation := curr^.phrase^
- ELSE
- translation := 'Unable to translate';
- IF translation = '_' THEN
- translate := ' '
- ELSE
- translate := translation;
- END;
-
- PROCEDURE init_language(language_name : STRING; program_name : STRING);
- BEGIN
- IF language_name = '' THEN
- language_name := 'ENGLISH';
- translation_list := NIL;
- load_language(Language_name,program_name);
- END;
-
- PROCEDURE end_language;
- BEGIN
- clear_translation_list(translation_list);
- END;
-
- END.
- ---Cut Here----->8----->8----->8----->8----->8----->8----->8----->8-----
-
- begin 644 phrases.lng
- M4F5P;&%C92!-64%04"!W:71H('EO=7(@<')O9W)A;2!N86UE*',I+@H*+2TM
- M0W5T($AE<F4M+2TM+3@\+2TM+2TX/"TM+2TM.#PM+2TM+3@\+2TM+2TX/"TM
- M+2TM.#PM+2TM+3@\+2TM+2TX/"TM+2TM.#PM+2T*3%],04Y'54%'12P*>R!-
- M64%04`I%3D=,25-(($5N9VQI<V@*1E)%3D-(($9R86YC86ES"DE404Q)04X@
- M271A;&EA;F\*4U!!3DE32"!%<W!A;F]L"GT*3%]!8F]U="P*>R!-64%04`I%
- M3D=,25-(($%B;W5T"D9214Y#2"!!=71O=7(*251!3$E!3B!2:6=U87)D;PI3
- M4$%.25-(($%C97)C82!D90I]"DQ?07!R+`I[($U905!0"D5.1TQ)4T@@07!R
- M"D9214Y#2"!!=G(*251!3$E!3B!!<'(*4U!!3DE32"!!8G(*?0I,7T%P<FEL
- M+`I[($U905!0"D5.1TQ)4T@@07!R:6P*1E)%3D-(($%V<FEL"DE404Q)04X@
- M07!R:6QE"E-004Y)4T@@06)R:6P*?0I,7T%U9RP*>R!-64%04`I%3D=,25-(
- M($%U9PI&4D5.0T@@06]T"DE404Q)04X@06=T"E-004Y)4T@@06=O"GT*3%]!
- M=6=U<W0L"GL@35E!4%`*14Y'3$E32"!!=6=U<W0*1E)%3D-(($%O%G0*251!
- M3$E!3B!!9V]S=&\*4U!!3DE32"!!9V]S=&\*?0I,7T-H86YG95]$:7)E8W1O
- M<GDL"GL@35E!4%`*14Y'3$E32"!#:&%N9V4@1&ER96-T;W)Y"D9214Y#2"!#
- M:&%N9V5R('("<&5R=&]I<F4*251!3$E!3B!#86UB:6\@9&D@9&ER96-T;W)Y
- M"E-004Y)4T@@0V%M8FEA<B!D:7)E8W1O<FEO"GT*3%]#:&5C:U]P871H7V]R
- M7W-P96QL:6YG+`I[($U905!0"D5.1TQ)4T@@0VAE8VL@=&AE('!A=&@@;W(@
- M<W!E;&QI;F<N"D9214Y#2"!0975T+0AT<F4@97)R975R('-E;G1I97(@;W4@
- M`G!E;&QA=&EO;BX*251!3$E!3B!697)I9FEC87)E(&EL('!E<F-A<G-O(&\@
- M:6P@;F]M92X*4U!!3DE32"!697)I9FEQ=64@;&$@<G5T82!O(&QA(&]R=&]G
- M<F%F(6$N"GT*3%]#;&]S92P*>R!-64%04`I%3D=,25-(($-L;W-E"D9214Y#
- M2"!&97)M97(*251!3$E!3B!#:&EU9&D*4U!!3DE32"!#97)R87(*?0I,7T-U
- M<G)E;G1?9&ER96-T;W)Y+`I[($U905!0"D5.1TQ)4T@@0W5R<F5N="!$:7)E
- M8W1O<GD*1E)%3D-((%("<&5R=&]I<F4@0V]U<F%N=`I)5$%,24%.($1I<F5C
- M=&]R>2!#;W)R96YT90I34$%.25-(($1I<F5C=&]R:6\@8V]R<FEE;G1E"GT*
- M3%]#7V%?<V-A9&4L"GL@35E!4%`*14Y'3$E32"!#?F%^<V-A9&4*1E)%3D-(
- M($-^87YS8V%D90I)5$%,24%.($9I;F5S=')E(&EN('Y3?F]V<F%P<&]S:7II
- M;VYE"E-004Y)4T@@0WYA?G-C861A"GT*3%]$871E+`I[($U905!0"D5.1TQ)
- M4T@@1&%T90I&4D5.0T@@1&%T90I)5$%,24%.($1A=&$*4U!!3DE32"!&96-H
- M80I]"DQ?1&%T97-?9F]R7W!R;V9I;&5?;W5T<'5T+`I[($U905!0"D5.1TQ)
- M4T@@1&%T97,@9F]R(')E<&]R=&EN9R!S;VEL('!R;V9I;&4@=F%R:6%B;&5S
- M"D9214Y#2"!$871E<R!P;W5R(&PG;W5T<'5T(&1E<R!H;W)I>F]N<PI)5$%,
- M24%.($1A=&4@<&5R(&PG;W5T<'5T(&1E;&QA('1A=F]L82!D96P@<W5O;&\*
- M4U!!3DE32"!&96-H87,@<&%R82!R97!O<G1A<B!V87)I86)L97,@9&5L('!E
- M<F9I;"!D92!S=65L;PI]"DQ?1&%Y+`I[($U905!0"D5.1TQ)4T@@1&%Y"D92
- M14Y#2"!*;W5R"DE404Q)04X@1VEO<FYO"E-004Y)4T@@1"%A"GT*3%]$87ES
- M+`I[($U905!0"D5.1TQ)4T@@1&%Y<PI&4D5.0T@@2F]U<G,*251!3$E!3B!'
- M:6]R;FD*4U!!3DE32"!$(6%S"GT*3%]$87E?;V9?;6]N=&@L"GL@35E!4%`*
- M14Y'3$E32"!$87D@;V8@=&AE(&UO;G1H"D9214Y#2"!*;W5R(&1U(&UO:7,*
- M251!3$E!3B!);"!G:6]R;F\@9&5L(&UE<V4*4U!!3DE32"!$(6$@9&5L(&UE
- M<PI]"DQ?1&5C+`I[($U905!0"D5.1TQ)4T@@1&5C"D9214Y#2"!$96,*251!
- M3$E!3B!$:6,*4U!!3DE32"!$96,*?0I,7T1E8V5M8F5R+`I[($U905!0"D5.
- M1TQ)4T@@1&5C96UB97(*1E)%3D-(($1E8V5M8G)E"DE404Q)04X@1&EC96UB
- M<F4*4U!!3DE32"!$:6-I96UB<F4*?0I,7V1E9F%U;'0L"GL@35E!4%`*14Y'
- M3$E32"!D969A=6QT"D9214Y#2"!087(@9`)F875T"DE404Q)04X@<')E9&5F
- M:6YI=&\*4U!!3DE32"!S=&%N9&%R9`I]"DQ?1&5L971E+`I[($U905!0"D5.
- M1TQ)4T@@1&5L971E"D9214Y#2"!3=7!P<FEM97(*251!3$E!3B!#86YC96QL
- M80I34$%.25-((%-U<')I;6ER"GT*3%]%;G1E<BP*>R!-64%04`I%3D=,25-(
- M($5N=&5R"D9214Y#2"!%;G1R90I)5$%,24%.($EN=')O9'5R<F4*4U!!3DE3
- M2"!%;G1R90I]"DQ?17AI="P*>R!-64%04`I%3D=,25-(($5X:70*1E)%3D-(
- M(%%U:71T97(*251!3$E!3B!%<V-I"E-004Y)4T@@4V%L:7(*?0I,7T5X=&5N
- M<VEO;E]M=7-T7VYO=%]S<&5C:69I960L"GL@35E!4%`*14Y'3$E32"!4:&4@
- M97AT96YS:6]N(&UU<W0@;F]T(&)E('-P96-I9FEE9"X*1E)%3D-(($5X=&5N
- M<VEO;B!N)V5S="!P87,@;F5C97-S86ER92X*251!3$E!3B!,)V5S=&5N<VEO
- M;F4@;F]N(&1E=F4@97-S97)E('-P96-I9FEC871A+@I34$%.25-(($QA(&5X
- M=&5N<VEO;B!N;R!D96)E(&5S<&5C:69I8V%R<V4N"GT*3%]%7WA?:70L"GL@
- M35E!4%`*14Y'3$E32"!%?GA^:70*1E)%3D-(('Y1?G5I='1E<@I)5$%,24%.
- M($5^<WYC:0I34$%.25-(('Y3?F%L:7(*?0I,7T9E8BP*>R!-64%04`I%3D=,
- M25-(($9E8@I&4D5.0T@@1F5V"DE404Q)04X@1F5B"E-004Y)4T@@1F5B"GT*
- M3%]&96)R=6%R>2P*>R!-64%04`I%3D=,25-(($9E8G)U87)Y"D9214Y#2"!&
- M979R:65R"DE404Q)04X@1F5B8G)A:6\*4U!!3DE32"!&96)R97)O"GT*3%](
- M96QP+`I[($U905!0"D5.1TQ)4T@@2&5L<`I&4D5.0T@@06ED90I)5$%,24%.
- M($%I=71O"E-004Y)4T@@07EU9&$*?0I,7TAO=7)S+`I[($U905!0"D5.1TQ)
- M4T@@2&]U<G,*1E)%3D-((&AE=7)E<PI)5$%,24%.($]R90I34$%.25-((&AO
- M<F%S"GT*3%]);G-E<G0L"GL@35E!4%`*14Y'3$E32"!);G-E<G0*1E)%3D-(
- M($EN<V5R97(*251!3$E!3B!);G-E<FES8VD*4U!!3DE32"!);G-E<G1A<@I]
- M"DQ?2F%N+`I[($U905!0"D5.1TQ)4T@@2F%N"D9214Y#2"!*86X*251!3$E!
- M3B!'96X*4U!!3DE32"!%;G(*?0I,7TIA;G5A<GDL"GL@35E!4%`*14Y'3$E3
- M2"!*86YU87)Y"D9214Y#2"!*86YV:65R"DE404Q)04X@1V5N;F%I;PI34$%.
- M25-(($5N97)O"GT*3%]*=6PL"GL@35E!4%`*14Y'3$E32"!*=6P*1E)%3D-(
- M($IU;`I)5$%,24%.($QU9PI34$%.25-(($IU;`I]"DQ?2G5L>2P*>R!-64%0
- M4`I%3D=,25-(($IU;'D*1E)%3D-(($IU:6QL970*251!3$E!3B!,=6=L:6\*
- M4U!!3DE32"!*=6QI;PI]"DQ?2G5N+`I[($U905!0"D5.1TQ)4T@@2G5N"D92
- M14Y#2"!*=6X*251!3$E!3B!':74*4U!!3DE32"!*=6X*?0I,7TIU;F4L"GL@
- M35E!4%`*14Y'3$E32"!*=6YE"D9214Y#2"!*=6EN"DE404Q)04X@1VEU9VYO
- M"E-004Y)4T@@2G5N:6\*?0I,7TQI;F5S7W!E<E]P86=E+`I[($U905!0"D5.
- M1TQ)4T@@3&EN97,@<&5R('!A9V4*1E)%3D-(($QI9VYE<R!P87(@<&%G90I)
- M5$%,24%.(%)I9VAE('!E<B!P86=I;F$*4U!!3DE32"!,(6YE87,@<&]R('`@
- M9VEN80I]"DQ?3&EN95]W:61T:"P*>R!-64%04`I%3D=,25-(($QI;F4@=VED
- M=&@*1E)%3D-(($QO;F=U975R(&1E(&QI;F=E<PI)5$%,24%.($QA<F=H97IZ
- M82!R:6=A"E-004Y)4T@@06YC:&\@9&4@;&$@;"%N96$*?0I,7TQO860L"GL@
- M35E!4%`*14Y'3$E32"!,;V%D"D9214Y#2"!,96-T=7)E"DE404Q)04X@0V%R
- M:6-A"E-004Y)4T@@06)R:7(*?0I,7TQO861?0W)E871E+`I[($U905!0"D5.
- M1TQ)4T@@3&]A9"]#<F5A=&4*1E)%3D-(($-H87)G97(O0W("97(*251!3$E!
- M3B!#87)I8V$O0W)E80I34$%.25-(($%B<FER+V-R96%R"GT*3%]-87(L"GL@
- M35E!4%`*14Y'3$E32"!-87(*1E)%3D-(($UA<@I)5$%,24%.($UA<@I34$%.
- M25-(($UA<@I]"DQ?36%R8V@L"GL@35E!4%`*14Y'3$E32"!-87)C:`I&4D5.
- M0T@@36%R<PI)5$%,24%.($UA<GIO"E-004Y)4T@@36%R>F\*?0I,7TUA>2P*
- M>R!-64%04`I%3D=,25-(($UA>0I&4D5.0T@@36%I"DE404Q)04X@36%G9VEO
- M"E-004Y)4T@@36%Y;PI]"DQ?36]U<V4L"GL@35E!4%`*14Y'3$E32"!-;W5S
- M90I&4D5.0T@@4V]U<FES"DE404Q)04X@36]U<V4*4U!!3DE32"!2870B;@I]
- M"DQ?3F5X=%]W:6YD;W<L"GL@35E!4%`*14Y'3$E32"!.97AT('=I;F1O=PI&
- M4D5.0T@@1F5N"'1R92!S=6EV86YT"DE404Q)04X@4')O<W-I;6$@9FEN97-T
- M<F$*4U!!3DE32"!696YT86YA(%-I9W5I96YT90I]"DQ?3F]T7T%V86EL86)L
- M92P*>R!-64%04`I%3D=,25-(($YO="!!=F%I;&%B;&4*1E)%3D-(($YO;B!$
- M:7-P;VYI8FQE"DE404Q)04X@3F]N($1I<W!O;FEB:6QE"E-004Y)4T@@3F\@
- M9&ES<&]N:6)L90I]"DQ?3F]T7V5N;W5G:%]M96UO<GE?=&]?8V]M<&QE=&5?
- M;W!E<F%T:6]N+`I[($U905!0"D5.1TQ)4T@@3F]T(&5N;W5G:"!M96UO<GD@
- M879A:6QA8FQE('1O(&-O;7!L971E(&]P97)A=&EO;BX*1E)%3D-(($T";6]R
- M:64@;F]N(&1I<W!O;FEB;&4N($]P`G)A=&EO;B!N;VX@8V]M<&QE="X*251!
- M3$E!3B!-96UO<FEA(&1I<W!O;FEB:6QE(&EN<W5F9FEC:65N=&4@<&5R(&-O
- M;7!L971A<F4@;"=O<&5R87II;VYE+@I34$%.25-(($YO(&AA>2!S=69I8VEE
- M;G1E(&UE;6]R:6$@<&%R82!C;VUP;&5T87(@;&$@;W!E<F%C:2)N+@I]"DQ?
- M3F]T7W5S960L"GL@35E!4%`*14Y'3$E32"!.;W0@57-E9`I&4D5.0T@@26YU
- M=&EL:7,""DE404Q)04X@3F]N(%5T:6QI>GIA=&\*4U!!3DE32"!.;R!S92!U
- M<V$*?0I,7TYO=BP*>R!-64%04`I%3D=,25-(($YO=@I&4D5.0T@@3F]V"DE4
- M04Q)04X@3F]V"E-004Y)4T@@3F]V"GT*3%].;W9E;6)E<BP*>R!-64%04`I%
- M3D=,25-(($YO=F5M8F5R"D9214Y#2"!.;W9E;6)R90I)5$%,24%.($YO=F5M
- M8G)E"E-004Y)4T@@3F]V:65M8G)E"GT*3%]/8W0L"GL@35E!4%`*14Y'3$E3
- M2"!/8W0*1E)%3D-(($]C=`I)5$%,24%.($]T=`I34$%.25-(($]C=`I]"DQ?
- M3V-T;V)E<BP*>R!-64%04`I%3D=,25-(($]C=&]B97(*1E)%3D-(($]C=&]B
- M<F4*251!3$E!3B!/='1O8G)E"E-004Y)4T@@3V-T=6)R90I]"DQ?3W!E;BP*
- M>R!-64%04`I%3D=,25-(($]P96X*1E)%3D-(($]U=G)I<@I)5$%,24%.($%P
- M<FD*4U!!3DE32"!!8G)I<@I]"DQ?3W!E;E]A7T9I;&4L"GL@35E!4%`*14Y'
- M3$E32"!/<&5N(&$@1FEL90I&4D5.0T@@3W5V<FER('5N92!F:6-H:65R"DE4
- M04Q)04X@07!R:2!U;B!&:6QE"E-004Y)4T@@06)R:7(@=6X@87)C:&EV;PI]
- M"DQ?3U]+7RP*>R!-64%04`I%3D=,25-(($]^2WX*1E)%3D-(($]^2WX*251!
- M3$E!3B!^17YS96=U:0I34$%.25-(('Y'?G5A<F1A<@I]"DQ?4&%G:6YA=&EO
- M;BP*>R!-64%04`I%3D=,25-((%!A9VEN871I;VX*1E)%3D-((%!A9VEN871I
- M;VX*251!3$E!3B!);7!A9VEN87II;VYE"E-004Y)4T@@4&%G:6YA8VDB;@I]
- M"DQ?4&QE87-E7W=A:70L"GL@35E!4%`*14Y'3$E32"!0;&5A<V4@5V%I="XN
- M+@I&4D5.0T@@071T96YD97HN+BX*251!3$E!3B!0<F5G;R!A='1E;F1E<F4N
- M+BX*4U!!3DE32"!%<W!E<F4L('!O<B!F879O<BXN+@I]"DQ?4')E<W-?4D54
- M55).7W1O7V-O;G1I;G5E+`I[($U905!0"D5.1TQ)4T@@4')E<W,@6U)E='5R
- M;ET@=&\@8V]N=&EN=64N"D9214Y#2"!487!E<B!;(#Q$1%D@72!P;W5R(&-O
- M;G1I;G5E<BX*251!3$E!3B!0<F5M97)E(%M);G9I;UT@<&5R(&-O;G1I;G5A
- M<F4N"E-004Y)4T@@4')E<VEO;F4@6T5N=')A<ET@<&%R82!C;VYT:6YU87(N
- M"GT*3%]0<F5V7W=I;F1O=RP*>R!-64%04`I%3D=,25-((%!R978@=VEN9&]W
- M"D9214Y#2"!&96X"=')E('!R`F-E9`(*251!3$E!3B!&:6YE<W1R82!P<F5C
- M+@I34$%.25-((%9E;G1A;F$@86YT97)I;W(*?0I,7U-A=F4L"GL@35E!4%`*
- M14Y'3$E32"!3879E"D9214Y#2"!3875V97(*251!3$E!3B!386QV"E-004Y)
- M4T@@1W5A<F1A<@I]"DQ?4V5L96-T7V%?1FEL92P*>R!-64%04`I%3D=,25-(
- M(%-E;&5C="!A($9I;&4*1E)%3D-(($-H;VES:7(@=6X@9FEC:&EE<@I)5$%,
- M24%.(%-E;&5Z:6]N82!U;B!S:6QE"E-004Y)4T@@4V5L96-C:6]N92!U;B!A
- M<F-H:79O"GT*3%]397!T96UB97(L"GL@35E!4%`*14Y'3$E32"!397!T96UB
- M97(*1E)%3D-((%-E<'1E;6)R90I)5$%,24%.(%-E='1E;6)R90I34$%.25-(
- M(%-E<'1I96UB<F4*?0I,7U-P="P*>R!-64%04`I%3D=,25-((%-P=`I&4D5.
- M0T@@4W!T"DE404Q)04X@4V5T"E-004Y)4T@@4W!T"GT*3%]4>7!E7T58251?
- M=&]?<F5T=7)N+`I[($U905!0"D5.1TQ)4T@@5'EP92!%6$E4('1O(')E='5R
- M;BXN+@I&4D5.0T@@5&%P97H@15A)5"`%(')E=&]U<FYE<BXN+@I)5$%,24%.
- M($EN=FEA(&EL(&-O;6%N9&\@15A)5"!P97(@<FET;W)N87)E+BXN"E-004Y)
- M4T@@17-C<FEB82!%6$E4('!A<F$@<F5T;W)N87(N+BX*?0I,7UEE87(L"GL@
- M35E!4%`*14Y'3$E32"!996%R"DE404Q)04X@06YN;PI34$%.25-(($$D;PI&
- M4D5.0T@@06YN90(*?0I,7UIO;VTL"GL@35E!4%`*14Y'3$E32"!:;V]M"D92
- M14Y#2"!:;V]M"DE404Q)04X@6F]O;0I34$%.25-((%IO;VT*?0I,7U]!7W!P
- M96YD+`I[($U905!0"D5.1TQ)4T@@?D%^<'!E;F0*1E)%3D-(('Y!?FIO=71E
- M<@I)5$%,24%.('Y!?F=G:75N9VD*4U!!3DE32"!^07YG<F5G87(*?0I,7U]#
- M7V%N8V5L+`I[($U905!0"D5.1TQ)4T@@?D-^86YC96P*1E)%3D-(('Y!?FYN
- M=6QE<@I)5$%,24%.($%^;GYN=6QL80I34$%.25-(('Y#?F%N8V5L87(*?0I,
- M7U]#7VAD:7(L"GL@35E!4%`*14Y'3$E32"!^0WYH1&ER"D9214Y#2"!^0WYH
- M86YG97(*251!3$E!3B!^0WYA;6)I80I34$%.25-(('Y#?F%M8FEA<@I]"DQ?
- M7T-?;&]S92P*>R!-64%04`I%3D=,25-(('Y#?FQO<V4*1E)%3D-(('Y&?F5R
- M;65R"DE404Q)04X@?D-^:&EU9&D*4U!!3DE32"!^0WYE<G)A<@I]"DQ?7T1?
- M96QE=&4L"GL@35E!4%`*14Y'3$E32"!^1'YE;&5T90I&4D5.0T@@?E-^=7!P
- M<FEM97(*251!3$E!3B!^0WYA;F-E;&QA"E-004Y)4T@@?E-^=7!R:6UI<@I]
- M"DQ?7T1?:7)E8W1O<GDL"GL@35E!4%`*14Y'3$E32"!^1'YI<F5C=&]R>0I&
- M4D5.0T@@?E)^`G!E<G1O:7)E"DE404Q)04X@?D1^:7)E8W1O<GD*4U!!3DE3
- M2"!^1'YI<F5C=&]R:6\*?0I,7U]$7T]37W-H96QL+`I[($U905!0"D5.1TQ)
- M4T@@?D1^3U,@<VAE;&P*1E)%3D-(('Y$?D]3('-H96QL"DE404Q)04X@?D1^
- M3U,@<VAE;&P*4U!!3DE32"!^1'Y/4R!S:&5L;`I]"DQ?7T5?>&ET+`I[($U9
- M05!0"D5.1TQ)4T@@?D5^>&ET"D9214Y#2"!^47YU:71T97(*251!3$E!3B!^
- M17YS8VD*4U!!3DE32"!^4WYA;&ER"GT*3%]?1E]I;&4L"GL@35E!4%`*14Y'
- M3$E32"!^1GYI;&4*1E)%3D-(('Y&?FEC:&EE<@I)5$%,24%.('Y&?FEL90I3
- M4$%.25-(('Y&?FEC:&5R;PI]"DQ?7TE?;G-E<G0L"GL@35E!4%`*14Y'3$E3
- M2"!^27YN<V5R=`I&4D5.0T@@?DE^;G-E<F5R"DE404Q)04X@?DE^;G-E<FES
- M8VD*4U!!3DE32"!^27YN<V5R=&%R"GT*3%]?3%]O860L"GL@35E!4%`*14Y'
- M3$E32"!^3'YO860*1E)%3D-(('Y,?F5C='5R90I)5$%,24%.('Y#?F%R:6-A
- M"E-004Y)4T@@?D%^8G)I<@I]"DQ?7TY?86UE+`I[($U905!0"D5.1TQ)4T@@
- M?DY^86UE"D9214Y#2"!^3GYO;0I)5$%,24%.('Y.?F]M90I34$%.25-(('Y.
- M?F]M8G)E"GT*3%]?3E]E>'1?=VEN9&]W+`I[($U905!0"D9214Y#2"!^1GYE
- M;@AT<F4@<W5I=F%N=`I%3D=,25-(('Y.?F5X="!W:6YD;W<*251!3$E!3B!^
- M4'YR;W-S:6UA(&9I;F5S=')A"E-004Y)4T@@5F5N=&%N82!^4WYI9W5I96YT
- M90I]"DQ?7T]?<&5N+`I[($U905!0"D5.1TQ)4T@@?D]^<&5N"D9214Y#2"!^
- M3WYP96X*251!3$E!3B!^07YP<FD*4U!!3DE32"!^07YB<FER"GT*3%]?3U]R
- M:6=I;BP*>R!-64%04`I%3D=,25-(('Y/?G)I9VEN"D9214Y#2"!/<FEG:6YE
- M"DE404Q)04X@?D]^<FEG:6YE"E-004Y)4T@@?D]^<FEG:6YA;`I]"DQ?7T]?
- M=F5R=W)I=&4L"GL@35E!4%`*14Y'3$E32"!^3WYV97)W<FET90I&4D5.0T@@
- M?E)^96UP;&%C97(*251!3$E!3B!^4GYI<V-R:79I"E-004Y)4T@@?D-^86UB
- M:6%R"GT*3%]?4%]R:6YT"GL@35E!4%`*14Y'3$E32"!^4'YR:6YT"D9214Y#
- M2"!^27YM<')I;65R:64*251!3$E!3B!^4WYT86UP80I34$%.25-(('Y)?FUP
- M<FEM:7(*?0I,7U]27V5S:7IE7VUO=F4L"GL@35E!4%`*14Y'3$E32"!^4GYE
- M<VEZ92]M;W9E"D9214Y#2"!^0WYA;&EB<F%G90I)5$%,24%.('Y2?FED:6UE
- M;G-I;VYA+VUU;W9I"E-004Y)4T@@0V%M8FEA<B!^5'YA;6$D;R]M;W9E<@I]
- M"DQ?7U)?=6YT:6UE7V=R87!H+`I[($U905!0"D5.1TQ)4T@@?E)^=6YT:6UE
- M($=R87!H"D9214Y#2"!^1WYR87!H:7%U90I)5$%,24%.('Y'?G)A9FEC:2!V
- M<R!T96UP;PI34$%.25-(('Y'?G(@9FEC;W,*?0I,7U]37V%V92P*>R!-64%0
- M4`I%3D=,25-(('Y3?F%V90I&4D5.0T@@?E-^875V97(*251!3$E!3B!^4WYA
- M;'9A"E-004Y)4T@@?D=^=6%R9&%R"GT*3%]?5%]I;&4L"GL@35E!4%`*14Y'
- M3$E32"!^5'YI;&4*1E)%3D-(('Y#?A-T92`%(&,3=&4*251!3$E!3B!^07YF
- M9FEA;F-A;65N=&\@9&5L;&4@9FEN97-T<F4*4U!!3DE32"!^5GYE;G1A;F%S
- M(&-O<W1A9&\@82!C;W-T861O"GT*3%]?5E]I9&5O7VUO9&5?,C5?-3`L"GL@
- M35E!4%`*14Y'3$E32"!^5GYI9&5O(&UO9&4@,C4O-3`*1E)%3D-(('Y6?FED
- M96\@;6]D92`R-2\U,`I)5$%,24%.('Y3?F-H97)M;R!I;B!-;V1A;&ET!2`R
- M-2\U,`I34$%.25-((&UO9&$@9&5L('Y6?FED96\@,C4O-3`*?0I,7U]77VEN
- M9&]W+`I[($U905!0"D5.1TQ)4T@@?E=^:6YD;W<*1E)%3D-(('Y&?F5N"'1R
- M90I)5$%,24%.('Y&?FEN97-T<F$*4U!!3DE32"!^5GYE;G1A;F$*?0I,7U]:
- M7V]O;2P*>R!-64%04`I&4D5.0T@@?EI^;V]M"D5.1TQ)4T@@?EI^;V]M"DE4
- M04Q)04X@?EI^;V]M"E-004Y)4T@@?EI^;V]M"GT*3%]$87E?;V9?>65A<BP*
- M>R!-64%04`I%3D=,25-(($1A>2!O9B!T:&4@>65A<CL*1E)%3D-(($IO=7(@
- M9&4@;"=A;FX"93L*251!3$E!3B!':6]R;F\@9&5L;"=A;FYO"E-004Y)4T@@
- M1"%A(&1E;"!A)&\["GT*3%]D:7-A8FQE9"P*>R!-64%04`I%3D=,25-((&1I
- M<V%B;&5D"D9214Y#2"!N;VX@:&%B:6QI=`(*251!3$E!3B!D:7-A8FEL:71A
- M=&D*4U!!3DE32"!D97-H86)I;&ET861O"GT*3%]E;F%B;&5D+`I[($U905!0
- M"D5.1TQ)4T@@96YA8FQE9`I&4D5.0T@@:&%B:6QI=`(*251!3$E!3B!A8FEL
- M:71A=&D*4U!!3DE32"!H86)I;&ET861O"GT*3%]&04E,140L"GL@35E!4%`*
- M14Y'3$E32"!&04E,140*1E)%3D-((!!#2$5#"DE404Q)04X@1D%,3$E43PI3
- M4$%.25-(($9204-!4T$*?0I,7VYO=%]V86QI9"P*>R!-64%04`I%3D=,25-(
- M(&YO="!V86QI9`I&4D5.0T@@;F]N('9A;&%B;&4N"DE404Q)04X@;F]N('9A
- M;&ED;PI34$%.25-((&YO(&5S('8@;&ED;PI]"DQ?4$%34T5$+`I[($U905!0
- M"D5.1TQ)4T@@4$%34T5$"D9214Y#2"!005-3$`I)5$%,24%.(%!!4U-!5$\*
- M4U!!3DE32"!%6$E43U-/"GT*3%]686QI9&%T:6YG+`I[($U905!0"D5.1TQ)
- M4T@@5F%L:61A=&EN9PI&4D5.0T@@5F%L:61A=&EO;B!E;B!C;W5R<PI)5$%,
- M24%.(%9A;&ED87II;VYE(&EN(&%T=&\*4U!!3DE32"!686QI9&%N9&\*?0I,
- M7U9A;&ED871I;VXL"GL@35E!4%`*14Y'3$E32"!686QI9&%T:6]N"D9214Y#
- M2"!686QI9&%T:6]N"DE404Q)04X@5F%L:61A>FEO;F4*4U!!3DE32"!686QI
- M9&%C:2)N"GT*3%]697)I9GEI;F=?97AI<W1A;F-E7V]F7V9I;&4L"GL@35E!
- M4%`*14Y'3$E32"!697)I9GEI;F<@97AI<W1E;F-E(&]F(&9I;&4*1E)%3D-(
- M(%8"<FEF:6-A=&EO;B!D92!L)P)X:7-T96YC92!D=2!F:6-H:65R"DE404Q)
- M04X@5F5R:69I8V$@9&5L;"=E<VES=&5N>F$@9&5L(&9I;&4@:6X@871T;PI3
- M4$%.25-((%9E<FEF:6-A;F1O(&5X:7-T96YC:6$@9&5L(&%R8VAI=F\*?0HM
- M+2U#=70@2&5R92TM+2TM/C@M+2TM+3XX+2TM+2T^."TM+2TM/C@M+2TM+3XX
- <+2TM+2T^."TM+2TM/C@M+2TM+3XX+2TM+2T*"BT^
- `
- end
-