From 4832ca7bc8412feae6459911bdce34885e928ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Thu, 11 Mar 2021 15:44:53 +0100 Subject: [PATCH] #1585 SVG import - support for style tag (CSS) --- CHANGELOG.md | 2 + libsrc/ffdec_lib/lexers/css.flex | 203 ++ .../flash/importers/svg/SvgImporter.java | 83 +- .../flash/importers/svg/SvgStyle.java | 41 +- .../flash/importers/svg/css/CssLexer.java | 2195 +++++++++++++++++ .../importers/svg/css/CssParseException.java | 15 + .../importers/svg/css/CssParsedSymbol.java | 41 + .../flash/importers/svg/css/CssParser.java | 477 ++++ .../importers/svg/css/CssSelectorToXPath.java | 686 ++++++ .../importers/svg/css/CssSymbolType.java | 36 + 10 files changed, 3766 insertions(+), 13 deletions(-) create mode 100644 libsrc/ffdec_lib/lexers/css.flex create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssLexer.java create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParseException.java create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParsedSymbol.java create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParser.java create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssSelectorToXPath.java create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssSymbolType.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 8883a0dd8..93820cf3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - [#843] Compound assignments (like +=) decompilation and direct editation - [#1221] Separate icons for different actionscript objects (class/interface/frame/) - AS3 P-code - hilight and edit traits outside classes +- [#1585] SVG import - support for style tag (CSS) ### Changed - [#1471] Import script menuitem renamed to Import scripts. @@ -2098,6 +2099,7 @@ All notable changes to this project will be documented in this file. [#1156]: https://www.free-decompiler.com/flash/issues/1156 [#843]: https://www.free-decompiler.com/flash/issues/843 [#1221]: https://www.free-decompiler.com/flash/issues/1221 +[#1585]: https://www.free-decompiler.com/flash/issues/1585 [#1471]: https://www.free-decompiler.com/flash/issues/1471 [#1396]: https://www.free-decompiler.com/flash/issues/1396 [#1254]: https://www.free-decompiler.com/flash/issues/1254 diff --git a/libsrc/ffdec_lib/lexers/css.flex b/libsrc/ffdec_lib/lexers/css.flex new file mode 100644 index 000000000..74332fdfc --- /dev/null +++ b/libsrc/ffdec_lib/lexers/css.flex @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2010-2016 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.importers.svg.css; +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +%% + +%public +%class CssLexer +%final +%unicode +%char +%ignorecase +%type CssParsedSymbol + +%{ + + StringBuilder string = new StringBuilder(); + + private static String xmlTagName = ""; + + public int yychar() { + return yychar; + } + + private final Stack pushedBack = new Stack<>(); + + public int yyline() { + return yyline + 1; + } + + private boolean doBuffer = false; + private List buffer = new ArrayList<>(); + + public void startBuffer(){ + doBuffer = true; + } + + public String getAndClearBuffer(){ + StringBuilder sb = new StringBuilder(); + for(CssParsedSymbol s:buffer){ + sb.append(s.value); + } + buffer.clear(); + doBuffer = false; + return sb.toString(); + } + + public int getPos(){ + int pos = yychar() + yylength(); + for(CssParsedSymbol p:pushedBack) { + pos -= p.value.length(); + } + return pos; + } + + public void pushback(CssParsedSymbol symb) { + pushedBack.push(symb); + if(!buffer.isEmpty()){ + buffer.remove(buffer.size()-1); + } + last = null; + } + + CssParsedSymbol last; + public CssParsedSymbol lex() throws java.io.IOException { + CssParsedSymbol ret = null; + if (!pushedBack.isEmpty()){ + ret = last = pushedBack.pop(); + } else { + ret = last = yylex(); + } + if (doBuffer){ + buffer.add(ret); + } + return ret; + } + +%} + + +h= [0-9a-fA-F] +nonascii= [\240-\377] +unicode= \\{h}{1,6}(\r\n|[ \t\r\n\f])? +escape= {unicode}|\\[^\r\n\f0-9a-fA-F] +nmstart= [_a-zA-Z]|{nonascii}|{escape} +nmchar= [_a-zA-Z0-9-]|{nonascii}|{escape} +string1= "\"" ([^\n\r\f\\\"]|\\{nl}|{escape})* "\"" +string2= \'([^\n\r\f\\']|\\{nl}|{escape})*\' +badstring1= "\"" ([^\n\r\f\\\"]|\\{nl}|{escape})*\\? +badstring2= \'([^\n\r\f\\']|\\{nl}|{escape})*\\? +badcomment1= \/\*[^*]*\*+([^/*][^*]*\*+)* +badcomment2= \/\*[^*]*(\*+[^/*][^*]*)* +baduri1= {U}{R}{L}\({w}([!#$%&*-\[\]-~]|{nonascii}|{escape})*{w} +baduri2= {U}{R}{L}\({w}{string}{w} +baduri3= {U}{R}{L}\({w}{badstring} +comment= \/\*[^*]*\*+([^/*][^*]*\*+)*\/ +ident= -?{nmstart}{nmchar}* +name= {nmchar}+ +num= [-+]?[0-9]+|[-+]?[0-9]*"."[0-9]+ +string= {string1}|{string2} +badstring= {badstring1}|{badstring2} +badcomment= {badcomment1}|{badcomment2} +baduri= {baduri1}|{baduri2}|{baduri3} +url= ([!#$%&*-~]|{nonascii}|{escape})* +s= [ \t\r\n\f]+ +w= {s}? +nl= \n|\r\n|\r|\f + +A= A|a|\\0{0,4}(41|61)(\r\n|[ \t\r\n\f])? +C= C|c|\\0{0,4}(43|63)(\r\n|[ \t\r\n\f])? +D= D|d|\\0{0,4}(44|64)(\r\n|[ \t\r\n\f])? +E= E|e|\\0{0,4}(45|65)(\r\n|[ \t\r\n\f])? +G= G|g|\\0{0,4}(47|67)(\r\n|[ \t\r\n\f])?|\\g +H= H|h|\\0{0,4}(48|68)(\r\n|[ \t\r\n\f])?|\\h +I= I|i|\\0{0,4}(49|69)(\r\n|[ \t\r\n\f])?|\\i +K= K|k|\\0{0,4}(4b|6b)(\r\n|[ \t\r\n\f])?|\\k +L= L|l|\\0{0,4}(4c|6c)(\r\n|[ \t\r\n\f])?|\\l +M= M|m|\\0{0,4}(4d|6d)(\r\n|[ \t\r\n\f])?|\\m +N= N|n|\\0{0,4}(4e|6e)(\r\n|[ \t\r\n\f])?|\\n +O= O|o|\\0{0,4}(4f|6f)(\r\n|[ \t\r\n\f])?|\\o +P= P|p|\\0{0,4}(50|70)(\r\n|[ \t\r\n\f])?|\\p +R= R|r|\\0{0,4}(52|72)(\r\n|[ \t\r\n\f])?|\\r +S= S|s|\\0{0,4}(53|73)(\r\n|[ \t\r\n\f])?|\\s +T= T|t|\\0{0,4}(54|74)(\r\n|[ \t\r\n\f])?|\\t +U= U|u|\\0{0,4}(55|75)(\r\n|[ \t\r\n\f])?|\\u +X= X|x|\\0{0,4}(58|78)(\r\n|[ \t\r\n\f])?|\\x +Z= Z|z|\\0{0,4}(5a|7a)(\r\n|[ \t\r\n\f])?|\\z + +%% + + { + + {s} {return new CssParsedSymbol(yytext(), CssSymbolType.S);} + +\/\*[^*]*\*+([^/*][^*]*\*+)*\/ /* ignore comments */ +{badcomment} /* unclosed comment at EOF */ + +"" {return new CssParsedSymbol(yytext(), CssSymbolType.CDC);} +"~=" {return new CssParsedSymbol(yytext(), CssSymbolType.INCLUDES);} +"|=" {return new CssParsedSymbol(yytext(), CssSymbolType.DASHMATCH);} + +{string} {return new CssParsedSymbol(yytext(), CssSymbolType.STRING);} +{badstring} {return new CssParsedSymbol(yytext(), CssSymbolType.BAD_STRING);} + +{ident} {return new CssParsedSymbol(yytext(), CssSymbolType.IDENT);} + +"#"{name} {return new CssParsedSymbol(yytext(), CssSymbolType.HASH);} + +@{I}{M}{P}{O}{R}{T} {return new CssParsedSymbol(yytext(), CssSymbolType.IMPORT_SYM);} +@{P}{A}{G}{E} {return new CssParsedSymbol(yytext(), CssSymbolType.PAGE_SYM);} +@{M}{E}{D}{I}{A} {return new CssParsedSymbol(yytext(), CssSymbolType.MEDIA_SYM);} +"@charset " {return new CssParsedSymbol(yytext(), CssSymbolType.CHARSET_SYM);} + +"!"({w}|{comment})*{I}{M}{P}{O}{R}{T}{A}{N}{T} {return new CssParsedSymbol(yytext(), CssSymbolType.IMPORTANT_SYM);} + +{num}{E}{M} {return new CssParsedSymbol(yytext(), CssSymbolType.EMS);} +{num}{E}{X} {return new CssParsedSymbol(yytext(), CssSymbolType.EXS);} +{num}{P}{X} {return new CssParsedSymbol(yytext(), CssSymbolType.LENGTH);} +{num}{C}{M} {return new CssParsedSymbol(yytext(), CssSymbolType.LENGTH);} +{num}{M}{M} {return new CssParsedSymbol(yytext(), CssSymbolType.LENGTH);} +{num}{I}{N} {return new CssParsedSymbol(yytext(), CssSymbolType.LENGTH);} +{num}{P}{T} {return new CssParsedSymbol(yytext(), CssSymbolType.LENGTH);} +{num}{P}{C} {return new CssParsedSymbol(yytext(), CssSymbolType.LENGTH);} +{num}{D}{E}{G} {return new CssParsedSymbol(yytext(), CssSymbolType.ANGLE);} +{num}{R}{A}{D} {return new CssParsedSymbol(yytext(), CssSymbolType.ANGLE);} +{num}{G}{R}{A}{D} {return new CssParsedSymbol(yytext(), CssSymbolType.ANGLE);} +{num}{M}{S} {return new CssParsedSymbol(yytext(), CssSymbolType.TIME);} +{num}{S} {return new CssParsedSymbol(yytext(), CssSymbolType.TIME);} +{num}{H}{Z} {return new CssParsedSymbol(yytext(), CssSymbolType.FREQ);} +{num}{K}{H}{Z} {return new CssParsedSymbol(yytext(), CssSymbolType.FREQ);} +{num}{ident} {return new CssParsedSymbol(yytext(), CssSymbolType.DIMENSION);} + +{num}% {return new CssParsedSymbol(yytext(), CssSymbolType.PERCENTAGE);} +{num} {return new CssParsedSymbol(yytext(), CssSymbolType.NUMBER);} + +{U}{R}{L}"("{w}{string}{w}")" {return new CssParsedSymbol(yytext(), CssSymbolType.URI);} +{U}{R}{L}"("{w}{url}{w}")" {return new CssParsedSymbol(yytext(), CssSymbolType.URI);} +{baduri} {return new CssParsedSymbol(yytext(), CssSymbolType.BAD_URI);} + +{ident}"(" {return new CssParsedSymbol(yytext(), CssSymbolType.FUNCTION);} +{comment} {} +. {return new CssParsedSymbol(yytext(), CssSymbolType.OTHER);} +} + +<> { return new CssParsedSymbol("", CssSymbolType.EOF); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgImporter.java index 677e35193..10602e499 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgImporter.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.importers.svg; import com.jpexs.decompiler.flash.ReadOnlyTagList; @@ -24,6 +25,9 @@ import com.jpexs.decompiler.flash.exporters.modes.ShapeExportMode; import com.jpexs.decompiler.flash.exporters.settings.ShapeExportSettings; import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter; import com.jpexs.decompiler.flash.importers.ShapeImporter; +import com.jpexs.decompiler.flash.importers.svg.css.CssParseException; +import com.jpexs.decompiler.flash.importers.svg.css.CssParser; +import com.jpexs.decompiler.flash.importers.svg.css.CssSelectorToXPath; import com.jpexs.decompiler.flash.tags.DefineShape4Tag; import com.jpexs.decompiler.flash.tags.ExportAssetsTag; import com.jpexs.decompiler.flash.tags.Tag; @@ -66,8 +70,13 @@ import javax.imageio.ImageIO; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; @@ -211,6 +220,55 @@ public class SvgImporter { } } + private void processStyle(Element element) { + String styleSheet = element.getTextContent().trim(); + CssParser cssParser = new CssParser(styleSheet); + CssSelectorToXPath selectorToXPath = new CssSelectorToXPath(); + Document doc = element.getOwnerDocument(); + try { + cssParser.styleshet(); + XPath xPath = XPathFactory.newInstance().newXPath(); + for (int i = 0; i < cssParser.getCountRulesets(); i++) { + String selector = cssParser.getSelector(i); + String xPathExpression = selectorToXPath.css2xpath(selector); + try { + NodeList nodeList = (NodeList) xPath.compile(xPathExpression).evaluate(doc, XPathConstants.NODESET); + for (int j = 0; j < nodeList.getLength(); j++) { + Node node = nodeList.item(j); + NamedNodeMap attrs = node.getAttributes(); + Node styleAttr = attrs.getNamedItem("ffdec-style"); + if (styleAttr != null) { + styleAttr.setNodeValue(styleAttr.getNodeValue() + ";" + "{" + cssParser.getSpecifity(i) + "}" + cssParser.getDeclarations(i)); + attrs.setNamedItem(styleAttr); + } else { + Node styleNode = doc.createAttribute("ffdec-style"); + styleNode.setNodeValue("{" + cssParser.getSpecifity(i) + "}" + cssParser.getDeclarations(i)); + attrs.setNamedItem(styleNode); + } + } + } catch (XPathExpressionException ex) { + Logger.getLogger(SvgImporter.class.getName()).log(Level.SEVERE, null, ex); + } + } + } catch (IOException | CssParseException ex) { + showWarning("CannotParseCSSStyle", "Cannot parse CSS style: " + ex.getMessage()); + } + } + + private void processDefs(Element element) { + for (int i = 0; i < element.getChildNodes().getLength(); i++) { + Node childNode = element.getChildNodes().item(i); + if (childNode instanceof Element) { + Element childElement = (Element) childNode; + String tagName = childElement.getTagName(); + if ("style".equals(tagName)) { + processStyle(childElement); + } else if ("defs".equals(tagName)) { + processDefs(childElement); + } + } + } + } private void processSvgObject(Map idMap, int shapeNum, SHAPEWITHSTYLE shapes, Element element, Matrix transform, SvgStyle style) { for (int i = 0; i < element.getChildNodes().getLength(); i++) { Node childNode = element.getChildNodes().item(i); @@ -220,7 +278,9 @@ public class SvgImporter { SvgStyle newStyle = new SvgStyle(this, idMap, childElement); Matrix m = Matrix.parseSvgMatrix(childElement.getAttribute("transform"), 1, 1); Matrix m2 = m == null ? transform : transform.concatenate(m); - if ("g".equals(tagName)) { + if ("style".equals(tagName)) { + processStyle(childElement); + } else if ("g".equals(tagName)) { processSvgObject(idMap, shapeNum, shapes, childElement, m2, newStyle); } else if ("path".equals(tagName)) { processPath(shapeNum, shapes, childElement, m2, newStyle); @@ -236,7 +296,9 @@ public class SvgImporter { processPolyline(shapeNum, shapes, childElement, m2, newStyle); } else if ("polygon".equals(tagName)) { processPolygon(shapeNum, shapes, childElement, m2, newStyle); - } else if ("defs".equals(tagName) || "title".equals(tagName) || "desc".equals(tagName) + } else if ("defs".equals(tagName)) { + processDefs(childElement); + } else if ("title".equals(tagName) || "desc".equals(tagName) || "radialGradient".equals(tagName) || "linearGradient".equals(tagName)) { // ignore } else { @@ -1035,6 +1097,7 @@ public class SvgImporter { //Stub for w3 test. TODO: refactor and move to test directory. It's here because of easy access - compiling single file private static void svgTest(String name) throws IOException, InterruptedException { + System.err.println("running test " + name); if (!new File(name + ".original.svg").exists()) { URL svgUrl = new URL("http://www.w3.org/Graphics/SVG/Test/20061213/svggen/" + name + ".svg"); byte[] svgData = Helper.readStream(svgUrl.openStream()); @@ -1048,7 +1111,7 @@ public class SvgImporter { String svgDataS = Helper.readTextFile(name + ".orig.svg"); SWF swf = new SWF(); DefineShape4Tag st = new DefineShape4Tag(swf); - st = (DefineShape4Tag) (new SvgImporter().importSvg(st, svgDataS)); + st = (DefineShape4Tag) (new SvgImporter().importSvg(st, svgDataS, false)); swf.addTag(st); SerializableImage si = new SerializableImage(480, 360, BufferedImage.TYPE_4BYTE_ABGR); BitmapExporter.export(swf, st.shapes, Color.yellow, si, new Matrix(), new Matrix(), null); @@ -1301,13 +1364,13 @@ public class SvgImporter { // svgTest("struct-use-01-t"); // svgTest("struct-use-03-t"); // svgTest("struct-use-05-b"); -// svgTest("styling-css-01-b"); -// svgTest("styling-css-02-b"); -// svgTest("styling-css-03-b"); -// svgTest("styling-css-04-f"); + svgTest("styling-css-01-b"); + svgTest("styling-css-02-b"); + svgTest("styling-css-03-b"); + svgTest("styling-css-04-f"); // svgTest("styling-css-05-b"); // svgTest("styling-css-06-b"); -// svgTest("styling-inherit-01-b"); + svgTest("styling-inherit-01-b"); // svgTest("styling-pres-01-t"); // svgTest("text-align-01-b"); // svgTest("text-align-02-b"); @@ -1341,7 +1404,7 @@ public class SvgImporter { // svgTest("text-tspan-01-b"); // svgTest("text-ws-01-t"); // svgTest("text-ws-02-t"); -// svgTest("types-basicDOM-01-b"); +// svgTest("types-basicDOM-01-b"); } private void applyFillGradients(SvgFill fill, FILLSTYLE fillStyle, RECT bounds, StyleChangeRecord scr, Matrix transform, int shapeNum, SvgStyle style) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgStyle.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgStyle.java index d653b4cad..be235f33b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgStyle.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgStyle.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.importers.svg; import com.jpexs.decompiler.flash.importers.ShapeImporter; @@ -21,6 +22,8 @@ import com.jpexs.helpers.Helper; import java.awt.Color; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -56,9 +59,42 @@ class SvgStyle { private Map getStyleAttributeValues(Element element) { // todo: cache + Map styleValues = new HashMap<>(); + String styleStr = ""; + if (element.hasAttribute("ffdec-style")) { + styleStr += element.getAttribute("ffdec-style"); + } if (element.hasAttribute("style")) { - String[] styleDefs = element.getAttribute("style").split(";"); + styleStr += "{1000}" + element.getAttribute("style"); + } + + if (!styleStr.isEmpty()) { + String[] rulesBySpec = styleStr.split("\\{"); + List rulesBySpecList = Arrays.asList(rulesBySpec); + List rulesBySpecListUnordered = new ArrayList<>(rulesBySpecList); + rulesBySpecList.sort(new Comparator() { + @Override + public int compare(String o1, String o2) { + if (o1.isEmpty()) { + return -1; + } + if (o2.isEmpty()) { + return 1; + } + int r1 = Integer.parseInt(o1.substring(0, o1.indexOf("}"))); + int r2 = Integer.parseInt(o2.substring(0, o2.indexOf("}"))); + if (r1 == r2) { + return rulesBySpecListUnordered.indexOf(r1) - rulesBySpecListUnordered.indexOf(r2); + } + return r1 - r2; + } + }); + for (int i = 0; i < rulesBySpecList.size(); i++) { + rulesBySpecList.set(i, rulesBySpecList.get(i).substring(rulesBySpecList.get(i).indexOf("}") + 1)); + } + styleStr = String.join(";", rulesBySpecList) + ";"; + String[] styleDefs = styleStr.split(";"); for (String styleDef : styleDefs) { if (!styleDef.contains(":")) { continue; @@ -75,7 +111,6 @@ class SvgStyle { } } } - return styleValues; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssLexer.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssLexer.java new file mode 100644 index 000000000..3c6ea6c24 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssLexer.java @@ -0,0 +1,2195 @@ +/* The following code was generated by JFlex 1.6.0 */ + +/* + * Copyright (C) 2010-2016 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.importers.svg.css; +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + + +/** + * This class is a scanner generated by + * JFlex 1.6.0 + * from the specification file C:/Dropbox/Programovani/JavaSE/FFDec/libsrc/ffdec_lib/lexers/css.flex + */ +public final class CssLexer { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int YYINITIAL = 0; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0 + }; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\11\0\1\6\1\5\1\73\1\7\1\4\22\0\1\70\1\61\1\12"+ + "\1\66\1\17\1\71\1\17\1\13\1\16\1\72\1\15\1\20\1\17"+ + "\1\11\1\21\1\14\1\23\1\25\1\1\1\30\1\24\1\33\1\26"+ + "\1\35\1\37\1\41\2\17\1\60\1\64\1\62\1\17\1\67\1\22"+ + "\1\43\1\27\1\31\1\32\1\10\1\34\1\36\1\40\1\2\1\42"+ + "\1\44\1\45\1\46\1\47\1\50\1\2\1\51\1\53\1\54\1\55"+ + "\2\2\1\56\1\2\1\57\1\17\1\3\2\17\1\2\1\17\1\22"+ + "\1\43\1\27\1\31\1\32\1\10\1\34\1\36\1\40\1\2\1\42"+ + "\1\44\1\45\1\46\1\47\1\50\1\2\1\51\1\53\1\54\1\55"+ + "\2\2\1\56\1\2\1\57\1\17\1\65\1\17\1\63\6\0\1\73"+ + "\32\0\140\2\60\0\2\0\115\0\1\52\u1ea8\0\1\73\1\73\u0100\0"+ + "\1\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\udee5\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\1\0\1\1\1\2\1\3\1\1\1\4\1\1\2\5"+ + "\3\1\1\3\5\1\1\6\3\0\12\6\1\7\1\10"+ + "\1\0\1\11\3\3\1\0\1\5\1\12\1\5\1\0"+ + "\1\2\1\0\1\3\4\0\1\13\1\14\1\15\7\0"+ + "\4\6\1\0\1\16\1\0\1\6\1\0\1\17\1\20"+ + "\2\0\1\21\5\0\1\6\5\3\1\22\4\5\1\0"+ + "\2\3\1\0\1\3\5\0\1\15\12\0\17\6\1\7"+ + "\4\6\1\0\1\23\22\6\1\0\5\3\2\5\1\24"+ + "\5\3\1\25\7\0\2\15\21\0\16\6\1\7\14\6"+ + "\1\16\1\7\2\6\1\16\10\6\1\17\1\20\4\6"+ + "\1\21\16\6\4\3\2\5\1\0\7\3\1\25\1\0"+ + "\2\25\1\26\10\0\1\15\26\0\1\27\16\6\1\7"+ + "\2\6\1\16\1\23\2\6\2\16\6\6\1\23\3\6"+ + "\1\17\1\20\1\17\1\20\4\6\2\21\15\6\1\23"+ + "\2\6\3\3\2\5\1\0\7\3\3\25\1\0\1\26"+ + "\2\25\11\0\1\15\21\0\1\30\6\0\15\6\1\7"+ + "\2\6\1\16\1\23\2\6\1\16\5\6\2\23\3\6"+ + "\1\17\1\20\4\6\1\21\16\6\2\3\2\5\2\0"+ + "\5\3\2\25\1\0\2\25\1\26\4\25\11\0\1\15"+ + "\11\0\1\31\13\0\1\27\13\6\1\7\2\6\1\16"+ + "\1\23\1\6\1\16\4\6\1\23\2\6\1\17\1\20"+ + "\2\6\1\21\11\6\2\5\1\0\3\3\1\25\1\0"+ + "\4\25\11\0\1\15\14\0\1\30\2\0\1\27\1\16"+ + "\2\6\1\23\1\17\1\20\1\21\2\6\1\0\1\3"+ + "\1\25\1\0\3\25\11\0\1\32\4\0\1\31\2\0"+ + "\1\30\1\0\1\23\1\33\1\25\2\0\3\25\10\0"+ + "\1\34\2\0\1\31\1\0\1\25\1\0\3\25\11\0"+ + "\3\25\4\0\1\34\3\0\1\34\2\0"; + + private static int [] zzUnpackAction() { + int [] result = new int[684]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\74\0\170\0\264\0\360\0\u012c\0\u0168\0\u01a4"+ + "\0\u01e0\0\u021c\0\u0258\0\u0294\0\u02d0\0\u030c\0\u0348\0\u0384"+ + "\0\u03c0\0\u03fc\0\u0438\0\u0474\0\u04b0\0\u0294\0\u04ec\0\u0528"+ + "\0\u0564\0\u05a0\0\u05dc\0\u0618\0\u0654\0\u0690\0\u06cc\0\u0708"+ + "\0\u0438\0\74\0\u0744\0\74\0\u0780\0\u07bc\0\u07f8\0\u0834"+ + "\0\u0870\0\74\0\u08ac\0\u08e8\0\u0924\0\u0960\0\u099c\0\u09d8"+ + "\0\u030c\0\u0a14\0\u0a50\0\74\0\74\0\u03c0\0\u0a8c\0\u0ac8"+ + "\0\u0b04\0\u0b40\0\u0b7c\0\u0bb8\0\u0bf4\0\u0c30\0\u0c6c\0\u0ca8"+ + "\0\u0ce4\0\u0d20\0\u0438\0\u0d5c\0\u0d98\0\u0dd4\0\u0438\0\u0438"+ + "\0\u0e10\0\u0e4c\0\u0438\0\u0e88\0\u0ec4\0\u0f00\0\u0f3c\0\u0f78"+ + "\0\u0fb4\0\u0ff0\0\u102c\0\u1068\0\u10a4\0\u10e0\0\74\0\u111c"+ + "\0\u1158\0\u1194\0\u11d0\0\u120c\0\u1248\0\u1284\0\u12c0\0\u12fc"+ + "\0\u1338\0\u1374\0\u13b0\0\u13ec\0\u1428\0\u1464\0\u14a0\0\u14dc"+ + "\0\u1518\0\u1554\0\u1590\0\u15cc\0\u1608\0\u1644\0\u1680\0\u16bc"+ + "\0\u16f8\0\u1734\0\u1770\0\u17ac\0\u17e8\0\u1824\0\u1860\0\u189c"+ + "\0\u18d8\0\u1914\0\u1950\0\u198c\0\u19c8\0\u1a04\0\u1a40\0\u1a7c"+ + "\0\u1ab8\0\u1af4\0\u1b30\0\u1b6c\0\u1ba8\0\u0438\0\u1be4\0\u1c20"+ + "\0\u1c5c\0\u1c98\0\u1cd4\0\u1d10\0\u1d4c\0\u1d88\0\u1dc4\0\u1e00"+ + "\0\u1e3c\0\u1e78\0\u1eb4\0\u1ef0\0\u1f2c\0\u1f68\0\u1fa4\0\u1fe0"+ + "\0\u201c\0\u2058\0\u2094\0\u20d0\0\u210c\0\u2148\0\u2184\0\u21c0"+ + "\0\u21fc\0\u2238\0\u2274\0\u22b0\0\u22ec\0\u2328\0\u2364\0\u23a0"+ + "\0\u23dc\0\u2418\0\u2454\0\u2490\0\u24cc\0\u2508\0\u2544\0\u2580"+ + "\0\u25bc\0\u25f8\0\u2634\0\u2670\0\u26ac\0\u26e8\0\u2724\0\u2760"+ + "\0\u279c\0\u27d8\0\u2814\0\u2850\0\u288c\0\u28c8\0\u2904\0\u2940"+ + "\0\u297c\0\u29b8\0\u29f4\0\u2a30\0\u2a6c\0\u2aa8\0\u2ae4\0\u2b20"+ + "\0\u2b5c\0\u2b98\0\u2bd4\0\u2c10\0\u2c4c\0\u2c88\0\u2cc4\0\u2d00"+ + "\0\u2d3c\0\u2d78\0\u2db4\0\u2df0\0\u2e2c\0\u2e68\0\u2ea4\0\u2ee0"+ + "\0\u2f1c\0\u2f58\0\u2f94\0\u2fd0\0\u29b8\0\u300c\0\u3048\0\u3084"+ + "\0\u30c0\0\u30fc\0\u3138\0\u3174\0\u31b0\0\u31ec\0\u3228\0\u3264"+ + "\0\u32a0\0\u32dc\0\u3318\0\u3354\0\u3390\0\u33cc\0\u3408\0\u3444"+ + "\0\u3480\0\u34bc\0\u34f8\0\u3534\0\u3570\0\u35ac\0\u35e8\0\u3624"+ + "\0\u3660\0\u369c\0\u36d8\0\u3714\0\u3750\0\u378c\0\u37c8\0\u3804"+ + "\0\u3840\0\u387c\0\u38b8\0\u38f4\0\u3930\0\u396c\0\u39a8\0\u39e4"+ + "\0\u3a20\0\u3a5c\0\u3a98\0\u3ad4\0\u3b10\0\u3b4c\0\u3b88\0\u3bc4"+ + "\0\74\0\u3c00\0\u3c3c\0\u3c78\0\u3cb4\0\u3cf0\0\u3d2c\0\u3d68"+ + "\0\u3da4\0\u3de0\0\u3e1c\0\u3e58\0\u3e94\0\u3ed0\0\u3f0c\0\u3f48"+ + "\0\u3f84\0\u3fc0\0\u3ffc\0\u4038\0\u4074\0\u40b0\0\u40ec\0\u4128"+ + "\0\u4164\0\u41a0\0\u41dc\0\u4218\0\u4254\0\u4290\0\u42cc\0\u4308"+ + "\0\74\0\u4344\0\u4380\0\u43bc\0\u43f8\0\u4434\0\u4470\0\u44ac"+ + "\0\u44e8\0\u4524\0\u4560\0\u459c\0\u45d8\0\u4614\0\u4650\0\u468c"+ + "\0\u46c8\0\u4704\0\u4344\0\u4344\0\u4740\0\u477c\0\u47b8\0\u47f4"+ + "\0\u4830\0\u486c\0\u48a8\0\u48e4\0\u4920\0\u495c\0\u4998\0\u49d4"+ + "\0\u4a10\0\u4a4c\0\u4a88\0\u4ac4\0\u4b00\0\u4b3c\0\u4b78\0\u4bb4"+ + "\0\u4bf0\0\u4c2c\0\u4c68\0\u4ca4\0\u4ce0\0\u4d1c\0\u4d58\0\u4d94"+ + "\0\u4dd0\0\u4e0c\0\u4e48\0\u4e84\0\u4ec0\0\u4efc\0\u4f38\0\u4f74"+ + "\0\u4fb0\0\u29b8\0\u4fec\0\u5028\0\u5064\0\u50a0\0\u50dc\0\u5118"+ + "\0\u5154\0\u5190\0\u51cc\0\u5208\0\u5244\0\u5280\0\u52bc\0\u52f8"+ + "\0\u5334\0\u5370\0\u53ac\0\u53e8\0\u5424\0\u3b10\0\u5460\0\u549c"+ + "\0\u54d8\0\u5514\0\u5550\0\u558c\0\u55c8\0\u5604\0\u5640\0\u567c"+ + "\0\u56b8\0\u56f4\0\u5730\0\u576c\0\u57a8\0\u57e4\0\u5820\0\u585c"+ + "\0\u5898\0\u58d4\0\u5910\0\u594c\0\u5988\0\u59c4\0\u5a00\0\u5a3c"+ + "\0\u5a78\0\u5ab4\0\u5af0\0\74\0\u5b2c\0\u5b68\0\u5ba4\0\u5be0"+ + "\0\u5c1c\0\u5c58\0\u5c94\0\u5cd0\0\u5d0c\0\u5d48\0\u5d84\0\u5dc0"+ + "\0\u5dfc\0\u5e38\0\u5e74\0\u5eb0\0\u5eec\0\u5f28\0\u5f64\0\u5fa0"+ + "\0\u5fdc\0\u6018\0\u5c94\0\u5c94\0\u6054\0\u6090\0\u60cc\0\u6108"+ + "\0\u6144\0\u6180\0\u61bc\0\u61f8\0\u6234\0\u6270\0\u62ac\0\u62e8"+ + "\0\u6324\0\u6360\0\u639c\0\u63d8\0\u6414\0\u6450\0\u648c\0\u64c8"+ + "\0\u6504\0\u6540\0\u657c\0\u65b8\0\u65f4\0\u6630\0\u666c\0\u66a8"+ + "\0\u66e4\0\u6720\0\u675c\0\u6798\0\u67d4\0\u6810\0\u684c\0\u6888"+ + "\0\u68c4\0\u6900\0\u693c\0\u6978\0\u69b4\0\u69f0\0\u6a2c\0\u6a68"+ + "\0\u6aa4\0\u6ae0\0\u6b1c\0\u6b58\0\u6b94\0\u6bd0\0\u6b58\0\u6c0c"+ + "\0\u6c48\0\u6c84\0\u6cc0\0\u6cfc\0\u6d38\0\u6d74\0\u6db0\0\u6dec"+ + "\0\u6e28\0\u6e64\0\u6ea0\0\u6edc\0\u6f18\0\u6f54\0\u6f90\0\u6fcc"+ + "\0\u7008\0\u7044\0\u7080\0\u70bc\0\u70f8\0\u7134\0\74\0\u7170"+ + "\0\u71ac\0\u71e8\0\u7224\0\u7260\0\u729c\0\u72d8\0\u7314\0\u7350"+ + "\0\u738c\0\u73c8\0\u7404\0\u7440\0\u747c\0\u74b8\0\u74f4\0\u7530"+ + "\0\u756c\0\u75a8\0\u75e4\0\u7620\0\u765c\0\u7698\0\u76d4\0\u7710"+ + "\0\u774c\0\u7440\0\u7440\0\u7788\0\u77c4\0\u7800\0\u783c\0\u7878"+ + "\0\u78b4\0\u78f0\0\u792c\0\u7968\0\u79a4\0\u79e0\0\u7a1c\0\u7a58"+ + "\0\u7a94\0\u7ad0\0\u7b0c\0\u7b48\0\u7b84\0\u7bc0\0\u7bfc\0\u7c38"+ + "\0\u7c74\0\u7cb0\0\u7cec\0\u7d28\0\u7d64\0\u7da0\0\u7ddc\0\u7e18"+ + "\0\u7e54\0\u7e90\0\u7ecc\0\u7f08\0\u7f44\0\u7f80\0\u7fbc\0\u7ff8"+ + "\0\u8034\0\u8070\0\u80ac\0\u80e8\0\u8124\0\u8160\0\u819c\0\u81d8"+ + "\0\u8214\0\u8250\0\u828c\0\u82c8\0\u8304\0\u8340\0\u837c\0\u83b8"+ + "\0\u83f4\0\u8430\0\u846c\0\u84a8\0\u84e4\0\u8520\0\u855c\0\u8598"+ + "\0\u85d4\0\u8610\0\u864c\0\u8688\0\u86c4\0\u8700\0\u873c\0\u8778"+ + "\0\u87b4\0\u87f0\0\u882c\0\u8868\0\u88a4\0\u88e0\0\u891c\0\u8958"+ + "\0\u8994\0\u89d0\0\u8a0c\0\u8a48\0\u8a84\0\u8ac0\0\u8afc\0\u8b38"+ + "\0\u8b74\0\74\0\u8bb0\0\u8bec\0\u8c28\0\u8c64\0\u8ca0\0\u8cdc"+ + "\0\u8d18\0\u8d54\0\u8d90\0\u8dcc\0\u5190\0\u8e08\0\u8e44\0\u8e80"+ + "\0\u8ebc\0\u8ef8\0\u8f34\0\u8f70\0\u8fac\0\u8fe8\0\u9024\0\u9060"+ + "\0\u909c\0\u90d8\0\u9114\0\74\0\u9150\0\u918c\0\u91c8\0\u9204"+ + "\0\u9240\0\u927c\0\u92b8\0\u92f4\0\u9330\0\u936c\0\u93a8\0\u93e4"+ + "\0\u9420\0\u945c\0\u9498\0\u94d4\0\u9510\0\u954c\0\u9588\0\u95c4"+ + "\0\u9600\0\u963c\0\u9678\0\u96b4\0\u96f0\0\u972c\0\u9768\0\u97a4"+ + "\0\u97e0\0\u981c\0\u9858\0\u9894"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[684]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\1\2\1\3\1\4\1\5\4\6\1\4\1\7\1\10"+ + "\1\11\1\12\3\2\1\13\1\14\1\4\4\3\1\4"+ + "\1\3\2\4\1\3\1\4\1\3\1\4\1\3\1\4"+ + "\1\3\10\4\1\2\2\4\1\15\2\4\1\2\1\16"+ + "\1\2\1\17\1\2\1\20\1\21\1\22\1\6\2\2"+ + "\76\0\1\3\1\23\1\24\4\0\1\23\1\25\7\0"+ + "\1\26\1\23\4\3\1\27\1\3\1\30\1\31\1\3"+ + "\1\32\1\3\1\33\1\3\1\34\1\3\1\35\2\23"+ + "\1\36\2\23\1\37\1\40\1\0\1\41\4\23\11\0"+ + "\1\42\3\0\2\4\1\43\4\0\2\4\4\0\1\44"+ + "\3\0\30\4\1\0\5\4\14\0\1\4\1\45\2\4"+ + "\2\0\1\4\1\0\1\45\11\4\1\45\1\46\7\45"+ + "\1\47\1\4\1\47\1\4\1\45\1\4\1\45\1\4"+ + "\1\45\11\4\1\15\16\4\4\0\4\6\60\0\1\6"+ + "\4\0\1\3\1\4\1\43\4\0\1\4\1\50\7\0"+ + "\1\26\1\4\4\3\1\4\1\3\2\4\1\3\1\4"+ + "\1\3\1\4\1\3\1\4\1\3\10\4\1\0\5\4"+ + "\14\0\3\10\1\51\2\0\1\10\1\0\2\10\1\52"+ + "\61\10\3\11\1\53\2\0\1\11\1\0\3\11\1\52"+ + "\60\11\15\0\1\54\57\0\1\3\17\0\1\26\1\0"+ + "\4\3\1\0\1\3\2\0\1\3\1\0\1\3\1\0"+ + "\1\3\1\0\1\3\33\0\1\55\21\0\4\55\1\0"+ + "\1\55\2\0\1\55\1\0\1\55\1\0\1\55\1\0"+ + "\1\55\33\0\2\4\1\56\4\0\2\4\4\0\1\44"+ + "\3\0\27\4\1\57\1\0\5\4\17\0\1\60\4\61"+ + "\4\0\1\62\23\0\1\63\27\0\1\61\67\0\1\64"+ + "\73\0\1\65\10\0\2\66\1\67\4\0\2\66\10\0"+ + "\30\66\1\0\5\66\17\0\1\70\23\0\1\71\10\0"+ + "\1\72\4\0\1\73\2\0\1\74\24\0\2\23\1\75"+ + "\4\0\2\23\10\0\30\23\1\0\5\23\14\0\1\23"+ + "\1\76\2\23\2\0\1\23\1\0\1\76\11\23\1\76"+ + "\1\77\1\100\1\76\1\100\4\76\1\101\1\32\1\101"+ + "\1\33\1\76\1\34\1\76\1\35\1\76\1\23\1\36"+ + "\2\23\1\37\1\40\1\23\1\41\20\23\2\0\1\23"+ + "\1\75\4\0\1\23\11\0\1\23\4\0\1\23\1\0"+ + "\2\23\1\0\1\23\1\0\1\23\1\0\1\23\1\0"+ + "\10\23\1\0\5\23\15\0\2\23\1\102\4\0\2\23"+ + "\10\0\23\23\1\103\4\23\1\0\5\23\15\0\2\23"+ + "\1\104\4\0\2\23\10\0\10\23\1\105\17\23\1\0"+ + "\5\23\15\0\2\23\1\106\4\0\2\23\10\0\23\23"+ + "\1\107\4\23\1\0\3\23\1\110\1\23\15\0\2\23"+ + "\1\111\4\0\2\23\10\0\27\23\1\40\1\0\5\23"+ + "\15\0\2\23\1\112\4\0\2\23\10\0\30\23\1\0"+ + "\4\23\1\113\15\0\2\23\1\114\4\0\2\23\10\0"+ + "\24\23\1\103\3\23\1\0\5\23\15\0\2\23\1\115"+ + "\4\0\2\23\10\0\14\23\1\33\13\23\1\0\5\23"+ + "\15\0\2\23\1\116\4\0\2\23\10\0\23\23\1\103"+ + "\4\23\1\0\1\41\4\23\15\0\2\23\1\117\4\0"+ + "\2\23\10\0\5\23\1\103\22\23\1\0\1\23\1\103"+ + "\1\23\1\103\1\23\15\0\2\23\1\120\4\0\2\23"+ + "\10\0\1\121\27\23\1\0\5\23\14\0\1\4\1\45"+ + "\2\4\2\0\1\4\1\0\1\45\11\4\12\45\1\4"+ + "\1\45\1\4\1\45\1\4\1\45\1\4\1\45\30\4"+ + "\1\0\1\122\1\4\1\43\1\123\3\4\1\122\1\4"+ + "\4\0\1\44\3\0\12\122\1\4\1\122\1\4\1\122"+ + "\1\4\1\122\1\4\1\122\6\4\1\0\5\4\10\0"+ + "\1\4\4\0\1\122\1\4\1\43\1\123\3\4\1\122"+ + "\1\4\4\0\1\44\3\0\1\122\1\124\7\122\1\125"+ + "\1\4\1\125\1\4\1\122\1\4\1\122\1\4\1\122"+ + "\6\4\1\0\5\4\10\0\1\4\4\0\1\122\1\4"+ + "\1\43\1\123\3\4\1\122\1\4\4\0\1\44\3\0"+ + "\11\122\1\126\1\4\1\122\1\4\1\122\1\4\1\122"+ + "\1\4\1\122\6\4\1\0\5\4\10\0\1\4\65\0"+ + "\1\127\11\0\1\10\1\130\2\10\1\131\3\10\1\130"+ + "\11\10\12\130\1\10\1\130\1\10\1\130\1\10\1\130"+ + "\1\10\1\130\30\10\1\11\1\132\2\11\1\133\3\11"+ + "\1\132\11\11\12\132\1\11\1\132\1\11\1\132\1\11"+ + "\1\132\1\11\1\132\30\11\15\54\1\134\56\54\1\0"+ + "\1\55\1\23\1\24\4\0\1\23\1\25\10\0\1\23"+ + "\4\55\1\27\1\55\1\30\1\31\1\55\1\32\1\55"+ + "\1\33\1\55\1\34\1\55\1\35\2\23\1\36\2\23"+ + "\1\37\1\40\1\0\1\41\4\23\11\0\1\42\2\0"+ + "\1\4\1\45\2\4\2\0\1\4\1\0\1\45\11\4"+ + "\1\45\1\135\7\45\1\136\1\4\1\136\1\4\1\45"+ + "\1\4\1\45\1\4\1\45\5\4\1\57\22\4\1\0"+ + "\2\4\1\137\4\0\2\4\4\0\1\44\3\0\22\4"+ + "\1\140\5\4\1\0\5\4\37\0\1\141\1\142\1\0"+ + "\1\142\11\0\1\63\50\0\1\143\61\0\1\144\41\0"+ + "\1\145\26\0\1\66\1\146\2\66\2\0\1\66\1\0"+ + "\1\146\11\66\12\146\1\66\1\146\1\66\1\146\1\66"+ + "\1\146\1\66\1\146\30\66\23\0\1\147\1\150\1\0"+ + "\1\150\4\0\1\151\1\0\1\151\2\0\1\72\4\0"+ + "\1\73\2\0\1\74\61\0\1\152\40\0\1\153\41\0"+ + "\1\154\31\0\1\155\26\0\1\156\44\0\1\157\16\0"+ + "\1\160\51\0\1\23\1\76\2\23\2\0\1\23\1\0"+ + "\1\76\11\23\12\76\1\23\1\76\1\23\1\76\1\23"+ + "\1\76\1\23\1\76\30\23\1\0\1\161\1\23\1\75"+ + "\1\162\3\23\1\161\1\23\10\0\12\161\1\23\1\161"+ + "\1\23\1\161\1\23\1\161\1\23\1\161\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\161\1\23\1\75\1\162"+ + "\3\23\1\161\1\23\10\0\1\161\1\163\1\164\1\161"+ + "\1\164\4\161\1\165\1\23\1\165\1\23\1\161\1\23"+ + "\1\161\1\23\1\161\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\161\1\23\1\75\1\162\3\23\1\161\1\23"+ + "\10\0\2\161\1\166\3\161\1\167\1\170\1\161\1\171"+ + "\1\23\1\172\1\23\1\173\1\23\1\174\1\23\1\175"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\176\1\23"+ + "\1\75\1\162\3\23\1\161\1\23\10\0\1\161\1\177"+ + "\4\161\1\200\3\161\1\23\1\161\1\23\1\161\1\23"+ + "\1\161\1\23\1\161\6\23\1\0\5\23\10\0\1\23"+ + "\3\0\1\23\1\76\2\23\2\0\1\23\1\0\1\76"+ + "\11\23\1\76\1\201\1\202\1\76\1\202\5\76\1\23"+ + "\1\76\1\23\1\76\1\23\1\76\1\23\1\76\1\23"+ + "\1\103\27\23\1\76\2\23\2\0\1\23\1\0\1\76"+ + "\11\23\1\76\1\203\1\204\1\76\1\204\5\76\1\23"+ + "\1\76\1\23\1\76\1\23\1\76\1\23\1\76\30\23"+ + "\1\0\2\23\1\205\4\0\2\23\10\0\12\23\1\206"+ + "\15\23\1\0\5\23\14\0\1\23\1\76\2\23\2\0"+ + "\1\23\1\0\1\76\11\23\1\76\1\207\1\210\1\76"+ + "\1\210\4\76\1\211\1\23\1\211\1\23\1\76\1\23"+ + "\1\76\1\23\1\76\1\23\1\107\10\23\1\110\16\23"+ + "\1\76\2\23\2\0\1\23\1\0\1\76\11\23\1\76"+ + "\1\212\7\76\1\213\1\23\1\213\1\23\1\76\1\23"+ + "\1\76\1\23\1\76\5\23\1\40\23\23\1\76\2\23"+ + "\2\0\1\23\1\0\1\76\11\23\1\76\1\214\7\76"+ + "\1\215\1\23\1\215\1\23\1\76\1\23\1\76\1\23"+ + "\1\76\13\23\1\113\15\23\1\76\2\23\2\0\1\23"+ + "\1\0\1\76\11\23\1\76\1\216\1\217\1\76\1\217"+ + "\5\76\1\23\1\76\1\23\1\76\1\23\1\76\1\23"+ + "\1\76\2\23\1\103\26\23\1\76\2\23\2\0\1\23"+ + "\1\0\1\76\11\23\1\76\1\220\1\221\1\76\1\221"+ + "\5\76\1\23\1\76\1\33\1\76\1\23\1\76\1\23"+ + "\1\76\31\23\1\76\2\23\2\0\1\23\1\0\1\76"+ + "\11\23\1\76\1\222\1\202\1\76\1\202\4\76\1\223"+ + "\1\23\1\223\1\23\1\76\1\23\1\76\1\23\1\76"+ + "\1\23\1\103\5\23\1\41\21\23\1\76\2\23\2\0"+ + "\1\23\1\0\1\76\11\23\1\76\1\224\1\225\1\76"+ + "\1\225\4\76\1\226\1\23\1\226\1\23\1\76\1\23"+ + "\1\76\1\23\1\76\10\23\1\103\1\23\1\103\16\23"+ + "\1\76\2\23\2\0\1\23\1\0\1\76\11\23\1\76"+ + "\1\227\1\230\1\76\1\230\5\76\1\23\1\76\1\23"+ + "\1\76\1\23\1\76\1\23\1\76\30\23\1\0\2\23"+ + "\1\231\4\0\2\23\10\0\7\23\1\206\20\23\1\0"+ + "\5\23\15\0\1\232\1\4\1\43\1\123\3\4\1\232"+ + "\1\4\4\0\1\44\3\0\12\232\1\4\1\232\1\4"+ + "\1\232\1\4\1\232\1\4\1\232\6\4\1\0\5\4"+ + "\10\0\1\4\4\0\2\4\1\43\1\0\1\4\2\0"+ + "\2\4\4\0\1\44\3\0\30\4\1\0\5\4\15\0"+ + "\1\232\1\4\1\43\1\123\3\4\1\232\1\4\4\0"+ + "\1\44\3\0\1\232\1\233\7\232\1\234\1\4\1\234"+ + "\1\4\1\232\1\4\1\232\1\4\1\232\6\4\1\0"+ + "\5\4\10\0\1\4\4\0\1\232\1\4\1\43\1\123"+ + "\3\4\1\232\1\4\4\0\1\44\3\0\11\232\1\235"+ + "\1\4\1\232\1\4\1\232\1\4\1\232\1\4\1\232"+ + "\6\4\1\0\5\4\10\0\1\4\4\0\1\232\1\4"+ + "\1\56\1\236\3\15\1\232\1\4\4\0\1\44\3\0"+ + "\12\232\1\4\1\232\1\4\1\232\1\4\1\232\1\4"+ + "\1\232\5\4\1\57\1\0\5\4\10\0\1\15\3\0"+ + "\1\10\1\237\1\10\1\51\1\131\3\10\1\237\1\10"+ + "\1\52\7\10\12\237\1\10\1\237\1\10\1\237\1\10"+ + "\1\237\1\10\1\237\33\10\1\51\1\0\2\10\1\0"+ + "\2\10\1\52\61\10\1\11\1\240\1\11\1\53\1\133"+ + "\3\11\1\240\2\11\1\52\6\11\12\240\1\11\1\240"+ + "\1\11\1\240\1\11\1\240\1\11\1\240\33\11\1\53"+ + "\1\0\2\11\1\0\3\11\1\52\60\11\14\54\1\241"+ + "\1\134\56\54\1\0\1\122\1\4\1\43\1\123\3\4"+ + "\1\122\1\4\4\0\1\44\3\0\1\122\1\242\7\122"+ + "\1\243\1\4\1\243\1\4\1\122\1\4\1\122\1\4"+ + "\1\122\6\4\1\0\5\4\10\0\1\4\4\0\1\244"+ + "\1\4\1\43\1\123\3\4\1\122\1\4\4\0\1\44"+ + "\3\0\12\122\1\4\1\122\1\4\1\122\1\4\1\122"+ + "\1\4\1\122\6\4\1\0\5\4\10\0\1\4\3\0"+ + "\1\4\1\45\2\4\2\0\1\4\1\0\1\45\11\4"+ + "\1\45\1\245\1\246\1\45\1\246\5\45\1\4\1\45"+ + "\1\4\1\45\1\4\1\45\1\4\1\45\1\140\27\4"+ + "\1\0\2\4\1\43\4\0\2\4\4\0\1\247\3\0"+ + "\30\4\1\0\5\4\37\0\1\250\1\142\1\0\1\142"+ + "\106\0\1\251\32\0\15\143\1\252\56\143\23\0\1\253"+ + "\1\254\1\0\1\254\16\0\1\145\31\0\1\255\44\0"+ + "\1\256\24\0\1\257\1\66\1\67\1\260\3\66\1\257"+ + "\1\66\10\0\12\257\1\66\1\257\1\66\1\257\1\66"+ + "\1\257\1\66\1\257\6\66\1\0\5\66\10\0\1\66"+ + "\26\0\1\261\1\150\1\0\1\150\4\0\1\151\1\0"+ + "\1\151\67\0\1\262\7\0\1\263\55\0\1\264\72\0"+ + "\1\265\74\0\1\266\1\267\1\0\1\267\16\0\1\154"+ + "\31\0\1\270\44\0\1\271\46\0\1\272\1\273\1\0"+ + "\1\273\50\0\1\274\25\0\1\275\65\0\1\276\1\277"+ + "\1\0\1\277\50\0\1\300\30\0\1\301\40\0\1\302"+ + "\1\23\1\75\1\162\3\23\1\302\1\23\10\0\12\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\1\23\1\302"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\2\23\1\75"+ + "\1\0\1\23\2\0\2\23\10\0\30\23\1\0\5\23"+ + "\15\0\1\302\1\23\1\75\1\162\3\23\1\302\1\23"+ + "\10\0\1\302\1\303\1\304\1\302\1\304\4\302\1\305"+ + "\1\23\1\305\1\23\1\302\1\23\1\302\1\23\1\302"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\302\1\23"+ + "\1\75\1\162\3\23\1\302\1\23\10\0\2\302\1\306"+ + "\3\302\1\307\1\310\1\302\1\311\1\23\1\312\1\23"+ + "\1\313\1\23\1\314\1\23\1\315\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\316\1\23\1\75\1\162\3\23"+ + "\1\302\1\23\10\0\1\302\1\317\4\302\1\320\3\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\1\23\1\302"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\302\1\23"+ + "\1\104\1\321\3\30\1\302\1\23\10\0\10\302\1\322"+ + "\1\302\1\23\1\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\6\23\1\0\5\23\10\0\1\30\4\0\1\302"+ + "\1\23\1\102\1\323\3\27\1\302\1\23\10\0\12\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\1\23\1\302"+ + "\1\23\1\103\4\23\1\0\5\23\10\0\1\27\4\0"+ + "\1\302\1\23\1\116\1\324\3\36\1\302\1\23\10\0"+ + "\12\302\1\23\1\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\1\23\1\103\4\23\1\0\1\41\4\23\10\0"+ + "\1\36\4\0\1\302\1\23\1\106\1\325\3\31\1\302"+ + "\1\23\10\0\12\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\1\23\1\302\1\23\1\107\4\23\1\0\3\23"+ + "\1\110\1\23\10\0\1\31\4\0\1\302\1\23\1\111"+ + "\1\326\3\32\1\302\1\23\10\0\12\302\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\5\23\1\40"+ + "\1\0\5\23\10\0\1\32\4\0\1\302\1\23\1\112"+ + "\1\327\3\33\1\302\1\23\10\0\12\302\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\6\23\1\0"+ + "\4\23\1\113\10\0\1\33\4\0\1\302\1\23\1\114"+ + "\1\330\3\34\1\302\1\23\10\0\12\302\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\2\23\1\103"+ + "\3\23\1\0\5\23\10\0\1\34\4\0\1\302\1\23"+ + "\1\115\1\331\3\35\1\302\1\23\10\0\12\302\1\23"+ + "\1\302\1\33\1\302\1\23\1\302\1\23\1\302\6\23"+ + "\1\0\5\23\10\0\1\35\4\0\1\302\1\23\1\120"+ + "\1\332\3\40\1\302\1\23\10\0\1\333\11\302\1\23"+ + "\1\302\1\23\1\302\1\23\1\302\1\23\1\302\6\23"+ + "\1\0\5\23\10\0\1\40\4\0\1\302\1\23\1\117"+ + "\1\334\3\37\1\302\1\23\10\0\5\302\1\335\4\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\1\23\1\302"+ + "\6\23\1\0\1\23\1\103\1\23\1\103\1\23\10\0"+ + "\1\37\4\0\1\302\1\23\1\75\1\336\3\41\1\302"+ + "\1\23\10\0\12\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\1\23\1\302\6\23\1\0\5\23\10\0\1\41"+ + "\4\0\1\161\1\23\1\75\1\162\3\23\1\161\1\23"+ + "\10\0\1\161\1\337\1\340\1\161\1\340\5\161\1\23"+ + "\1\161\1\23\1\161\1\23\1\161\1\23\1\161\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\161\1\23\1\75"+ + "\1\162\3\23\1\161\1\23\10\0\7\161\1\341\2\161"+ + "\1\23\1\161\1\23\1\161\1\23\1\161\1\23\1\161"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\161\1\23"+ + "\1\75\1\162\3\23\1\161\1\23\10\0\1\161\1\342"+ + "\1\343\1\161\1\343\5\161\1\23\1\161\1\23\1\161"+ + "\1\23\1\161\1\23\1\161\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\161\1\23\1\75\1\162\3\23\1\161"+ + "\1\23\10\0\11\161\1\344\1\23\1\161\1\23\1\161"+ + "\1\23\1\161\1\23\1\161\6\23\1\0\5\23\10\0"+ + "\1\23\3\0\1\23\1\76\2\23\2\0\1\23\1\0"+ + "\1\76\11\23\1\76\1\345\1\346\1\76\1\346\5\76"+ + "\1\206\1\76\1\23\1\76\1\23\1\76\1\23\1\76"+ + "\30\23\1\0\1\161\1\23\1\75\1\162\3\23\1\161"+ + "\1\23\10\0\1\161\1\347\1\350\1\161\1\350\4\161"+ + "\1\351\1\23\1\351\1\23\1\161\1\23\1\161\1\23"+ + "\1\161\6\23\1\0\5\23\10\0\1\23\4\0\1\161"+ + "\1\23\1\75\1\162\3\23\1\161\1\23\10\0\7\161"+ + "\1\352\2\161\1\23\1\161\1\23\1\161\1\23\1\161"+ + "\1\23\1\161\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\161\1\23\1\75\1\162\3\23\1\161\1\23\10\0"+ + "\12\161\1\23\1\161\1\23\1\353\1\23\1\161\1\23"+ + "\1\161\6\23\1\0\5\23\10\0\1\23\4\0\1\161"+ + "\1\23\1\75\1\162\3\23\1\161\1\23\10\0\1\161"+ + "\1\354\7\161\1\355\1\23\1\355\1\23\1\161\1\23"+ + "\1\161\1\23\1\161\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\176\1\23\1\75\1\162\3\23\1\161\1\23"+ + "\10\0\12\161\1\23\1\161\1\23\1\161\1\23\1\161"+ + "\1\23\1\161\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\161\1\23\1\75\1\162\3\23\1\161\1\23\10\0"+ + "\1\161\1\356\7\161\1\357\1\23\1\357\1\23\1\161"+ + "\1\23\1\161\1\23\1\161\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\161\1\23\1\75\1\162\3\23\1\161"+ + "\1\23\10\0\1\360\11\161\1\23\1\161\1\23\1\161"+ + "\1\23\1\161\1\23\1\161\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\161\1\23\1\75\1\162\3\23\1\161"+ + "\1\23\10\0\1\161\1\361\1\362\1\161\1\362\5\161"+ + "\1\23\1\161\1\23\1\161\1\23\1\161\1\23\1\161"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\161\1\23"+ + "\1\75\1\162\3\23\1\161\1\23\10\0\10\161\1\341"+ + "\1\161\1\23\1\161\1\23\1\161\1\23\1\161\1\23"+ + "\1\161\6\23\1\0\5\23\10\0\1\23\4\0\1\161"+ + "\1\23\1\75\1\162\3\23\1\161\1\23\10\0\1\161"+ + "\1\363\1\364\1\161\1\364\5\161\1\23\1\161\1\23"+ + "\1\161\1\23\1\161\1\23\1\161\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\161\1\23\1\75\1\162\3\23"+ + "\1\161\1\23\10\0\12\161\1\23\1\161\1\23\1\173"+ + "\1\23\1\161\1\23\1\161\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\161\1\23\1\75\1\162\3\23\1\161"+ + "\1\23\10\0\1\161\1\365\1\340\1\161\1\340\4\161"+ + "\1\366\1\23\1\366\1\23\1\161\1\23\1\161\1\23"+ + "\1\161\6\23\1\0\5\23\10\0\1\23\4\0\1\161"+ + "\1\23\1\75\1\162\3\23\1\161\1\23\10\0\6\161"+ + "\1\200\3\161\1\23\1\161\1\23\1\161\1\23\1\161"+ + "\1\23\1\161\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\161\1\23\1\75\1\162\3\23\1\161\1\23\10\0"+ + "\1\161\1\367\1\370\1\161\1\370\4\161\1\371\1\23"+ + "\1\371\1\23\1\161\1\23\1\161\1\23\1\161\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\161\1\23\1\75"+ + "\1\162\3\23\1\161\1\23\10\0\6\161\1\341\3\161"+ + "\1\23\1\161\1\23\1\161\1\23\1\161\1\23\1\161"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\161\1\23"+ + "\1\75\1\162\3\23\1\161\1\23\10\0\2\161\1\341"+ + "\7\161\1\23\1\161\1\23\1\341\1\23\1\161\1\23"+ + "\1\161\6\23\1\0\5\23\10\0\1\23\4\0\1\161"+ + "\1\23\1\75\1\162\3\23\1\161\1\23\10\0\1\161"+ + "\1\372\1\373\1\161\1\373\5\161\1\23\1\161\1\23"+ + "\1\161\1\23\1\161\1\23\1\161\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\161\1\23\1\75\1\162\3\23"+ + "\1\161\1\23\10\0\3\161\1\374\6\161\1\23\1\161"+ + "\1\23\1\161\1\23\1\161\1\23\1\161\6\23\1\0"+ + "\5\23\10\0\1\23\3\0\1\23\1\76\2\23\2\0"+ + "\1\23\1\0\1\76\11\23\1\76\1\375\1\376\1\76"+ + "\1\376\5\76\1\23\1\76\1\23\1\76\1\23\1\76"+ + "\1\23\1\76\30\23\1\0\1\377\1\4\1\43\1\123"+ + "\3\4\1\377\1\4\4\0\1\44\3\0\12\377\1\4"+ + "\1\377\1\4\1\377\1\4\1\377\1\4\1\377\6\4"+ + "\1\0\5\4\10\0\1\4\4\0\1\377\1\4\1\43"+ + "\1\123\3\4\1\377\1\4\4\0\1\44\3\0\1\377"+ + "\1\u0100\7\377\1\u0101\1\4\1\u0101\1\4\1\377\1\4"+ + "\1\377\1\4\1\377\6\4\1\0\5\4\10\0\1\4"+ + "\4\0\1\377\1\4\1\43\1\123\3\4\1\377\1\4"+ + "\4\0\1\44\3\0\11\377\1\u0102\1\4\1\377\1\4"+ + "\1\377\1\4\1\377\1\4\1\377\6\4\1\0\5\4"+ + "\10\0\1\4\4\0\1\377\1\4\1\56\1\236\3\15"+ + "\1\377\1\4\4\0\1\44\3\0\12\377\1\4\1\377"+ + "\1\4\1\377\1\4\1\377\1\4\1\377\5\4\1\57"+ + "\1\0\5\4\10\0\1\15\4\0\2\4\1\56\1\0"+ + "\1\15\2\0\2\4\4\0\1\44\3\0\27\4\1\57"+ + "\1\0\5\4\14\0\1\10\1\u0103\1\10\1\51\1\131"+ + "\3\10\1\u0103\1\10\1\52\7\10\12\u0103\1\10\1\u0103"+ + "\1\10\1\u0103\1\10\1\u0103\1\10\1\u0103\30\10\1\11"+ + "\1\u0104\1\11\1\53\1\133\3\11\1\u0104\2\11\1\52"+ + "\6\11\12\u0104\1\11\1\u0104\1\11\1\u0104\1\11\1\u0104"+ + "\1\11\1\u0104\30\11\14\0\1\u0105\60\0\1\232\1\4"+ + "\1\43\1\123\3\4\1\232\1\4\4\0\1\44\3\0"+ + "\1\232\1\u0106\7\232\1\u0107\1\4\1\u0107\1\4\1\232"+ + "\1\4\1\232\1\4\1\232\6\4\1\0\5\4\10\0"+ + "\1\4\4\0\1\u0108\1\4\1\43\1\123\3\4\1\232"+ + "\1\4\4\0\1\44\3\0\12\232\1\4\1\232\1\4"+ + "\1\232\1\4\1\232\1\4\1\232\6\4\1\0\5\4"+ + "\10\0\1\4\4\0\1\232\1\4\1\137\1\u0109\3\57"+ + "\1\232\1\4\4\0\1\44\3\0\12\232\1\4\1\232"+ + "\1\4\1\232\1\4\1\232\1\4\1\232\1\140\5\4"+ + "\1\0\5\4\10\0\1\57\4\0\1\122\1\4\1\43"+ + "\1\123\3\4\1\122\1\4\4\0\1\44\3\0\1\122"+ + "\1\u010a\1\u010b\1\122\1\u010b\5\122\1\4\1\122\1\4"+ + "\1\122\1\4\1\122\1\4\1\122\6\4\1\0\5\4"+ + "\10\0\1\4\4\0\1\122\1\4\1\43\1\123\3\4"+ + "\1\122\1\4\4\0\1\44\3\0\5\122\1\u010c\4\122"+ + "\1\4\1\122\1\4\1\122\1\4\1\122\1\4\1\122"+ + "\6\4\1\0\5\4\10\0\1\4\4\0\2\u010d\1\u010e"+ + "\4\247\2\u010d\1\u010f\1\u0110\2\u010d\1\0\33\u010d\1\0"+ + "\15\u010d\1\247\1\u010d\1\u0111\24\0\1\u0112\1\142\1\0"+ + "\1\142\50\0\1\144\1\u0113\3\63\35\0\1\145\22\0"+ + "\1\63\3\0\14\143\1\61\1\252\56\143\23\0\1\u0114"+ + "\1\254\1\0\1\254\76\0\1\u0115\65\0\1\u0116\7\0"+ + "\1\u0117\1\0\1\u0117\12\0\1\256\26\0\1\u0118\43\0"+ + "\1\u0119\25\0\1\u011a\1\66\1\67\1\260\3\66\1\u011a"+ + "\1\66\10\0\12\u011a\1\66\1\u011a\1\66\1\u011a\1\66"+ + "\1\u011a\1\66\1\u011a\6\66\1\0\5\66\10\0\1\66"+ + "\4\0\2\66\1\67\1\0\1\66\2\0\2\66\10\0"+ + "\30\66\1\0\5\66\37\0\1\u011b\1\150\1\0\1\150"+ + "\4\0\1\151\1\0\1\151\41\0\1\155\1\u011c\3\73"+ + "\22\0\1\156\35\0\1\73\6\0\1\153\1\u011d\3\72"+ + "\35\0\1\154\22\0\1\72\6\0\1\157\1\u011e\3\74"+ + "\12\0\1\160\45\0\1\74\54\0\1\u011f\45\0\1\u0120"+ + "\1\267\1\0\1\267\76\0\1\u0121\65\0\1\u0122\7\0"+ + "\1\u0123\1\0\1\u0123\12\0\1\271\26\0\1\u0124\43\0"+ + "\1\u0125\47\0\1\u0126\1\273\1\0\1\273\100\0\1\u0127"+ + "\63\0\1\u0128\1\u0129\1\0\1\u0129\50\0\1\u012a\34\0"+ + "\1\u012b\56\0\1\u012c\1\277\1\0\1\277\72\0\1\u012d"+ + "\71\0\1\u012e\1\u012f\1\0\1\u012f\5\0\1\301\42\0"+ + "\1\u0130\26\0\1\u0131\42\0\1\u0132\1\23\1\75\1\162"+ + "\3\23\1\u0132\1\23\10\0\12\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\u0132\1\23\1\75\1\162\3\23"+ + "\1\u0132\1\23\10\0\1\u0132\1\u0133\1\u0134\1\u0132\1\u0134"+ + "\4\u0132\1\u0135\1\23\1\u0135\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\u0132\1\23\1\75\1\162\3\23\1\u0132\1\23\10\0"+ + "\2\u0132\1\u0136\3\u0132\1\u0137\1\u0138\1\u0132\1\u0139\1\23"+ + "\1\u013a\1\23\1\u013b\1\23\1\u013c\1\23\1\u013d\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u013e\1\23\1\75"+ + "\1\162\3\23\1\u0132\1\23\10\0\1\u0132\1\u013f\4\u0132"+ + "\1\u0140\3\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\u0132\1\23\1\104\1\321\3\30\1\u0132\1\23\10\0"+ + "\10\u0132\1\u0141\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0\1\30"+ + "\4\0\1\u0132\1\23\1\102\1\323\3\27\1\u0132\1\23"+ + "\10\0\12\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\1\23\1\103\4\23\1\0\5\23\10\0"+ + "\1\27\4\0\1\u0132\1\23\1\116\1\324\3\36\1\u0132"+ + "\1\23\10\0\12\u0132\1\23\1\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\1\23\1\103\4\23\1\0\1\41"+ + "\4\23\10\0\1\36\4\0\1\u0132\1\23\1\106\1\325"+ + "\3\31\1\u0132\1\23\10\0\12\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\107\4\23"+ + "\1\0\3\23\1\110\1\23\10\0\1\31\4\0\1\u0132"+ + "\1\23\1\111\1\326\3\32\1\u0132\1\23\10\0\12\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\5\23\1\40\1\0\5\23\10\0\1\32\4\0\1\u0132"+ + "\1\23\1\112\1\327\3\33\1\u0132\1\23\10\0\12\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\6\23\1\0\4\23\1\113\10\0\1\33\4\0\1\u0132"+ + "\1\23\1\114\1\330\3\34\1\u0132\1\23\10\0\12\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\2\23\1\103\3\23\1\0\5\23\10\0\1\34\4\0"+ + "\1\u0132\1\23\1\115\1\331\3\35\1\u0132\1\23\10\0"+ + "\12\u0132\1\23\1\u0132\1\33\1\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\6\23\1\0\5\23\10\0\1\35\4\0\1\u0132"+ + "\1\23\1\120\1\332\3\40\1\u0132\1\23\10\0\1\u0142"+ + "\11\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\6\23\1\0\5\23\10\0\1\40\4\0\1\u0132"+ + "\1\23\1\117\1\334\3\37\1\u0132\1\23\10\0\5\u0132"+ + "\1\u0143\4\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\6\23\1\0\1\23\1\103\1\23\1\103"+ + "\1\23\10\0\1\37\4\0\1\u0132\1\23\1\75\1\336"+ + "\3\41\1\u0132\1\23\10\0\12\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23"+ + "\10\0\1\41\4\0\2\23\1\104\1\0\1\30\2\0"+ + "\2\23\10\0\10\23\1\105\17\23\1\0\5\23\15\0"+ + "\1\u0132\1\23\1\205\1\162\3\23\1\u0132\1\23\10\0"+ + "\12\u0132\1\206\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\6\23\1\0\5\23\10\0\1\23\4\0\2\23"+ + "\1\102\1\0\1\27\2\0\2\23\10\0\23\23\1\103"+ + "\4\23\1\0\5\23\15\0\2\23\1\116\1\0\1\36"+ + "\2\0\2\23\10\0\23\23\1\103\4\23\1\0\1\41"+ + "\4\23\15\0\2\23\1\106\1\0\1\31\2\0\2\23"+ + "\10\0\23\23\1\107\4\23\1\0\3\23\1\110\1\23"+ + "\15\0\2\23\1\111\1\0\1\32\2\0\2\23\10\0"+ + "\27\23\1\40\1\0\5\23\15\0\2\23\1\112\1\0"+ + "\1\33\2\0\2\23\10\0\30\23\1\0\4\23\1\113"+ + "\15\0\2\23\1\114\1\0\1\34\2\0\2\23\10\0"+ + "\24\23\1\103\3\23\1\0\5\23\15\0\2\23\1\115"+ + "\1\0\1\35\2\0\2\23\10\0\14\23\1\33\13\23"+ + "\1\0\5\23\15\0\2\23\1\120\1\0\1\40\2\0"+ + "\2\23\10\0\1\121\27\23\1\0\5\23\15\0\1\u0132"+ + "\1\23\1\231\1\162\3\23\1\u0132\1\23\10\0\7\u0132"+ + "\1\u0144\2\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\2\23\1\117\1\0\1\37\2\0\2\23\10\0\5\23"+ + "\1\103\22\23\1\0\1\23\1\103\1\23\1\103\1\23"+ + "\15\0\2\23\1\75\1\0\1\41\2\0\2\23\10\0"+ + "\30\23\1\0\5\23\15\0\1\302\1\23\1\75\1\162"+ + "\3\23\1\302\1\23\10\0\1\302\1\u0145\1\u0146\1\302"+ + "\1\u0146\5\302\1\23\1\302\1\23\1\302\1\23\1\302"+ + "\1\23\1\302\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\302\1\23\1\75\1\162\3\23\1\302\1\23\10\0"+ + "\7\302\1\u0147\2\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\1\23\1\302\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\302\1\23\1\75\1\u0148\3\103\1\302\1\23"+ + "\10\0\12\302\1\23\1\302\1\23\1\302\1\23\1\302"+ + "\1\23\1\302\6\23\1\0\5\23\10\0\1\103\4\0"+ + "\1\302\1\23\1\75\1\162\3\23\1\302\1\23\10\0"+ + "\1\302\1\u0149\1\u014a\1\302\1\u014a\5\302\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\302\1\23\1\75\1\162"+ + "\3\23\1\302\1\23\10\0\11\302\1\u014b\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\302\1\23\1\205\1\u014c"+ + "\3\105\1\302\1\23\10\0\12\302\1\206\1\302\1\23"+ + "\1\302\1\23\1\302\1\23\1\302\6\23\1\0\5\23"+ + "\10\0\1\105\4\0\1\161\1\23\1\75\1\162\3\23"+ + "\1\161\1\23\10\0\1\161\1\u014d\1\u014e\1\161\1\u014e"+ + "\5\161\1\23\1\161\1\23\1\161\1\23\1\161\1\23"+ + "\1\161\6\23\1\0\5\23\10\0\1\23\4\0\1\161"+ + "\1\23\1\75\1\162\3\23\1\161\1\23\10\0\12\161"+ + "\1\23\1\u014f\1\23\1\161\1\23\1\161\1\23\1\161"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\302\1\23"+ + "\1\75\1\162\3\23\1\302\1\23\10\0\1\302\1\u0150"+ + "\1\u0151\1\302\1\u0151\4\302\1\u0152\1\23\1\u0152\1\23"+ + "\1\302\1\23\1\302\1\23\1\302\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\302\1\23\1\75\1\162\3\23"+ + "\1\302\1\23\10\0\7\302\1\u0153\2\302\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\302\1\23\1\75\1\162"+ + "\3\23\1\302\1\23\10\0\12\302\1\23\1\302\1\23"+ + "\1\u0154\1\23\1\302\1\23\1\302\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\302\1\23\1\75\1\u0155\3\107"+ + "\1\302\1\23\10\0\12\302\1\23\1\302\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\6\23\1\0\5\23\10\0"+ + "\1\107\4\0\1\302\1\23\1\75\1\u0156\3\110\1\302"+ + "\1\23\10\0\12\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\1\23\1\302\6\23\1\0\5\23\10\0\1\110"+ + "\4\0\1\302\1\23\1\75\1\162\3\23\1\302\1\23"+ + "\10\0\1\302\1\u0157\7\302\1\u0158\1\23\1\u0158\1\23"+ + "\1\302\1\23\1\302\1\23\1\302\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\316\1\23\1\75\1\162\3\23"+ + "\1\302\1\23\10\0\12\302\1\23\1\302\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\302\1\23\1\75\1\162\3\23\1\302"+ + "\1\23\10\0\1\302\1\u0159\7\302\1\u015a\1\23\1\u015a"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\302\1\23\1\75\1\162"+ + "\3\23\1\302\1\23\10\0\1\u015b\11\302\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\302\1\23\1\75\1\u015c"+ + "\3\113\1\302\1\23\10\0\12\302\1\23\1\302\1\23"+ + "\1\302\1\23\1\302\1\23\1\302\6\23\1\0\5\23"+ + "\10\0\1\113\4\0\1\302\1\23\1\75\1\162\3\23"+ + "\1\302\1\23\10\0\1\302\1\u015d\1\u015e\1\302\1\u015e"+ + "\5\302\1\23\1\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\6\23\1\0\5\23\10\0\1\23\4\0\1\302"+ + "\1\23\1\75\1\162\3\23\1\302\1\23\10\0\10\302"+ + "\1\u0147\1\302\1\23\1\302\1\23\1\302\1\23\1\302"+ + "\1\23\1\302\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\302\1\23\1\75\1\162\3\23\1\302\1\23\10\0"+ + "\1\302\1\u015f\1\u0160\1\302\1\u0160\5\302\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\302\1\23\1\75\1\162"+ + "\3\23\1\302\1\23\10\0\12\302\1\23\1\302\1\23"+ + "\1\313\1\23\1\302\1\23\1\302\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\302\1\23\1\75\1\162\3\23"+ + "\1\302\1\23\10\0\1\302\1\u0161\1\u0146\1\302\1\u0146"+ + "\4\302\1\u0162\1\23\1\u0162\1\23\1\302\1\23\1\302"+ + "\1\23\1\302\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\302\1\23\1\75\1\162\3\23\1\302\1\23\10\0"+ + "\6\302\1\320\3\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\1\23\1\302\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\302\1\23\1\75\1\162\3\23\1\302\1\23"+ + "\10\0\1\302\1\u0163\1\u0164\1\302\1\u0164\4\302\1\u0165"+ + "\1\23\1\u0165\1\23\1\302\1\23\1\302\1\23\1\302"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\302\1\23"+ + "\1\75\1\162\3\23\1\302\1\23\10\0\6\302\1\u0147"+ + "\3\302\1\23\1\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\6\23\1\0\5\23\10\0\1\23\4\0\1\302"+ + "\1\23\1\75\1\162\3\23\1\302\1\23\10\0\2\302"+ + "\1\u0147\7\302\1\23\1\302\1\23\1\u0147\1\23\1\302"+ + "\1\23\1\302\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\302\1\23\1\75\1\162\3\23\1\302\1\23\10\0"+ + "\1\302\1\u0166\1\u0167\1\302\1\u0167\5\302\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\302\1\23\1\75\1\162"+ + "\3\23\1\302\1\23\10\0\3\302\1\u0168\6\302\1\23"+ + "\1\302\1\23\1\302\1\23\1\302\1\23\1\302\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\302\1\23\1\231"+ + "\1\u0169\3\121\1\302\1\23\10\0\7\302\1\u016a\2\302"+ + "\1\23\1\302\1\23\1\302\1\23\1\302\1\23\1\302"+ + "\6\23\1\0\5\23\10\0\1\121\4\0\1\161\1\23"+ + "\1\75\1\162\3\23\1\161\1\23\10\0\1\161\1\u016b"+ + "\1\u016c\1\161\1\u016c\5\161\1\23\1\161\1\23\1\161"+ + "\1\23\1\161\1\23\1\161\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\161\1\23\1\75\1\162\3\23\1\161"+ + "\1\23\10\0\2\161\1\u014f\7\161\1\23\1\161\1\23"+ + "\1\161\1\23\1\161\1\23\1\161\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\u016d\1\4\1\43\1\123\3\4"+ + "\1\u016d\1\4\4\0\1\44\3\0\12\u016d\1\4\1\u016d"+ + "\1\4\1\u016d\1\4\1\u016d\1\4\1\u016d\6\4\1\0"+ + "\5\4\10\0\1\4\4\0\1\u016d\1\4\1\43\1\123"+ + "\3\4\1\u016d\1\4\4\0\1\44\3\0\11\u016d\1\u016e"+ + "\1\4\1\u016e\1\4\1\u016d\1\4\1\u016d\1\4\1\u016d"+ + "\6\4\1\0\5\4\10\0\1\4\4\0\1\u016d\1\4"+ + "\1\43\1\123\3\4\1\u016d\1\4\4\0\1\44\3\0"+ + "\11\u016d\1\u016f\1\4\1\u016d\1\4\1\u016d\1\4\1\u016d"+ + "\1\4\1\u016d\6\4\1\0\5\4\10\0\1\4\4\0"+ + "\1\u016d\1\4\1\56\1\236\3\15\1\u016d\1\4\4\0"+ + "\1\44\3\0\12\u016d\1\4\1\u016d\1\4\1\u016d\1\4"+ + "\1\u016d\1\4\1\u016d\5\4\1\57\1\0\5\4\10\0"+ + "\1\15\3\0\1\10\1\u0170\1\10\1\51\1\131\3\10"+ + "\1\u0170\1\10\1\52\7\10\12\u0170\1\10\1\u0170\1\10"+ + "\1\u0170\1\10\1\u0170\1\10\1\u0170\30\10\1\11\1\u0171"+ + "\1\11\1\53\1\133\3\11\1\u0171\2\11\1\52\6\11"+ + "\12\u0171\1\11\1\u0171\1\11\1\u0171\1\11\1\u0171\1\11"+ + "\1\u0171\30\11\15\0\1\u0172\57\0\1\377\1\4\1\43"+ + "\1\123\3\4\1\377\1\4\4\0\1\44\3\0\1\377"+ + "\1\u0173\7\377\1\u0174\1\4\1\u0174\1\4\1\377\1\4"+ + "\1\377\1\4\1\377\6\4\1\0\5\4\10\0\1\4"+ + "\4\0\1\u0175\1\4\1\43\1\123\3\4\1\377\1\4"+ + "\4\0\1\44\3\0\12\377\1\4\1\377\1\4\1\377"+ + "\1\4\1\377\1\4\1\377\6\4\1\0\5\4\10\0"+ + "\1\4\4\0\1\377\1\4\1\137\1\u0109\3\57\1\377"+ + "\1\4\4\0\1\44\3\0\12\377\1\4\1\377\1\4"+ + "\1\377\1\4\1\377\1\4\1\377\1\140\5\4\1\0"+ + "\5\4\10\0\1\57\4\0\2\4\1\137\1\0\1\57"+ + "\2\0\2\4\4\0\1\44\3\0\22\4\1\140\5\4"+ + "\1\0\5\4\15\0\1\232\1\4\1\43\1\123\3\4"+ + "\1\232\1\4\4\0\1\44\3\0\1\232\1\u0176\1\u0177"+ + "\1\232\1\u0177\5\232\1\4\1\232\1\4\1\232\1\4"+ + "\1\232\1\4\1\232\6\4\1\0\5\4\10\0\1\4"+ + "\4\0\1\232\1\4\1\43\1\123\3\4\1\232\1\4"+ + "\4\0\1\44\3\0\5\232\1\u0178\4\232\1\4\1\232"+ + "\1\4\1\232\1\4\1\232\1\4\1\232\6\4\1\0"+ + "\5\4\10\0\1\4\4\0\1\232\1\4\1\43\1\u0179"+ + "\3\140\1\232\1\4\4\0\1\247\3\0\12\232\1\4"+ + "\1\232\1\4\1\232\1\4\1\232\1\4\1\232\6\4"+ + "\1\0\5\4\10\0\1\140\4\0\2\u010d\1\u010e\4\u017a"+ + "\2\u010d\2\0\2\u010d\1\0\33\u010d\1\0\15\u010d\1\u017a"+ + "\1\u010d\1\u0111\1\0\1\u010d\1\u017b\1\u010d\1\u017c\2\u017d"+ + "\1\u010d\1\u017d\1\u017b\11\u010d\12\u017b\1\u010d\1\u017b\1\u010d"+ + "\1\u017b\1\u010d\1\u017b\1\u010d\1\u017b\26\u010d\1\u017e\1\u010d"+ + "\3\u010f\1\u017f\2\0\1\u010f\1\0\2\u010f\1\u017a\61\u010f"+ + "\3\u0110\1\u0180\2\0\1\u0110\1\0\3\u0110\1\u017a\60\u0110"+ + "\23\0\1\u0181\1\142\1\0\1\142\50\0\1\144\1\0"+ + "\1\63\37\0\1\145\51\0\1\u0182\1\254\1\0\1\254"+ + "\50\0\1\255\1\u0183\3\145\40\0\1\256\17\0\1\145"+ + "\26\0\1\u0184\7\0\1\u0117\1\0\1\u0117\61\0\1\u0185"+ + "\73\0\1\u0186\1\u0187\1\0\1\u0187\20\0\1\u0119\27\0"+ + "\1\u0188\45\0\1\u0189\23\0\1\u018a\1\66\1\67\1\260"+ + "\3\66\1\u018a\1\66\10\0\12\u018a\1\66\1\u018a\1\66"+ + "\1\u018a\1\66\1\u018a\1\66\1\u018a\6\66\1\0\5\66"+ + "\10\0\1\66\26\0\1\u018b\1\150\1\0\1\150\4\0"+ + "\1\151\1\0\1\151\41\0\1\155\1\0\1\73\24\0"+ + "\1\156\44\0\1\153\1\0\1\72\37\0\1\154\31\0"+ + "\1\157\1\0\1\74\14\0\1\160\123\0\2\u018c\43\0"+ + "\1\u018d\1\267\1\0\1\267\50\0\1\270\1\u018e\3\154"+ + "\40\0\1\271\17\0\1\154\26\0\1\u018f\7\0\1\u0123"+ + "\1\0\1\u0123\61\0\1\u0190\73\0\1\u0191\1\u0192\1\0"+ + "\1\u0192\20\0\1\u0125\27\0\1\u0193\45\0\1\u0194\45\0"+ + "\1\u0195\1\273\1\0\1\273\50\0\1\274\1\u0196\3\156"+ + "\21\0\1\275\36\0\1\156\26\0\1\u0197\1\u0129\1\0"+ + "\1\u0129\71\0\1\u0198\72\0\1\u0199\1\u019a\1\0\1\u019a"+ + "\11\0\1\u012b\36\0\1\u019b\16\0\1\u019c\74\0\1\u019d"+ + "\1\277\1\0\1\277\50\0\1\300\1\u019e\3\160\24\0"+ + "\1\301\33\0\1\160\26\0\1\u019f\1\u012f\1\0\1\u012f"+ + "\102\0\1\u01a0\61\0\1\u01a1\1\u01a2\1\0\1\u01a2\46\0"+ + "\1\u01a3\1\23\1\75\1\162\3\23\1\u01a3\1\23\10\0"+ + "\12\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\6\23\1\0\5\23\10\0\1\23\4\0\1\u01a3"+ + "\1\23\1\75\1\162\3\23\1\u01a3\1\23\10\0\2\u01a3"+ + "\1\u01a4\1\u01a3\1\u01a4\4\u01a3\1\u01a5\1\23\1\u01a5\1\23"+ + "\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\u01a3\1\23\1\75\1\162\3\23"+ + "\1\u01a3\1\23\10\0\2\u01a3\1\u01a6\3\u01a3\1\u01a7\1\u01a8"+ + "\1\u01a3\1\u01a9\1\23\1\u01aa\1\23\1\u01ab\1\23\1\u01ac"+ + "\1\23\1\u01ad\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\u01ae\1\23\1\75\1\162\3\23\1\u01a3\1\23\10\0"+ + "\1\u01a3\1\u01af\4\u01a3\1\u01b0\3\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\u01a3\1\23\1\104\1\321\3\30"+ + "\1\u01a3\1\23\10\0\10\u01a3\1\u01b1\1\u01a3\1\23\1\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0"+ + "\5\23\10\0\1\30\4\0\1\u01a3\1\23\1\102\1\323"+ + "\3\27\1\u01a3\1\23\10\0\12\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\103\4\23"+ + "\1\0\5\23\10\0\1\27\4\0\1\u01a3\1\23\1\116"+ + "\1\324\3\36\1\u01a3\1\23\10\0\12\u01a3\1\23\1\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\103"+ + "\4\23\1\0\1\41\4\23\10\0\1\36\4\0\1\u01a3"+ + "\1\23\1\106\1\325\3\31\1\u01a3\1\23\10\0\12\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\1\23\1\107\4\23\1\0\3\23\1\110\1\23\10\0"+ + "\1\31\4\0\1\u01a3\1\23\1\111\1\326\3\32\1\u01a3"+ + "\1\23\10\0\12\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\5\23\1\40\1\0\5\23\10\0"+ + "\1\32\4\0\1\u01a3\1\23\1\112\1\327\3\33\1\u01a3"+ + "\1\23\10\0\12\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\6\23\1\0\4\23\1\113\10\0"+ + "\1\33\4\0\1\u01a3\1\23\1\114\1\330\3\34\1\u01a3"+ + "\1\23\10\0\12\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\2\23\1\103\3\23\1\0\5\23"+ + "\10\0\1\34\4\0\1\u01a3\1\23\1\115\1\331\3\35"+ + "\1\u01a3\1\23\10\0\12\u01a3\1\23\1\u01a3\1\33\1\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23\10\0"+ + "\1\35\4\0\1\u01a3\1\23\1\120\1\332\3\40\1\u01a3"+ + "\1\23\10\0\1\u01b2\11\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23\10\0"+ + "\1\40\4\0\1\u01a3\1\23\1\117\1\334\3\37\1\u01a3"+ + "\1\23\10\0\5\u01a3\1\u01b3\4\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0\1\23"+ + "\1\103\1\23\1\103\1\23\10\0\1\37\4\0\1\u01a3"+ + "\1\23\1\75\1\336\3\41\1\u01a3\1\23\10\0\12\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\6\23\1\0\5\23\10\0\1\41\4\0\1\u01a3\1\23"+ + "\1\205\1\162\3\23\1\u01a3\1\23\10\0\12\u01a3\1\206"+ + "\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u01a3\1\23\1\231"+ + "\1\162\3\23\1\u01a3\1\23\10\0\7\u01a3\1\u01b4\2\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\u0132\1\23"+ + "\1\75\1\162\3\23\1\u0132\1\23\10\0\1\u0132\1\u01b5"+ + "\1\u01b6\1\u0132\1\u01b6\5\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u0132\1\23\1\75\1\162\3\23\1\u0132"+ + "\1\23\10\0\7\u0132\1\u01b7\2\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\u0132\1\23\1\75\1\u0148\3\103"+ + "\1\u0132\1\23\10\0\12\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0"+ + "\1\103\4\0\2\23\1\75\1\0\1\103\2\0\2\23"+ + "\10\0\30\23\1\0\5\23\15\0\1\u0132\1\23\1\75"+ + "\1\162\3\23\1\u0132\1\23\10\0\1\u0132\1\u01b8\1\u01b9"+ + "\1\u0132\1\u01b9\5\u0132\1\23\1\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\u0132\1\23\1\75\1\162\3\23\1\u0132\1\23"+ + "\10\0\11\u0132\1\u01ba\1\23\1\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\u0132\1\23\1\205\1\u014c\3\105\1\u0132\1\23"+ + "\10\0\12\u0132\1\206\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\6\23\1\0\5\23\10\0\1\105\4\0"+ + "\2\23\1\205\1\0\1\105\2\0\2\23\10\0\12\23"+ + "\1\206\15\23\1\0\5\23\15\0\1\302\1\23\1\75"+ + "\1\162\3\23\1\302\1\23\10\0\1\302\1\u01bb\1\u01bc"+ + "\1\302\1\u01bc\5\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\1\23\1\302\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\302\1\23\1\75\1\162\3\23\1\302\1\23"+ + "\10\0\12\302\1\23\1\u01bd\1\23\1\302\1\23\1\302"+ + "\1\23\1\302\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\302\1\23\1\75\1\u01be\3\206\1\302\1\23\10\0"+ + "\12\302\1\23\1\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\6\23\1\0\5\23\10\0\1\206\4\0\1\u0132"+ + "\1\23\1\75\1\162\3\23\1\u0132\1\23\10\0\1\u0132"+ + "\1\u01bf\1\u01c0\1\u0132\1\u01c0\4\u0132\1\u01c1\1\23\1\u01c1"+ + "\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\u0132\1\23\1\75\1\162"+ + "\3\23\1\u0132\1\23\10\0\7\u0132\1\u01c2\2\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u0132\1\23\1\75"+ + "\1\162\3\23\1\u0132\1\23\10\0\12\u0132\1\23\1\u0132"+ + "\1\23\1\u01c3\1\23\1\u0132\1\23\1\u0132\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\u0132\1\23\1\75\1\u0155"+ + "\3\107\1\u0132\1\23\10\0\12\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23"+ + "\10\0\1\107\4\0\1\u0132\1\23\1\75\1\u0156\3\110"+ + "\1\u0132\1\23\10\0\12\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0"+ + "\1\110\4\0\2\23\1\75\1\0\1\107\2\0\2\23"+ + "\10\0\30\23\1\0\5\23\15\0\2\23\1\75\1\0"+ + "\1\110\2\0\2\23\10\0\30\23\1\0\5\23\15\0"+ + "\1\u0132\1\23\1\75\1\162\3\23\1\u0132\1\23\10\0"+ + "\1\u0132\1\u01c4\7\u0132\1\u01c5\1\23\1\u01c5\1\23\1\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u013e\1\23\1\75\1\162\3\23\1\u0132"+ + "\1\23\10\0\12\u0132\1\23\1\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\u0132\1\23\1\75\1\162\3\23\1\u0132\1\23"+ + "\10\0\1\u0132\1\u01c6\7\u0132\1\u01c7\1\23\1\u01c7\1\23"+ + "\1\u0132\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\u0132\1\23\1\75\1\162\3\23"+ + "\1\u0132\1\23\10\0\1\u01c8\11\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\u0132\1\23\1\75\1\u015c\3\113"+ + "\1\u0132\1\23\10\0\12\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0"+ + "\1\113\4\0\2\23\1\75\1\0\1\113\2\0\2\23"+ + "\10\0\30\23\1\0\5\23\15\0\1\u0132\1\23\1\75"+ + "\1\162\3\23\1\u0132\1\23\10\0\1\u0132\1\u01c9\1\u01ca"+ + "\1\u0132\1\u01ca\5\u0132\1\23\1\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\u0132\1\23\1\75\1\162\3\23\1\u0132\1\23"+ + "\10\0\10\u0132\1\u01b7\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u0132\1\23\1\75\1\162\3\23\1\u0132"+ + "\1\23\10\0\1\u0132\1\u01cb\1\u01cc\1\u0132\1\u01cc\5\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\u0132\1\23"+ + "\1\75\1\162\3\23\1\u0132\1\23\10\0\12\u0132\1\23"+ + "\1\u0132\1\23\1\u013b\1\23\1\u0132\1\23\1\u0132\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u0132\1\23\1\75"+ + "\1\162\3\23\1\u0132\1\23\10\0\1\u0132\1\u01cd\1\u01b6"+ + "\1\u0132\1\u01b6\4\u0132\1\u01ce\1\23\1\u01ce\1\23\1\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u0132\1\23\1\75\1\162\3\23\1\u0132"+ + "\1\23\10\0\6\u0132\1\u0140\3\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\u0132\1\23\1\75\1\162\3\23"+ + "\1\u0132\1\23\10\0\1\u0132\1\u01cf\1\u01d0\1\u0132\1\u01d0"+ + "\4\u0132\1\u01d1\1\23\1\u01d1\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\u0132\1\23\1\75\1\162\3\23\1\u0132\1\23\10\0"+ + "\6\u0132\1\u01b7\3\u0132\1\23\1\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\u0132\1\23\1\75\1\162\3\23\1\u0132\1\23"+ + "\10\0\2\u0132\1\u01b7\7\u0132\1\23\1\u0132\1\23\1\u01b7"+ + "\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u0132\1\23\1\75\1\162\3\23\1\u0132"+ + "\1\23\10\0\1\u0132\1\u01d2\1\u01d3\1\u0132\1\u01d3\5\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\u0132\1\23"+ + "\1\75\1\162\3\23\1\u0132\1\23\10\0\3\u0132\1\u01d4"+ + "\6\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23"+ + "\1\u0132\6\23\1\0\5\23\10\0\1\23\4\0\1\u0132"+ + "\1\23\1\231\1\u0169\3\121\1\u0132\1\23\10\0\7\u0132"+ + "\1\u0144\2\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\6\23\1\0\5\23\10\0\1\121\4\0"+ + "\2\23\1\231\1\0\1\121\2\0\2\23\10\0\7\23"+ + "\1\206\20\23\1\0\5\23\15\0\1\302\1\23\1\75"+ + "\1\162\3\23\1\302\1\23\10\0\1\302\1\u01d5\1\u01d6"+ + "\1\302\1\u01d6\5\302\1\23\1\302\1\23\1\302\1\23"+ + "\1\302\1\23\1\302\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\302\1\23\1\75\1\162\3\23\1\302\1\23"+ + "\10\0\2\302\1\u01bd\7\302\1\23\1\302\1\23\1\302"+ + "\1\23\1\302\1\23\1\302\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u01d7\1\4\1\43\1\123\3\4\1\u01d7"+ + "\1\4\4\0\1\44\3\0\12\u01d7\1\4\1\u01d7\1\4"+ + "\1\u01d7\1\4\1\u01d7\1\4\1\u01d7\6\4\1\0\5\4"+ + "\10\0\1\4\4\0\1\u01d7\1\4\1\43\1\123\3\4"+ + "\1\u01d7\1\4\4\0\1\44\3\0\11\u01d7\1\u01d8\1\4"+ + "\1\u01d7\1\4\1\u01d7\1\4\1\u01d7\1\4\1\u01d7\6\4"+ + "\1\0\5\4\10\0\1\4\4\0\1\u01d7\1\4\1\56"+ + "\1\236\3\15\1\u01d7\1\4\4\0\1\44\3\0\12\u01d7"+ + "\1\4\1\u01d7\1\4\1\u01d7\1\4\1\u01d7\1\4\1\u01d7"+ + "\5\4\1\57\1\0\5\4\10\0\1\15\3\0\1\10"+ + "\1\u01d9\1\10\1\51\1\131\3\10\1\u01d9\1\10\1\52"+ + "\7\10\12\u01d9\1\10\1\u01d9\1\10\1\u01d9\1\10\1\u01d9"+ + "\1\10\1\u01d9\30\10\1\11\1\u01da\1\11\1\53\1\133"+ + "\3\11\1\u01da\2\11\1\52\6\11\12\u01da\1\11\1\u01da"+ + "\1\11\1\u01da\1\11\1\u01da\1\11\1\u01da\30\11\15\u0172"+ + "\1\u01db\42\u0172\1\u01dc\13\u0172\1\0\1\u016d\1\4\1\43"+ + "\1\123\3\4\1\u016d\1\4\4\0\1\44\3\0\11\u016d"+ + "\1\u01dd\1\4\1\u01dd\1\4\1\u016d\1\4\1\u016d\1\4"+ + "\1\u016d\6\4\1\0\5\4\10\0\1\4\4\0\1\u01de"+ + "\1\4\1\43\1\123\3\4\1\u016d\1\4\4\0\1\44"+ + "\3\0\12\u016d\1\4\1\u016d\1\4\1\u016d\1\4\1\u016d"+ + "\1\4\1\u016d\6\4\1\0\5\4\10\0\1\4\4\0"+ + "\1\u016d\1\4\1\137\1\u0109\3\57\1\u016d\1\4\4\0"+ + "\1\44\3\0\12\u016d\1\4\1\u016d\1\4\1\u016d\1\4"+ + "\1\u016d\1\4\1\u016d\1\140\5\4\1\0\5\4\10\0"+ + "\1\57\4\0\1\377\1\4\1\43\1\123\3\4\1\377"+ + "\1\4\4\0\1\44\3\0\1\377\1\u01df\1\u01e0\1\377"+ + "\1\u01e0\5\377\1\4\1\377\1\4\1\377\1\4\1\377"+ + "\1\4\1\377\6\4\1\0\5\4\10\0\1\4\4\0"+ + "\1\377\1\4\1\43\1\123\3\4\1\377\1\4\4\0"+ + "\1\44\3\0\5\377\1\u01e1\4\377\1\4\1\377\1\4"+ + "\1\377\1\4\1\377\1\4\1\377\6\4\1\0\5\4"+ + "\10\0\1\4\4\0\1\377\1\4\1\43\1\u0179\3\140"+ + "\1\377\1\4\4\0\1\247\3\0\12\377\1\4\1\377"+ + "\1\4\1\377\1\4\1\377\1\4\1\377\6\4\1\0"+ + "\5\4\10\0\1\140\4\0\2\4\1\43\1\0\1\140"+ + "\2\0\2\4\4\0\1\247\3\0\30\4\1\0\5\4"+ + "\20\0\4\u017a\60\0\1\u017a\1\0\1\u0111\2\0\1\u01e2"+ + "\1\u010d\1\u010e\1\u01e3\3\u010d\1\u01e2\1\u010d\2\0\2\u010d"+ + "\1\0\3\u010d\12\u01e2\1\u010d\1\u01e2\1\u010d\1\u01e2\1\u010d"+ + "\1\u01e2\1\u010d\1\u01e2\6\u010d\1\0\17\u010d\1\u0111\1\0"+ + "\1\u01e4\1\u01e5\1\u010d\1\u010e\2\u017a\1\u01e6\1\u017a\1\u01e5"+ + "\1\u010d\2\u01e4\2\u010d\1\u01e4\3\u010d\12\u01e5\1\u010d\1\u01e5"+ + "\1\u010d\1\u01e5\1\u010d\1\u01e5\1\u010d\1\u01e5\6\u010d\1\u01e4"+ + "\15\u010d\1\u01e6\1\u010d\1\u01e7\1\u01e4\4\0\4\u017d\60\0"+ + "\1\u017d\1\0\1\u0111\1\0\1\u010f\1\u01e8\2\u010f\1\u01e9"+ + "\3\u010f\1\u01e8\11\u010f\12\u01e8\1\u010f\1\u01e8\1\u010f\1\u01e8"+ + "\1\u010f\1\u01e8\1\u010f\1\u01e8\30\u010f\1\u0110\1\u01ea\2\u0110"+ + "\1\u01eb\3\u0110\1\u01ea\11\u0110\12\u01ea\1\u0110\1\u01ea\1\u0110"+ + "\1\u01ea\1\u0110\1\u01ea\1\u0110\1\u01ea\30\u0110\24\0\1\142"+ + "\1\0\1\142\70\0\1\u01ec\1\254\1\0\1\254\50\0"+ + "\1\255\1\0\1\145\42\0\1\256\46\0\1\u01ed\7\0"+ + "\1\u0117\1\0\1\u0117\41\0\1\u0118\1\u01ee\3\256\37\0"+ + "\1\u0119\20\0\1\256\26\0\1\u01ef\1\u0187\1\0\1\u0187"+ + "\55\0\1\u01f0\106\0\1\u01f1\7\0\1\u01f2\1\0\1\u01f2"+ + "\13\0\1\u0189\25\0\1\u01f3\50\0\1\u01f4\20\0\1\u01f5"+ + "\1\66\1\67\1\260\3\66\1\u01f5\1\66\10\0\12\u01f5"+ + "\1\66\1\u01f5\1\66\1\u01f5\1\66\1\u01f5\1\66\1\u01f5"+ + "\6\66\1\0\5\66\10\0\1\66\27\0\1\150\1\0"+ + "\1\150\4\0\1\151\1\0\1\151\70\0\1\u01f6\64\0"+ + "\1\u01f7\1\267\1\0\1\267\50\0\1\270\1\0\1\154"+ + "\42\0\1\271\46\0\1\u01f8\7\0\1\u0123\1\0\1\u0123"+ + "\41\0\1\u0124\1\u01f9\3\271\37\0\1\u0125\20\0\1\271"+ + "\26\0\1\u01fa\1\u0192\1\0\1\u0192\55\0\1\u01fb\106\0"+ + "\1\u01fc\7\0\1\u01fd\1\0\1\u01fd\13\0\1\u0194\25\0"+ + "\1\u01fe\50\0\1\u01ff\42\0\1\u0200\1\273\1\0\1\273"+ + "\50\0\1\274\1\0\1\156\23\0\1\275\65\0\1\u0201"+ + "\1\u0129\1\0\1\u0129\50\0\1\u012a\1\u0202\3\275\30\0"+ + "\1\u012b\27\0\1\275\26\0\1\u0203\1\u019a\1\0\1\u019a"+ + "\106\0\1\u0204\55\0\1\u0205\1\u0206\1\0\1\u0206\70\0"+ + "\1\u0207\1\277\1\0\1\277\50\0\1\300\1\0\1\160"+ + "\26\0\1\301\62\0\1\u0208\1\u012f\1\0\1\u012f\50\0"+ + "\1\u0130\1\u0209\3\301\22\0\1\u0131\35\0\1\301\26\0"+ + "\1\u020a\1\u01a2\1\0\1\u01a2\100\0\1\u020b\41\0\1\u020c"+ + "\1\23\1\75\1\162\3\23\1\u020c\1\23\10\0\12\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\u020c\1\23"+ + "\1\75\1\162\3\23\1\u020c\1\23\10\0\2\u020c\1\u020d"+ + "\3\u020c\1\u020e\1\u020f\1\u020c\1\u0210\1\23\1\u0211\1\23"+ + "\1\u0212\1\23\1\u0213\1\23\1\u0214\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\u0215\1\23\1\75\1\162\3\23"+ + "\1\u020c\1\23\10\0\1\u020c\1\u0216\4\u020c\1\u0217\3\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\u020c\1\23"+ + "\1\104\1\321\3\30\1\u020c\1\23\10\0\10\u020c\1\u0218"+ + "\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23"+ + "\1\u020c\6\23\1\0\5\23\10\0\1\30\4\0\1\u020c"+ + "\1\23\1\102\1\323\3\27\1\u020c\1\23\10\0\12\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\1\23\1\103\4\23\1\0\5\23\10\0\1\27\4\0"+ + "\1\u020c\1\23\1\116\1\324\3\36\1\u020c\1\23\10\0"+ + "\12\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23"+ + "\1\u020c\1\23\1\103\4\23\1\0\1\41\4\23\10\0"+ + "\1\36\4\0\1\u020c\1\23\1\106\1\325\3\31\1\u020c"+ + "\1\23\10\0\12\u020c\1\23\1\u020c\1\23\1\u020c\1\23"+ + "\1\u020c\1\23\1\u020c\1\23\1\107\4\23\1\0\3\23"+ + "\1\110\1\23\10\0\1\31\4\0\1\u020c\1\23\1\111"+ + "\1\326\3\32\1\u020c\1\23\10\0\12\u020c\1\23\1\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\5\23\1\40"+ + "\1\0\5\23\10\0\1\32\4\0\1\u020c\1\23\1\112"+ + "\1\327\3\33\1\u020c\1\23\10\0\12\u020c\1\23\1\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\6\23\1\0"+ + "\4\23\1\113\10\0\1\33\4\0\1\u020c\1\23\1\114"+ + "\1\330\3\34\1\u020c\1\23\10\0\12\u020c\1\23\1\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\2\23\1\103"+ + "\3\23\1\0\5\23\10\0\1\34\4\0\1\u020c\1\23"+ + "\1\115\1\331\3\35\1\u020c\1\23\10\0\12\u020c\1\23"+ + "\1\u020c\1\33\1\u020c\1\23\1\u020c\1\23\1\u020c\6\23"+ + "\1\0\5\23\10\0\1\35\4\0\1\u020c\1\23\1\120"+ + "\1\332\3\40\1\u020c\1\23\10\0\1\u0219\11\u020c\1\23"+ + "\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\6\23"+ + "\1\0\5\23\10\0\1\40\4\0\1\u020c\1\23\1\117"+ + "\1\334\3\37\1\u020c\1\23\10\0\5\u020c\1\u021a\4\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\6\23\1\0\1\23\1\103\1\23\1\103\1\23\10\0"+ + "\1\37\4\0\1\u020c\1\23\1\75\1\336\3\41\1\u020c"+ + "\1\23\10\0\12\u020c\1\23\1\u020c\1\23\1\u020c\1\23"+ + "\1\u020c\1\23\1\u020c\6\23\1\0\5\23\10\0\1\41"+ + "\4\0\1\u020c\1\23\1\205\1\162\3\23\1\u020c\1\23"+ + "\10\0\12\u020c\1\206\1\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\1\23\1\u020c\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\u020c\1\23\1\231\1\162\3\23\1\u020c\1\23\10\0"+ + "\7\u020c\1\u021b\2\u020c\1\23\1\u020c\1\23\1\u020c\1\23"+ + "\1\u020c\1\23\1\u020c\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\u01a3\1\23\1\75\1\162\3\23\1\u01a3\1\23"+ + "\10\0\2\u01a3\1\u021c\1\u01a3\1\u021c\5\u01a3\1\23\1\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\u01a3\1\23\1\75\1\162"+ + "\3\23\1\u01a3\1\23\10\0\7\u01a3\1\u021d\2\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u01a3\1\23\1\75"+ + "\1\u0148\3\103\1\u01a3\1\23\10\0\12\u01a3\1\23\1\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0"+ + "\5\23\10\0\1\103\4\0\1\u01a3\1\23\1\75\1\162"+ + "\3\23\1\u01a3\1\23\10\0\2\u01a3\1\u021e\1\u01a3\1\u021e"+ + "\5\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\6\23\1\0\5\23\10\0\1\23\4\0\1\u01a3"+ + "\1\23\1\75\1\162\3\23\1\u01a3\1\23\10\0\11\u01a3"+ + "\1\u021f\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\6\23\1\0\5\23\10\0\1\23\4\0\1\u01a3"+ + "\1\23\1\205\1\u014c\3\105\1\u01a3\1\23\10\0\12\u01a3"+ + "\1\206\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\6\23\1\0\5\23\10\0\1\105\4\0\1\u0132\1\23"+ + "\1\75\1\162\3\23\1\u0132\1\23\10\0\1\u0132\1\u0220"+ + "\1\u0221\1\u0132\1\u0221\5\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u0132\1\23\1\75\1\162\3\23\1\u0132"+ + "\1\23\10\0\12\u0132\1\23\1\u0222\1\23\1\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\u0132\1\23\1\75\1\u01be\3\206\1\u0132\1\23"+ + "\10\0\12\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\1\23\1\u0132\6\23\1\0\5\23\10\0\1\206\4\0"+ + "\2\23\1\75\1\0\1\206\2\0\2\23\10\0\30\23"+ + "\1\0\5\23\15\0\1\u01a3\1\23\1\75\1\162\3\23"+ + "\1\u01a3\1\23\10\0\2\u01a3\1\u0223\1\u01a3\1\u0223\4\u01a3"+ + "\1\u0224\1\23\1\u0224\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\6\23\1\0\5\23\10\0\1\23\4\0\1\u01a3"+ + "\1\23\1\75\1\162\3\23\1\u01a3\1\23\10\0\7\u01a3"+ + "\1\u0225\2\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\1\23\1\u01a3\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\u01a3\1\23\1\75\1\162\3\23\1\u01a3\1\23\10\0"+ + "\12\u01a3\1\23\1\u01a3\1\23\1\u0226\1\23\1\u01a3\1\23"+ + "\1\u01a3\6\23\1\0\5\23\10\0\1\23\4\0\1\u01a3"+ + "\1\23\1\75\1\u0155\3\107\1\u01a3\1\23\10\0\12\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\6\23\1\0\5\23\10\0\1\107\4\0\1\u01a3\1\23"+ + "\1\75\1\u0156\3\110\1\u01a3\1\23\10\0\12\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23"+ + "\1\0\5\23\10\0\1\110\4\0\1\u01a3\1\23\1\75"+ + "\1\162\3\23\1\u01a3\1\23\10\0\11\u01a3\1\u0227\1\23"+ + "\1\u0227\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u01ae\1\23\1\75"+ + "\1\162\3\23\1\u01a3\1\23\10\0\12\u01a3\1\23\1\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\u01a3\1\23\1\75\1\162"+ + "\3\23\1\u01a3\1\23\10\0\11\u01a3\1\u0228\1\23\1\u0228"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\u01a3\1\23\1\75\1\162"+ + "\3\23\1\u01a3\1\23\10\0\1\u0229\11\u01a3\1\23\1\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\u01a3\1\23\1\75\1\u015c"+ + "\3\113\1\u01a3\1\23\10\0\12\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23"+ + "\10\0\1\113\4\0\1\u01a3\1\23\1\75\1\162\3\23"+ + "\1\u01a3\1\23\10\0\2\u01a3\1\u022a\1\u01a3\1\u022a\5\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\u01a3\1\23"+ + "\1\75\1\162\3\23\1\u01a3\1\23\10\0\10\u01a3\1\u021d"+ + "\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\6\23\1\0\5\23\10\0\1\23\4\0\1\u01a3"+ + "\1\23\1\75\1\162\3\23\1\u01a3\1\23\10\0\2\u01a3"+ + "\1\u022b\1\u01a3\1\u022b\5\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u01a3\1\23\1\75\1\162\3\23\1\u01a3"+ + "\1\23\10\0\12\u01a3\1\23\1\u01a3\1\23\1\u01ab\1\23"+ + "\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\u01a3\1\23\1\75\1\162\3\23\1\u01a3\1\23"+ + "\10\0\2\u01a3\1\u021c\1\u01a3\1\u021c\4\u01a3\1\u022c\1\23"+ + "\1\u022c\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u01a3\1\23\1\75"+ + "\1\162\3\23\1\u01a3\1\23\10\0\6\u01a3\1\u01b0\3\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\u01a3\1\23"+ + "\1\75\1\162\3\23\1\u01a3\1\23\10\0\2\u01a3\1\u022d"+ + "\1\u01a3\1\u022d\4\u01a3\1\u022e\1\23\1\u022e\1\23\1\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u01a3\1\23\1\75\1\162\3\23\1\u01a3"+ + "\1\23\10\0\6\u01a3\1\u021d\3\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\u01a3\1\23\1\75\1\162\3\23"+ + "\1\u01a3\1\23\10\0\2\u01a3\1\u021d\7\u01a3\1\23\1\u01a3"+ + "\1\23\1\u021d\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\u01a3\1\23\1\75\1\162"+ + "\3\23\1\u01a3\1\23\10\0\2\u01a3\1\u022f\1\u01a3\1\u022f"+ + "\5\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\6\23\1\0\5\23\10\0\1\23\4\0\1\u01a3"+ + "\1\23\1\75\1\162\3\23\1\u01a3\1\23\10\0\3\u01a3"+ + "\1\u0230\6\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\1\23\1\u01a3\6\23\1\0\5\23\10\0\1\23\4\0"+ + "\1\u01a3\1\23\1\231\1\u0169\3\121\1\u01a3\1\23\10\0"+ + "\7\u01a3\1\u01b4\2\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23\10\0\1\121"+ + "\4\0\1\u0132\1\23\1\75\1\162\3\23\1\u0132\1\23"+ + "\10\0\1\u0132\1\u0231\1\u0232\1\u0132\1\u0232\5\u0132\1\23"+ + "\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u0132\1\23\1\75"+ + "\1\162\3\23\1\u0132\1\23\10\0\2\u0132\1\u0222\7\u0132"+ + "\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132\1\23\1\u0132"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\2\4\1\43"+ + "\1\123\5\4\4\0\1\44\3\0\30\4\1\0\5\4"+ + "\10\0\1\4\4\0\2\4\1\56\1\236\3\15\2\4"+ + "\4\0\1\44\3\0\27\4\1\57\1\0\5\4\10\0"+ + "\1\15\3\0\1\10\1\u0233\1\10\1\51\1\131\3\10"+ + "\1\u0233\1\10\1\52\7\10\12\u0233\1\10\1\u0233\1\10"+ + "\1\u0233\1\10\1\u0233\1\10\1\u0233\30\10\1\11\1\u0234"+ + "\1\11\1\53\1\133\3\11\1\u0234\2\11\1\52\6\11"+ + "\12\u0234\1\11\1\u0234\1\11\1\u0234\1\11\1\u0234\1\11"+ + "\1\u0234\30\11\14\u0172\1\0\1\u01db\42\u0172\1\u01dc\30\u0172"+ + "\1\u01db\42\u0172\1\u01dc\1\u0235\12\u0172\1\0\1\u0236\1\4"+ + "\1\43\1\123\3\4\1\u01d7\1\4\4\0\1\44\3\0"+ + "\12\u01d7\1\4\1\u01d7\1\4\1\u01d7\1\4\1\u01d7\1\4"+ + "\1\u01d7\6\4\1\0\5\4\10\0\1\4\4\0\1\u01d7"+ + "\1\4\1\137\1\u0109\3\57\1\u01d7\1\4\4\0\1\44"+ + "\3\0\12\u01d7\1\4\1\u01d7\1\4\1\u01d7\1\4\1\u01d7"+ + "\1\4\1\u01d7\1\140\5\4\1\0\5\4\10\0\1\57"+ + "\4\0\1\u016d\1\4\1\43\1\123\3\4\1\u016d\1\4"+ + "\4\0\1\44\3\0\2\u016d\1\u0237\1\u016d\1\u0237\5\u016d"+ + "\1\4\1\u016d\1\4\1\u016d\1\4\1\u016d\1\4\1\u016d"+ + "\6\4\1\0\5\4\10\0\1\4\4\0\1\u016d\1\4"+ + "\1\43\1\123\3\4\1\u016d\1\4\4\0\1\44\3\0"+ + "\5\u016d\1\u0238\4\u016d\1\4\1\u016d\1\4\1\u016d\1\4"+ + "\1\u016d\1\4\1\u016d\6\4\1\0\5\4\10\0\1\4"+ + "\4\0\1\u016d\1\4\1\43\1\u0179\3\140\1\u016d\1\4"+ + "\4\0\1\247\3\0\12\u016d\1\4\1\u016d\1\4\1\u016d"+ + "\1\4\1\u016d\1\4\1\u016d\6\4\1\0\5\4\10\0"+ + "\1\140\4\0\1\u0239\1\u010d\1\u010e\1\u01e3\3\u010d\1\u0239"+ + "\1\u010d\2\0\2\u010d\1\0\3\u010d\12\u0239\1\u010d\1\u0239"+ + "\1\u010d\1\u0239\1\u010d\1\u0239\1\u010d\1\u0239\6\u010d\1\0"+ + "\17\u010d\1\u0111\2\0\2\u010d\1\u010e\1\u017a\1\u010d\2\u017a"+ + "\2\u010d\2\0\2\u010d\1\0\33\u010d\1\0\15\u010d\1\u017a"+ + "\1\u010d\1\u0111\2\0\2\u01e4\1\u023a\4\u017d\2\u01e4\2\0"+ + "\2\u01e4\1\0\33\u01e4\1\0\15\u01e4\1\u017d\1\u01e4\1\u0111"+ + "\2\0\1\u023b\1\u010d\1\u010e\1\u023c\3\u01e6\1\u023b\1\u010d"+ + "\2\0\2\u010d\1\0\3\u010d\12\u023b\1\u010d\1\u023b\1\u010d"+ + "\1\u023b\1\u010d\1\u023b\1\u010d\1\u023b\6\u010d\1\0\15\u010d"+ + "\1\u01e6\1\u010d\1\u0111\2\0\2\u01e4\1\u023a\4\u017a\2\u01e4"+ + "\2\0\2\u01e4\1\0\33\u01e4\1\0\15\u01e4\1\u017a\1\u01e4"+ + "\1\u0111\1\0\1\u010f\1\u023d\1\u010f\1\u017f\1\u01e9\3\u010f"+ + "\1\u023d\1\u010f\1\u017a\7\u010f\12\u023d\1\u010f\1\u023d\1\u010f"+ + "\1\u023d\1\u010f\1\u023d\1\u010f\1\u023d\33\u010f\1\u017f\1\0"+ + "\2\u010f\1\0\2\u010f\1\u017a\61\u010f\1\u0110\1\u023e\1\u0110"+ + "\1\u0180\1\u01eb\3\u0110\1\u023e\2\u0110\1\u017a\6\u0110\12\u023e"+ + "\1\u0110\1\u023e\1\u0110\1\u023e\1\u0110\1\u023e\1\u0110\1\u023e"+ + "\33\u0110\1\u0180\1\0\2\u0110\1\0\3\u0110\1\u017a\60\u0110"+ + "\24\0\1\254\1\0\1\254\70\0\1\u023f\7\0\1\u0117"+ + "\1\0\1\u0117\41\0\1\u0118\1\0\1\256\41\0\1\u0119"+ + "\47\0\1\u0240\1\u0187\1\0\1\u0187\50\0\1\u0188\1\u0241"+ + "\3\u0119\41\0\1\u0189\16\0\1\u0119\26\0\1\u0242\7\0"+ + "\1\u01f2\1\0\1\u01f2\37\0\1\u0243\115\0\1\u0244\7\0"+ + "\1\u0245\1\0\1\u0245\16\0\1\u01f4\22\0\1\u0246\16\0"+ + "\1\u0247\52\0\1\u0248\1\66\1\67\1\260\3\66\1\u0248"+ + "\1\66\10\0\12\u0248\1\66\1\u0248\1\66\1\u0248\1\66"+ + "\1\u0248\1\66\1\u0248\6\66\1\0\5\66\10\0\1\66"+ + "\57\0\1\u0249\43\0\1\267\1\0\1\267\70\0\1\u024a"+ + "\7\0\1\u0123\1\0\1\u0123\41\0\1\u0124\1\0\1\271"+ + "\41\0\1\u0125\47\0\1\u024b\1\u0192\1\0\1\u0192\50\0"+ + "\1\u0193\1\u024c\3\u0125\41\0\1\u0194\16\0\1\u0125\26\0"+ + "\1\u024d\7\0\1\u01fd\1\0\1\u01fd\37\0\1\u024e\115\0"+ + "\1\u024f\7\0\1\u0250\1\0\1\u0250\16\0\1\u01ff\43\0"+ + "\1\273\1\0\1\273\70\0\1\u0251\1\u0129\1\0\1\u0129"+ + "\50\0\1\u012a\1\0\1\275\32\0\1\u012b\56\0\1\u0252"+ + "\1\u019a\1\0\1\u019a\50\0\1\u019b\1\u0253\3\u012b\12\0"+ + "\1\u019c\45\0\1\u012b\26\0\1\u0254\1\u0206\1\0\1\u0206"+ + "\72\0\1\u0255\72\0\1\277\1\0\1\277\70\0\1\u0256"+ + "\1\u012f\1\0\1\u012f\50\0\1\u0130\1\0\1\301\24\0"+ + "\1\u0131\64\0\1\u0257\1\u01a2\1\0\1\u01a2\51\0\1\u0258"+ + "\3\u0131\60\0\1\u0131\4\0\2\23\1\75\1\162\5\23"+ + "\10\0\30\23\1\0\5\23\10\0\1\23\4\0\2\23"+ + "\1\104\1\321\3\30\2\23\10\0\10\23\1\105\17\23"+ + "\1\0\5\23\10\0\1\30\4\0\2\23\1\102\1\323"+ + "\3\27\2\23\10\0\23\23\1\103\4\23\1\0\5\23"+ + "\10\0\1\27\4\0\2\23\1\116\1\324\3\36\2\23"+ + "\10\0\23\23\1\103\4\23\1\0\1\41\4\23\10\0"+ + "\1\36\4\0\2\23\1\106\1\325\3\31\2\23\10\0"+ + "\23\23\1\107\4\23\1\0\3\23\1\110\1\23\10\0"+ + "\1\31\4\0\2\23\1\111\1\326\3\32\2\23\10\0"+ + "\27\23\1\40\1\0\5\23\10\0\1\32\4\0\2\23"+ + "\1\112\1\327\3\33\2\23\10\0\30\23\1\0\4\23"+ + "\1\113\10\0\1\33\4\0\2\23\1\114\1\330\3\34"+ + "\2\23\10\0\24\23\1\103\3\23\1\0\5\23\10\0"+ + "\1\34\4\0\2\23\1\115\1\331\3\35\2\23\10\0"+ + "\14\23\1\33\13\23\1\0\5\23\10\0\1\35\4\0"+ + "\2\23\1\120\1\332\3\40\2\23\10\0\1\121\27\23"+ + "\1\0\5\23\10\0\1\40\4\0\2\23\1\117\1\334"+ + "\3\37\2\23\10\0\5\23\1\103\22\23\1\0\1\23"+ + "\1\103\1\23\1\103\1\23\10\0\1\37\4\0\2\23"+ + "\1\75\1\336\3\41\2\23\10\0\30\23\1\0\5\23"+ + "\10\0\1\41\4\0\2\23\1\205\1\162\5\23\10\0"+ + "\12\23\1\206\15\23\1\0\5\23\10\0\1\23\4\0"+ + "\2\23\1\231\1\162\5\23\10\0\7\23\1\206\20\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u020c\1\23\1\75"+ + "\1\162\3\23\1\u020c\1\23\10\0\7\u020c\1\u0259\2\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\u020c\1\23"+ + "\1\75\1\u0148\3\103\1\u020c\1\23\10\0\12\u020c\1\23"+ + "\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\6\23"+ + "\1\0\5\23\10\0\1\103\4\0\1\u020c\1\23\1\75"+ + "\1\162\3\23\1\u020c\1\23\10\0\11\u020c\1\u025a\1\23"+ + "\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u020c\1\23\1\205"+ + "\1\u014c\3\105\1\u020c\1\23\10\0\12\u020c\1\206\1\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\6\23\1\0"+ + "\5\23\10\0\1\105\4\0\1\u01a3\1\23\1\75\1\162"+ + "\3\23\1\u01a3\1\23\10\0\2\u01a3\1\u025b\1\u01a3\1\u025b"+ + "\5\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\6\23\1\0\5\23\10\0\1\23\4\0\1\u01a3"+ + "\1\23\1\75\1\162\3\23\1\u01a3\1\23\10\0\12\u01a3"+ + "\1\23\1\u025c\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\u01a3\1\23"+ + "\1\75\1\u01be\3\206\1\u01a3\1\23\10\0\12\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23\1\u01a3\6\23"+ + "\1\0\5\23\10\0\1\206\4\0\1\u020c\1\23\1\75"+ + "\1\162\3\23\1\u020c\1\23\10\0\7\u020c\1\u025d\2\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\6\23\1\0\5\23\10\0\1\23\4\0\1\u020c\1\23"+ + "\1\75\1\162\3\23\1\u020c\1\23\10\0\12\u020c\1\23"+ + "\1\u020c\1\23\1\u025e\1\23\1\u020c\1\23\1\u020c\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u020c\1\23\1\75"+ + "\1\u0155\3\107\1\u020c\1\23\10\0\12\u020c\1\23\1\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\6\23\1\0"+ + "\5\23\10\0\1\107\4\0\1\u020c\1\23\1\75\1\u0156"+ + "\3\110\1\u020c\1\23\10\0\12\u020c\1\23\1\u020c\1\23"+ + "\1\u020c\1\23\1\u020c\1\23\1\u020c\6\23\1\0\5\23"+ + "\10\0\1\110\4\0\1\u0215\1\23\1\75\1\162\3\23"+ + "\1\u020c\1\23\10\0\12\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u020c\1\23\1\75\1\162\3\23\1\u020c"+ + "\1\23\10\0\1\u025f\11\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u020c\1\23\1\75\1\u015c\3\113\1\u020c"+ + "\1\23\10\0\12\u020c\1\23\1\u020c\1\23\1\u020c\1\23"+ + "\1\u020c\1\23\1\u020c\6\23\1\0\5\23\10\0\1\113"+ + "\4\0\1\u020c\1\23\1\75\1\162\3\23\1\u020c\1\23"+ + "\10\0\10\u020c\1\u0259\1\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u020c\1\23\1\75\1\162\3\23\1\u020c"+ + "\1\23\10\0\12\u020c\1\23\1\u020c\1\23\1\u0212\1\23"+ + "\1\u020c\1\23\1\u020c\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\u020c\1\23\1\75\1\162\3\23\1\u020c\1\23"+ + "\10\0\6\u020c\1\u0217\3\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u020c\1\23\1\75\1\162\3\23\1\u020c"+ + "\1\23\10\0\6\u020c\1\u0259\3\u020c\1\23\1\u020c\1\23"+ + "\1\u020c\1\23\1\u020c\1\23\1\u020c\6\23\1\0\5\23"+ + "\10\0\1\23\4\0\1\u020c\1\23\1\75\1\162\3\23"+ + "\1\u020c\1\23\10\0\2\u020c\1\u0259\7\u020c\1\23\1\u020c"+ + "\1\23\1\u0259\1\23\1\u020c\1\23\1\u020c\6\23\1\0"+ + "\5\23\10\0\1\23\4\0\1\u020c\1\23\1\75\1\162"+ + "\3\23\1\u020c\1\23\10\0\3\u020c\1\u0260\6\u020c\1\23"+ + "\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\6\23"+ + "\1\0\5\23\10\0\1\23\4\0\1\u020c\1\23\1\231"+ + "\1\u0169\3\121\1\u020c\1\23\10\0\7\u020c\1\u021b\2\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c"+ + "\6\23\1\0\5\23\10\0\1\121\4\0\1\u01a3\1\23"+ + "\1\75\1\162\3\23\1\u01a3\1\23\10\0\2\u01a3\1\u0261"+ + "\1\u01a3\1\u0261\5\u01a3\1\23\1\u01a3\1\23\1\u01a3\1\23"+ + "\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23\10\0\1\23"+ + "\4\0\1\u01a3\1\23\1\75\1\162\3\23\1\u01a3\1\23"+ + "\10\0\2\u01a3\1\u025c\7\u01a3\1\23\1\u01a3\1\23\1\u01a3"+ + "\1\23\1\u01a3\1\23\1\u01a3\6\23\1\0\5\23\10\0"+ + "\1\23\3\0\3\10\1\51\1\131\5\10\1\52\61\10"+ + "\3\11\1\53\1\133\6\11\1\52\60\11\11\u0172\1\u0262"+ + "\3\u0172\1\u01db\42\u0172\1\u01dc\13\u0172\1\0\2\4\1\137"+ + "\1\u0109\3\57\2\4\4\0\1\44\3\0\22\4\1\140"+ + "\5\4\1\0\5\4\10\0\1\57\4\0\1\u01d7\1\4"+ + "\1\43\1\123\3\4\1\u01d7\1\4\4\0\1\44\3\0"+ + "\5\u01d7\1\u0263\4\u01d7\1\4\1\u01d7\1\4\1\u01d7\1\4"+ + "\1\u01d7\1\4\1\u01d7\6\4\1\0\5\4\10\0\1\4"+ + "\4\0\1\u01d7\1\4\1\43\1\u0179\3\140\1\u01d7\1\4"+ + "\4\0\1\247\3\0\12\u01d7\1\4\1\u01d7\1\4\1\u01d7"+ + "\1\4\1\u01d7\1\4\1\u01d7\6\4\1\0\5\4\10\0"+ + "\1\140\4\0\1\u0264\1\u010d\1\u010e\1\u01e3\3\u010d\1\u0264"+ + "\1\u010d\2\0\2\u010d\1\0\3\u010d\12\u0264\1\u010d\1\u0264"+ + "\1\u010d\1\u0264\1\u010d\1\u0264\1\u010d\1\u0264\6\u010d\1\0"+ + "\17\u010d\1\u0111\1\0\1\u01e4\1\u0265\1\u01e4\1\u023a\2\u017d"+ + "\1\u01e4\1\u017d\1\u0265\11\u01e4\12\u0265\1\u01e4\1\u0265\1\u01e4"+ + "\1\u0265\1\u01e4\1\u0265\1\u01e4\1\u0265\26\u01e4\1\u01e7\1\u01e4"+ + "\1\0\1\u0266\1\u010d\1\u010e\1\u023c\3\u01e6\1\u0266\1\u010d"+ + "\2\0\2\u010d\1\0\3\u010d\12\u0266\1\u010d\1\u0266\1\u010d"+ + "\1\u0266\1\u010d\1\u0266\1\u010d\1\u0266\6\u010d\1\0\15\u010d"+ + "\1\u01e6\1\u010d\1\u0111\2\0\2\u01e4\1\u023a\1\u017a\1\u01e6"+ + "\2\u017a\2\u01e4\2\0\2\u01e4\1\0\33\u01e4\1\0\15\u01e4"+ + "\1\u017a\1\u01e4\1\u0111\1\0\1\u010f\1\u0267\1\u010f\1\u017f"+ + "\1\u01e9\3\u010f\1\u0267\1\u010f\1\u017a\7\u010f\12\u0267\1\u010f"+ + "\1\u0267\1\u010f\1\u0267\1\u010f\1\u0267\1\u010f\1\u0267\30\u010f"+ + "\1\u0110\1\u0268\1\u0110\1\u0180\1\u01eb\3\u0110\1\u0268\2\u0110"+ + "\1\u017a\6\u0110\12\u0268\1\u0110\1\u0268\1\u0110\1\u0268\1\u0110"+ + "\1\u0268\1\u0110\1\u0268\30\u0110\33\0\1\u0117\1\0\1\u0117"+ + "\61\0\1\u0269\1\u0187\1\0\1\u0187\50\0\1\u0188\1\0"+ + "\1\u0119\43\0\1\u0189\45\0\1\u026a\7\0\1\u01f2\1\0"+ + "\1\u01f2\41\0\1\u01f3\1\u026b\3\u0189\44\0\1\u01f4\13\0"+ + "\1\u0189\26\0\1\u026c\7\0\1\u0245\1\0\1\u0245\62\0"+ + "\1\u026d\72\0\1\u026e\1\u026f\1\0\1\u026f\50\0\1\u0270"+ + "\42\0\1\u0271\26\0\2\66\1\67\1\260\5\66\10\0"+ + "\30\66\1\0\5\66\10\0\1\66\73\0\1\u0272\36\0"+ + "\1\u0123\1\0\1\u0123\61\0\1\u0273\1\u0192\1\0\1\u0192"+ + "\50\0\1\u0193\1\0\1\u0125\43\0\1\u0194\45\0\1\u0274"+ + "\7\0\1\u01fd\1\0\1\u01fd\41\0\1\u01fe\1\u0275\3\u0194"+ + "\44\0\1\u01ff\13\0\1\u0194\26\0\1\u0276\7\0\1\u0250"+ + "\1\0\1\u0250\62\0\1\u0277\73\0\1\u0129\1\0\1\u0129"+ + "\70\0\1\u0278\1\u019a\1\0\1\u019a\50\0\1\u019b\1\0"+ + "\1\u012b\14\0\1\u019c\74\0\1\u0279\1\u0206\1\0\1\u0206"+ + "\51\0\1\u027a\3\u019c\60\0\1\u019c\27\0\1\u012f\1\0"+ + "\1\u012f\70\0\1\u027b\1\u01a2\1\0\1\u01a2\52\0\1\u0131"+ + "\67\0\2\23\1\75\1\u0148\3\103\2\23\10\0\30\23"+ + "\1\0\5\23\10\0\1\103\4\0\2\23\1\205\1\u014c"+ + "\3\105\2\23\10\0\12\23\1\206\15\23\1\0\5\23"+ + "\10\0\1\105\4\0\1\u020c\1\23\1\75\1\162\3\23"+ + "\1\u020c\1\23\10\0\12\u020c\1\23\1\u027c\1\23\1\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\6\23\1\0\5\23\10\0"+ + "\1\23\4\0\1\u020c\1\23\1\75\1\u01be\3\206\1\u020c"+ + "\1\23\10\0\12\u020c\1\23\1\u020c\1\23\1\u020c\1\23"+ + "\1\u020c\1\23\1\u020c\6\23\1\0\5\23\10\0\1\206"+ + "\4\0\2\23\1\75\1\u0155\3\107\2\23\10\0\30\23"+ + "\1\0\5\23\10\0\1\107\4\0\2\23\1\75\1\u0156"+ + "\3\110\2\23\10\0\30\23\1\0\5\23\10\0\1\110"+ + "\4\0\2\23\1\75\1\u015c\3\113\2\23\10\0\30\23"+ + "\1\0\5\23\10\0\1\113\4\0\2\23\1\231\1\u0169"+ + "\3\121\2\23\10\0\7\23\1\206\20\23\1\0\5\23"+ + "\10\0\1\121\4\0\1\u020c\1\23\1\75\1\162\3\23"+ + "\1\u020c\1\23\10\0\2\u020c\1\u027c\7\u020c\1\23\1\u020c"+ + "\1\23\1\u020c\1\23\1\u020c\1\23\1\u020c\6\23\1\0"+ + "\5\23\10\0\1\23\3\0\11\u0172\1\u027d\3\u0172\1\u01db"+ + "\42\u0172\1\u01dc\13\u0172\1\0\2\4\1\43\1\u0179\3\140"+ + "\2\4\4\0\1\247\3\0\30\4\1\0\5\4\10\0"+ + "\1\140\4\0\1\u027e\1\u010d\1\u010e\1\u01e3\3\u010d\1\u027e"+ + "\1\u010d\2\0\2\u010d\1\0\3\u010d\12\u027e\1\u010d\1\u027e"+ + "\1\u010d\1\u027e\1\u010d\1\u027e\1\u010d\1\u027e\6\u010d\1\0"+ + "\17\u010d\1\u0111\2\0\1\u027f\1\u01e4\1\u023a\1\u0280\3\u01e4"+ + "\1\u027f\1\u01e4\2\0\2\u01e4\1\0\3\u01e4\12\u027f\1\u01e4"+ + "\1\u027f\1\u01e4\1\u027f\1\u01e4\1\u027f\1\u01e4\1\u027f\6\u01e4"+ + "\1\0\17\u01e4\1\u0111\2\0\1\u0281\1\u010d\1\u010e\1\u023c"+ + "\3\u01e6\1\u0281\1\u010d\2\0\2\u010d\1\0\3\u010d\12\u0281"+ + "\1\u010d\1\u0281\1\u010d\1\u0281\1\u010d\1\u0281\1\u010d\1\u0281"+ + "\6\u010d\1\0\15\u010d\1\u01e6\1\u010d\1\u0111\1\0\1\u010f"+ + "\1\u0282\1\u010f\1\u017f\1\u01e9\3\u010f\1\u0282\1\u010f\1\u017a"+ + "\7\u010f\12\u0282\1\u010f\1\u0282\1\u010f\1\u0282\1\u010f\1\u0282"+ + "\1\u010f\1\u0282\30\u010f\1\u0110\1\u0283\1\u0110\1\u0180\1\u01eb"+ + "\3\u0110\1\u0283\2\u0110\1\u017a\6\u0110\12\u0283\1\u0110\1\u0283"+ + "\1\u0110\1\u0283\1\u0110\1\u0283\1\u0110\1\u0283\30\u0110\24\0"+ + "\1\u0187\1\0\1\u0187\70\0\1\u0284\7\0\1\u01f2\1\0"+ + "\1\u01f2\41\0\1\u01f3\1\0\1\u0189\46\0\1\u01f4\42\0"+ + "\1\u0285\7\0\1\u0245\1\0\1\u0245\41\0\1\u0246\1\u0286"+ + "\3\u01f4\12\0\1\u0247\45\0\1\u01f4\26\0\1\u0287\1\u026f"+ + "\1\0\1\u026f\72\0\1\u0288\71\0\1\u0289\1\u028a\1\0"+ + "\1\u028a\17\0\1\u0271\30\0\1\u028b\50\0\1\u028c\43\0"+ + "\1\u0192\1\0\1\u0192\70\0\1\u028d\7\0\1\u01fd\1\0"+ + "\1\u01fd\41\0\1\u01fe\1\0\1\u0194\46\0\1\u01ff\42\0"+ + "\1\u028e\7\0\1\u0250\1\0\1\u0250\42\0\1\u028f\3\u01ff"+ + "\60\0\1\u01ff\27\0\1\u019a\1\0\1\u019a\70\0\1\u0290"+ + "\1\u0206\1\0\1\u0206\52\0\1\u019c\112\0\1\u01a2\1\0"+ + "\1\u01a2\46\0\2\23\1\75\1\u01be\3\206\2\23\10\0"+ + "\30\23\1\0\5\23\10\0\1\206\4\0\1\u0291\1\u010d"+ + "\1\u010e\1\u01e3\3\u010d\1\u0291\1\u010d\2\0\2\u010d\1\0"+ + "\3\u010d\12\u0291\1\u010d\1\u0291\1\u010d\1\u0291\1\u010d\1\u0291"+ + "\1\u010d\1\u0291\6\u010d\1\0\17\u010d\1\u0111\2\0\1\u0292"+ + "\1\u01e4\1\u023a\1\u0280\3\u01e4\1\u0292\1\u01e4\2\0\2\u01e4"+ + "\1\0\3\u01e4\12\u0292\1\u01e4\1\u0292\1\u01e4\1\u0292\1\u01e4"+ + "\1\u0292\1\u01e4\1\u0292\6\u01e4\1\0\17\u01e4\1\u0111\2\0"+ + "\2\u01e4\1\u023a\1\u017d\1\u01e4\2\u017d\2\u01e4\2\0\2\u01e4"+ + "\1\0\33\u01e4\1\0\15\u01e4\1\u017d\1\u01e4\1\u0111\2\0"+ + "\1\u0293\1\u010d\1\u010e\1\u023c\3\u01e6\1\u0293\1\u010d\2\0"+ + "\2\u010d\1\0\3\u010d\12\u0293\1\u010d\1\u0293\1\u010d\1\u0293"+ + "\1\u010d\1\u0293\1\u010d\1\u0293\6\u010d\1\0\15\u010d\1\u01e6"+ + "\1\u010d\1\u0111\1\0\1\u010f\1\u0294\1\u010f\1\u017f\1\u01e9"+ + "\3\u010f\1\u0294\1\u010f\1\u017a\7\u010f\12\u0294\1\u010f\1\u0294"+ + "\1\u010f\1\u0294\1\u010f\1\u0294\1\u010f\1\u0294\30\u010f\1\u0110"+ + "\1\u0295\1\u0110\1\u0180\1\u01eb\3\u0110\1\u0295\2\u0110\1\u017a"+ + "\6\u0110\12\u0295\1\u0110\1\u0295\1\u0110\1\u0295\1\u0110\1\u0295"+ + "\1\u0110\1\u0295\30\u0110\33\0\1\u01f2\1\0\1\u01f2\61\0"+ + "\1\u0296\7\0\1\u0245\1\0\1\u0245\41\0\1\u0246\1\0"+ + "\1\u01f4\14\0\1\u0247\74\0\1\u0297\1\u026f\1\0\1\u026f"+ + "\50\0\1\u0270\1\u0298\3\u0247\36\0\1\u0271\21\0\1\u0247"+ + "\26\0\1\u0299\1\u028a\1\0\1\u028a\77\0\1\u029a\64\0"+ + "\1\u029b\7\0\1\u029c\1\0\1\u029c\16\0\1\u028c\52\0"+ + "\1\u01fd\1\0\1\u01fd\61\0\1\u029d\7\0\1\u0250\1\0"+ + "\1\u0250\43\0\1\u01ff\112\0\1\u0206\1\0\1\u0206\46\0"+ + "\2\u010d\1\u010e\1\u01e3\5\u010d\2\0\2\u010d\1\0\33\u010d"+ + "\1\0\17\u010d\1\u0111\2\0\1\u029e\1\u01e4\1\u023a\1\u0280"+ + "\3\u01e4\1\u029e\1\u01e4\2\0\2\u01e4\1\0\3\u01e4\12\u029e"+ + "\1\u01e4\1\u029e\1\u01e4\1\u029e\1\u01e4\1\u029e\1\u01e4\1\u029e"+ + "\6\u01e4\1\0\17\u01e4\1\u0111\2\0\1\u029f\1\u010d\1\u010e"+ + "\1\u023c\3\u01e6\1\u029f\1\u010d\2\0\2\u010d\1\0\3\u010d"+ + "\12\u029f\1\u010d\1\u029f\1\u010d\1\u029f\1\u010d\1\u029f\1\u010d"+ + "\1\u029f\6\u010d\1\0\15\u010d\1\u01e6\1\u010d\1\u0111\1\0"+ + "\1\u010f\1\u02a0\1\u010f\1\u017f\1\u01e9\3\u010f\1\u02a0\1\u010f"+ + "\1\u017a\7\u010f\12\u02a0\1\u010f\1\u02a0\1\u010f\1\u02a0\1\u010f"+ + "\1\u02a0\1\u010f\1\u02a0\30\u010f\1\u0110\1\u02a1\1\u0110\1\u0180"+ + "\1\u01eb\3\u0110\1\u02a1\2\u0110\1\u017a\6\u0110\12\u02a1\1\u0110"+ + "\1\u02a1\1\u0110\1\u02a1\1\u0110\1\u02a1\1\u0110\1\u02a1\30\u0110"+ + "\33\0\1\u0245\1\0\1\u0245\61\0\1\u02a2\1\u026f\1\0"+ + "\1\u026f\50\0\1\u0270\1\0\1\u0247\40\0\1\u0271\50\0"+ + "\1\u02a3\1\u028a\1\0\1\u028a\50\0\1\u028b\1\u02a4\3\u0271"+ + "\44\0\1\u028c\13\0\1\u0271\26\0\1\u02a5\7\0\1\u029c"+ + "\1\0\1\u029c\62\0\1\u02a6\102\0\1\u0250\1\0\1\u0250"+ + "\37\0\1\u02a7\1\u01e4\1\u023a\1\u0280\3\u01e4\1\u02a7\1\u01e4"+ + "\2\0\2\u01e4\1\0\3\u01e4\12\u02a7\1\u01e4\1\u02a7\1\u01e4"+ + "\1\u02a7\1\u01e4\1\u02a7\1\u01e4\1\u02a7\6\u01e4\1\0\17\u01e4"+ + "\1\u0111\2\0\2\u010d\1\u010e\1\u023c\3\u01e6\2\u010d\2\0"+ + "\2\u010d\1\0\33\u010d\1\0\15\u010d\1\u01e6\1\u010d\1\u0111"+ + "\1\0\3\u010f\1\u017f\1\u01e9\5\u010f\1\u017a\61\u010f\3\u0110"+ + "\1\u0180\1\u01eb\6\u0110\1\u017a\60\u0110\24\0\1\u026f\1\0"+ + "\1\u026f\70\0\1\u02a8\1\u028a\1\0\1\u028a\50\0\1\u028b"+ + "\1\0\1\u0271\46\0\1\u028c\42\0\1\u02a9\7\0\1\u029c"+ + "\1\0\1\u029c\42\0\1\u02aa\3\u028c\60\0\1\u028c\4\0"+ + "\1\u02ab\1\u01e4\1\u023a\1\u0280\3\u01e4\1\u02ab\1\u01e4\2\0"+ + "\2\u01e4\1\0\3\u01e4\12\u02ab\1\u01e4\1\u02ab\1\u01e4\1\u02ab"+ + "\1\u01e4\1\u02ab\1\u01e4\1\u02ab\6\u01e4\1\0\17\u01e4\1\u0111"+ + "\25\0\1\u028a\1\0\1\u028a\70\0\1\u02ac\7\0\1\u029c"+ + "\1\0\1\u029c\43\0\1\u028c\67\0\2\u01e4\1\u023a\1\u0280"+ + "\5\u01e4\2\0\2\u01e4\1\0\33\u01e4\1\0\17\u01e4\1\u0111"+ + "\34\0\1\u029c\1\0\1\u029c\36\0"; + + private static int [] zzUnpackTrans() { + int [] result = new int[39120]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\1\0\1\11\21\1\3\0\13\1\1\11\1\0\1\11"+ + "\3\1\1\0\1\1\1\11\1\1\1\0\1\1\1\0"+ + "\1\1\4\0\2\11\1\1\7\0\4\1\1\0\1\1"+ + "\1\0\1\1\1\0\2\1\2\0\1\1\5\0\6\1"+ + "\1\11\4\1\1\0\2\1\1\0\1\1\5\0\1\1"+ + "\12\0\24\1\1\0\23\1\1\0\16\1\7\0\2\1"+ + "\21\0\103\1\1\0\10\1\1\0\2\1\1\11\10\0"+ + "\1\1\26\0\1\11\100\1\1\0\12\1\1\0\3\1"+ + "\11\0\1\1\21\0\1\11\6\0\70\1\2\0\7\1"+ + "\1\0\7\1\11\0\1\1\11\0\1\11\13\0\52\1"+ + "\1\0\4\1\1\0\4\1\11\0\1\1\14\0\1\1"+ + "\2\0\12\1\1\0\2\1\1\0\3\1\11\0\1\11"+ + "\4\0\1\1\2\0\1\1\1\0\3\1\2\0\3\1"+ + "\10\0\1\11\2\0\1\1\1\0\1\1\1\0\3\1"+ + "\11\0\3\1\4\0\1\1\3\0\1\1\2\0"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[684]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /** + * The number of occupied positions in zzBuffer beyond zzEndRead. + * When a lead/high surrogate has been read from the input stream + * into the final zzBuffer position, this will have a value of 1; + * otherwise, it will have a value of 0. + */ + private int zzFinalHighSurrogate = 0; + + /* user code: */ + + StringBuilder string = new StringBuilder(); + + private static String xmlTagName = ""; + + public int yychar() { + return yychar; + } + + private final Stack pushedBack = new Stack<>(); + + public int yyline() { + return yyline + 1; + } + + private boolean doBuffer = false; + private List buffer = new ArrayList<>(); + + public void startBuffer(){ + doBuffer = true; + } + + public String getAndClearBuffer(){ + StringBuilder sb = new StringBuilder(); + for(CssParsedSymbol s:buffer){ + sb.append(s.value); + } + buffer.clear(); + doBuffer = false; + return sb.toString(); + } + + public int getPos(){ + int pos = yychar() + yylength(); + for(CssParsedSymbol p:pushedBack) { + pos -= p.value.length(); + } + return pos; + } + + public void pushback(CssParsedSymbol symb) { + pushedBack.push(symb); + if(!buffer.isEmpty()){ + buffer.remove(buffer.size()-1); + } + last = null; + } + + CssParsedSymbol last; + public CssParsedSymbol lex() throws java.io.IOException { + CssParsedSymbol ret = null; + if (!pushedBack.isEmpty()){ + ret = last = pushedBack.pop(); + } else { + ret = last = yylex(); + } + if (doBuffer){ + buffer.add(ret); + } + return ret; + } + + + + /** + * Creates a new scanner + * + * @param in the java.io.Reader to read input from. + */ + public CssLexer(java.io.Reader in) { + this.zzReader = in; + } + + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x110000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 256) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length - zzFinalHighSurrogate) { + /* if not: blow it up */ + char newBuffer[] = new char[zzBuffer.length*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + } + + /* fill the buffer with new input */ + int requested = zzBuffer.length - zzEndRead; + int totalRead = 0; + while (totalRead < requested) { + int numRead = zzReader.read(zzBuffer, zzEndRead + totalRead, requested - totalRead); + if (numRead == -1) { + break; + } + totalRead += numRead; + } + + if (totalRead > 0) { + zzEndRead += totalRead; + if (totalRead == requested) { /* possibly more input available */ + if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) { + --zzEndRead; + zzFinalHighSurrogate = 1; + } + } + return false; + } + + // totalRead = 0: End of stream + return true; + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * Internal scan buffer is resized down to its initial length, if it has grown. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEOFDone = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = 0; + zzFinalHighSurrogate = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + if (zzBuffer.length > ZZ_BUFFERSIZE) + zzBuffer = new char[ZZ_BUFFERSIZE]; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public CssParsedSymbol yylex() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + yychar+= zzMarkedPosL-zzStartRead; + + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; + + // set up zzAction for empty match case: + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + } + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 1: + { return new CssParsedSymbol(yytext(), CssSymbolType.OTHER); + } + case 29: break; + case 2: + { return new CssParsedSymbol(yytext(), CssSymbolType.NUMBER); + } + case 30: break; + case 3: + { return new CssParsedSymbol(yytext(), CssSymbolType.IDENT); + } + case 31: break; + case 4: + { return new CssParsedSymbol(yytext(), CssSymbolType.S); + } + case 32: break; + case 5: + { return new CssParsedSymbol(yytext(), CssSymbolType.BAD_STRING); + } + case 33: break; + case 6: + { return new CssParsedSymbol(yytext(), CssSymbolType.DIMENSION); + } + case 34: break; + case 7: + { return new CssParsedSymbol(yytext(), CssSymbolType.TIME); + } + case 35: break; + case 8: + { return new CssParsedSymbol(yytext(), CssSymbolType.PERCENTAGE); + } + case 36: break; + case 9: + { return new CssParsedSymbol(yytext(), CssSymbolType.FUNCTION); + } + case 37: break; + case 10: + { return new CssParsedSymbol(yytext(), CssSymbolType.STRING); + } + case 38: break; + case 11: + { return new CssParsedSymbol(yytext(), CssSymbolType.INCLUDES); + } + case 39: break; + case 12: + { return new CssParsedSymbol(yytext(), CssSymbolType.DASHMATCH); + } + case 40: break; + case 13: + { return new CssParsedSymbol(yytext(), CssSymbolType.HASH); + } + case 41: break; + case 14: + { return new CssParsedSymbol(yytext(), CssSymbolType.LENGTH); + } + case 42: break; + case 15: + { return new CssParsedSymbol(yytext(), CssSymbolType.EMS); + } + case 43: break; + case 16: + { return new CssParsedSymbol(yytext(), CssSymbolType.EXS); + } + case 44: break; + case 17: + { return new CssParsedSymbol(yytext(), CssSymbolType.FREQ); + } + case 45: break; + case 18: + { return new CssParsedSymbol(yytext(), CssSymbolType.CDC); + } + case 46: break; + case 19: + { return new CssParsedSymbol(yytext(), CssSymbolType.ANGLE); + } + case 47: break; + case 20: + { + } + case 48: break; + case 21: + { return new CssParsedSymbol(yytext(), CssSymbolType.BAD_URI); + } + case 49: break; + case 22: + { return new CssParsedSymbol(yytext(), CssSymbolType.URI); + } + case 50: break; + case 23: + { return new CssParsedSymbol(yytext(), CssSymbolType.PAGE_SYM); + } + case 51: break; + case 24: + { return new CssParsedSymbol(yytext(), CssSymbolType.MEDIA_SYM); + } + case 52: break; + case 25: + { return new CssParsedSymbol(yytext(), CssSymbolType.IMPORT_SYM); + } + case 53: break; + case 26: + { return new CssParsedSymbol(yytext(), CssSymbolType.CHARSET_SYM); + } + case 54: break; + case 27: + { return new CssParsedSymbol(yytext(), CssSymbolType.CDO); + } + case 55: break; + case 28: + { return new CssParsedSymbol(yytext(), CssSymbolType.IMPORTANT_SYM); + } + case 56: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + { + return new CssParsedSymbol("", CssSymbolType.EOF); + } + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParseException.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParseException.java new file mode 100644 index 000000000..9bb40cd79 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParseException.java @@ -0,0 +1,15 @@ +package com.jpexs.decompiler.flash.importers.svg.css; + +/** + * + * @author JPEXS + */ +public class CssParseException extends Exception { + public CssParseException(String s) { + super(s); + } + + public CssParseException() { + + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParsedSymbol.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParsedSymbol.java new file mode 100644 index 000000000..3f35c5136 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParsedSymbol.java @@ -0,0 +1,41 @@ +package com.jpexs.decompiler.flash.importers.svg.css; + +/** + * + * @author JPEXS + */ +public class CssParsedSymbol { + public String value; + public CssSymbolType type; + + public CssParsedSymbol(String value, CssSymbolType type) { + this.value = value; + this.type = type; + } + + public boolean isType(String... ss){ + if(type == CssSymbolType.OTHER){ + for(String s:ss){ + if(s.equals(value)){ + return true; + } + } + } + return false; + } + + public boolean isType(CssSymbolType... types){ + for(CssSymbolType type:types){ + if(this.type == type){ + return true; + } + } + return false; + } + + @Override + public String toString() { + return type.toString() + ": " + value; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParser.java new file mode 100644 index 000000000..9a330ba1e --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssParser.java @@ -0,0 +1,477 @@ +package com.jpexs.decompiler.flash.importers.svg.css; + +import com.jpexs.helpers.Reference; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * + * CSS Stylesheet parser. Based on https://www.w3.org/TR/CSS21/grammar.html + * + * @author JPEXS + */ +public class CssParser { + + private final CssLexer lexer; + private final String s; + + private final List selectors = new ArrayList<>(); + private final List declarations = new ArrayList<>(); + + private final List> propNames = new ArrayList<>(); + private final List> propValues = new ArrayList<>(); + + private final List specifities = new ArrayList<>(); + + public CssParser(String s) { + this.s = s; + this.lexer = new CssLexer(new StringReader(s)); + } + + public void styleshet() throws IOException, CssParseException { + CssParsedSymbol symb = lex(); + if (symb.type == CssSymbolType.CHARSET_SYM) { + expect(CssSymbolType.STRING); + expect(";"); + symb = lex(); + } + while (symb.isType(CssSymbolType.S, CssSymbolType.CDO, CssSymbolType.CDC)) { + symb = lex(); + } + while (symb.type == CssSymbolType.IMPORT_SYM) { + sstar(); + expect(CssSymbolType.STRING, CssSymbolType.URI); + sstar(); + symb = lex(); + if (!symb.isType(";")) { + lexer.pushback(symb); + media_list(); + expect(";"); + } + sstar(); + symb = lex(); + while (symb.isType(CssSymbolType.CDO, CssSymbolType.CDC)) { + sstar(); + symb = lex(); + } + } + + while (symb.type != CssSymbolType.EOF) { + if (symb.type == CssSymbolType.MEDIA_SYM) { + lexer.pushback(symb); + media(); + } else if (symb.type == CssSymbolType.PAGE_SYM) { + lexer.pushback(symb); + List propNames = new ArrayList<>(); + List propValues = new ArrayList<>(); + page(propNames, propValues); + } else { + lexer.pushback(symb); + if (!ruleset()) { + break; + } + } + symb = lex(); + while (symb.isType(CssSymbolType.CDO, CssSymbolType.CDC)) { + sstar(); + symb = lex(); + } + } + } + + private boolean ruleset() throws IOException, CssParseException { + int posSelectorStart = lexer.getPos(); + int specifity = selector(); + if (specifity == -1) { + return false; + } + CssParsedSymbol symb = lex(); + while (symb.isType(",")) { + sstar(); + specifity += selector(); + symb = lex(); + } + expect(symb, "{"); + + int posSelectorEnd = lexer.getPos() - 1; + String selectorStr = s.substring(posSelectorStart, posSelectorEnd).trim(); + selectors.add(selectorStr); + specifities.add(specifity); + + int declarationsStart = lexer.getPos(); + Reference propName = new Reference<>(""); + Reference propValue = new Reference<>(""); + + List propNames = new ArrayList<>(); + List propValues = new ArrayList<>(); + + sstar(); + symb = lex(); + if (symb.type == CssSymbolType.IDENT) { + lexer.pushback(symb); + declaration(propName, propValue); + propNames.add(propName.getVal()); + propValues.add(propValue.getVal()); + symb = lex(); + } + while (symb.isType(";")) { + sstar(); + symb = lex(); + if (symb.type == CssSymbolType.IDENT) { + lexer.pushback(symb); + declaration(propName, propValue); + propNames.add(propName.getVal()); + propValues.add(propValue.getVal()); + symb = lex(); + } + } + expect(symb, "}"); + int declarationsEnd = lexer.getPos() - 1; + String declaration = s.substring(declarationsStart, declarationsEnd); + declarations.add(declaration); + + this.propNames.add(propNames); + this.propValues.add(propValues); + + sstar(); + return true; + } + + private int selector() throws IOException, CssParseException { + int specifity = simple_selector(); + if (specifity == -1) { + return -1; + } + + CssParsedSymbol symb = lex(); + if (symb.type == CssSymbolType.S) { + while (symb.type == CssSymbolType.S) { + symb = lex(); + } + if (symb.isType("+", ">")) { + sstar(); + specifity += selector(); + } else { + lexer.pushback(symb); + if (symb.isType("*", ".", "[", ":") || symb.isType(CssSymbolType.IDENT, CssSymbolType.HASH)) { + specifity += selector(); + } + } + } else if (symb.isType("+", ">")) { + sstar(); + specifity += selector(); + } else { + lexer.pushback(symb); + } + return specifity; + } + + private int simple_selector() throws IOException, CssParseException { + CssParsedSymbol symb = lex(); + int specifity = 0; + if (symb.isType(CssSymbolType.IDENT) || symb.isType("*")) { + if (symb.isType(CssSymbolType.IDENT)) { + specifity += 1; + } + while (true) { + symb = lex(); + if (symb.type == CssSymbolType.HASH) { + specifity += 100; + } else if (symb.isType(".")) { + expect(CssSymbolType.IDENT); + specifity += 10; + } else if (symb.isType("[")) { + lexer.pushback(symb); + attrib(); + specifity += 10; + } else if (symb.isType(":")) { + lexer.pushback(symb); + pseudo(); + specifity += 10; + } else { + lexer.pushback(symb); + break; + } + } + } else { + int count = 0; + while (true) { + if (symb.type == CssSymbolType.HASH) { + specifity += 100; + count++; + } else if (symb.isType(".")) { + expect(CssSymbolType.IDENT); + specifity += 10; + count++; + } else if (symb.isType("[")) { + lexer.pushback(symb); + attrib(); + specifity += 10; + count++; + } else if (symb.isType(":")) { + lexer.pushback(symb); + pseudo(); + specifity += 10; + count++; + } else { + if (count == 0) { + lexer.pushback(symb); + return -1; + } + break; + } + symb = lex(); + } + lexer.pushback(symb); + } + return specifity; + } + + private void pseudo() throws IOException, CssParseException { + expect(":"); + CssParsedSymbol symb = lex(); + if (symb.type == CssSymbolType.IDENT) { + //okay + } else if (symb.type == CssSymbolType.FUNCTION) { + sstar(); + symb = lex(); + if (symb.type == CssSymbolType.IDENT) { + sstar(); + symb = lex(); + } + expect(symb, ")"); + } + } + + private void attrib() throws IOException, CssParseException { + expect("["); + sstar(); + expect(CssSymbolType.IDENT); + sstar(); + CssParsedSymbol symb = lex(); + if (symb.isType(CssSymbolType.INCLUDES, CssSymbolType.DASHMATCH) || symb.isType("=")) { + sstar(); + expect(CssSymbolType.IDENT, CssSymbolType.STRING); + sstar(); + symb = lex(); + } + expect(symb, "]"); + + } + + private void page(List propNames, List propValues) throws IOException, CssParseException { + expect(CssSymbolType.PAGE_SYM); + sstar(); + CssParsedSymbol symb = lex(); + if (symb.isType(":")) { //pseudo_page + expect(CssSymbolType.IDENT); + sstar(); + symb = lex(); + } + expect(symb, "{"); + sstar(); + Reference propName = new Reference<>(""); + Reference propValue = new Reference<>(""); + declaration(propName, propValue); + propNames.add(propName.getVal()); + propValues.add(propValue.getVal()); + symb = lex(); + while (symb.isType(";")) { + sstar(); + symb = lex(); + if (!symb.isType(";", "}")) { + declaration(propName, propValue); + propNames.add(propName.getVal()); + propValues.add(propValue.getVal()); + } + } + expect(symb, "}"); + + } + + private void declaration(Reference propName, Reference propValue) throws IOException, CssParseException { + CssParsedSymbol symb = lex(); + expect(symb, CssSymbolType.IDENT); + propName.setVal(symb.value); + sstar(); + expect(":"); + sstar(); + lexer.startBuffer(); + expr(); + symb = lex(); + if (symb.type == CssSymbolType.IMPORTANT_SYM) { + sstar(); + } else { + lexer.pushback(symb); + } + propValue.setVal(lexer.getAndClearBuffer()); + } + + private void expr() throws IOException, CssParseException { + term(true); + while (true) { + CssParsedSymbol symb = lex(); + if (symb.isType("/", ",")) { + sstar(); + term(true); + } else { + lexer.pushback(symb); + if (!term(false)) { + break; + } + } + } + + } + + private boolean term(boolean required) throws IOException, CssParseException { + CssParsedSymbol symb = lex(); + if (symb.isType("-", "+")) { + symb = lex(); + } + if (symb.isType(CssSymbolType.NUMBER, CssSymbolType.PERCENTAGE, + CssSymbolType.LENGTH, CssSymbolType.EMS, CssSymbolType.EXS, + CssSymbolType.ANGLE, CssSymbolType.TIME, CssSymbolType.FREQ)) { + sstar(); + } else if (symb.isType(CssSymbolType.STRING, CssSymbolType.IDENT, CssSymbolType.URI)) { + sstar(); + } else if (symb.type == CssSymbolType.HASH) { + sstar(); + } else if (symb.type == CssSymbolType.FUNCTION) { + sstar(); + expr(); + expect(")"); + sstar(); + } else { + lexer.pushback(symb); + if (required) { + throw new CssParseException(); + } + return false; + } + return true; + } + + + private void media() throws IOException, CssParseException { + expect(CssSymbolType.MEDIA_SYM); + sstar(); + media_list(); + expect("{"); + sstar(); + CssParsedSymbol symb = lex(); + while (!symb.isType("}")) { + if (!ruleset()) { + break; + } + symb = lex(); + } + sstar(); + } + + private void medium() throws IOException, CssParseException { + expect(CssSymbolType.IDENT); + sstar(); + } + + private void media_list() throws IOException, CssParseException { + medium(); + CssParsedSymbol symb = lex(); + while (symb.isType(",")) { + sstar(); + medium(); + } + lexer.pushback(symb); + } + + private void sstar() throws IOException { + CssParsedSymbol symb = lex(); + while (symb.type == CssSymbolType.S) { + symb = lex(); + } + lexer.pushback(symb); + } + + private CssParsedSymbol lex() throws IOException { + CssParsedSymbol v = lexer.lex(); + //System.err.println("" + v); + return v; + } + + private void expect(String s) throws IOException, CssParseException { + CssParsedSymbol symb = lex(); + if (symb.type != CssSymbolType.OTHER) { + throw new CssParseException(s + " expected but " + symb + " found"); + } + if (!s.equals(symb.value)) { + throw new CssParseException(s + " expected but " + symb + " found"); + } + } + + private void expect(CssParsedSymbol symb, String s) throws IOException, CssParseException { + if (symb.type != CssSymbolType.OTHER) { + throw new CssParseException(s + " expected but " + symb + " found"); + } + if (!s.equals(symb.value)) { + throw new CssParseException(s + " expected but " + symb.value + " found"); + } + } + + private void expect(CssParsedSymbol symb, CssSymbolType... types) throws IOException, CssParseException { + List toPrint = new ArrayList<>(); + for (CssSymbolType type : types) { + toPrint.add(type.toString()); + if (symb.type == type) { + return; + } + } + + throw new CssParseException(String.join(",", toPrint) + " expected but " + symb + " found"); + } + + private void expect(CssSymbolType... types) throws IOException, CssParseException { + List toPrint = new ArrayList<>(); + CssParsedSymbol symb = lex(); + + for (CssSymbolType type : types) { + toPrint.add(type.toString()); + if (symb.type == type) { + return; + } + } + + throw new CssParseException(String.join(",", toPrint) + " expected but " + symb + " found"); + } + + public int getCountRulesets() { + return declarations.size(); + } + + public String getSelector(int index) { + return selectors.get(index); + } + + public String getDeclarations(int index) { + return declarations.get(index); + } + + public int getPropertyCount(int index) { + return propNames.get(index).size(); + } + + public String getPropertyName(int ruleSetIndex, int propertyIndex) { + return propNames.get(ruleSetIndex).get(propertyIndex); + } + + public String getPropertyValue(int ruleSetIndex, int propertyIndex) { + return propValues.get(ruleSetIndex).get(propertyIndex); + } + + public int getSpecifity(int index) { + return specifities.get(index); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssSelectorToXPath.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssSelectorToXPath.java new file mode 100644 index 000000000..65628e9fe --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssSelectorToXPath.java @@ -0,0 +1,686 @@ +package com.jpexs.decompiler.flash.importers.svg.css; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @author JPEXS + * + * Based on implementation https://github.com/css2xpath/css2xpath + * + */ +public class CssSelectorToXPath { + + private String xpath_to_lower(String s) { + return "translate(" + + (s == null ? "normalize-space()" : s) + + ", 'ABCDEFGHJIKLMNOPQRSTUVWXYZ'" + + ", 'abcdefghjiklmnopqrstuvwxyz')"; + } + + private String xpath_ends_with(String s1, String s2) { + return "substring(" + s1 + "," + + "string-length(" + s1 + ")-string-length(" + s2 + ")+1)=" + s2; + } + + private String xpath_url(String s) { + return "substring-before(concat(substring-after(" + + (s == null ? xpath_url_attrs : s) + ",\"://\"),\"?\"),\"?\")"; + } + + private String xpath_url_path(String s) { + return "substring-after(" + (s == null || s.isEmpty() ? xpath_url_attrs : s) + ",\"/\")"; + } + + private String xpath_url_domain(String s) { + return "substring-before(concat(substring-after(" + + (s == null || s.isEmpty() ? xpath_url_attrs : s) + ",\"://\"),\"/\"),\"/\")"; + } + private final String xpath_url_attrs = "@href|@src"; + private final String xpath_lower_case = xpath_to_lower(null); + private final String xpath_ns_uri = "ancestor-or-self::*[last()]/@url"; + private final String xpath_ns_path = xpath_url_path(xpath_url(xpath_ns_uri)); + private final String xpath_has_protocal = "(starts-with(" + xpath_url_attrs + ",\"http://\") or starts-with(" + xpath_url_attrs + ",\"https://\"))"; + private final String xpath_is_internal = "starts-with(" + xpath_url(null) + "," + xpath_url_domain(xpath_ns_uri) + ") or " + xpath_ends_with(xpath_url_domain(null), xpath_url_domain(xpath_ns_uri)); + private final String xpath_is_local = "(" + xpath_has_protocal + " and starts-with(" + xpath_url(null) + "," + xpath_url(xpath_ns_uri) + "))"; + private final String xpath_is_path = "starts-with(" + xpath_url_attrs + ",\"/\")"; + private final String xpath_is_local_path = "starts-with(" + xpath_url_path(null) + "," + xpath_ns_path + ")"; + private final String xpath_normalize_space = "normalize-space()"; + private final String xpath_internal = "[not(" + xpath_has_protocal + ") or " + xpath_is_internal + "]"; + private final String xpath_external = "[" + xpath_has_protocal + " and not(" + xpath_is_internal + ")]"; + private final char escape_literal = (char) 30; + private final char escape_parens = (char) 31; + private final String regex_string_literal = "(\"[^\"\\x1E]*\"|'[^'\\x1E]*'|=\\s*[^\\s\\]\\'\\\"]+)"; // /g + private final String regex_escaped_literal = "['\"]?(\\x1E+)['\"]?"; // /g; + private final String regex_css_wrap_pseudo = "(\\x1F\\)|[^\\)])\\:(first|limit|last|gt|lt|eq|nth)([^\\-]|$)"; // bez g + private final String regex_specal_chars = "[\\x1C-\\x1F]+"; // /g; + private final String regex_first_axis = "^([\\s\\(\\x1F]*)(\\.?[^\\.\\/\\(]{1,2}[a-z]*:*)"; + private final String regex_filter_prefix = "(^|\\/|\\:)\\["; // /g; + private final String regex_attr_prefix = "([^\\(\\[\\/\\|\\s\\x1F])\\@"; // /g; + private final String regex_nth_equation = "^([-0-9]*)n.*?([0-9]*)$"; //bez g + private final String css_combinators_regex = "\\s*(!?[+>~,^ ])\\s*(\\.?\\/+|[a-z\\-]+::)?([a-z\\-]+\\()?((and\\s*|or\\s*|mod\\s*)?[^+>~,\\s'\"\\]\\|\\^\\$\\!\\<\\=\\x1C-\\x1F]+)?"; // /g; + + // Check if string is numeric + private boolean isNumeric(String s) { + try { + Integer.parseInt(s); + } catch (NumberFormatException nfe) { + return false; + } + return true; + } + + private String css_combinators_callback(String match, String operator, String axis, String func, String literal, String exclude, int offset, String orig) { + String prefix = ""; // If we can, we'll prefix a '.' + + // XPath operators can look like node-name selectors + // Detect false positive for " and", " or", " mod" + if (operator.equals(" ") && exclude != null) { + return match; + } + + if (axis == null) { + // Only allow node-selecting XPath functions + // Detect false positive for " + count(...)", " count(...)", " > position()", etc. + if (func != null && (!func.equals("node(") && !func.equals("text(") && !func.equals("comment("))) { + return null; + } else if (literal == null) { + literal = func; + } // Handle case " + text()", " > comment()", etc. where "func" is our "literal" + + // XPath math operators match some CSS combinators + // Detect false positive for " + 1", " > 1", etc. + if (isNumeric(literal)) { + return match; + } + + if (orig.length() <= offset - 1) { + prefix = "."; + } else { + char prevChar = orig.charAt(offset - 1); + + if (prevChar == '(' + || prevChar == '|' + || prevChar == ':') { + prefix = "."; + } + } + } + + // Return if we don't have a selector to follow the axis + if (literal == null) { + if (offset + match.length() == orig.length()) { + literal = "*"; + } else { + return match; + } + } + + switch (operator) { + case " ": + return "//" + literal; + case ">": + return "/" + literal; + case "+": + return prefix + "/following-sibling::*[1]/self::" + literal; + case "~": + return prefix + "/following-sibling::" + literal; + case ",": + if (axis == null) { + + } + axis = ".//"; + return "|" + axis + literal; + case "^": // first child + return "/child::*[1]/self::" + literal; + case "!^": // last child + return "/child::*[last()]/self::" + literal; + case "! ": // ancestor-or-self + return "/ancestor-or-self::" + literal; + case "!>": // direct parent + return "/parent::" + literal; + case "!+": // adjacent preceding sibling + return "/preceding-sibling::*[1]/self::" + literal; + case "!~": // preceding sibling + return "/preceding-sibling::" + literal; + // case '~~' + // return '/following-sibling::*/self::|'+selectorStart(orig, offset)+'/preceding-sibling::*/self::'+literal; + } + return null; + } + + private final String css_attributes_regex = "\\[([^\\@\\|\\*\\=\\^\\~\\$\\!\\(\\/\\s\\x1C-\\x1F]+)\\s*(([\\|\\*\\~\\^\\$\\!]?)=?\\s*(\\x1E+))?\\]"; // /g; + + private String css_attributes_callback(String str, String attr, String comp, String op, String val, int offset, String orig) { + String axis = ""; + //String prevChar = offset == 0 ? "" : "" + orig.charAt(offset - 1); + + /* + if (prevChar === '/' || // found after an axis shortcut ("/", "//", etc.) + prevChar === ':') // found after an axis ("self::", "parent::", etc.) + axis = '*';*/ + if (op == null) { + op = ""; + } + + switch (op) { + case "!": + return axis + "[not(@" + attr + ") or @" + attr + "!=\"" + val + "\"]"; + case "$": + return axis + "[substring(@" + attr + ",string-length(@" + attr + ")-(string-length(\"" + val + "'\")-1))=\"" + val + "\"]"; + case "^": + return axis + "[starts-with(@" + attr + ",\"" + val + "\")]"; + case "~": + return axis + "[contains(concat(\" \",normalize-space(@" + attr + "),\" \"),concat(\" \",\"" + val + "\",\" \"))]"; + case "*": + return axis + "[contains(@" + attr + ",\"" + val + "\")]"; + case "|": + return axis + "[@" + attr + "=\"" + val + "\" or starts-with(@" + attr + ",concat(\"" + val + "\",\"-\"))]"; + default: + if (comp == null) { + if (attr.charAt(attr.length() - 1) == '(' || attr.matches("^[0-9]+$") || attr.indexOf(':') != -1) { + return str; + } + return axis + "[@" + attr + "]"; + } else { + return axis + "[@" + attr + "=\"" + val + "\"]"; + } + } + } + + private final String css_pseudo_classes_regex = ":([a-z\\-]+)(\\((\\x1F+)(([^\\x1F]+(\\3\\x1F+)?)*)(\\3\\)))?"; // /g; + + private String css_pseudo_classes_callback(String match, String name, String g1, String g2, String arg, String g3, String g4, String g5, int offset, String orig) { + if ((offset - 2 >= 0) && orig.charAt(offset - 1) == ':' && orig.charAt(offset - 2) != ':') { + // XPath "axis::node-name" will match + // Detect false positive ":node-name" + return match; + } + + if ("odd".equals(name) || "even".equals(name)) { + arg = name; + name = "nth-of-type"; + } + + switch (name) { // name.toLowerCase()? + case "after": + return "[count(" + css2xpath("preceding::" + arg, true) + ") > 0]"; + case "after-sibling": + return "[count(" + css2xpath("preceding-sibling::" + arg, true) + ") > 0]"; + case "before": + return "[count(" + css2xpath("following::" + arg, true) + ") > 0]"; + case "before-sibling": + return "[count(" + css2xpath("following-sibling::" + arg, true) + ") > 0]"; + case "checked": + return "[@selected or @checked]"; + case "contains": + return "[contains(" + xpath_normalize_space + "," + arg + ")]"; + case "icontains": + return "[contains(" + xpath_lower_case + "," + xpath_to_lower(arg) + ")]"; + case "empty": + return "[not(*) and not(normalize-space())]"; + case "enabled": + case "disabled": + return "[@" + name + "]"; + case "first-child": + return "[not(preceding-sibling::*)]"; + case "first": + case "limit": + case "first-of-type": + if (arg != null) { + return "[position()<=" + arg + "]"; + } + return "[1]"; + case "gt": + // Position starts at 0 for consistency with Sizzle selectors + return "[position()>" + (Integer.parseInt(arg, 10) + 1) + "]"; + case "lt": + // Position starts at 0 for consistency with Sizzle selectors + return "[position()<" + (Integer.parseInt(arg, 10) + 1) + "]"; + case "last-child": + return "[not(following-sibling::*)]"; + case "only-child": + return "[not(preceding-sibling::*) and not(following-sibling::*)]"; + case "only-of-type": + return "[not(preceding-sibling::*[name()=name(self::node())]) and not(following-sibling::*[name()=name(self::node())])]"; + case "nth-child": + if (isNumeric(arg)) { + return "[(count(preceding-sibling::*)+1) = " + arg + "]"; + } + switch (arg) { + case "even": + return "[(count(preceding-sibling::*)+1) mod 2=0]"; + case "odd": + return "[(count(preceding-sibling::*)+1) mod 2=1]"; + default: + String[] a = (arg == null || arg.isEmpty() ? "0" : arg).replaceAll(regex_nth_equation, "$1+$2").split("\\+"); + String a0; + if (a.length < 1 || a[0].isEmpty()) { + a0 = "1"; + } else { + a0 = a[0]; + } + String a1; + if (a.length < 2 || a[1].isEmpty()) { + a1 = "0"; + } else { + a1 = a[1]; + } + return "[(count(preceding-sibling::*)+1)>=" + a1 + " and ((count(preceding-sibling::*)+1)-" + a1 + ") mod " + a0 + "=0]"; + } + case "nth-of-type": + if (isNumeric(arg)) { + return "[" + arg + "]"; + } + switch (arg) { + case "odd": + return "[position() mod 2=1]"; + case "even": + return "[position() mod 2=0 and position()>=0]"; + default: + String[] a = (arg == null || arg.isEmpty() ? "0" : arg).replaceAll(regex_nth_equation, "$1+$2").split("\\+"); + String a0; + if (a.length < 1 || a[0].isEmpty()) { + a0 = "1"; + } else { + a0 = a[0]; + } + String a1; + if (a.length < 2 || a[1].isEmpty()) { + a1 = "0"; + } else { + a1 = a[1]; + } + return "[position()>=" + a1 + " and (position()-" + a1 + ") mod " + a0 + "=0]"; + } + case "eq": + case "nth": + // Position starts at 0 for consistency with Sizzle selectors + if (isNumeric(arg)) { + return "[" + (Integer.parseInt(arg, 10) + 1) + "]"; + } + + return "[1]"; + case "text": + return "[@type=\"text\"]"; + case "istarts-with": + return "[starts-with(" + xpath_lower_case + "," + xpath_to_lower(arg) + ")]"; + case "starts-with": + return "[starts-with(" + xpath_normalize_space + "," + arg + ")]"; + case "iends-with": + return "[" + xpath_ends_with(xpath_lower_case, xpath_to_lower(arg)) + "]"; + case "ends-with": + return "[" + xpath_ends_with(xpath_normalize_space, arg) + "]"; + case "has": + String xpath1 = prependAxis(css2xpath(arg, true), ".//"); + + return "[count(" + xpath1 + ") > 0]"; + case "has-sibling": + String xpath2 = css2xpath("preceding-sibling::" + arg, true); + + return "[count(" + xpath2 + ") > 0 or count(following-sibling::" + xpath2.substring(19) + ") > 0]"; + case "has-parent": + return "[count(" + css2xpath("parent::" + arg, true) + ") > 0]"; + case "has-ancestor": + return "[count(" + css2xpath("ancestor::" + arg, true) + ") > 0]"; + case "last": + case "last-of-type": + if (arg != null) { + return "[position()>last()-" + arg + "]"; + } + return "[last()]"; + case "selected": // Sizzle: "(option) elements that are currently selected" + return "[local-name()=\"option\" and @selected]"; + case "skip": + case "skip-first": + return "[position()>" + arg + "]"; + case "skip-last": + if (arg != null) { + return "[last()-position()>=" + arg + "]"; + } + return "[position()= 2 && "::".equals(literal.substring(literal.length() - 2))) { + mat.appendReplacement(buf, mat.group()); + } else { + if (literal.charAt(0) == '[') { + axis += "*"; + } + mat.appendReplacement(buf, start + axis + literal); + } + + } + mat.appendTail(buf); + return buf.toString(); + } + + // Find the begining of the selector, starting at i and working backwards + private int selectorStart(String s, int i) { + int depth = 0; + int offset = 0; + + while (i-- > 0) { + switch (s.charAt(i)) { + case ' ': + case escape_parens: + offset++; + break; + case '[': + case '(': + depth--; + + if (depth < 0) { + return ++i + offset; + } + break; + case ']': + case ')': + depth++; + break; + case ',': + case '|': + if (depth == 0) { + return ++i + offset; + } + default: + offset = 0; + } + } + + return 0; + } + + // Append escape "char" to "open" or "close" + private String escapeChar(String s, String open, String close, char chr) { + Pattern pat = Pattern.compile("[\\" + open + "\\" + close + "]"); + StringBuffer buf = new StringBuffer(); + Matcher mat = pat.matcher(s); + int depth = 0; + while (mat.find()) { + if (open.equals(mat.group())) { + depth++; + } + if (open.equals(mat.group())) { + mat.appendReplacement(buf, mat.group() + repeat("" + chr, depth)); + } else { + mat.appendReplacement(buf, repeat("" + chr, depth--) + mat.group()); + } + } + mat.appendTail(buf); + return buf.toString(); + /*int depth = 0; + + return s.replace(new RegExp('[\\' + open + '\\' + close + ']', 'g'), function (a) { + if (a === open) { + depth++; + } + + if (a === open) { + return a + repeat(chr, depth); + } else { + return repeat(chr, depth--) + a; + } + })*/ + } + + private String repeat(String str, int num) { + String result = ""; + + while (true) { + if ((num & 1) == 1) { + result += str; + } + num >>>= 1; + + if (num <= 0) { + break; + } + str += str; + } + + return result; + } + + private static interface ReplaceCallBack { + + public String run(Matcher mat, String s); + } + + private String replace(String s, String regexp, ReplaceCallBack callback) { + Pattern pat = Pattern.compile(regexp); + StringBuffer sb = new StringBuffer(); + Matcher m = pat.matcher(s); + while (m.find()) { + m.appendReplacement(sb, callback.run(m, s)); + } + m.appendTail(sb); + return sb.toString(); + } + + private int search(String s, String regexp) { + Pattern pat = Pattern.compile(regexp); + Matcher m = pat.matcher(s); + if (m.find()) { + return m.start(); + } + return -1; + } + + public String css2xpath(String s) { + return css2xpath(s, false); + } + + public String css2xpath(String s, boolean nested) { + if (nested == true) { + // Replace :pseudo-classes + final String s1 = s; + s = replace(s, css_pseudo_classes_regex, new ReplaceCallBack() { + @Override + public String run(Matcher mat, String s) { + return css_pseudo_classes_callback(mat.group(), mat.group(1), mat.group(1), mat.group(2), mat.group(3), mat.group(4), mat.group(5), mat.group(6), mat.start(), s); + } + }); + s = replace(s, css_pseudo_classes_regex, new ReplaceCallBack() { + @Override + public String run(Matcher mat, String s) { + return css_pseudo_classes_callback(mat.group(), mat.group(1), mat.group(2), mat.group(3), mat.group(4), + mat.group(5), mat.group(6), mat.group(7), mat.start(), s); + } + }); + + // Replace #ids and .classes + s = replace(s, css_ids_classes_regex, new ReplaceCallBack() { + @Override + public String run(Matcher mat, String s) { + return css_ids_classes_callback(mat.group(), mat.group(1), mat.group(2), mat.start(), s); + } + }); + + return s; + } + + // Tag open and close parenthesis pairs (for RegExp searches) + s = escapeChar(s, "(", ")", escape_parens); + + // Remove and save any string literals + List literals = new ArrayList<>(); + + s = replace(s, regex_string_literal, new ReplaceCallBack() { + @Override + public String run(Matcher mat, String fullS) { + String s = mat.group(); + String a = mat.group(1); + + if (a.charAt(0) == '=') { + a = a.substring(1).trim(); + + if (isNumeric(a)) { + return s; + } + } else { + a = a.substring(1, a.length() - 1); + } + + literals.add(a); + return repeat("" + escape_literal, literals.size()); + + } + }); + + // Replace CSS combinators (" ", "+", ">", "~", ",") and reverse combinators ("!", "!+", "!>", "!~") + s = replace(s, css_combinators_regex, new ReplaceCallBack() { + @Override + public String run(Matcher mat, String s) { + return css_combinators_callback(mat.group(), mat.group(1), mat.group(2), mat.group(3), mat.group(4), mat.group(5), mat.start(), s); + } + }); + + // Replace CSS attribute filters + s = replace(s, css_attributes_regex, new ReplaceCallBack() { + @Override + public String run(Matcher mat, String s) { + return css_attributes_callback(mat.group(), mat.group(1), mat.group(2), mat.group(3), mat.group(4), mat.start(), s); + } + }); + + // Wrap certain :pseudo-classes in parens (to collect node-sets) + while (true) { + int index = search(s, regex_css_wrap_pseudo); + + if (index == -1) { + break; + } + index = s.indexOf(':', index); + int start = selectorStart(s, index); + + s = s.substring(0, start) + + '(' + s.substring(start, index) + ')' + + s.substring(index); + } + + // Replace :pseudo-classes + s = replace(s, css_pseudo_classes_regex, new ReplaceCallBack() { + @Override + public String run(Matcher mat, String s) { + return css_pseudo_classes_callback(mat.group(), mat.group(1), mat.group(2), mat.group(3), mat.group(4), mat.group(5), mat.group(6), mat.group(7), mat.start(), s); + } + }); + + // Replace #ids and .classes + s = replace(s, css_ids_classes_regex, new ReplaceCallBack() { + @Override + public String run(Matcher mat, String s) { + return css_ids_classes_callback(mat.group(), mat.group(1), mat.group(2), mat.start(), s); + } + }); + + // Restore the saved string literals + s = replace(s, regex_escaped_literal, new ReplaceCallBack() { + @Override + public String run(Matcher mat, String a) { + String str = literals.get(mat.group(1).length() - 1); + + return "\"" + str + "\""; + } + }); + + // Remove any special characters + s = s.replaceAll(regex_specal_chars, ""); + + // add * to stand-alone filters + s = s.replaceAll(regex_filter_prefix, "$1*["); + + // add "/" between @attribute selectors + s = s.replaceAll(regex_attr_prefix, "$1/@"); + + /* + Combine multiple filters? + + s = escapeChar(s, '[', ']', filter_char); + s = s.replace(/(\x1D+)\]\[\1(.+?[^\x1D])\1\]/g, ' and ($2)$1]') + */ + s = prependAxis(s, ".//"); // prepend ".//" axis to begining of CSS selector + return s; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssSymbolType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssSymbolType.java new file mode 100644 index 000000000..8c1ecbe3a --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/css/CssSymbolType.java @@ -0,0 +1,36 @@ +package com.jpexs.decompiler.flash.importers.svg.css; + +/** + * + * @author JPEXS + */ +public enum CssSymbolType { + S, + CDO, + CDC, + INCLUDES, + DASHMATCH, + STRING, + BAD_STRING, + IDENT, + HASH, + IMPORT_SYM, + PAGE_SYM, + MEDIA_SYM, + CHARSET_SYM, + IMPORTANT_SYM, + EMS, + EXS, + LENGTH, + ANGLE, + TIME, + FREQ, + DIMENSION, + PERCENTAGE, + NUMBER, + URI, + BAD_URI, + FUNCTION, + EOF, + OTHER +}