Coverage for src/robotide/lib/compat/parsing/language.py: 67%

198 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-06 10:40 +0100

1# Copyright 2023- Robot Framework Foundation 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14import os.path 2a }c

15import sys 2a }c

16 

17try: 2a }c

18 from robot.conf.languages import Language 2a }c

19except ImportError as e: 

20 sys.stderr.write(f"Trying to import robot's languages module returned error: {repr(e)}\n") 

21 sys.stderr.write("You need to have Robot Framework v6.0 or newer to use languages in test suites.\n") 

22 try: 

23 # Using local copy of https://github.com/robotframework/robotframework/blob/v7.0.1/src/robot/conf/languages.py 

24 from .languages import Language 

25 except ImportError as e: 

26 sys.stderr.write(f"RIDE: Trying to import robot's languages module returned error: {repr(e)}\n") 

27 Language = None 

28from robot.errors import DataError 2a }c

29from robotide.lib.robot.utils import Utf8Reader 2a }c

30 

31 

32def check_file_language(path): 2a }c

33 """ 

34 Returns the language code if defined and valid, error if not valid, or None if file does not have preamble. 

35 

36 :param path: Path to robot or resource file 

37 :return: language, error or None 

38 """ 

39 if not Language: 39 ↛ 40line 39 didn't jump to line 40 because the condition on line 39 was never true2a e ! r hdidsdtdjdudvd# kds ldt $ wd% ' ( ) * + , z mdndxdZ 0 1 2 3 4 u v S w x A B C D E 5 6 7 8 9 Y @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`codb h g occ i F d j k l m n o p q y - f pdqd.

40 return None 

41 language_string = None 2a e ! r hdidsdtdjdudvd# kds ldt $ wd% ' ( ) * + , z mdndxdZ 0 1 2 3 4 u v S w x A B C D E 5 6 7 8 9 Y @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`codb h g occ i F d j k l m n o p q y - f pdqd.

42 if os.path.isfile(path): 2a e ! r hdidsdtdjdudvd# kds ldt $ wd% ' ( ) * + , z mdndxdZ 0 1 2 3 4 u v S w x A B C D E 5 6 7 8 9 Y @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`codb h g occ i F d j k l m n o p q y - f pdqd.

43 language_string = read(path) 2a e r hdidjdkds ldt z mdndu v S w x A B C D E @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`codb h g occ i F d j k l m n o p q y f pdqd

44 if not language_string: 2a e ! r hdidsdtdjdudvd# kds ldt $ wd% ' ( ) * + , z mdndxdZ 0 1 2 3 4 u v S w x A B C D E 5 6 7 8 9 Y @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`codb h g occ i F d j k l m n o p q y - f pdqd.

45 return None 2a e ! r hdidsdtdjdudvd# kds ldt $ wd% ' ( ) * + , z mdndxdZ 0 1 2 3 4 u v S w x A B C D E 5 6 7 8 9 Y ~codb h g c i F d j k l m n o p q y - f pdqd.

46 # If preamble exists, proceed with language detection 

47 try: 2a e @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc`cb g occ d f

48 from robot.conf.languages import Languages 2a e @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc`cb g occ d f

49 except ImportError as err: 

50 sys.stderr.write(f"Trying to import robot's languages module returned error: {repr(err)}\n") 

51 try: 

52 from .languages import Languages 

53 except ImportError: 

54 return None 

55 try: 2a e @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc`cb g occ d f

56 build_lang = Languages(language_string, add_english=False) 2a e @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc`cb g occ d f

57 except (DataError, ModuleNotFoundError) as err: 2`c

58 sys.stderr.write(f"File language definition returned error: {repr(err)}\n") 2`c

