DIRECTORY Basics USING [], CHNameP2V0 USING [], Convert USING [RopeFromAtom, AtomFromRope], CrRPC USING [CreateClientHandle, DestroyClientHandle, Error, Handle], Dictionary, DictionaryP1313V1, Rope, UserProfile USING [Token], XNS, XNSCH USING [LookupAddressFromRope], XNSCHName USING [Name]; DictionaryClientImpl: CEDAR MONITOR IMPORTS Convert, CrRPC, DictionaryP1313V1, UserProfile, XNSCH EXPORTS Dictionary ~ { OPEN Dictionary1: DictionaryP1313V1, Dictionary; ROPE: TYPE ~ Rope.ROPE; ExternalSynonymSeqHandle: TYPE ~ REF ExternalSynonymSeqObject; ExternalSynonymSeqObject: PUBLIC TYPE ~ RECORD [ handle: Dictionary1.SynonymClasses ]; Error: PUBLIC ERROR [problem: Problem, explanation: ROPE] ~ CODE; dictServer: PUBLIC ROPE ฌ UserProfile.Token["Dictionary.Server", "DictServer:PARC:Xerox"]; CrHandleFromRope: INTERNAL PROC [pattern: ROPE] RETURNS [h: CrRPC.Handle, name: XNSCHName.Name] ~ { transport: ATOM ~ IF ( BYTES[CARDINAL] = 2 ) THEN $SPP ELSE $CMUX; addr: XNS.Address; [name, addr] ฌ XNSCH.LookupAddressFromRope[pattern]; IF ( addr = XNS.unknownAddress ) THEN ERROR Error[courier, "Address not found"]; h ฌ CrRPC.CreateClientHandle[transport, NEW[XNS.Address ฌ addr]]; }; CourierProc: TYPE ~ PROC [h: CrRPC.Handle]; Guarded: ENTRY PROC [proc: CourierProc] ~ { ENABLE { UNWIND => { NULL }; Dictionary1.UseCourier, CrRPC.Error => { ERROR Error[courier, NIL] }; Dictionary1.RemoteError => { ERROR Error[service, string]; }; }; distingName: XNSCHName.Name; h: CrRPC.Handle ฌ NIL; [h, distingName] ฌ CrHandleFromRope[dictServer]; proc[h]; CrRPC.DestroyClientHandle[h]; }; DictionariesAvailableFor: PROC [seq: Dictionary1.DictionariesAvailable] RETURNS [list: DictionariesList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO rope: ROPE ~ seq.body[i]; item: ATOM ~ Convert.AtomFromRope[rope]; list ฌ CONS[item, list]; ENDLOOP; }; LanguagesFor: PROC [seq: Dictionary1.Languages] RETURNS [list: LanguagesList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO rope: ROPE ~ seq.body[i]; item: ATOM ~ Convert.AtomFromRope[rope]; list ฌ CONS[item, list]; ENDLOOP; }; Looks2For: PROC [seq: Dictionary1.Looks2] RETURNS [list: Looks2List] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO rope: ROPE ~ seq.body[i]; item: ATOM ~ Convert.AtomFromRope[rope]; list ฌ CONS[item, list]; ENDLOOP; }; WordsFor: PROC [seq: Dictionary1.Words] RETURNS [list: WordsList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO item: ROPE ~ seq.body[i]; list ฌ CONS[item, list]; ENDLOOP; }; SynonymClassFor: PROC [seq: Dictionary1.SynonymClass] RETURNS [list: SynonymClassList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO item: ROPE ~ seq.body[i]; list ฌ CONS[item, list]; ENDLOOP; }; IntegersFor: PROC [seq: Dictionary1.Integers] RETURNS [list: IntegersList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO item: INT32 ~ seq.body[i]; list ฌ CONS[item, list]; ENDLOOP; }; ConjugationsFor: PROC [seq: Dictionary1.Conjugations] RETURNS [list: ConjugationsList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO conj: Dictionary1.Conjugation ~ seq.body[i]; partOfSpeech: ATOM ~ Convert.AtomFromRope[conj.partsOfSpeech]; status: ATOM ~ Convert.AtomFromRope[conj.status]; item: ConjugationPointer ~ NEW[ExternalConjugationObject ฌ [partOfSpeech: partOfSpeech, definition: conj.definition, status: status] ]; list ฌ CONS[item, list]; ENDLOOP; }; RunsFor: PROC [seq: Dictionary1.Runs] RETURNS [list: RunList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO run: Dictionary1.Run ~ seq.body[i]; font: ATOM ~ Convert.AtomFromRope[run.font]; item: RunPointer ~ NEW[ExternalRunObject ฌ [start: run.start, length: run.length, font: font] ]; list ฌ CONS[item, list]; ENDLOOP; }; LooksFor: PROC [seq: Dictionary1.Looks] RETURNS [list: LooksList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO looks2: Dictionary1.Looks2 ~ seq.body[i]; item: Looks2List ~ Looks2For[looks2]; list ฌ CONS[item, list]; ENDLOOP; }; RawDefinitionFor: PROC [seq: Dictionary1.RawDefinition] RETURNS [list: RawDefinitionList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO comp: Dictionary1.Component ~ seq.body[i]; type: ATOM ~ Convert.AtomFromRope[comp.type]; defaultFont: ATOM ~ Convert.AtomFromRope[comp.defaultFont]; runList: RunList ~ RunsFor[comp.runs]; item: ComponentPointer ~ NEW[ExternalComponentObject ฌ [type: type, text: comp.text, defaultFont: defaultFont, runs: runList] ]; list ฌ CONS[item, list]; ENDLOOP; }; SynonymClassesFor: PROC [seq: Dictionary1.SynonymClasses] RETURNS [list: SynonymClassesList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO class: Dictionary1.SynonymClass ~ seq.body[i]; item: SynonymClassList ~ SynonymClassFor[class]; list ฌ CONS[item, list]; ENDLOOP; }; IntersectionResultsFor: PROC [seq: Dictionary1.IntersectionResults] RETURNS [list: IntersectionResultsList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO result: Dictionary1.IntersectionResult ~ seq.body[i]; keysList: WordsList ~ WordsFor[result.keys]; resultsList: WordsList ~ WordsFor[result.results]; item: IntersectionResultsPointer ~ NEW[ExternalIntersectionResultsObject ฌ [keys: keysList, results: resultsList] ]; list ฌ CONS[item, list]; ENDLOOP; }; RawIntersectionResultsFor: PROC [seq: Dictionary1.RawIntersectionResults] RETURNS [list: RawIntersectionResultsList] ~ { FOR i: CARDINAL DECREASING IN [0..seq.length) DO result: Dictionary1.RawIntersectionResult ~ seq.body[i]; keysList: WordsList ~ WordsFor[result.keys]; resultsList: IntegersList ~ IntegersFor[result.results]; item: RawIntersectionResultsPointer ~ NEW[ExternalRawIntersectionResultsObject ฌ [keys: keysList, results: resultsList] ]; list ฌ CONS[item, list]; ENDLOOP; }; SequenceToList: PROC [sequence: REF] RETURNS [any: REF] ~ { WITH sequence SELECT FROM conjugationSeq: Dictionary1.Conjugations => { conjugationsList: ConjugationsList ~ ConjugationsFor[conjugationSeq]; any ฌ NEW[ConjugationsList ฌ conjugationsList]; }; dictionariesSeq: Dictionary1.DictionariesAvailable => { dictionariesList: DictionariesList ~ DictionariesAvailableFor[dictionariesSeq]; any ฌ NEW[DictionariesList ฌ dictionariesList]; }; integersSeq: Dictionary1.Integers => { integersList: IntegersList ~ IntegersFor[integersSeq]; any ฌ NEW[IntegersList ฌ integersList]; }; intersectionResultsSeq: Dictionary1.IntersectionResults => { intersectionResultsList: IntersectionResultsList ~ IntersectionResultsFor[intersectionResultsSeq]; any ฌ NEW[IntersectionResultsList ฌ intersectionResultsList]; }; languagesSeq: Dictionary1.Languages => { languagesList: LanguagesList ~ LanguagesFor[languagesSeq]; any ฌ NEW[LanguagesList ฌ languagesList]; }; looks2Seq: Dictionary1.Looks2 => { looks2List: Looks2List ~ Looks2For[looks2Seq]; any ฌ NEW[Looks2List ฌ looks2List]; }; looksSeq: Dictionary1.Looks => { looksList: LooksList ~ LooksFor[looksSeq]; any ฌ NEW[LooksList ฌ looksList]; }; rawDefinitionSeq: Dictionary1.RawDefinition => { rawDefinitionList: RawDefinitionList ~ RawDefinitionFor[rawDefinitionSeq]; any ฌ NEW[RawDefinitionList ฌ rawDefinitionList]; }; rawIntersectionResultsSeq: Dictionary1.RawIntersectionResults => { rawIntersectionResultsList: RawIntersectionResultsList ~ RawIntersectionResultsFor[rawIntersectionResultsSeq]; any ฌ NEW[RawIntersectionResultsList ฌ rawIntersectionResultsList]; }; runSeq: Dictionary1.Runs => { runList: RunList ~ RunsFor[runSeq]; any ฌ NEW[RunList ฌ runList]; }; synonymClassesSeq: Dictionary1.SynonymClasses => { synonymClassesList: SynonymClassesList ~ SynonymClassesFor[synonymClassesSeq]; any ฌ NEW[SynonymClassesList ฌ synonymClassesList]; }; synonymClassSeq: Dictionary1.SynonymClass => { synonymClassList: SynonymClassList ~ SynonymClassFor[synonymClassSeq]; any ฌ NEW[SynonymClassList ฌ synonymClassList]; }; wordsSeq: Dictionary1.Words => { wordsList: WordsList ~ WordsFor[wordsSeq]; any ฌ NEW[WordsList ฌ wordsList]; }; ENDCASE => { NULL }; }; Languages: PUBLIC PROC [user: ROPE] RETURNS [languages: LanguagesList] = { xx: Dictionary1.Languages; LanguagesOp: CourierProc ~ { xx ฌ Dictionary1.GetLanguages[h, user]; }; Guarded[LanguagesOp]; languages ฌ LanguagesFor[xx]; }; Analyze: PUBLIC PROC [word: Word, language: Language] RETURNS [analyses: ROPE] = { lrope: ROPE ~ Convert.RopeFromAtom[language, FALSE]; AnalyzeOp: CourierProc ~ { analyses ฌ Dictionary1.Analyze[h, word, lrope]; }; Guarded[AnalyzeOp]; }; Translate: PUBLIC PROC [wordNumber: WordNumber, language: Language] RETURNS [word: Word] = { lrope: ROPE ~ Convert.RopeFromAtom[language, FALSE]; TranslateOp: CourierProc ~ { word ฌ Dictionary1.ConvertWordNumber[h, wordNumber, lrope]; }; Guarded[TranslateOp]; }; ProofRead: PUBLIC PROC [paragraph: Paragraph, language: Language] RETURNS [wordPosition: WordPosition] = { lrope: ROPE ~ Convert.RopeFromAtom[language, FALSE]; temp: Dictionary1.Selection ฌ [0, 0]; ProofReadOp: CourierProc ~ { temp ฌ Dictionary1.ProofRead[h, paragraph, lrope]; }; Guarded[ProofReadOp]; wordPosition ฌ NEW[ExternalWordPositionObject ฌ [temp.start, temp.length] ]; }; Corrections: PUBLIC PROC [word: Word, language: Language] RETURNS [wordsList: WordsList] = { lrope: ROPE ~ Convert.RopeFromAtom[language, FALSE]; xx: Dictionary1.Words; CorrectionsOp: CourierProc ~ { xx ฌ Dictionary1.Corrections[h, word, lrope]; }; Guarded[CorrectionsOp]; wordsList ฌ WordsFor[xx]; }; Status: PUBLIC PROC RETURNS [statusInfo: ROPE] = { StatusOp: CourierProc ~ { statusInfo ฌ Dictionary1.Status[h]; }; Guarded[StatusOp]; }; CountWords: PUBLIC PROC [paragraph: Paragraph, language: Language] RETURNS [wordCount: INT32 ฌ 0] = { lrope: ROPE ~ Convert.RopeFromAtom[language, FALSE]; CountWordsOp: CourierProc ~ { wordCount ฌ Dictionary1.CountWords[h, paragraph, lrope]; }; Guarded[CountWordsOp]; }; Conjugate: PUBLIC PROC [word: Word, form: Form, alternates: Alternates, language: Language] RETURNS [conjugationsList: ConjugationsList] = { frope: ROPE ~ Convert.RopeFromAtom[form, FALSE]; arope: ROPE ~ Convert.RopeFromAtom[alternates, FALSE]; lrope: ROPE ~ Convert.RopeFromAtom[language, FALSE]; xx: Dictionary1.Conjugations; ConjugateOp: CourierProc ~ { xx ฌ Dictionary1.Conjugate[h, word, frope, arope, lrope]; }; Guarded[ConjugateOp]; conjugationsList ฌ ConjugationsFor[xx]; }; Dictionaries: PUBLIC PROC [user: User] RETURNS [dictionariesList: DictionariesList] = { xx: Dictionary1.DictionariesAvailable; DictionariesOp: CourierProc ~ { xx ฌ Dictionary1.Dictionaries[h, user]; }; Guarded[DictionariesOp]; dictionariesList ฌ DictionariesAvailableFor[xx]; }; GetDefinition: PUBLIC PROC [word: Word, dictionary: Dictionary] RETURNS [definition: Definition] = { drope: ROPE ~ Convert.RopeFromAtom[dictionary, FALSE]; temp: Dictionary1.Definition; runs: RunList; GetDefinitionOp: CourierProc ~ { temp ฌ Dictionary1.GetDefinition[h, word, drope]; }; Guarded[GetDefinitionOp]; runs ฌ RunsFor[temp.runs]; definition ฌ NEW[ExternalDefinitionObject ฌ [definition: temp.definition, looks: runs] ]; }; Pronunciation: PUBLIC PROC [word: Word, dictionary: Dictionary] RETURNS [wordPronounced: ROPE] = { drope: ROPE ~ Convert.RopeFromAtom[dictionary, FALSE]; PronunciationOp: CourierProc ~ { wordPronounced ฌ Dictionary1.Pronunciation[h, word, drope]; }; Guarded[PronunciationOp]; }; GetLooks: PUBLIC PROC [dictionary: Dictionary] RETURNS [looksList: LooksList] = { drope: ROPE ~ Convert.RopeFromAtom[dictionary, FALSE]; xx: Dictionary1.Looks; GetLooksOp: CourierProc ~ { xx ฌ Dictionary1.GetLooks[h, drope]; }; Guarded[GetLooksOp]; looksList ฌ LooksFor[xx]; }; Enumerate: PUBLIC PROC [wordNumber: WordNumber, dictionary: Dictionary] RETURNS [definition: Definition] = { drope: ROPE ~ Convert.RopeFromAtom[dictionary, FALSE]; temp: Dictionary1.Definition; runs: RunList; EnumerateOp: CourierProc ~ { temp ฌ Dictionary1.Enumerate[h, wordNumber, drope]; }; Guarded[EnumerateOp]; runs ฌ RunsFor[temp.runs]; definition ฌ NEW[ExternalDefinitionObject ฌ [definition: temp.definition, looks: runs] ]; }; ConvertCodes: PROC [codes: CodesList] RETURNS [seq: Dictionary1.Codes] ~ { length: CARDINAL ฌ 0; FOR tail: CodesList ฌ codes, tail.rest WHILE ( tail # NIL ) DO length ฌ length.SUCC; ENDLOOP; seq ฌ NEW[Dictionary1.CodesObject[length]]; FOR i: CARDINAL IN [0..length) DO rope: ROPE ~ Convert.RopeFromAtom[codes.first]; seq[i] ฌ rope; codes ฌ codes.rest; ENDLOOP; }; EnumerateRaw: PUBLIC PROC [wordNumber: WordNumber, codes: CodesList, dictionary: Dictionary] RETURNS [rawDefinitionList: RawDefinitionList] = { drope: ROPE ~ Convert.RopeFromAtom[dictionary, FALSE]; seq: Dictionary1.Codes ~ ConvertCodes[codes]; xx: Dictionary1.RawDefinition; EnumerateRawOp: CourierProc ~ { xx ฌ Dictionary1.EnumerateRaw[h, wordNumber, seq, drope]; }; Guarded[EnumerateRawOp]; rawDefinitionList ฌ RawDefinitionFor[xx]; }; SearchForWord: PUBLIC PROC [unparsedClasses: UnparsedClasses, minKeyWords: MinKeyWords, minWord: MinWord, maxWord: MaxWord, dictionary: Dictionary] RETURNS [intersectionResultsList: IntersectionResultsList] = { drope: ROPE ~ Convert.RopeFromAtom[dictionary, FALSE]; xx: Dictionary1.IntersectionResults; trans: REF; SearchForWordOp: CourierProc ~ { xx ฌ Dictionary1.SearchForWord[h, unparsedClasses, minKeyWords, minWord, maxWord, drope]; }; Guarded[SearchForWordOp]; intersectionResultsList ฌ IntersectionResultsFor[xx]; }; Synonyms: PUBLIC PROC [word: Word, dictionary: Dictionary] RETURNS [externalSynonymHandle: ExternalSynonymHandle] = { drope: ROPE ~ Convert.RopeFromAtom[dictionary, FALSE]; internal: Dictionary1.SynonymClasses; external: ExternalSynonymSeqHandle; classes: SynonymClassesList; SynonymsOp: CourierProc ~ { internal ฌ Dictionary1.Synonyms[h, word, drope]; }; Guarded[SynonymsOp]; external ฌ NEW[ExternalSynonymSeqObject ฌ [handle: internal] ]; classes ฌ SynonymClassesFor[internal]; externalSynonymHandle ฌ NEW[ExternalSynonymObject ฌ [synonymList: classes, externalSynonymSeqHandle: external] ]; }; NewSearchForWord: PUBLIC PROC [externalSynonymHandle: ExternalSynonymHandle, minKeyWords: MinKeyWords, minWord: MinWord, maxWord: MaxWord, dictionary: Dictionary] RETURNS [intersectionResultsList: IntersectionResultsList] = { drope: ROPE ~ Convert.RopeFromAtom[dictionary, FALSE]; classes: Dictionary1.SynonymClasses ~ externalSynonymHandle.externalSynonymSeqHandle.handle; xx: Dictionary1.IntersectionResults; trans: REF; NewSearchForWordOp: CourierProc ~ { xx ฌ Dictionary1.NewSearchForWord[h, classes, minKeyWords, minWord, maxWord, drope]; }; Guarded[NewSearchForWordOp]; intersectionResultsList ฌ IntersectionResultsFor[xx]; }; RawSearchForWord: PUBLIC PROC [externalSynonymHandle: ExternalSynonymHandle, minKeyWords: MinKeyWords, minWord: MinWord, maxWord: MaxWord, dictionary: Dictionary] RETURNS [rawIntersectionResultsList: RawIntersectionResultsList] = { drope: ROPE ~ Convert.RopeFromAtom[dictionary, FALSE]; classes: Dictionary1.SynonymClasses ~ externalSynonymHandle.externalSynonymSeqHandle.handle; xx: Dictionary1.RawIntersectionResults; trans: REF; RawSearchForWordOp: CourierProc ~ { xx ฌ Dictionary1.RawSearchForWord[h, classes, minKeyWords, minWord, maxWord, drope]; }; Guarded[RawSearchForWordOp]; rawIntersectionResultsList ฌ RawIntersectionResultsFor[xx]; }; }. <DictionaryClientImpl.mesa Copyright ำ 1985, 1986, 1987, 1989, 1990, 1992 by Xerox Corporation. All rights reserved. Jack Kent August 19, 1987 1:10:53 pm PDT Bob Hagmann January 3, 1989 3:39:08 pm PST Bill Jackson (bj), March 7, 1990 5:27 pm PST Willie-s, May 22, 1992 2:12 pm PDT Private (Opaque) Type Guard list of Atom list of Rope list of Int32 from here on out, the woods gets a bit thicker... data translation (cheap polymorphism) converts Courier random access lists (sequences) into Cedar lists Public procs have to figure out how big to make the sequence สบ•NewlineDelimiter –(cedarcode) style˜codešœ™Kšœ ฯeœO™ZKšœ(™(K™*K™,K™"K™—šฯk ˜ Kšœžœ˜Kšœ žœ˜Kšœžœ˜+Kšœžœ:˜EKšœ ˜ Kšœ˜Kšœ˜Kšœ žœ ˜Kšžœ˜Kšžœžœ˜$Kšœ žœ˜K˜—šฯnœžœžœ˜$Kšžœ1ž˜=Kšžœ˜KšžœŸ œ ˜0Kšžœžœžœ˜headšฯz™Kšœžœžœ˜>šœžœžœžœ˜0Kšœ#˜#K˜——š ™Kš Ÿœžœžœ!žœžœ˜AK˜Kšœ žœžœC˜ZK˜š Ÿœžœžœ žœžœ,˜cKš œ žœžœžœžœžœžœ˜BKšœžœ ˜Kšœžœ ˜4Kšžœ žœžœžœ%˜PKšœ(žœžœ˜AK˜K˜—Kšœ žœžœ˜+K˜šŸœžœžœ˜+šžœ˜Kšžœžœ˜Kšœ)žœžœ˜EKšœžœ˜=K˜—Kšœ/žœ˜3K˜0Kšœ˜Kšœ˜Kšœ˜——š  ™ šŸœžœ*žœ˜lš žœžœž œžœžœ˜1Kšœžœ˜Kšœžœ˜(Kšœžœ ˜Kšžœ˜—K˜K˜—šŸ œžœžœ˜Qš žœžœž œžœžœ˜1Kšœžœ˜Kšœžœ˜(Kšœžœ ˜Kšžœ˜—K˜K˜—šŸ œžœžœ˜Hš žœžœž œžœžœ˜1Kšœžœ˜Kšœžœ˜(Kšœžœ ˜Kšžœ˜—K˜——š  ™ šŸœžœžœ˜Eš žœžœž œžœž˜0Kšœžœ˜Kšœžœ ˜Kšžœ˜—K˜K˜—šŸœžœ!žœ˜Zš žœžœž œžœž˜0Kšœžœ˜Kšœžœ ˜Kšžœ˜ —K˜——š  ™ šŸ œžœžœ˜Nš žœžœž œžœžœ˜1Kšœžœ˜Kšœžœ ˜Kšžœ˜—K˜——š 1™1šŸœžœ!žœ˜Zš žœžœž œžœžœ˜1Kšœ,˜,Kšœžœ,˜>Kšœžœ%˜1Kšœžœi˜‡Kšœžœ ˜Kšžœ˜—K˜K˜—šŸœžœžœ˜Aš žœžœž œžœžœ˜1Kšœ#˜#Kšœžœ"˜,KšœžœJ˜`Kšœžœ ˜Kšžœ˜—K˜K˜—šŸœžœžœ˜Eš žœžœž œžœžœ˜1Kšœ)˜)Kšœ%˜%Kšœžœ ˜Kšžœ˜—K˜K˜—šŸœžœ"žœ˜]š žœžœž œžœžœ˜1Kšœ*˜*Kšœžœ#˜-Kšœ žœ*˜;Kšœ&˜&Kšœžœd˜€Kšœžœ ˜Kšžœ˜—K˜K˜—šŸœžœ#žœ˜`š žœžœž œžœž˜0Kšœ.˜.Kšœ1˜1Kšœžœ ˜Kšžœ˜—K˜K˜—šŸœžœ(žœ$˜oš žœžœž œžœž˜0Kšœ5˜5Kšœ,˜,Kšœ2˜2Kšœ#žœN˜tKšœžœ ˜Kšžœ˜—K˜K˜—šŸœžœ+žœ'˜xš žœžœž œžœžœ˜1Kšœ8˜8Kšœ,˜,Kšœ8˜8Kšœ&žœQ˜zKšœžœ ˜Kšžœ˜—K˜——š %™%K™AK™š Ÿœžœ žœžœžœ˜;šžœ žœž˜šœ-˜-KšœE˜EKšœžœ&˜/K˜—šœ7˜7KšœO˜OKšœžœ&˜/K˜—šœ&˜&Kšœ6˜6Kšœžœ˜(K˜—šœ<˜K˜—šœ(˜(Kšœ:˜:Kšœžœ!˜*K˜—šœ"˜"Kšœ.˜.Kšœžœ˜$K˜—šœ ˜ Kšœ*˜*Kšœžœ˜"K˜—šœ0˜0KšœJ˜JKšœžœ(˜1K˜—šœB˜BKšœn˜nKšœžœ;˜DK˜—šœ˜Kšœ#˜#Kšœžœ˜K˜—šœ2˜2KšœN˜NKšœžœ+˜4K˜—šœ.˜.KšœF˜FKšœžœ'˜0K˜—šœ ˜ Kšœ*˜*Kšœžœ˜"K˜—Kšžœžœ˜—K˜——š  ™ š Ÿ œžœžœžœžœ˜JKšœ˜šŸ œ˜K˜'Kšœ˜—Kšœ˜K˜K˜K˜—š Ÿœžœžœ"žœ žœ˜RKšœžœ"žœ˜4šŸ œ˜K˜/K˜—Kšœ˜K˜K˜—šŸ œžœžœ.žœ˜\Kšœžœ"žœ˜4šŸ œ˜K˜;K˜—Kšœ˜K˜K˜—šŸ œžœžœ,žœ!˜jKšœžœ"žœ˜4K˜%šŸ œ˜K˜2K˜—Kšœ˜Kšœžœ:˜LK˜K˜—šŸ œžœžœ"žœ˜\Kšœžœ"žœ˜4Kšœ˜šŸ œ˜K˜-K˜—Kšœ˜K˜K˜K˜—š Ÿœžœžœžœžœ˜2šŸœ˜K˜#K˜—Kšœ˜K˜K˜—š Ÿ œžœžœ,žœ žœ ˜eKšœžœ"žœ˜4šŸ œ˜K•StartOfExpansion8[h: CrRPC.Handle, paragraph: ROPE, language: ROPE]˜8K˜—Kšœ˜K˜K˜—šŸ œžœžœFžœ)˜ŒKšœžœžœ˜0Kšœžœ$žœ˜6Kšœžœ"žœ˜4Kšœ˜šŸ œ˜K˜9K˜—Kšœ˜K˜'K˜K˜—šŸ œžœžœžœ)˜WKšœ&˜&šŸœ˜K˜'K˜—Kšœ˜K˜0K˜K˜—šŸ œžœžœ&žœ˜dKšœžœ$žœ˜6Kšœ˜Kšœ˜šŸœ˜ K˜1K˜—Kšœ˜K˜Kšœ žœI˜YK˜K˜—š Ÿ œžœžœ&žœžœ˜bKšœžœ$žœ˜6šŸœ˜ K˜;K˜—Kšœ˜K˜K˜—šŸœžœžœžœ˜QKšœžœ$žœ˜6Kšœ˜šŸ œ˜K˜$Kšœ˜—Kšœ˜K˜K˜K˜—šŸ œžœžœ1žœ˜lKšœžœ$žœ˜6Kšœ˜Kšœ˜šŸ œ˜K˜3K˜—Kšœ˜K˜Kšœ žœI˜YK˜K˜—šŸ œžœžœ˜JKšœžœ˜š žœ$žœ žœžœžœžœ˜]K™/—Kšœžœ"˜+šžœžœžœ ž˜!Kšœžœ%˜/K˜K˜Kšžœ˜—K˜K˜—šŸ œžœžœDžœ+˜Kšœžœ$žœ˜6Kšœ-˜-Kšœ˜šŸœ˜K˜9Kšœ˜—Kšœ˜K˜)K˜K˜—šŸ œžœžœzžœ7˜าKšœžœ$žœ˜6Kšœ$˜$Kšœžœ˜ šŸœ˜ K˜YK˜—Kšœ˜K˜5K˜K˜—šŸœžœžœ&žœ3˜uKšœžœ$žœ˜6Kšœ%˜%Kšœ#˜#Kšœ˜šŸ œ˜K˜0K˜—Kšœ˜Kšœ žœ1˜?K˜&KšœžœV˜qK˜K˜—šŸœžœžœ†žœ7˜แKšœžœ$žœ˜6Kšœ\˜\Kšœ$˜$Kšœžœ˜ šŸœ˜#K˜TK˜—Kšœ˜K˜5K˜K˜—šŸœžœžœ†žœ=˜็Kšœžœ$žœ˜6Kšœ\˜\Kšœ'˜'Kšœžœ˜ šŸœ˜#K˜TK˜—Kšœ˜K˜;K˜K˜——K˜˜K˜———…—;M