59 return None 2`c

60 if build_lang: 60 ↛ exitline 60 didn't return from function 'check_file_language' because the condition on line 60 was always true2a e @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncb g occ d f

61 # print(f"DEBUG: check_file_language {build_lang.settings}\n{build_lang.headers}\n{build_lang.true_strings}" 

62 # f"\n{build_lang.false_strings}\n{build_lang.bdd_prefixes}") 

63 lang = [] 2a e @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncb g occ d f

64 for ll in build_lang: 2a e @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncb g occ d f

65 lang.append(ll.code.replace('-', '_')) 2a e @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncb g occ d f

66 return lang 2a e @b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncb g occ d f

67 

68 

69def get_language_name(lang_code): 2a }c

70 """ 

71 Returns the language name if valid from name or code. 

72 

73 :param lang_code: language code or name 

74 :return: language name or None 

75 """ 

76 if lang_code and len(lang_code) < 2: 

77 return None 

78 if not Language or not lang_code: 

79 return None 

80 try: 

81 from robot.conf.languages import Languages 

82 except ImportError as err: 

83 sys.stderr.write(f"Trying to import robot's languages module returned error: {repr(err)}\n") 

84 try: 

85 from .languages import Languages 

86 except ImportError: 

87 return None 

88 try: 

89 build_lang = Languages(lang_code.replace('_', '-'), add_english=False) 

90 except (DataError, ModuleNotFoundError) as err: 

91 sys.stderr.write(f"File language definition returned error: {repr(err)}\n") 

92 return None 

93 if build_lang: 

94 for lang in build_lang: 

95 return lang.name 

96 

97 

98def read(path): 2a }c

99 lang = None 2a e r hdidjdkds ldt z mdndu v S w x A B C D E adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`codb h g occ i F d j k l m n o p q y f pdqd

100 for lineno, line in enumerate(Utf8Reader(path).readlines(), start=1): 2a e r hdidjdkds ldt z mdndu v S w x A B C D E adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`codb h g occ i F d j k l m n o p q y f pdqd

101 row = line.rstrip() 2a e r hdidjdkds ldt z mdndu v S w x A B C D E adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`codb h g occ i F d j k l m n o p q y f pdqd

102 if row and row.strip().startswith('*'): 2a e r hdidjdkds ldt z mdndu v S w x A B C D E adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`codb h g occ i F d j k l m n o p q y f pdqd

103 break 2a e r hdidjdkds ldt z mdndu v S w x A B C D E adX bdcdddedfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`codb h g occ i F d j k l m n o p q y f pdqd

104 else: 

105 if row.startswith('Language:'): 2a e adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`cb g occ d f

106 content = row.split('#') 2a e adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc`cb g occ d f

107 if len(content) > 1: 107 ↛ 108line 107 didn't jump to line 108 because the condition on line 107 was never true2a e adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc`cb g occ d f

108 content = content[0] 

109 else: 

110 content = row 2a e adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc`cb g occ d f

111 lang = content[len('Language:'):].strip() 2a e adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc`cb g occ d f

112 mlang = lang.split(',') 2a e adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc`cb g occ d f

113 if len(mlang) > 1: 113 ↛ 114line 113 didn't jump to line 114 because the condition on line 113 was never true2a e adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc`cb g occ d f

114 lang = mlang[:] 

115 return lang 2a e r hdidjdkds ldt z mdndu v S w x A B C D E adX bdcdddedrdfdgd@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcnc~c`codb h g occ i F d j k l m n o p q y f pdqd

116 

117 

118def get_headers_for(language, tables_headers, lowercase=True): 2a }c

119 _setting_table_names = 'Setting', 'Settings' 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

120 _variable_table_names = 'Variable', 'Variables' 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

121 _testcase_table_names = 'Test Case', 'Test Cases', 'Task', 'Tasks' 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

122 _keyword_table_names = 'Keyword', 'Keywords' 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

123 _comment_table_names = 'Comment', 'Comments' 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

124 t_en = [(_setting_table_names,), 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

125 (_variable_table_names,), 

126 (_testcase_table_names,), 

127 (_keyword_table_names,), 

128 (_comment_table_names,)] 

129 # print(f"DEBUG: language.py get_headers_for ENTER {language=} tables_headers={tables_headers}") 

130 if not Language: 130 ↛ 131line 130 didn't jump to line 131 because the condition on line 130 was never true2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

131 return t_en 

132 assert tables_headers is not None 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

133 if not language: 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

134 language = ['en'] 1aQeRrstzuvwxABCDEbhgciFdjklmnopqyf

135 languages = set() 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

136 for mlang in language: 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

137 try: 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

138 if not mlang: 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

139 mlang = 'en' 1aGHIJKLMNOP

140 lang = Language.from_name(mlang.replace('_', '-')) 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

141 languages.add(lang) 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

142 except ValueError: 2T {c|c

143 print(f"DEBUG: language.py get_headers_for Exception at language={mlang}") 2T {c|c

144 

145 tables_headers = [item.lower() for item in list(tables_headers)] if lowercase else tables_headers 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

146 if not languages: 2a Q e R r s G t z H I u v w x A B C D E J K L M N O P U V T W {c|cb h g c i F d j k l m n o p q y f

147 # print("DEBUG: language.py get_headers_for languages set is empty returning original tables_headers") 

148 return tables_headers 2{c|c

149 # print(f"DEBUG: language.py get_headers_for BEFORE BUILD TABLE {language=} tables_headers={tables_headers}") 

150 build_table = set() 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

151 for lang in languages: 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

152 headers = lang.headers 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

153 # print(f"DEBUG: language.py get_headers_for HEADERS headers={headers}, table_headers={tables_headers}") 

154 for item in tables_headers: 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

155 build_headings = [] 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

156 inx = 0 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

157 for k, v in zip(headers.keys(), headers.values()): 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

158 try: 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

159 if v.lower() == item.lower(): 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

160 header = list(headers.keys())[inx].lower() if lowercase else list(headers.keys())[inx] 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

161 build_headings.append(header) 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

162 break 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

163 except Exception as ex: 

164 print(f"DEBUG: robotide.lib.compat.parsing.language.py get_headers: {ex}") 

165 pass 

166 inx += 1 1aQeRrsGtzHIuvwxABCDEJKLMNOPbhgciFdjklmnopqyf

167 for bh in build_headings: 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

168 build_table.add(bh) 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

169 # print(f"DEBUG: language.py get_headers_for BEFORE RE-BUILD TABLE build_table= {build_table}") 

170 mod_headers = list(tables_headers) 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

171 if build_table: 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

172 new_table = list(build_table) 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

173 for k in new_table: 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

174 if k in mod_headers: 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

175 mod_headers.remove(k) 1aQeRrsGtzHIuvwxABCDEJKLMNOPTbhgciFdjklmnopqyf

176 for th in mod_headers: 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

177 if th != '': 177 ↛ 176line 177 didn't jump to line 176 because the condition on line 177 was always true1aQeRrsGtzHIuvwxABCDEJKLMNOPUVWbhgciFdjklmnopqyf

178 new_table.append(th) 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVWbhgciFdjklmnopqyf

179 # print(f"DEBUG: language.py get_headers_for RETURN table= {new_table}") 

180 return tuple(new_table) 1aQeRrsGtzHIuvwxABCDEJKLMNOPUVTWbhgciFdjklmnopqyf

181 # print(f"DEBUG: language.py get_headers_for RETURN AFTER FAILED BUILD TABLE tables_headers={tables_headers}") 

182 return tables_headers 1aQeRrsGtzHIuvwxABCDEJKLMNOPbhgciFdjklmnopqyf

183 

184 

185def get_settings_for(language, settings_names): 2a }c

186 assert settings_names is not None 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

187 if not Language: 187 ↛ 188line 187 didn't jump to line 188 because the condition on line 187 was never true2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

188 return settings_names 

189 if not language or len(language) == 0: 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

190 language = ['en'] 2a e } r s t z ebfbpbqbsbtbubvbwbxbybzbAbBbCbDbEbu v w x E 5 6 7 8 9 Y GbHbb h g c i d j k l m n o p q y f Qb= ? @ [ ] ^ _ ` { | XbYbZb0b1b2b

191 languages = set() 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

192 if isinstance(language, list): 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

193 for mlang in language: 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 sbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P Ecb h g c i F d j k l m n o p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

194 try: 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 sbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P Ecb h g c i F d j k l m n o p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

195 if not mlang: 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 sbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P Ecb h g c i F d j k l m n o p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

196 mlang = 'en' 1aGHI/:;JKLMNOP

197 lang = Language.from_name(mlang.replace('_', '-')) 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 sbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P Ecb h g c i F d j k l m n o p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

198 languages.add(lang) 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 sbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P Ecb h g c i F d j k l m n o p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

199 except (ValueError, AttributeError): 

200 return settings_names 

201 # print(f"DEBUG: language.py get_settings_for Exception at language={mlang}") 

202 else: 

203 lang = Language.from_name(language.replace('_', '-')) 2a 0c1c2c3c4c5c6c7cX b 8ch c 9c!c#c$c%c'c(c)c*c+c,ci -c.cd /c:c;c=c?c@c[c]c^cj k l m n _co p q

204 languages.add(lang) 2a 0c1c2c3c4c5c6c7cX b 8ch c 9c!c#c$c%c'c(c)c*c+c,ci -c.cd /c:c;c=c?c@c[c]c^cj k l m n _co p q

205 # DEBUG: settings_names = [item.lower() for item in list(settings_names)] 

206 if not languages: 206 ↛ 207line 206 didn't jump to line 207 because the condition on line 206 was never true2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

207 print("DEBUG: language.py get_settings_for languages set is empty") 

208 return {} 

209 

210 build_table = {} 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

211 for lang in languages: 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

212 settings = lang.settings 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

213 for item in settings_names: 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

214 inx = 0 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

215 for k, v in zip(settings.keys(), settings.values()): 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

216 try: 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

217 if v.lower() == item.lower(): 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

218 setting = list(settings.keys())[inx] 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , +b,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbBbCbDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y GbHbIbJbKbLbMbNbL M N O P X b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f ObPbQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | Xb. YbZb0b1b2b

219 build_table[setting] = item 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , +b,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbBbCbDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y GbHbIbJbKbLbMbNbL M N O P X b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f ObPbQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | Xb. YbZb0b1b2b

220 break 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , +b,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbBbCbDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y GbHbIbJbKbLbMbNbL M N O P X b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f ObPbQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | Xb. YbZb0b1b2b

221 except Exception as ex: 

222 print(f"DEBUG: robotide.lib.compat.parsing.language.py get_settings: {ex}") 

223 pass 

224 inx += 1 2a Q e 9b!b#b$bR } ! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b3b4b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

225 # print(f"DEBUG: language.py get_settings_for RETURN build_table={build_table}") 

226 return build_table 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

227 

228 

229def get_english_label(lang, label): 2a }c

230 assert label is not None 

231 if not Language: 

232 return label 

233 if not lang: 

234 lang = ['en'] 

235 mlang = None 

236 if isinstance(lang, list): 

237 try: 

238 mlang = Language.from_name(lang[0].replace('_', '-')) # Only care for a single language 

239 except ValueError: 

240 # print(f"DEBUG: language.py get_english_label Exception at language={lang}") 

241 pass 

242 else: 

243 mlang = Language.from_name(lang.replace('_', '-')) 

244 if not mlang: 

245 # print(f"DEBUG: language.py get_english_label lang={lang} not found") 

246 return None 

247 setting_names = list(mlang.settings.keys()) 

248 try: 

249 index = setting_names.index(label) 

250 except ValueError: 

251 # print(f"DEBUG: language.py get_english_label Exception at getting index {lang} returning={label}") 

252 return label 

253 en_label = list(mlang.settings.values())[index] 

254 return en_label 

255 

256 

257def get_localized_setting(language: [], english_name: str): 2a }c

258 if not language: 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

259 return english_name 2a e %b'b(b)b*br s t /b3b4b:b5b6b7bZ 0 1 2 3 4 u v w x A B C D Y b h c i F d j k l m n o p q y f

260 settings = get_settings_for(language, (english_name,)) 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

261 try: 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

262 result = list(settings.keys())[list(settings.values()).index(english_name)] 2a Q e 9b!b#b$bR } %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsc+btc,b-b.b/b3b4b:b5b6b7b;b=bz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6csbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P EcX b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

263 except ValueError: 2a Q e R } ! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsctcz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 sbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P Ecb h g c i F d j k l m n o p q y - f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

264 return english_name 2a Q e R } ! r # s G t $ ~ abbbcbdb% ' ( ) * + , pcqcrcsctcz ebfbgbhbibjbkblbmbnbobpbqbucrbH I / : Z 0 1 2 3 4 sbtbubvbwbxbybzbAbvcBbCbwcxcycDbEbu v S Fbw x A B C D E ; J K 5 6 7 8 9 Y zcAcBcGbHbCcDcIbJbKbLbMbNbL M N O P Ecb h g c i F d j k l m n o p q y - f FcGcObPbHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcQb8bRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | ZcXb. YbZb0b1b2b

265 return result 2a Q e 9b!b#b$bR %b'b(b)b*b! r # s G t $ ~ abbbcbdb% ' ( ) * + , +b,b-b.b/b3b4b:b5b6b7b;b=bz gbhbibjbkblbmbnbobrbH I / : Z 0 1 2 3 4 0c1c2c3c4c5c6cu v S Fbw x A B C D E ; J K 7c5 6 7 8 9 Y IbJbKbLbMbNbL M N O P X b 8ch g c 9c!c#c$c%c'c(c)c*c+c,ci -c.cF d /c:c;c=c?c@c[c]c^cj k l m n _co p q y ?b- f ObPbRbSbTbUbVbWb= ? @ [ ] ^ _ ` { | .