From c6ca941ccc017a8869f4def717cfeb640f965077 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 6 Mar 2013 07:39:19 -0800 Subject: Moved scaladoc sources into separate directory. This change is not externally visible. It moves the scaladoc sources into src/scaladoc and adds an ant target for building them. The compilation products are still packaged into scala-compiler.jar as before, but with a small change to build.xml a separate jar can be created instead. --- src/scaladoc/scala/tools/ant/Scaladoc.scala | 695 +++ src/scaladoc/scala/tools/nsc/ScalaDoc.scala | 72 + src/scaladoc/scala/tools/nsc/doc/DocFactory.scala | 132 + src/scaladoc/scala/tools/nsc/doc/DocParser.scala | 69 + src/scaladoc/scala/tools/nsc/doc/Index.scala | 17 + .../scala/tools/nsc/doc/ScaladocGlobal.scala | 106 + src/scaladoc/scala/tools/nsc/doc/Settings.scala | 368 ++ .../scala/tools/nsc/doc/Uncompilable.scala | 51 + src/scaladoc/scala/tools/nsc/doc/Universe.scala | 16 + .../tools/nsc/doc/base/CommentFactoryBase.scala | 936 +++ src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala | 15 + .../tools/nsc/doc/base/MemberLookupBase.scala | 206 + .../scala/tools/nsc/doc/base/comment/Body.scala | 89 + .../scala/tools/nsc/doc/base/comment/Comment.scala | 131 + .../scala/tools/nsc/doc/doclet/Generator.scala | 30 + .../scala/tools/nsc/doc/doclet/Indexer.scala | 21 + .../scala/tools/nsc/doc/doclet/Universer.scala | 21 + src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala | 19 + .../scala/tools/nsc/doc/html/HtmlFactory.scala | 152 + .../scala/tools/nsc/doc/html/HtmlPage.scala | 224 + src/scaladoc/scala/tools/nsc/doc/html/Page.scala | 102 + .../scala/tools/nsc/doc/html/SyntaxHigh.scala | 286 + .../scala/tools/nsc/doc/html/page/Index.scala | 133 + .../tools/nsc/doc/html/page/IndexScript.scala | 69 + .../tools/nsc/doc/html/page/ReferenceIndex.scala | 58 + .../scala/tools/nsc/doc/html/page/Source.scala | 127 + .../scala/tools/nsc/doc/html/page/Template.scala | 967 +++ .../doc/html/page/diagram/DiagramGenerator.scala | 53 + .../nsc/doc/html/page/diagram/DiagramStats.scala | 66 + .../html/page/diagram/DotDiagramGenerator.scala | 506 ++ .../nsc/doc/html/page/diagram/DotRunner.scala | 225 + .../tools/nsc/doc/html/resource/lib/arrow-down.png | Bin 0 -> 6232 bytes .../nsc/doc/html/resource/lib/arrow-right.png | Bin 0 -> 6220 bytes .../tools/nsc/doc/html/resource/lib/class.png | Bin 0 -> 3357 bytes .../tools/nsc/doc/html/resource/lib/class_big.png | Bin 0 -> 7516 bytes .../nsc/doc/html/resource/lib/class_diagram.png | Bin 0 -> 3910 bytes .../doc/html/resource/lib/class_to_object_big.png | Bin 0 -> 9006 bytes .../nsc/doc/html/resource/lib/constructorsbg.gif | Bin 0 -> 1206 bytes .../nsc/doc/html/resource/lib/conversionbg.gif | Bin 0 -> 167 bytes .../tools/nsc/doc/html/resource/lib/defbg-blue.gif | Bin 0 -> 1544 bytes .../nsc/doc/html/resource/lib/defbg-green.gif | Bin 0 -> 1341 bytes .../tools/nsc/doc/html/resource/lib/diagrams.css | 143 + .../tools/nsc/doc/html/resource/lib/diagrams.js | 324 + .../nsc/doc/html/resource/lib/filter_box_left.png | Bin 0 -> 1692 bytes .../nsc/doc/html/resource/lib/filter_box_left.psd | Bin 0 -> 30823 bytes .../nsc/doc/html/resource/lib/filter_box_left2.gif | Bin 0 -> 1462 bytes .../nsc/doc/html/resource/lib/filter_box_right.png | Bin 0 -> 1803 bytes .../nsc/doc/html/resource/lib/filter_box_right.psd | Bin 0 -> 31295 bytes .../tools/nsc/doc/html/resource/lib/filterbg.gif | Bin 0 -> 1324 bytes .../nsc/doc/html/resource/lib/filterboxbarbg.gif | Bin 0 -> 1104 bytes .../nsc/doc/html/resource/lib/filterboxbarbg.png | Bin 0 -> 965 bytes .../nsc/doc/html/resource/lib/filterboxbg.gif | Bin 0 -> 1366 bytes .../nsc/doc/html/resource/lib/fullcommenttopbg.gif | Bin 0 -> 1115 bytes .../tools/nsc/doc/html/resource/lib/index.css | 338 ++ .../scala/tools/nsc/doc/html/resource/lib/index.js | 533 ++ .../tools/nsc/doc/html/resource/lib/jquery-ui.js | 6 + .../tools/nsc/doc/html/resource/lib/jquery.js | 2 + .../nsc/doc/html/resource/lib/jquery.layout.js | 5486 +++++++++++++++++ .../nsc/doc/html/resource/lib/modernizr.custom.js | 4 + .../nsc/doc/html/resource/lib/navigation-li-a.png | Bin 0 -> 1198 bytes .../nsc/doc/html/resource/lib/navigation-li.png | Bin 0 -> 2441 bytes .../tools/nsc/doc/html/resource/lib/object.png | Bin 0 -> 3356 bytes .../tools/nsc/doc/html/resource/lib/object_big.png | Bin 0 -> 7653 bytes .../nsc/doc/html/resource/lib/object_diagram.png | Bin 0 -> 3903 bytes .../doc/html/resource/lib/object_to_class_big.png | Bin 0 -> 9158 bytes .../doc/html/resource/lib/object_to_trait_big.png | Bin 0 -> 9200 bytes .../doc/html/resource/lib/object_to_type_big.png | Bin 0 -> 9158 bytes .../tools/nsc/doc/html/resource/lib/ownderbg2.gif | Bin 0 -> 1145 bytes .../tools/nsc/doc/html/resource/lib/ownerbg.gif | Bin 0 -> 1118 bytes .../tools/nsc/doc/html/resource/lib/ownerbg2.gif | Bin 0 -> 1145 bytes .../tools/nsc/doc/html/resource/lib/package.png | Bin 0 -> 3335 bytes .../nsc/doc/html/resource/lib/package_big.png | Bin 0 -> 7312 bytes .../tools/nsc/doc/html/resource/lib/packagesbg.gif | Bin 0 -> 1201 bytes .../tools/nsc/doc/html/resource/lib/raphael-min.js | 10 + .../tools/nsc/doc/html/resource/lib/ref-index.css | 30 + .../tools/nsc/doc/html/resource/lib/remove.png | Bin 0 -> 3186 bytes .../tools/nsc/doc/html/resource/lib/remove.psd | Bin 0 -> 28904 bytes .../tools/nsc/doc/html/resource/lib/scheduler.js | 71 + .../doc/html/resource/lib/selected-implicits.png | Bin 0 -> 1150 bytes .../html/resource/lib/selected-right-implicits.png | Bin 0 -> 646 bytes .../nsc/doc/html/resource/lib/selected-right.png | Bin 0 -> 1380 bytes .../tools/nsc/doc/html/resource/lib/selected.png | Bin 0 -> 1864 bytes .../nsc/doc/html/resource/lib/selected2-right.png | Bin 0 -> 1434 bytes .../tools/nsc/doc/html/resource/lib/selected2.png | Bin 0 -> 1965 bytes .../nsc/doc/html/resource/lib/signaturebg.gif | Bin 0 -> 1214 bytes .../nsc/doc/html/resource/lib/signaturebg2.gif | Bin 0 -> 1209 bytes .../tools/nsc/doc/html/resource/lib/template.css | 848 +++ .../tools/nsc/doc/html/resource/lib/template.js | 466 ++ .../nsc/doc/html/resource/lib/tools.tooltip.js | 14 + .../tools/nsc/doc/html/resource/lib/trait.png | Bin 0 -> 3374 bytes .../tools/nsc/doc/html/resource/lib/trait_big.png | Bin 0 -> 7410 bytes .../nsc/doc/html/resource/lib/trait_diagram.png | Bin 0 -> 3882 bytes .../doc/html/resource/lib/trait_to_object_big.png | Bin 0 -> 8967 bytes .../scala/tools/nsc/doc/html/resource/lib/type.png | Bin 0 -> 1445 bytes .../tools/nsc/doc/html/resource/lib/type_big.png | Bin 0 -> 4236 bytes .../nsc/doc/html/resource/lib/type_diagram.png | Bin 0 -> 1841 bytes .../tools/nsc/doc/html/resource/lib/type_tags.ai | 6376 ++++++++++++++++++++ .../doc/html/resource/lib/type_to_object_big.png | Bin 0 -> 4969 bytes .../tools/nsc/doc/html/resource/lib/typebg.gif | Bin 0 -> 1206 bytes .../tools/nsc/doc/html/resource/lib/unselected.png | Bin 0 -> 1879 bytes .../nsc/doc/html/resource/lib/valuemembersbg.gif | Bin 0 -> 1206 bytes .../tools/nsc/doc/html/resource/lib/versions.txt | 1 + .../scala/tools/nsc/doc/model/CommentFactory.scala | 112 + .../scala/tools/nsc/doc/model/Entity.scala | 601 ++ .../tools/nsc/doc/model/IndexModelFactory.scala | 58 + .../scala/tools/nsc/doc/model/MemberLookup.scala | 63 + .../scala/tools/nsc/doc/model/ModelFactory.scala | 1045 ++++ .../doc/model/ModelFactoryImplicitSupport.scala | 579 ++ .../nsc/doc/model/ModelFactoryTypeSupport.scala | 315 + .../scala/tools/nsc/doc/model/TreeEntity.scala | 27 + .../scala/tools/nsc/doc/model/TreeFactory.scala | 96 + .../scala/tools/nsc/doc/model/TypeEntity.scala | 27 + .../scala/tools/nsc/doc/model/ValueArgument.scala | 20 + .../scala/tools/nsc/doc/model/Visibility.scala | 39 + .../tools/nsc/doc/model/diagram/Diagram.scala | 137 + .../doc/model/diagram/DiagramDirectiveParser.scala | 257 + .../nsc/doc/model/diagram/DiagramFactory.scala | 254 + .../scala/tools/partest/ScaladocModelTest.scala | 203 + 118 files changed, 24447 insertions(+) create mode 100644 src/scaladoc/scala/tools/ant/Scaladoc.scala create mode 100644 src/scaladoc/scala/tools/nsc/ScalaDoc.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/DocFactory.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/DocParser.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/Index.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/Settings.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/Uncompilable.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/Universe.scala create mode 100755 src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala create mode 100755 src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala create mode 100755 src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala create mode 100755 src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/doclet/Indexer.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/doclet/Universer.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/Page.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala create mode 100755 src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/page/Source.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-down.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-right.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_big.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_diagram.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_to_object_big.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/constructorsbg.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/defbg-blue.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/defbg-green.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.css create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.js create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left.psd create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left2.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_right.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_right.psd create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterbg.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbg.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/fullcommenttopbg.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js create mode 100755 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.js create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/modernizr.custom.js create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li-a.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_big.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_diagram.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_class_big.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_trait_big.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_type_big.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownderbg2.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg2.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package_big.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/packagesbg.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/raphael-min.js create mode 100755 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.psd create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2-right.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg2.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/tools.tooltip.js create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_big.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_diagram.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_to_object_big.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_big.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_diagram.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_tags.ai create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_to_object_big.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/typebg.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/unselected.png create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/valuemembersbg.gif create mode 100644 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/versions.txt create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/Entity.scala create mode 100755 src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/TreeEntity.scala create mode 100755 src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/TypeEntity.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/ValueArgument.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/Visibility.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala create mode 100644 src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala create mode 100644 src/scaladoc/scala/tools/partest/ScaladocModelTest.scala (limited to 'src/scaladoc') diff --git a/src/scaladoc/scala/tools/ant/Scaladoc.scala b/src/scaladoc/scala/tools/ant/Scaladoc.scala new file mode 100644 index 0000000000..fd6d637212 --- /dev/null +++ b/src/scaladoc/scala/tools/ant/Scaladoc.scala @@ -0,0 +1,695 @@ +/* __ *\ +** ________ ___ / / ___ Scala Ant Tasks ** +** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + +package scala.tools.ant + +import java.io.File + +import org.apache.tools.ant.Project +import org.apache.tools.ant.types.{Path, Reference} +import org.apache.tools.ant.util.{FileUtils, GlobPatternMapper} + +import scala.tools.nsc.Global +import scala.tools.nsc.doc.Settings +import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} + +/** An Ant task to document Scala code. + * + * This task can take the following parameters as attributes: + * - `srcdir` (mandatory), + * - `srcref`, + * - `destdir`, + * - `classpath`, + * - `classpathref`, + * - `sourcepath`, + * - `sourcepathref`, + * - `bootclasspath`, + * - `bootclasspathref`, + * - `extdirs`, + * - `extdirsref`, + * - `encoding`, + * - `doctitle`, + * - `header`, + * - `footer`, + * - `top`, + * - `bottom`, + * - `addparams`, + * - `deprecation`, + * - `docgenerator`, + * - `docrootcontent`, + * - `unchecked`, + * - `nofail`, + * - `skipPackages`. + * + * It also takes the following parameters as nested elements: + * - `src` (for srcdir), + * - `classpath`, + * - `sourcepath`, + * - `bootclasspath`, + * - `extdirs`. + * + * @author Gilles Dubochet, Stephane Micheloud + */ +class Scaladoc extends ScalaMatchingTask { + + /** The unique Ant file utilities instance to use in this task. */ + private val fileUtils = FileUtils.getFileUtils() + +/*============================================================================*\ +** Ant user-properties ** +\*============================================================================*/ + + abstract class PermissibleValue { + val values: List[String] + def isPermissible(value: String): Boolean = + (value == "") || values.exists(_.startsWith(value)) + } + + /** Defines valid values for the `deprecation` and + * `unchecked` properties. + */ + object Flag extends PermissibleValue { + val values = List("yes", "no", "on", "off") + def getBooleanValue(value: String, flagName: String): Boolean = + if (Flag.isPermissible(value)) + ("yes".equals(value) || "on".equals(value)) + else + buildError("Unknown " + flagName + " flag '" + value + "'") + } + + /** The directories that contain source files to compile. */ + private var origin: Option[Path] = None + /** The directory to put the compiled files in. */ + private var destination: Option[File] = None + + /** The class path to use for this compilation. */ + private var classpath: Option[Path] = None + /** The source path to use for this compilation. */ + private var sourcepath: Option[Path] = None + /** The boot class path to use for this compilation. */ + private var bootclasspath: Option[Path] = None + /** The external extensions path to use for this compilation. */ + private var extdirs: Option[Path] = None + + /** The character encoding of the files to compile. */ + private var encoding: Option[String] = None + + /** The fully qualified name of a doclet class, which will be used to generate the documentation. */ + private var docgenerator: Option[String] = None + + /** The file from which the documentation content of the root package will be taken */ + private var docrootcontent: Option[File] = None + + /** The document title of the generated HTML documentation. */ + private var doctitle: Option[String] = None + + /** The document footer of the generated HTML documentation. */ + private var docfooter: Option[String] = None + + /** The document version, to be added to the title. */ + private var docversion: Option[String] = None + + /** Instruct the compiler to generate links to sources */ + private var docsourceurl: Option[String] = None + + /** Point scaladoc at uncompilable sources. */ + private var docUncompilable: Option[String] = None + + /** Instruct the compiler to use additional parameters */ + private var addParams: String = "" + + /** Instruct the compiler to generate deprecation information. */ + private var deprecation: Boolean = false + + /** Instruct the compiler to generate unchecked information. */ + private var unchecked: Boolean = false + + /** Instruct the ant task not to fail in the event of errors */ + private var nofail: Boolean = false + + /** Instruct the scaladoc tool to document implicit conversions */ + private var docImplicits: Boolean = false + + /** Instruct the scaladoc tool to document all (including impossible) implicit conversions */ + private var docImplicitsShowAll: Boolean = false + + /** Instruct the scaladoc tool to output implicits debugging information */ + private var docImplicitsDebug: Boolean = false + + /** Instruct the scaladoc tool to create diagrams */ + private var docDiagrams: Boolean = false + + /** Instruct the scaladoc tool to output diagram creation debugging information */ + private var docDiagramsDebug: Boolean = false + + /** Instruct the scaladoc tool to use the binary given to create diagrams */ + private var docDiagramsDotPath: Option[String] = None + + /** Instruct the scaladoc to produce textual ouput from html pages, for easy diff-ing */ + private var docRawOutput: Boolean = false + + /** Instruct the scaladoc not to generate prefixes */ + private var docNoPrefixes: Boolean = false + + /** Instruct the scaladoc tool to group similar functions together */ + private var docGroups: Boolean = false + + /** Instruct the scaladoc tool to skip certain packages */ + private var docSkipPackages: String = "" + +/*============================================================================*\ +** Properties setters ** +\*============================================================================*/ + + /** Sets the `srcdir` attribute. Used by [[http://ant.apache.org Ant]]. + * + * @param input The value of `origin`. + */ + def setSrcdir(input: Path) { + if (origin.isEmpty) origin = Some(input) + else origin.get.append(input) + } + + /** Sets the `origin` as a nested src Ant parameter. + * + * @return An origin path to be configured. + */ + def createSrc(): Path = { + if (origin.isEmpty) origin = Some(new Path(getProject)) + origin.get.createPath() + } + + /** Sets the `origin` as an external reference Ant parameter. + * + * @param input A reference to an origin path. + */ + def setSrcref(input: Reference) { + createSrc().setRefid(input) + } + + /** Sets the `destdir` attribute. Used by [[http://ant.apache.org Ant]]. + * + * @param input The value of `destination`. + */ + def setDestdir(input: File) { + destination = Some(input) + } + + /** Sets the `classpath` attribute. Used by [[http://ant.apache.org Ant]]. + * + * @param input The value of `classpath`. + */ + def setClasspath(input: Path) { + if (classpath.isEmpty) classpath = Some(input) + else classpath.get.append(input) + } + + /** Sets the `classpath` as a nested classpath Ant parameter. + * + * @return A class path to be configured. + */ + def createClasspath(): Path = { + if (classpath.isEmpty) classpath = Some(new Path(getProject)) + classpath.get.createPath() + } + + /** Sets the `classpath` as an external reference Ant parameter. + * + * @param input A reference to a class path. + */ + def setClasspathref(input: Reference) = + createClasspath().setRefid(input) + + /** Sets the `sourcepath` attribute. Used by [[http://ant.apache.org Ant]]. + * + * @param input The value of `sourcepath`. + */ + def setSourcepath(input: Path) = + if (sourcepath.isEmpty) sourcepath = Some(input) + else sourcepath.get.append(input) + + /** Sets the `sourcepath` as a nested sourcepath Ant parameter. + * + * @return A source path to be configured. + */ + def createSourcepath(): Path = { + if (sourcepath.isEmpty) sourcepath = Some(new Path(getProject)) + sourcepath.get.createPath() + } + + /** Sets the `sourcepath` as an external reference Ant parameter. + * + * @param input A reference to a source path. + */ + def setSourcepathref(input: Reference) = + createSourcepath().setRefid(input) + + /** Sets the `bootclasspath` attribute. Used by [[http://ant.apache.org Ant]]. + * + * @param input The value of `bootclasspath`. + */ + def setBootclasspath(input: Path) = + if (bootclasspath.isEmpty) bootclasspath = Some(input) + else bootclasspath.get.append(input) + + /** Sets the `bootclasspath` as a nested `sourcepath` Ant parameter. + * + * @return A source path to be configured. + */ + def createBootclasspath(): Path = { + if (bootclasspath.isEmpty) bootclasspath = Some(new Path(getProject)) + bootclasspath.get.createPath() + } + + /** Sets the `bootclasspath` as an external reference Ant parameter. + * + * @param input A reference to a source path. + */ + def setBootclasspathref(input: Reference) { + createBootclasspath().setRefid(input) + } + + /** Sets the external extensions path attribute. Used by [[http://ant.apache.org Ant]]. + * + * @param input The value of `extdirs`. + */ + def setExtdirs(input: Path) { + if (extdirs.isEmpty) extdirs = Some(input) + else extdirs.get.append(input) + } + + /** Sets the `extdirs` as a nested sourcepath Ant parameter. + * + * @return An extensions path to be configured. + */ + def createExtdirs(): Path = { + if (extdirs.isEmpty) extdirs = Some(new Path(getProject)) + extdirs.get.createPath() + } + + /** Sets the `extdirs` as an external reference Ant parameter. + * + * @param input A reference to an extensions path. + */ + def setExtdirsref(input: Reference) { + createExtdirs().setRefid(input) + } + + /** Sets the `encoding` attribute. Used by Ant. + * + * @param input The value of `encoding`. + */ + def setEncoding(input: String) { + encoding = Some(input) + } + + /** Sets the `docgenerator` attribute. + * + * @param input A fully qualified class name of a doclet. + */ + def setDocgenerator(input: String) { + docgenerator = Some(input) + } + + /** + * Sets the `docrootcontent` attribute. + * + * @param input The file from which the documentation content of the root + * package will be taken. + */ + def setDocrootcontent(input : File) { + docrootcontent = Some(input) + } + + /** Sets the `docversion` attribute. + * + * @param input The value of `docversion`. + */ + def setDocversion(input: String) { + docversion = Some(input) + } + + /** Sets the `docsourceurl` attribute. + * + * @param input The value of `docsourceurl`. + */ + def setDocsourceurl(input: String) { + docsourceurl = Some(input) + } + + /** Sets the `doctitle` attribute. + * + * @param input The value of `doctitle`. + */ + def setDoctitle(input: String) { + doctitle = Some(input) + } + + /** Sets the `docfooter` attribute. + * + * @param input The value of `docfooter`. + */ + def setDocfooter(input: String) { + docfooter = Some(input) + } + + /** Set the `addparams` info attribute. + * + * @param input The value for `addparams`. + */ + def setAddparams(input: String) { + addParams = input + } + + /** Set the `deprecation` info attribute. + * + * @param input One of the flags `yes/no` or `on/off`. + */ + def setDeprecation(input: String) { + if (Flag.isPermissible(input)) + deprecation = "yes".equals(input) || "on".equals(input) + else + buildError("Unknown deprecation flag '" + input + "'") + } + + /** Set the `unchecked` info attribute. + * + * @param input One of the flags `yes/no` or `on/off`. + */ + def setUnchecked(input: String) { + if (Flag.isPermissible(input)) + unchecked = "yes".equals(input) || "on".equals(input) + else + buildError("Unknown unchecked flag '" + input + "'") + } + + def setDocUncompilable(input: String) { + docUncompilable = Some(input) + } + + /** Set the `nofail` info attribute. + * + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. + */ + def setNoFail(input: String) = + nofail = Flag.getBooleanValue(input, "nofail") + + /** Set the `implicits` info attribute. + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setImplicits(input: String) = + docImplicits = Flag.getBooleanValue(input, "implicits") + + /** Set the `implicitsShowAll` info attribute to enable scaladoc to show all implicits, including those impossible to + * convert to from the default scope + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setImplicitsShowAll(input: String) = + docImplicitsShowAll = Flag.getBooleanValue(input, "implicitsShowAll") + + /** Set the `implicitsDebug` info attribute so scaladoc outputs implicit conversion debug information + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setImplicitsDebug(input: String) = + docImplicitsDebug = Flag.getBooleanValue(input, "implicitsDebug") + + /** Set the `diagrams` bit so Scaladoc adds diagrams to the documentation + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setDiagrams(input: String) = + docDiagrams = Flag.getBooleanValue(input, "diagrams") + + /** Set the `diagramsDebug` bit so Scaladoc outputs diagram building debug information + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setDiagramsDebug(input: String) = + docDiagramsDebug = Flag.getBooleanValue(input, "diagramsDebug") + + /** Set the `diagramsDotPath` attribute to the path where graphviz dot can be found (including the binary file name, + * eg: /usr/bin/dot) */ + def setDiagramsDotPath(input: String) = + docDiagramsDotPath = Some(input) + + /** Set the `rawOutput` bit so Scaladoc also outputs text from each html file + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setRawOutput(input: String) = + docRawOutput = Flag.getBooleanValue(input, "rawOutput") + + /** Set the `noPrefixes` bit to prevent Scaladoc from generating prefixes in + * front of types -- may lead to confusion, but significantly speeds up the generation. + * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */ + def setNoPrefixes(input: String) = + docNoPrefixes = Flag.getBooleanValue(input, "noPrefixes") + + /** Instruct the scaladoc tool to group similar functions together */ + def setGroups(input: String) = + docGroups = Flag.getBooleanValue(input, "groups") + + /** Instruct the scaladoc tool to skip certain packages. + * @param input A colon-delimited list of fully qualified package names that will be skipped from scaladoc. + */ + def setSkipPackages(input: String) = + docSkipPackages = input + +/*============================================================================*\ +** Properties getters ** +\*============================================================================*/ + + /** Gets the value of the `classpath` attribute in a + * Scala-friendly form. + * + * @return The class path as a list of files. + */ + private def getClasspath: List[File] = + if (classpath.isEmpty) buildError("Member 'classpath' is empty.") + else classpath.get.list().toList map nameToFile + + /** Gets the value of the `origin` attribute in a Scala-friendly + * form. + * + * @return The origin path as a list of files. + */ + private def getOrigin: List[File] = + if (origin.isEmpty) buildError("Member 'origin' is empty.") + else origin.get.list().toList map nameToFile + + /** Gets the value of the `destination` attribute in a + * Scala-friendly form. + * + * @return The destination as a file. + */ + private def getDestination: File = + if (destination.isEmpty) buildError("Member 'destination' is empty.") + else existing(getProject resolveFile destination.get.toString) + + /** Gets the value of the `sourcepath` attribute in a + * Scala-friendly form. + * + * @return The source path as a list of files. + */ + private def getSourcepath: List[File] = + if (sourcepath.isEmpty) buildError("Member 'sourcepath' is empty.") + else sourcepath.get.list().toList map nameToFile + + /** Gets the value of the `bootclasspath` attribute in a + * Scala-friendly form. + * + * @return The boot class path as a list of files. + */ + private def getBootclasspath: List[File] = + if (bootclasspath.isEmpty) buildError("Member 'bootclasspath' is empty.") + else bootclasspath.get.list().toList map nameToFile + + /** Gets the value of the `extdirs` attribute in a + * Scala-friendly form. + * + * @return The extensions path as a list of files. + */ + private def getExtdirs: List[File] = + if (extdirs.isEmpty) buildError("Member 'extdirs' is empty.") + else extdirs.get.list().toList map nameToFile + +/*============================================================================*\ +** Compilation and support methods ** +\*============================================================================*/ + + /** This is forwarding method to circumvent bug #281 in Scala 2. Remove when + * bug has been corrected. + */ + override protected def getDirectoryScanner(baseDir: java.io.File) = + super.getDirectoryScanner(baseDir) + + /** Transforms a string name into a file relative to the provided base + * directory. + * + * @param base A file pointing to the location relative to which the name + * will be resolved. + * @param name A relative or absolute path to the file as a string. + * @return A file created from the name and the base file. + */ + private def nameToFile(base: File)(name: String): File = + existing(fileUtils.resolveFile(base, name)) + + /** Transforms a string name into a file relative to the build root + * directory. + * + * @param name A relative or absolute path to the file as a string. + * @return A file created from the name. + */ + private def nameToFile(name: String): File = + existing(getProject resolveFile name) + + /** Tests if a file exists and prints a warning in case it doesn't. Always + * returns the file, even if it doesn't exist. + * + * @param file A file to test for existance. + * @return The same file. + */ + private def existing(file: File): File = { + if (!file.exists()) + log("Element '" + file.toString + "' does not exist.", + Project.MSG_WARN) + file + } + + /** Transforms a path into a Scalac-readable string. + * + * @param path A path to convert. + * @return A string-representation of the path like `a.jar:b.jar`. + */ + private def asString(path: List[File]): String = + path.map(asString).mkString("", File.pathSeparator, "") + + /** Transforms a file into a Scalac-readable string. + * + * @param file A file to convert. + * @return A string-representation of the file like `/x/k/a.scala`. + */ + private def asString(file: File): String = + file.getAbsolutePath() + +/*============================================================================*\ +** The big execute method ** +\*============================================================================*/ + + /** Initializes settings and source files */ + protected def initialize: Pair[Settings, List[File]] = { + // Tests if all mandatory attributes are set and valid. + if (origin.isEmpty) buildError("Attribute 'srcdir' is not set.") + if (getOrigin.isEmpty) buildError("Attribute 'srcdir' is not set.") + if (!destination.isEmpty && !destination.get.isDirectory()) + buildError("Attribute 'destdir' does not refer to an existing directory.") + if (destination.isEmpty) destination = Some(getOrigin.head) + + val mapper = new GlobPatternMapper() + mapper setTo "*.html" + mapper setFrom "*.scala" + + // Scans source directories to build up a compile lists. + // If force is false, only files were the .class file in destination is + // older than the .scala file will be used. + val sourceFiles: List[File] = + for { + originDir <- getOrigin + originFile <- { + val includedFiles = + getDirectoryScanner(originDir).getIncludedFiles() + val list = includedFiles.toList + if (list.length > 0) + log( + "Documenting " + list.length + " source file" + + (if (list.length > 1) "s" else "") + + (" to " + getDestination.toString) + ) + else + log("No files selected for documentation", Project.MSG_VERBOSE) + + list + } + } yield { + log(originFile, Project.MSG_DEBUG) + nameToFile(originDir)(originFile) + } + + def decodeEscapes(s: String): String = { + // In Ant script characters '<' and '>' must be encoded when + // used in attribute values, e.g. for attributes "doctitle", "header", .. + // in task Scaladoc you may write: + // doctitle="<div>Scala</div>" + // so we have to decode them here. + s.replaceAll("<", "<").replaceAll(">",">") + .replaceAll("&", "&").replaceAll(""", "\"") + } + + // Builds-up the compilation settings for Scalac with the existing Ant + // parameters. + val docSettings = new Settings(buildError) + docSettings.outdir.value = asString(destination.get) + if (!classpath.isEmpty) + docSettings.classpath.value = asString(getClasspath) + if (!sourcepath.isEmpty) + docSettings.sourcepath.value = asString(getSourcepath) + /*else if (origin.get.size() > 0) + settings.sourcepath.value = origin.get.list()(0)*/ + if (!bootclasspath.isEmpty) + docSettings.bootclasspath.value = asString(getBootclasspath) + if (!extdirs.isEmpty) docSettings.extdirs.value = asString(getExtdirs) + if (!encoding.isEmpty) docSettings.encoding.value = encoding.get + if (!doctitle.isEmpty) docSettings.doctitle.value = decodeEscapes(doctitle.get) + if (!docfooter.isEmpty) docSettings.docfooter.value = decodeEscapes(docfooter.get) + if (!docversion.isEmpty) docSettings.docversion.value = decodeEscapes(docversion.get) + if (!docsourceurl.isEmpty) docSettings.docsourceurl.value = decodeEscapes(docsourceurl.get) + if (!docUncompilable.isEmpty) docSettings.docUncompilable.value = decodeEscapes(docUncompilable.get) + + docSettings.deprecation.value = deprecation + docSettings.unchecked.value = unchecked + docSettings.docImplicits.value = docImplicits + docSettings.docImplicitsDebug.value = docImplicitsDebug + docSettings.docImplicitsShowAll.value = docImplicitsShowAll + docSettings.docDiagrams.value = docDiagrams + docSettings.docDiagramsDebug.value = docDiagramsDebug + docSettings.docRawOutput.value = docRawOutput + docSettings.docNoPrefixes.value = docNoPrefixes + docSettings.docGroups.value = docGroups + docSettings.docSkipPackages.value = docSkipPackages + if(!docDiagramsDotPath.isEmpty) docSettings.docDiagramsDotPath.value = docDiagramsDotPath.get + + if (!docgenerator.isEmpty) docSettings.docgenerator.value = docgenerator.get + if (!docrootcontent.isEmpty) docSettings.docRootContent.value = docrootcontent.get.getAbsolutePath() + log("Scaladoc params = '" + addParams + "'", Project.MSG_DEBUG) + + docSettings processArgumentString addParams + Pair(docSettings, sourceFiles) + } + + def safeBuildError(message: String): Unit = if (nofail) log(message) else buildError(message) + + /** Performs the compilation. */ + override def execute() = { + val Pair(docSettings, sourceFiles) = initialize + val reporter = new ConsoleReporter(docSettings) + try { + val docProcessor = new scala.tools.nsc.doc.DocFactory(reporter, docSettings) + docProcessor.document(sourceFiles.map (_.toString)) + if (reporter.ERROR.count > 0) + safeBuildError( + "Document failed with " + + reporter.ERROR.count + " error" + + (if (reporter.ERROR.count > 1) "s" else "") + + "; see the documenter error output for details.") + else if (reporter.WARNING.count > 0) + log( + "Document succeeded with " + + reporter.WARNING.count + " warning" + + (if (reporter.WARNING.count > 1) "s" else "") + + "; see the documenter output for details.") + reporter.printSummary() + } catch { + case exception: Throwable => + exception.printStackTrace() + val msg = Option(exception.getMessage) getOrElse "no error message provided" + safeBuildError(s"Document failed because of an internal documenter error ($msg); see the error output for details.") + } + } +} diff --git a/src/scaladoc/scala/tools/nsc/ScalaDoc.scala b/src/scaladoc/scala/tools/nsc/ScalaDoc.scala new file mode 100644 index 0000000000..52a0c20a11 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/ScalaDoc.scala @@ -0,0 +1,72 @@ +/* scaladoc, a documentation generator for Scala + * Copyright 2005-2013 LAMP/EPFL + * @author Martin Odersky + * @author Geoffrey Washburn + */ + +package scala.tools.nsc + +import java.io.File.pathSeparator +import scala.tools.nsc.doc.DocFactory +import scala.tools.nsc.reporters.ConsoleReporter +import scala.reflect.internal.util.FakePos + +/** The main class for scaladoc, a front-end for the Scala compiler + * that generates documentation from source files. + */ +class ScalaDoc { + val versionMsg = "Scaladoc %s -- %s".format(Properties.versionString, Properties.copyrightString) + + def process(args: Array[String]): Boolean = { + var reporter: ConsoleReporter = null + val docSettings = new doc.Settings(msg => reporter.error(FakePos("scaladoc"), msg + "\n scaladoc -help gives more information"), + msg => reporter.printMessage(msg)) + reporter = new ConsoleReporter(docSettings) { + // need to do this so that the Global instance doesn't trash all the + // symbols just because there was an error + override def hasErrors = false + } + val command = new ScalaDoc.Command(args.toList, docSettings) + def hasFiles = command.files.nonEmpty || docSettings.uncompilableFiles.nonEmpty + + if (docSettings.version.value) + reporter.echo(versionMsg) + else if (docSettings.Xhelp.value) + reporter.echo(command.xusageMsg) + else if (docSettings.Yhelp.value) + reporter.echo(command.yusageMsg) + else if (docSettings.showPlugins.value) + reporter.warning(null, "Plugins are not available when using Scaladoc") + else if (docSettings.showPhases.value) + reporter.warning(null, "Phases are restricted when using Scaladoc") + else if (docSettings.help.value || !hasFiles) + reporter.echo(command.usageMsg) + else + try { new DocFactory(reporter, docSettings) document command.files } + catch { + case ex @ FatalError(msg) => + if (docSettings.debug.value) ex.printStackTrace() + reporter.error(null, "fatal error: " + msg) + } + finally reporter.printSummary() + + // not much point in returning !reporter.hasErrors when it has + // been overridden with constant false. + true + } +} + +object ScalaDoc extends ScalaDoc { + class Command(arguments: List[String], settings: doc.Settings) extends CompilerCommand(arguments, settings) { + override def cmdName = "scaladoc" + override def usageMsg = ( + createUsageMsg("where possible scaladoc", shouldExplain = false, x => x.isStandard && settings.isScaladocSpecific(x.name)) + + "\n\nStandard scalac options also available:" + + createUsageMsg(x => x.isStandard && !settings.isScaladocSpecific(x.name)) + ) + } + + def main(args: Array[String]): Unit = sys exit { + if (process(args)) 0 else 1 + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala new file mode 100644 index 0000000000..b4d2adaad4 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala @@ -0,0 +1,132 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author David Bernard, Manohar Jonnalagedda + */ + +package scala.tools.nsc +package doc + +import scala.util.control.ControlThrowable +import reporters.Reporter +import scala.reflect.internal.util.BatchSourceFile + +/** A documentation processor controls the process of generating Scala + * documentation, which is as follows. + * + * * A simplified compiler instance (with only the front-end phases enabled) + * * is created, and additional `sourceless` comments are registered. + * * Documentable files are compiled, thereby filling the compiler's symbol table. + * * A documentation model is extracted from the post-compilation symbol table. + * * A generator is used to transform the model into the correct final format (HTML). + * + * A processor contains a single compiler instantiated from the processor's + * `settings`. Each call to `document` uses the same compiler instance with + * the same symbol table. In particular, this implies that the scaladoc site + * obtained from a call to `run` will contain documentation about files compiled + * during previous calls to the same processor's `run` method. + * + * @param reporter The reporter to which both documentation and compilation errors will be reported. + * @param settings The settings to be used by the documenter and compiler for generating documentation. + * + * @author Gilles Dubochet */ +class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor => + /** The unique compiler instance used by this processor and constructed from its `settings`. */ + object compiler extends ScaladocGlobal(settings, reporter) + + /** Creates a scaladoc site for all symbols defined in this call's `source`, + * as well as those defined in `sources` of previous calls to the same processor. + * @param source The list of paths (relative to the compiler's source path, + * or absolute) of files to document or the source code. */ + def makeUniverse(source: Either[List[String], String]): Option[Universe] = { + assert(settings.docformat.value == "html") + source match { + case Left(files) => + new compiler.Run() compile files + case Right(sourceCode) => + new compiler.Run() compileSources List(new BatchSourceFile("newSource", sourceCode)) + } + + if (reporter.hasErrors) + return None + + val extraTemplatesToDocument: Set[compiler.Symbol] = { + if (settings.docUncompilable.isDefault) Set() + else { + val uncompilable = new { + val global: compiler.type = compiler + val settings = processor.settings + } with Uncompilable { } + + compiler.docComments ++= uncompilable.comments + docdbg("" + uncompilable) + + uncompilable.templates + } + } + + val modelFactory = ( + new { override val global: compiler.type = compiler } + with model.ModelFactory(compiler, settings) + with model.ModelFactoryImplicitSupport + with model.ModelFactoryTypeSupport + with model.diagram.DiagramFactory + with model.CommentFactory + with model.TreeFactory + with model.MemberLookup { + override def templateShouldDocument(sym: compiler.Symbol, inTpl: DocTemplateImpl) = + extraTemplatesToDocument(sym) || super.templateShouldDocument(sym, inTpl) + } + ) + + modelFactory.makeModel match { + case Some(madeModel) => + if (!settings.scaladocQuietRun) + println("model contains " + modelFactory.templatesCount + " documentable templates") + Some(madeModel) + case None => + if (!settings.scaladocQuietRun) + println("no documentable class found in compilation units") + None + } + } + + object NoCompilerRunException extends ControlThrowable { } + + val documentError: PartialFunction[Throwable, Unit] = { + case NoCompilerRunException => + reporter.info(null, "No documentation generated with unsucessful compiler run", force = false) + case _: ClassNotFoundException => + () + } + + /** Generate document(s) for all `files` containing scaladoc documenataion. + * @param files The list of paths (relative to the compiler's source path, or absolute) of files to document. */ + def document(files: List[String]) { + def generate() = { + import doclet._ + val docletClass = Class.forName(settings.docgenerator.value) // default is html.Doclet + val docletInstance = docletClass.newInstance().asInstanceOf[Generator] + + docletInstance match { + case universer: Universer => + val universe = makeUniverse(Left(files)) getOrElse { throw NoCompilerRunException } + universer setUniverse universe + + docletInstance match { + case indexer: Indexer => indexer setIndex model.IndexModelFactory.makeIndex(universe) + case _ => () + } + case _ => () + } + docletInstance.generate() + } + + try generate() + catch documentError + } + + private[doc] def docdbg(msg: String) { + if (settings.Ydocdebug.value) + println(msg) + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/DocParser.scala b/src/scaladoc/scala/tools/nsc/doc/DocParser.scala new file mode 100644 index 0000000000..6dc3e5a62b --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/DocParser.scala @@ -0,0 +1,69 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package nsc +package doc + +import reporters._ +import scala.reflect.internal.util._ +import DocParser.Parsed + +/** A very minimal global customized for extracting `DocDefs`. It stops + * right after parsing so it can read `DocDefs` from source code which would + * otherwise cause the compiler to go haywire. + */ +class DocParser(settings: nsc.Settings, reporter: Reporter) extends Global(settings, reporter) { + def this(settings: Settings) = this(settings, new ConsoleReporter(settings)) + def this() = this(new Settings(Console println _)) + + // the usual global initialization + locally { new Run() } + + override protected def computeInternalPhases() { + phasesSet += syntaxAnalyzer + } + + /** Returns a list of `DocParser.Parseds`, which hold the DocDefs found + * in the given code along with the surrounding trees. + */ + def docDefs(code: String) = { + def loop(enclosing: List[Tree], tree: Tree): List[Parsed] = tree match { + case x: PackageDef => x.stats flatMap (t => loop(enclosing :+ x, t)) + case x: DocDef => new Parsed(enclosing, x) :: loop(enclosing :+ x.definition, x.definition) + case x => x.children flatMap (t => loop(enclosing, t)) + } + loop(Nil, docUnit(code)) + } + + /** A compilation unit containing parsed source. + */ + def docUnit(code: String) = { + val unit = new CompilationUnit(new BatchSourceFile("", code)) + val scanner = newUnitParser(unit) + + scanner.compilationUnit() + } +} + +/** Since the DocParser's whole reason for existing involves trashing a + * global, it is designed to bottle up general `Global#Tree` types rather + * than path dependent ones. The recipient will have to deal. + */ +object DocParser { + type Tree = Global#Tree + type DefTree = Global#DefTree + type DocDef = Global#DocDef + type Name = Global#Name + + class Parsed(val enclosing: List[Tree], val docDef: DocDef) { + def nameChain: List[Name] = (enclosing :+ docDef.definition) collect { case x: DefTree => x.name } + def raw: String = docDef.comment.raw + + override def toString = ( + nameChain.init.map(x => if (x.isTypeName) x + "#" else x + ".").mkString + nameChain.last + ) + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/Index.scala b/src/scaladoc/scala/tools/nsc/doc/Index.scala new file mode 100644 index 0000000000..f9b9eecdb3 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/Index.scala @@ -0,0 +1,17 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.tools.nsc.doc + +import scala.collection._ + + +trait Index { + + type SymbolMap = SortedMap[String, SortedSet[model.MemberEntity]] + + def firstLetterIndex: Map[Char, SymbolMap] + +} diff --git a/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala b/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala new file mode 100644 index 0000000000..021e59a879 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala @@ -0,0 +1,106 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package doc + +import scala.util.control.ControlThrowable +import reporters.Reporter +import typechecker.Analyzer +import scala.reflect.internal.util.BatchSourceFile + +trait ScaladocAnalyzer extends Analyzer { + val global : Global // generally, a ScaladocGlobal + import global._ + + override def newTyper(context: Context): ScaladocTyper = new ScaladocTyper(context) + + class ScaladocTyper(context0: Context) extends Typer(context0) { + private def unit = context.unit + + override def typedDocDef(docDef: DocDef, mode: Mode, pt: Type): Tree = { + val sym = docDef.symbol + + if ((sym ne null) && (sym ne NoSymbol)) { + val comment = docDef.comment + fillDocComment(sym, comment) + val typer1 = newTyper(context.makeNewScope(docDef, context.owner)) + for (useCase <- comment.useCases) { + typer1.silent(_ => typer1 defineUseCases useCase) match { + case SilentTypeError(err) => + unit.warning(useCase.pos, err.errMsg) + case _ => + } + for (useCaseSym <- useCase.defined) { + if (sym.name != useCaseSym.name) + unit.warning(useCase.pos, "@usecase " + useCaseSym.name.decode + " does not match commented symbol: " + sym.name.decode) + } + } + } + + super.typedDocDef(docDef, mode, pt) + } + + def defineUseCases(useCase: UseCase): List[Symbol] = { + def stringParser(str: String): syntaxAnalyzer.Parser = { + val file = new BatchSourceFile(context.unit.source.file, str) { + override def positionInUltimateSource(pos: Position) = { + pos.withSource(context.unit.source, useCase.pos.start) + } + } + val unit = new CompilationUnit(file) + new syntaxAnalyzer.UnitParser(unit) + } + + val trees = stringParser(useCase.body+";").nonLocalDefOrDcl + val enclClass = context.enclClass.owner + + def defineAlias(name: Name) = ( + if (context.scope.lookup(name) == NoSymbol) { + lookupVariable(name.toString.substring(1), enclClass) foreach { repl => + silent(_.typedTypeConstructor(stringParser(repl).typ())) map { tpt => + val alias = enclClass.newAliasType(name.toTypeName, useCase.pos) + val tparams = cloneSymbolsAtOwner(tpt.tpe.typeSymbol.typeParams, alias) + val newInfo = genPolyType(tparams, appliedType(tpt.tpe, tparams map (_.tpe))) + alias setInfo newInfo + context.scope.enter(alias) + } + } + } + ) + + for (tree <- trees; t <- tree) + t match { + case Ident(name) if name startsWith '$' => defineAlias(name) + case _ => + } + + useCase.aliases = context.scope.toList + namer.enterSyms(trees) + typedStats(trees, NoSymbol) + useCase.defined = context.scope.toList filterNot (useCase.aliases contains _) + + if (settings.debug.value) + useCase.defined foreach (sym => println("defined use cases: %s:%s".format(sym, sym.tpe))) + + useCase.defined + } + } +} + +class ScaladocGlobal(settings: doc.Settings, reporter: Reporter) extends { + override val useOffsetPositions = false +} with Global(settings, reporter) { + override protected def computeInternalPhases() { + phasesSet += syntaxAnalyzer + phasesSet += analyzer.namerFactory + phasesSet += analyzer.packageObjects + phasesSet += analyzer.typerFactory + } + override def forScaladoc = true + override lazy val analyzer = new { + val global: ScaladocGlobal.this.type = ScaladocGlobal.this + } with ScaladocAnalyzer +} diff --git a/src/scaladoc/scala/tools/nsc/doc/Settings.scala b/src/scaladoc/scala/tools/nsc/doc/Settings.scala new file mode 100644 index 0000000000..90b94e1336 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/Settings.scala @@ -0,0 +1,368 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.tools.nsc +package doc + +import java.io.File +import scala.language.postfixOps + +/** An extended version of compiler settings, with additional Scaladoc-specific options. + * @param error A function that prints a string to the appropriate error stream + * @param printMsg A function that prints the string, without any extra boilerplate of error */ +class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) extends scala.tools.nsc.Settings(error) { + + /** A setting that defines in which format the documentation is output. ''Note:'' this setting is currently always + * `html`. */ + val docformat = ChoiceSetting ( + "-doc-format", + "format", + "Selects in which format documentation is rendered", + List("html"), + "html" + ) + + /** A setting that defines the overall title of the documentation, typically the name of the library being + * documented. ''Note:'' This setting is currently not used. */ + val doctitle = StringSetting ( + "-doc-title", + "title", + "The overall name of the Scaladoc site", + "" + ) + + /** A setting that defines the overall version number of the documentation, typically the version of the library being + * documented. ''Note:'' This setting is currently not used. */ + val docversion = StringSetting ( + "-doc-version", + "version", + "An optional version number, to be appended to the title", + "" + ) + + val docfooter = StringSetting ( + "-doc-footer", + "footer", + "A footer on every ScalaDoc page, by default the EPFL/Typesafe copyright notice. Can be overridden with a custom footer.", + "" + ) + + val docUncompilable = StringSetting ( + "-doc-no-compile", + "path", + "A directory containing sources which should be parsed, no more (e.g. AnyRef.scala)", + "" + ) + + lazy val uncompilableFiles = docUncompilable.value match { + case "" => Nil + case path => io.Directory(path).deepFiles filter (_ hasExtension "scala") toList + } + + /** A setting that defines a URL to be concatenated with source locations and show a link to source files. + * If needed the sourcepath option can be used to exclude undesired initial part of the link to sources */ + val docsourceurl = StringSetting ( + "-doc-source-url", + "url", + "A URL pattern used to build links to template sources; use variables, for example: ?{TPL_NAME} ('Seq'), ?{TPL_OWNER} ('scala.collection'), ?{FILE_PATH} ('scala/collection/Seq')", + "" + ) + + val docExternalDoc = MultiStringSetting ( + "-doc-external-doc", + "external-doc", + "comma-separated list of classpath_entry_path#doc_URL pairs describing external dependencies." + ) + + val useStupidTypes = BooleanSetting ( + "-Yuse-stupid-types", + "Print the types of inherited members as seen from their original definition context. Hint: you don't want to do that!" + ) + + val docgenerator = StringSetting ( + "-doc-generator", + "class-name", + "The fully qualified name of a doclet class, which will be used to generate the documentation", + "scala.tools.nsc.doc.html.Doclet" + ) + + val docRootContent = PathSetting ( + "-doc-root-content", + "The file from which the root package documentation should be imported.", + "" + ) + + val docImplicits = BooleanSetting ( + "-implicits", + "Document members inherited by implicit conversions." + ) + + val docImplicitsDebug = BooleanSetting ( + "-implicits-debug", + "Show debugging information for members inherited by implicit conversions." + ) + + val docImplicitsShowAll = BooleanSetting ( + "-implicits-show-all", + "Show members inherited by implicit conversions that are impossible in the default scope. " + + "(for example conversions that require Numeric[String] to be in scope)" + ) + + val docImplicitsSoundShadowing = BooleanSetting ( + "-implicits-sound-shadowing", + "Use a sound implicit shadowing calculation. Note: this interacts badly with usecases, so " + + "only use it if you haven't defined usecase for implicitly inherited members." + ) + + val docImplicitsHide = MultiStringSetting ( + "-implicits-hide", + "implicit(s)", + "Hide the members inherited by the given comma separated, fully qualified implicit conversions. Add dot (.) to include default conversions." + ) + + val docDiagrams = BooleanSetting ( + "-diagrams", + "Create inheritance diagrams for classes, traits and packages." + ) + + val docDiagramsDebug = BooleanSetting ( + "-diagrams-debug", + "Show debugging information for the diagram creation process." + ) + + val docDiagramsDotPath = PathSetting ( + "-diagrams-dot-path", + "The path to the dot executable used to generate the inheritance diagrams. Eg: /usr/bin/dot", + "dot" // by default, just pick up the system-wide dot + ) + + /** The maxium nuber of normal classes to show in the diagram */ + val docDiagramsMaxNormalClasses = IntSetting( + "-diagrams-max-classes", + "The maximum number of superclasses or subclasses to show in a diagram", + 15, + None, + _ => None + ) + + /** The maxium nuber of implcit classes to show in the diagram */ + val docDiagramsMaxImplicitClasses = IntSetting( + "-diagrams-max-implicits", + "The maximum number of implicitly converted classes to show in a diagram", + 10, + None, + _ => None + ) + + val docDiagramsDotTimeout = IntSetting( + "-diagrams-dot-timeout", + "The timeout before the graphviz dot util is forcefully closed, in seconds (default: 10)", + 10, + None, + _ => None + ) + + val docDiagramsDotRestart = IntSetting( + "-diagrams-dot-restart", + "The number of times to restart a malfunctioning dot process before disabling diagrams (default: 5)", + 5, + None, + _ => None + ) + + val docRawOutput = BooleanSetting ( + "-raw-output", + "For each html file, create another .html.raw file containing only the text. (can be used for quickly diffing two scaladoc outputs)" + ) + + val docNoPrefixes = BooleanSetting ( + "-no-prefixes", + "Prevents generating prefixes in types, possibly creating ambiguous references, but significantly speeding up scaladoc." + ) + + val docNoLinkWarnings = BooleanSetting ( + "-no-link-warnings", + "Avoid warnings for ambiguous and incorrect links." + ) + + val docSkipPackages = StringSetting ( + "-skip-packages", + ":...:", + "A colon-delimited list of fully qualified package names that will be skipped from scaladoc.", + "" + ) + + val docExpandAllTypes = BooleanSetting ( + "-expand-all-types", + "Expand all type aliases and abstract types into full template pages. (locally this can be done with the @template annotation)" + ) + + val docExternalUrls = MultiStringSetting ( + "-external-urls", + "externalUrl(s)", + "(deprecated) comma-separated list of package_names=doc_URL for external dependencies, where package names are ':'-separated" + ) + + val docGroups = BooleanSetting ( + "-groups", + "Group similar functions together (based on the @group annotation)" + ) + + // Somewhere slightly before r18708 scaladoc stopped building unless the + // self-type check was suppressed. I hijacked the slotted-for-removal-anyway + // suppress-vt-warnings option and renamed it for this purpose. + noSelfCheck.value = true + + // For improved help output. + def scaladocSpecific = Set[Settings#Setting]( + docformat, doctitle, docfooter, docversion, docUncompilable, docsourceurl, docgenerator, docRootContent, useStupidTypes, + docDiagrams, docDiagramsDebug, docDiagramsDotPath, + docDiagramsDotTimeout, docDiagramsDotRestart, + docImplicits, docImplicitsDebug, docImplicitsShowAll, docImplicitsHide, + docDiagramsMaxNormalClasses, docDiagramsMaxImplicitClasses, + docNoPrefixes, docNoLinkWarnings, docRawOutput, docSkipPackages, + docExpandAllTypes, docGroups + ) + val isScaladocSpecific: String => Boolean = scaladocSpecific map (_.name) + + override def isScaladoc = true + + // set by the testsuite, when checking test output + var scaladocQuietRun = false + + lazy val skipPackageNames = + if (docSkipPackages.value == "") + Set[String]() + else + docSkipPackages.value.toLowerCase.split(':').toSet + + def skipPackage(qname: String) = + skipPackageNames(qname.toLowerCase) + + lazy val hiddenImplicits: Set[String] = { + if (docImplicitsHide.value.isEmpty) hardcoded.commonConversionTargets + else docImplicitsHide.value.toSet flatMap { name: String => + if(name == ".") hardcoded.commonConversionTargets + else Set(name) + } + } + + def appendIndex(url: String): String = { + val index = "/index.html" + if (url.endsWith(index)) url else url + index + } + + // Deprecated together with 'docExternalUrls' option. + lazy val extUrlPackageMapping: Map[String, String] = (Map.empty[String, String] /: docExternalUrls.value) { + case (map, binding) => + val idx = binding indexOf "=" + val pkgs = binding substring (0, idx) split ":" + val url = appendIndex(binding substring (idx + 1)) + map ++ (pkgs map (_ -> url)) + } + + lazy val extUrlMapping: Map[String, String] = docExternalDoc.value flatMap { s => + val idx = s.indexOf("#") + if (idx > 0) { + val (first, last) = s.splitAt(idx) + Some(new File(first).getAbsolutePath -> appendIndex(last.substring(1))) + } else { + error(s"Illegal -doc-external-doc option; expected a pair with '#' separator, found: '$s'") + None + } + } toMap + + /** + * This is the hardcoded area of Scaladoc. This is where "undesirable" stuff gets eliminated. I know it's not pretty, + * but ultimately scaladoc has to be useful. :) + */ + object hardcoded { + + /** The common context bounds and some humanly explanations. Feel free to add more explanations + * `.scala.package.Numeric` is the type class + * `tparam` is the name of the type parameter it gets (this only describes type classes with 1 type param) + * the function result should be a humanly-understandable description of the type class + */ + val knownTypeClasses: Map[String, String => String] = Map() + + ("scala.math.Numeric" -> ((tparam: String) => tparam + " is a numeric class, such as Int, Long, Float or Double")) + + ("scala.math.Integral" -> ((tparam: String) => tparam + " is an integral numeric class, such as Int or Long")) + + ("scala.math.Fractional" -> ((tparam: String) => tparam + " is a fractional numeric class, such as Float or Double")) + + ("scala.reflect.Manifest" -> ((tparam: String) => tparam + " is accompanied by a Manifest, which is a runtime representation of its type that survives erasure")) + + ("scala.reflect.ClassManifest" -> ((tparam: String) => tparam + " is accompanied by a ClassManifest, which is a runtime representation of its type that survives erasure")) + + ("scala.reflect.OptManifest" -> ((tparam: String) => tparam + " is accompanied by an OptManifest, which can be either a runtime representation of its type or the NoManifest, which means the runtime type is not available")) + + ("scala.reflect.ClassTag" -> ((tparam: String) => tparam + " is accompanied by a ClassTag, which is a runtime representation of its type that survives erasure")) + + ("scala.reflect.api.TypeTags.WeakTypeTag" -> ((tparam: String) => tparam + " is accompanied by an WeakTypeTag, which is a runtime representation of its type that survives erasure")) + + ("scala.reflect.api.TypeTags.TypeTag" -> ((tparam: String) => tparam + " is accompanied by a TypeTag, which is a runtime representation of its type that survives erasure")) + + /** + * Set of classes to exclude from index and diagrams + * TODO: Should be configurable + */ + def isExcluded(qname: String) = { + ( ( qname.startsWith("scala.Tuple") || qname.startsWith("scala.Product") || + qname.startsWith("scala.Function") || qname.startsWith("scala.runtime.AbstractFunction") + ) && !( + qname == "scala.Tuple1" || qname == "scala.Tuple2" || + qname == "scala.Product" || qname == "scala.Product1" || qname == "scala.Product2" || + qname == "scala.Function" || qname == "scala.Function1" || qname == "scala.Function2" || + qname == "scala.runtime.AbstractFunction0" || qname == "scala.runtime.AbstractFunction1" || + qname == "scala.runtime.AbstractFunction2" + ) + ) + } + + /** Common conversion targets that affect any class in Scala */ + val commonConversionTargets = Set( + "scala.Predef.StringFormat", + "scala.Predef.StringAdd", + "scala.Predef.ArrowAssoc", + "scala.Predef.Ensuring", + "scala.collection.TraversableOnce.alternateImplicit") + + /** There's a reason all these are specialized by hand but documenting each of them is beyond the point */ + val arraySkipConversions = List( + "scala.Predef.refArrayOps", + "scala.Predef.intArrayOps", + "scala.Predef.doubleArrayOps", + "scala.Predef.longArrayOps", + "scala.Predef.floatArrayOps", + "scala.Predef.charArrayOps", + "scala.Predef.byteArrayOps", + "scala.Predef.shortArrayOps", + "scala.Predef.booleanArrayOps", + "scala.Predef.unitArrayOps", + "scala.LowPriorityImplicits.wrapRefArray", + "scala.LowPriorityImplicits.wrapIntArray", + "scala.LowPriorityImplicits.wrapDoubleArray", + "scala.LowPriorityImplicits.wrapLongArray", + "scala.LowPriorityImplicits.wrapFloatArray", + "scala.LowPriorityImplicits.wrapCharArray", + "scala.LowPriorityImplicits.wrapByteArray", + "scala.LowPriorityImplicits.wrapShortArray", + "scala.LowPriorityImplicits.wrapBooleanArray", + "scala.LowPriorityImplicits.wrapUnitArray", + "scala.LowPriorityImplicits.genericWrapArray") + + // included as names as here we don't have access to a Global with Definitions :( + def valueClassList = List("unit", "boolean", "byte", "short", "char", "int", "long", "float", "double") + def valueClassFilterPrefixes = List("scala.LowPriorityImplicits", "scala.Predef") + + /** Dirty, dirty, dirty hack: the value params conversions can all kick in -- and they are disambiguated by priority + * but showing priority in scaladoc would make no sense -- so we have to manually remove the conversions that we + * know will never get a chance to kick in. Anyway, DIRTY DIRTY DIRTY! */ + def valueClassFilter(value: String, conversionName: String): Boolean = { + val valueName = value.toLowerCase + val otherValues = valueClassList.filterNot(_ == valueName) + + for (prefix <- valueClassFilterPrefixes) + if (conversionName.startsWith(prefix)) + for (otherValue <- otherValues) + if (conversionName.startsWith(prefix + "." + otherValue)) + return false + + true + } + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/Uncompilable.scala b/src/scaladoc/scala/tools/nsc/doc/Uncompilable.scala new file mode 100644 index 0000000000..9447e36610 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/Uncompilable.scala @@ -0,0 +1,51 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package doc +import scala.language.implicitConversions +import scala.language.postfixOps + +/** Some glue between DocParser (which reads source files which can't be compiled) + * and the scaladoc model. + */ +trait Uncompilable { + val global: Global + val settings: Settings + + import global.{ reporter, inform, warning, newTypeName, newTermName, Symbol, DocComment, NoSymbol } + import global.definitions.AnyRefClass + import global.rootMirror.RootClass + + private implicit def translateName(name: Global#Name) = + if (name.isTypeName) newTypeName("" + name) else newTermName("" + name) + + def docSymbol(p: DocParser.Parsed) = p.nameChain.foldLeft(RootClass: Symbol)(_.tpe member _) + def docDefs(code: String) = new DocParser(settings, reporter) docDefs code + def docPairs(code: String) = docDefs(code) map (p => (docSymbol(p), new DocComment(p.raw))) + + lazy val pairs = files flatMap { f => + val comments = docPairs(f.slurp()) + if (settings.verbose.value) + inform("Found %d doc comments in parse-only file %s: %s".format(comments.size, f, comments.map(_._1).mkString(", "))) + + comments + } + def files = settings.uncompilableFiles + def symbols = pairs map (_._1) + def templates = symbols filter (x => x.isClass || x.isTrait || x == AnyRefClass/* which is now a type alias */) toSet + def comments = { + if (settings.debug.value || settings.verbose.value) + inform("Found %d uncompilable files: %s".format(files.size, files mkString ", ")) + + if (pairs.isEmpty) + warning("no doc comments read from " + settings.docUncompilable.value) + + pairs + } + override def toString = pairs.size + " uncompilable symbols:\n" + ( + symbols filterNot (_ == NoSymbol) map (x => " " + x.owner.fullName + " " + x.defString) mkString "\n" + ) +} diff --git a/src/scaladoc/scala/tools/nsc/doc/Universe.scala b/src/scaladoc/scala/tools/nsc/doc/Universe.scala new file mode 100644 index 0000000000..11520c810e --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/Universe.scala @@ -0,0 +1,16 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.tools.nsc.doc + +/** + * Class to hold common dependencies across Scaladoc classes. + * @author Pedro Furlanetto + * @author Gilles Dubochet + */ +trait Universe { + def settings: Settings + def rootPackage: model.Package +} diff --git a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala new file mode 100755 index 0000000000..2064d86860 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala @@ -0,0 +1,936 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Manohar Jonnalagedda + */ + +package scala.tools.nsc +package doc +package base + +import base.comment._ +import scala.collection._ +import scala.util.matching.Regex +import scala.reflect.internal.util.Position +import scala.language.postfixOps + +/** The comment parser transforms raw comment strings into `Comment` objects. + * Call `parse` to run the parser. Note that the parser is stateless and + * should only be built once for a given Scaladoc run. + * + * @author Manohar Jonnalagedda + * @author Gilles Dubochet */ +trait CommentFactoryBase { this: MemberLookupBase => + + val global: Global + import global.{ reporter, Symbol } + + /* Creates comments with necessary arguments */ + def createComment ( + body0: Option[Body] = None, + authors0: List[Body] = List.empty, + see0: List[Body] = List.empty, + result0: Option[Body] = None, + throws0: Map[String,Body] = Map.empty, + valueParams0: Map[String,Body] = Map.empty, + typeParams0: Map[String,Body] = Map.empty, + version0: Option[Body] = None, + since0: Option[Body] = None, + todo0: List[Body] = List.empty, + deprecated0: Option[Body] = None, + note0: List[Body] = List.empty, + example0: List[Body] = List.empty, + constructor0: Option[Body] = None, + source0: Option[String] = None, + inheritDiagram0: List[String] = List.empty, + contentDiagram0: List[String] = List.empty, + group0: Option[Body] = None, + groupDesc0: Map[String,Body] = Map.empty, + groupNames0: Map[String,Body] = Map.empty, + groupPrio0: Map[String,Body] = Map.empty + ) : Comment = new Comment{ + val body = if(body0 isDefined) body0.get else Body(Seq.empty) + val authors = authors0 + val see = see0 + val result = result0 + val throws = throws0 + val valueParams = valueParams0 + val typeParams = typeParams0 + val version = version0 + val since = since0 + val todo = todo0 + val deprecated = deprecated0 + val note = note0 + val example = example0 + val constructor = constructor0 + val inheritDiagram = inheritDiagram0 + val contentDiagram = contentDiagram0 + val groupDesc = groupDesc0 + val group = + group0 match { + case Some(Body(List(Paragraph(Chain(List(Summary(Text(groupId)))))))) => Some(groupId.toString.trim) + case _ => None + } + val groupPrio = groupPrio0 flatMap { + case (group, body) => + try { + body match { + case Body(List(Paragraph(Chain(List(Summary(Text(prio))))))) => List(group -> prio.trim.toInt) + case _ => List() + } + } catch { + case _: java.lang.NumberFormatException => List() + } + } + val groupNames = groupNames0 flatMap { + case (group, body) => + try { + body match { + case Body(List(Paragraph(Chain(List(Summary(Text(name))))))) if (!name.trim.contains("\n")) => List(group -> (name.trim)) + case _ => List() + } + } catch { + case _: java.lang.NumberFormatException => List() + } + } + + } + + private val endOfText = '\u0003' + private val endOfLine = '\u000A' + + /** Something that should not have happened, happened, and Scaladoc should exit. */ + private def oops(msg: String): Nothing = + throw FatalError("program logic: " + msg) + + /** The body of a line, dropping the (optional) start star-marker, + * one leading whitespace and all trailing whitespace. */ + private val CleanCommentLine = + new Regex("""(?:\s*\*\s?)?(.*)""") + + /** Dangerous HTML tags that should be replaced by something safer, + * such as wiki syntax, or that should be dropped. */ + private val DangerousTags = + new Regex("""<(/?(div|ol|ul|li|h[1-6]|p))( [^>]*)?/?>|""") + + /** Maps a dangerous HTML tag to a safe wiki replacement, or an empty string + * if it cannot be salvaged. */ + private def htmlReplacement(mtch: Regex.Match): String = mtch.group(1) match { + case "p" | "div" => "\n\n" + case "h1" => "\n= " + case "/h1" => " =\n" + case "h2" => "\n== " + case "/h2" => " ==\n" + case "h3" => "\n=== " + case "/h3" => " ===\n" + case "h4" | "h5" | "h6" => "\n==== " + case "/h4" | "/h5" | "/h6" => " ====\n" + case "li" => "\n * - " + case _ => "" + } + + /** Javadoc tags that should be replaced by something useful, such as wiki + * syntax, or that should be dropped. */ + private val JavadocTags = + new Regex("""\{\@(code|docRoot|inheritDoc|link|linkplain|literal|value)([^}]*)\}""") + + /** Maps a javadoc tag to a useful wiki replacement, or an empty string if it cannot be salvaged. */ + private def javadocReplacement(mtch: Regex.Match): String = mtch.group(1) match { + case "code" => "`" + mtch.group(2) + "`" + case "docRoot" => "" + case "inheritDoc" => "" + case "link" => "`" + mtch.group(2) + "`" + case "linkplain" => "`" + mtch.group(2) + "`" + case "literal" => mtch.group(2) + case "value" => "`" + mtch.group(2) + "`" + case _ => "" + } + + /** Safe HTML tags that can be kept. */ + private val SafeTags = + new Regex("""((&\w+;)|(&#\d+;)|(]*)?/?>))""") + + private val safeTagMarker = '\u000E' + + /** A Scaladoc tag not linked to a symbol and not followed by text */ + private val SingleTagRegex = + new Regex("""\s*@(\S+)\s*""") + + /** A Scaladoc tag not linked to a symbol. Returns the name of the tag, and the rest of the line. */ + private val SimpleTagRegex = + new Regex("""\s*@(\S+)\s+(.*)""") + + /** A Scaladoc tag linked to a symbol. Returns the name of the tag, the name + * of the symbol, and the rest of the line. */ + private val SymbolTagRegex = + new Regex("""\s*@(param|tparam|throws|groupdesc|groupname|groupprio)\s+(\S*)\s*(.*)""") + + /** The start of a scaladoc code block */ + private val CodeBlockStartRegex = + new Regex("""(.*?)((?:\{\{\{)|(?:\u000E]*)?>\u000E))(.*)""") + + /** The end of a scaladoc code block */ + private val CodeBlockEndRegex = + new Regex("""(.*?)((?:\}\}\})|(?:\u000E\u000E))(.*)""") + + /** A key used for a tag map. The key is built from the name of the tag and + * from the linked symbol if the tag has one. + * Equality on tag keys is structural. */ + private sealed abstract class TagKey { + def name: String + } + + private final case class SimpleTagKey(name: String) extends TagKey + private final case class SymbolTagKey(name: String, symbol: String) extends TagKey + + /** Parses a raw comment string into a `Comment` object. + * @param comment The expanded comment string (including start and end markers) to be parsed. + * @param src The raw comment source string. + * @param pos The position of the comment in source. */ + protected def parseAtSymbol(comment: String, src: String, pos: Position, siteOpt: Option[Symbol] = None): Comment = { + /** The cleaned raw comment as a list of lines. Cleaning removes comment + * start and end markers, line start markers and unnecessary whitespace. */ + def clean(comment: String): List[String] = { + def cleanLine(line: String): String = { + //replaceAll removes trailing whitespaces + line.replaceAll("""\s+$""", "") match { + case CleanCommentLine(ctl) => ctl + case tl => tl + } + } + val strippedComment = comment.trim.stripPrefix("/*").stripSuffix("*/") + val safeComment = DangerousTags.replaceAllIn(strippedComment, { htmlReplacement(_) }) + val javadoclessComment = JavadocTags.replaceAllIn(safeComment, { javadocReplacement(_) }) + val markedTagComment = + SafeTags.replaceAllIn(javadoclessComment, { mtch => + java.util.regex.Matcher.quoteReplacement(safeTagMarker + mtch.matched + safeTagMarker) + }) + markedTagComment.lines.toList map (cleanLine(_)) + } + + /** Parses a comment (in the form of a list of lines) to a `Comment` + * instance, recursively on lines. To do so, it splits the whole comment + * into main body and tag bodies, then runs the `WikiParser` on each body + * before creating the comment instance. + * + * @param docBody The body of the comment parsed until now. + * @param tags All tags parsed until now. + * @param lastTagKey The last parsed tag, or `None` if the tag section hasn't started. Lines that are not tagged + * are part of the previous tag or, if none exists, of the body. + * @param remaining The lines that must still recursively be parsed. + * @param inCodeBlock Whether the next line is part of a code block (in which no tags must be read). */ + def parse0 ( + docBody: StringBuilder, + tags: Map[TagKey, List[String]], + lastTagKey: Option[TagKey], + remaining: List[String], + inCodeBlock: Boolean + ): Comment = remaining match { + + case CodeBlockStartRegex(before, marker, after) :: ls if (!inCodeBlock) => + if (!before.trim.isEmpty && !after.trim.isEmpty) + parse0(docBody, tags, lastTagKey, before :: marker :: after :: ls, inCodeBlock = false) + else if (!before.trim.isEmpty) + parse0(docBody, tags, lastTagKey, before :: marker :: ls, inCodeBlock = false) + else if (!after.trim.isEmpty) + parse0(docBody, tags, lastTagKey, marker :: after :: ls, inCodeBlock = true) + else lastTagKey match { + case Some(key) => + val value = + ((tags get key): @unchecked) match { + case Some(b :: bs) => (b + endOfLine + marker) :: bs + case None => oops("lastTagKey set when no tag exists for key") + } + parse0(docBody, tags + (key -> value), lastTagKey, ls, inCodeBlock = true) + case None => + parse0(docBody append endOfLine append marker, tags, lastTagKey, ls, inCodeBlock = true) + } + + case CodeBlockEndRegex(before, marker, after) :: ls => + if (!before.trim.isEmpty && !after.trim.isEmpty) + parse0(docBody, tags, lastTagKey, before :: marker :: after :: ls, inCodeBlock = true) + if (!before.trim.isEmpty) + parse0(docBody, tags, lastTagKey, before :: marker :: ls, inCodeBlock = true) + else if (!after.trim.isEmpty) + parse0(docBody, tags, lastTagKey, marker :: after :: ls, inCodeBlock = false) + else lastTagKey match { + case Some(key) => + val value = + ((tags get key): @unchecked) match { + case Some(b :: bs) => (b + endOfLine + marker) :: bs + case None => oops("lastTagKey set when no tag exists for key") + } + parse0(docBody, tags + (key -> value), lastTagKey, ls, inCodeBlock = false) + case None => + parse0(docBody append endOfLine append marker, tags, lastTagKey, ls, inCodeBlock = false) + } + + case SymbolTagRegex(name, sym, body) :: ls if (!inCodeBlock) => + val key = SymbolTagKey(name, sym) + val value = body :: tags.getOrElse(key, Nil) + parse0(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) + + case SimpleTagRegex(name, body) :: ls if (!inCodeBlock) => + val key = SimpleTagKey(name) + val value = body :: tags.getOrElse(key, Nil) + parse0(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) + + case SingleTagRegex(name) :: ls if (!inCodeBlock) => + val key = SimpleTagKey(name) + val value = "" :: tags.getOrElse(key, Nil) + parse0(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) + + case line :: ls if (lastTagKey.isDefined) => + val key = lastTagKey.get + val value = + ((tags get key): @unchecked) match { + case Some(b :: bs) => (b + endOfLine + line) :: bs + case None => oops("lastTagKey set when no tag exists for key") + } + parse0(docBody, tags + (key -> value), lastTagKey, ls, inCodeBlock) + + case line :: ls => + if (docBody.length > 0) docBody append endOfLine + docBody append line + parse0(docBody, tags, lastTagKey, ls, inCodeBlock) + + case Nil => + // Take the {inheritance, content} diagram keys aside, as it doesn't need any parsing + val inheritDiagramTag = SimpleTagKey("inheritanceDiagram") + val contentDiagramTag = SimpleTagKey("contentDiagram") + + val inheritDiagramText: List[String] = tags.get(inheritDiagramTag) match { + case Some(list) => list + case None => List.empty + } + + val contentDiagramText: List[String] = tags.get(contentDiagramTag) match { + case Some(list) => list + case None => List.empty + } + + val stripTags=List(inheritDiagramTag, contentDiagramTag, SimpleTagKey("template"), SimpleTagKey("documentable")) + val tagsWithoutDiagram = tags.filterNot(pair => stripTags.contains(pair._1)) + + val bodyTags: mutable.Map[TagKey, List[Body]] = + mutable.Map(tagsWithoutDiagram mapValues {tag => tag map (parseWikiAtSymbol(_, pos, siteOpt))} toSeq: _*) + + def oneTag(key: SimpleTagKey): Option[Body] = + ((bodyTags remove key): @unchecked) match { + case Some(r :: rs) => + if (!rs.isEmpty) reporter.warning(pos, "Only one '@" + key.name + "' tag is allowed") + Some(r) + case None => None + } + + def allTags(key: SimpleTagKey): List[Body] = + (bodyTags remove key) getOrElse Nil + + def allSymsOneTag(key: TagKey): Map[String, Body] = { + val keys: Seq[SymbolTagKey] = + bodyTags.keys.toSeq flatMap { + case stk: SymbolTagKey if (stk.name == key.name) => Some(stk) + case stk: SimpleTagKey if (stk.name == key.name) => + reporter.warning(pos, "Tag '@" + stk.name + "' must be followed by a symbol name") + None + case _ => None + } + val pairs: Seq[(String, Body)] = + for (key <- keys) yield { + val bs = (bodyTags remove key).get + if (bs.length > 1) + reporter.warning(pos, "Only one '@" + key.name + "' tag for symbol " + key.symbol + " is allowed") + (key.symbol, bs.head) + } + Map.empty[String, Body] ++ pairs + } + + val com = createComment ( + body0 = Some(parseWikiAtSymbol(docBody.toString, pos, siteOpt)), + authors0 = allTags(SimpleTagKey("author")), + see0 = allTags(SimpleTagKey("see")), + result0 = oneTag(SimpleTagKey("return")), + throws0 = allSymsOneTag(SimpleTagKey("throws")), + valueParams0 = allSymsOneTag(SimpleTagKey("param")), + typeParams0 = allSymsOneTag(SimpleTagKey("tparam")), + version0 = oneTag(SimpleTagKey("version")), + since0 = oneTag(SimpleTagKey("since")), + todo0 = allTags(SimpleTagKey("todo")), + deprecated0 = oneTag(SimpleTagKey("deprecated")), + note0 = allTags(SimpleTagKey("note")), + example0 = allTags(SimpleTagKey("example")), + constructor0 = oneTag(SimpleTagKey("constructor")), + source0 = Some(clean(src).mkString("\n")), + inheritDiagram0 = inheritDiagramText, + contentDiagram0 = contentDiagramText, + group0 = oneTag(SimpleTagKey("group")), + groupDesc0 = allSymsOneTag(SimpleTagKey("groupdesc")), + groupNames0 = allSymsOneTag(SimpleTagKey("groupname")), + groupPrio0 = allSymsOneTag(SimpleTagKey("groupprio")) + ) + + for ((key, _) <- bodyTags) + reporter.warning(pos, "Tag '@" + key.name + "' is not recognised") + + com + + } + + parse0(new StringBuilder(comment.size), Map.empty, None, clean(comment), inCodeBlock = false) + + } + + /** Parses a string containing wiki syntax into a `Comment` object. + * Note that the string is assumed to be clean: + * - Removed Scaladoc start and end markers. + * - Removed start-of-line star and one whitespace afterwards (if present). + * - Removed all end-of-line whitespace. + * - Only `endOfLine` is used to mark line endings. */ + def parseWikiAtSymbol(string: String, pos: Position, siteOpt: Option[Symbol]): Body = new WikiParser(string, pos, siteOpt).document() + + /** TODO + * + * @author Ingo Maier + * @author Manohar Jonnalagedda + * @author Gilles Dubochet */ + protected final class WikiParser(val buffer: String, pos: Position, siteOpt: Option[Symbol]) extends CharReader(buffer) { wiki => + var summaryParsed = false + + def document(): Body = { + val blocks = new mutable.ListBuffer[Block] + while (char != endOfText) + blocks += block() + Body(blocks.toList) + } + + /* BLOCKS */ + + /** {{{ block ::= code | title | hrule | para }}} */ + def block(): Block = { + if (checkSkipInitWhitespace("{{{")) + code() + else if (checkSkipInitWhitespace('=')) + title() + else if (checkSkipInitWhitespace("----")) + hrule() + else if (checkList) + listBlock + else { + para() + } + } + + /** listStyle ::= '-' spc | '1.' spc | 'I.' spc | 'i.' spc | 'A.' spc | 'a.' spc + * Characters used to build lists and their constructors */ + protected val listStyles = Map[String, (Seq[Block] => Block)]( // TODO Should this be defined at some list companion? + "- " -> ( UnorderedList(_) ), + "1. " -> ( OrderedList(_,"decimal") ), + "I. " -> ( OrderedList(_,"upperRoman") ), + "i. " -> ( OrderedList(_,"lowerRoman") ), + "A. " -> ( OrderedList(_,"upperAlpha") ), + "a. " -> ( OrderedList(_,"lowerAlpha") ) + ) + + /** Checks if the current line is formed with more than one space and one the listStyles */ + def checkList = + (countWhitespace > 0) && (listStyles.keys exists { checkSkipInitWhitespace(_) }) + + /** {{{ + * nListBlock ::= nLine { mListBlock } + * nLine ::= nSpc listStyle para '\n' + * }}} + * Where n and m stand for the number of spaces. When `m > n`, a new list is nested. */ + def listBlock: Block = { + + /** Consumes one list item block and returns it, or None if the block is + * not a list or a different list. */ + def listLine(indent: Int, style: String): Option[Block] = + if (countWhitespace > indent && checkList) + Some(listBlock) + else if (countWhitespace != indent || !checkSkipInitWhitespace(style)) + None + else { + jumpWhitespace() + jump(style) + val p = Paragraph(inline(isInlineEnd = false)) + blockEnded("end of list line ") + Some(p) + } + + /** Consumes all list item blocks (possibly with nested lists) of the + * same list and returns the list block. */ + def listLevel(indent: Int, style: String): Block = { + val lines = mutable.ListBuffer.empty[Block] + var line: Option[Block] = listLine(indent, style) + while (line.isDefined) { + lines += line.get + line = listLine(indent, style) + } + val constructor = listStyles(style) + constructor(lines) + } + + val indent = countWhitespace + val style = (listStyles.keys find { checkSkipInitWhitespace(_) }).getOrElse(listStyles.keys.head) + listLevel(indent, style) + } + + def code(): Block = { + jumpWhitespace() + jump("{{{") + val str = readUntil("}}}") + if (char == endOfText) + reportError(pos, "unclosed code block") + else + jump("}}}") + blockEnded("code block") + Code(normalizeIndentation(str)) + } + + /** {{{ title ::= ('=' inline '=' | "==" inline "==" | ...) '\n' }}} */ + def title(): Block = { + jumpWhitespace() + val inLevel = repeatJump('=') + val text = inline(check("=" * inLevel)) + val outLevel = repeatJump('=', inLevel) + if (inLevel != outLevel) + reportError(pos, "unbalanced or unclosed heading") + blockEnded("heading") + Title(text, inLevel) + } + + /** {{{ hrule ::= "----" { '-' } '\n' }}} */ + def hrule(): Block = { + jumpWhitespace() + repeatJump('-') + blockEnded("horizontal rule") + HorizontalRule() + } + + /** {{{ para ::= inline '\n' }}} */ + def para(): Block = { + val p = + if (summaryParsed) + Paragraph(inline(isInlineEnd = false)) + else { + val s = summary() + val r = + if (checkParaEnded()) List(s) else List(s, inline(isInlineEnd = false)) + summaryParsed = true + Paragraph(Chain(r)) + } + while (char == endOfLine && char != endOfText) + nextChar() + p + } + + /* INLINES */ + + val OPEN_TAG = "^<([A-Za-z]+)( [^>]*)?(/?)>$".r + val CLOSE_TAG = "^$".r + private def readHTMLFrom(begin: HtmlTag): String = { + val list = mutable.ListBuffer.empty[String] + val stack = mutable.ListBuffer.empty[String] + + begin.close match { + case Some(HtmlTag(CLOSE_TAG(s))) => + stack += s + case _ => + return "" + } + + do { + val str = readUntil { char == safeTagMarker || char == endOfText } + nextChar() + + list += str + + str match { + case OPEN_TAG(s, _, standalone) => { + if (standalone != "/") { + stack += s + } + } + case CLOSE_TAG(s) => { + if (s == stack.last) { + stack.remove(stack.length-1) + } + } + case _ => ; + } + } while (stack.length > 0 && char != endOfText) + + list mkString "" + } + + def inline(isInlineEnd: => Boolean): Inline = { + + def inline0(): Inline = { + if (char == safeTagMarker) { + val tag = htmlTag() + HtmlTag(tag.data + readHTMLFrom(tag)) + } + else if (check("'''")) bold() + else if (check("''")) italic() + else if (check("`")) monospace() + else if (check("__")) underline() + else if (check("^")) superscript() + else if (check(",,")) subscript() + else if (check("[[")) link() + else { + val str = readUntil { char == safeTagMarker || check("''") || char == '`' || check("__") || char == '^' || check(",,") || check("[[") || isInlineEnd || checkParaEnded || char == endOfLine } + Text(str) + } + } + + val inlines: List[Inline] = { + val iss = mutable.ListBuffer.empty[Inline] + iss += inline0() + while (!isInlineEnd && !checkParaEnded) { + val skipEndOfLine = if (char == endOfLine) { + nextChar() + true + } else { + false + } + + val current = inline0() + (iss.last, current) match { + case (Text(t1), Text(t2)) if skipEndOfLine => + iss.update(iss.length - 1, Text(t1 + endOfLine + t2)) + case (i1, i2) if skipEndOfLine => + iss ++= List(Text(endOfLine.toString), i2) + case _ => iss += current + } + } + iss.toList + } + + inlines match { + case Nil => Text("") + case i :: Nil => i + case is => Chain(is) + } + + } + + def htmlTag(): HtmlTag = { + jump(safeTagMarker) + val read = readUntil(safeTagMarker) + if (char != endOfText) jump(safeTagMarker) + HtmlTag(read) + } + + def bold(): Inline = { + jump("'''") + val i = inline(check("'''")) + jump("'''") + Bold(i) + } + + def italic(): Inline = { + jump("''") + val i = inline(check("''")) + jump("''") + Italic(i) + } + + def monospace(): Inline = { + jump("`") + val i = inline(check("`")) + jump("`") + Monospace(i) + } + + def underline(): Inline = { + jump("__") + val i = inline(check("__")) + jump("__") + Underline(i) + } + + def superscript(): Inline = { + jump("^") + val i = inline(check("^")) + if (jump("^")) { + Superscript(i) + } else { + Chain(Seq(Text("^"), i)) + } + } + + def subscript(): Inline = { + jump(",,") + val i = inline(check(",,")) + jump(",,") + Subscript(i) + } + + def summary(): Inline = { + val i = inline(check(".")) + Summary( + if (jump(".")) + Chain(List(i, Text("."))) + else + i + ) + } + + def link(): Inline = { + val SchemeUri = """([a-z]+:.*)""".r + jump("[[") + val parens = 2 + repeatJump('[') + val start = "[" * parens + val stop = "]" * parens + //println("link with " + parens + " matching parens") + val target = readUntil { check(stop) || check(" ") } + val title = + if (!check(stop)) Some({ + jump(" ") + inline(check(stop)) + }) + else None + jump(stop) + + (target, title) match { + case (SchemeUri(uri), optTitle) => + Link(uri, optTitle getOrElse Text(uri)) + case (qualName, optTitle) => + makeEntityLink(optTitle getOrElse Text(target), pos, target, siteOpt) + } + } + + /* UTILITY */ + + /** {{{ eol ::= { whitespace } '\n' }}} */ + def blockEnded(blockType: String): Unit = { + if (char != endOfLine && char != endOfText) { + reportError(pos, "no additional content on same line after " + blockType) + jumpUntil(endOfLine) + } + while (char == endOfLine) + nextChar() + } + + /** + * Eliminates the (common) leading spaces in all lines, based on the first line + * For indented pieces of code, it reduces the indent to the least whitespace prefix: + * {{{ + * indented example + * another indented line + * if (condition) + * then do something; + * ^ this is the least whitespace prefix + * }}} + */ + def normalizeIndentation(_code: String): String = { + + val code = _code.trim + var maxSkip = Integer.MAX_VALUE + var crtSkip = 0 + var wsArea = true + var index = 0 + var firstLine = true + var emptyLine = true + + while (index < code.length) { + code(index) match { + case ' ' => + if (wsArea) + crtSkip += 1 + case c => + wsArea = (c == '\n') + maxSkip = if (firstLine || emptyLine) maxSkip else if (maxSkip <= crtSkip) maxSkip else crtSkip + crtSkip = if (c == '\n') 0 else crtSkip + firstLine = if (c == '\n') false else firstLine + emptyLine = if (c == '\n') true else false + } + index += 1 + } + + if (maxSkip == 0) + code + else { + index = 0 + val builder = new StringBuilder + while (index < code.length) { + builder.append(code(index)) + if (code(index) == '\n') { + // we want to skip as many spaces are available, if there are less spaces (like on empty lines, do not + // over-consume them) + index += 1 + val limit = index + maxSkip + while ((index < code.length) && (code(index) == ' ') && index < limit) + index += 1 + } + else + index += 1 + } + builder.toString + } + } + + def checkParaEnded(): Boolean = { + (char == endOfText) || + ((char == endOfLine) && { + val poff = offset + nextChar() // read EOL + val ok = { + checkSkipInitWhitespace(endOfLine) || + checkSkipInitWhitespace('=') || + checkSkipInitWhitespace("{{{") || + checkList || + checkSkipInitWhitespace('\u003D') + } + offset = poff + ok + }) + } + + def reportError(pos: Position, message: String) { + reporter.warning(pos, message) + } + } + + protected sealed class CharReader(buffer: String) { reader => + + var offset: Int = 0 + def char: Char = + if (offset >= buffer.length) endOfText else buffer charAt offset + + final def nextChar() { + offset += 1 + } + + final def check(chars: String): Boolean = { + val poff = offset + val ok = jump(chars) + offset = poff + ok + } + + def checkSkipInitWhitespace(c: Char): Boolean = { + val poff = offset + jumpWhitespace() + val ok = jump(c) + offset = poff + ok + } + + def checkSkipInitWhitespace(chars: String): Boolean = { + val poff = offset + jumpWhitespace() + val (ok0, chars0) = + if (chars.charAt(0) == ' ') + (offset > poff, chars substring 1) + else + (true, chars) + val ok = ok0 && jump(chars0) + offset = poff + ok + } + + def countWhitespace: Int = { + var count = 0 + val poff = offset + while (isWhitespace(char) && char != endOfText) { + nextChar() + count += 1 + } + offset = poff + count + } + + /* JUMPERS */ + + /** jumps a character and consumes it + * @return true only if the correct character has been jumped */ + final def jump(ch: Char): Boolean = { + if (char == ch) { + nextChar() + true + } + else false + } + + /** jumps all the characters in chars, consuming them in the process. + * @return true only if the correct characters have been jumped */ + final def jump(chars: String): Boolean = { + var index = 0 + while (index < chars.length && char == chars.charAt(index) && char != endOfText) { + nextChar() + index += 1 + } + index == chars.length + } + + final def repeatJump(c: Char, max: Int = Int.MaxValue): Int = { + var count = 0 + while (jump(c) && count < max) + count += 1 + count + } + + final def jumpUntil(ch: Char): Int = { + var count = 0 + while (char != ch && char != endOfText) { + nextChar() + count += 1 + } + count + } + + final def jumpUntil(pred: => Boolean): Int = { + var count = 0 + while (!pred && char != endOfText) { + nextChar() + count += 1 + } + count + } + + def jumpWhitespace() = jumpUntil(!isWhitespace(char)) + + /* READERS */ + + final def readUntil(c: Char): String = { + withRead { + while (char != c && char != endOfText) { + nextChar() + } + } + } + + final def readUntil(chars: String): String = { + assert(chars.length > 0) + withRead { + val c = chars.charAt(0) + while (!check(chars) && char != endOfText) { + nextChar() + while (char != c && char != endOfText) + nextChar() + } + } + } + + final def readUntil(pred: => Boolean): String = { + withRead { + while (char != endOfText && !pred) { + nextChar() + } + } + } + + private def withRead(read: => Unit): String = { + val start = offset + read + buffer.substring(start, offset) + } + + + /* CHARS CLASSES */ + + def isWhitespace(c: Char) = c == ' ' || c == '\t' + + } + +} diff --git a/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala b/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala new file mode 100755 index 0000000000..c11179800c --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala @@ -0,0 +1,15 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + */ + +package scala.tools.nsc +package doc +package base + +import scala.collection._ + +sealed trait LinkTo +final case class LinkToMember[Mbr, Tpl](mbr: Mbr, tpl: Tpl) extends LinkTo +final case class LinkToTpl[Tpl](tpl: Tpl) extends LinkTo +final case class LinkToExternal(name: String, url: String) extends LinkTo +final case class Tooltip(name: String) extends LinkTo diff --git a/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala new file mode 100755 index 0000000000..8d80333195 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala @@ -0,0 +1,206 @@ +package scala.tools.nsc +package doc +package base + +import comment._ + +/** This trait extracts all required information for documentation from compilation units. + * The base trait has been extracted to allow getting light-weight documentation + * for a particular symbol in the IDE.*/ +trait MemberLookupBase { + + val global: Global + import global._ + + def internalLink(sym: Symbol, site: Symbol): Option[LinkTo] + def chooseLink(links: List[LinkTo]): LinkTo + def toString(link: LinkTo): String + def findExternalLink(sym: Symbol, name: String): Option[LinkToExternal] + def warnNoLink: Boolean + + import global._ + import rootMirror.{RootPackage, EmptyPackage} + + private def isRoot(s: Symbol) = s.isRootSymbol || s.isEmptyPackage || s.isEmptyPackageClass + + def makeEntityLink(title: Inline, pos: Position, query: String, siteOpt: Option[Symbol]) = + new EntityLink(title) { lazy val link = memberLookup(pos, query, siteOpt) } + + private var showExplanation = true + private def explanation: String = + if (showExplanation) { + showExplanation = false + """ + |Quick crash course on using Scaladoc links + |========================================== + |Disambiguating terms and types: Prefix terms with '$' and types with '!' in case both names are in use: + | - [[scala.collection.immutable.List!.apply class List's apply method]] and + | - [[scala.collection.immutable.List$.apply object List's apply method]] + |Disambiguating overloaded members: If a term is overloaded, you can indicate the first part of its signature followed by *: + | - [[[scala.collection.immutable.List$.fill[A](Int)(⇒A):List[A]* Fill with a single parameter]]] + | - [[[scala.collection.immutable.List$.fill[A](Int,Int)(⇒A):List[List[A]]* Fill with a two parameters]]] + |Notes: + | - you can use any number of matching square brackets to avoid interference with the signature + | - you can use \\. to escape dots in prefixes (don't forget to use * at the end to match the signature!) + | - you can use \\# to escape hashes, otherwise they will be considered as delimiters, like dots.""".stripMargin + } else "" + + def memberLookup(pos: Position, query: String, siteOpt: Option[Symbol]): LinkTo = { + var members = breakMembers(query) + + // (1) First look in the root package, as most of the links are qualified + val fromRoot = lookupInRootPackage(pos, members) + + // (2) Or recursively go into each containing template. + val fromParents = siteOpt.fold(Stream.empty[Symbol]) { s => + Stream.iterate(s)(_.owner) + }.takeWhile (!isRoot(_)).map { + lookupInTemplate(pos, members, _) + } + + val syms = (fromRoot +: fromParents) find (!_.isEmpty) getOrElse Nil + + val links = syms flatMap { case (sym, site) => internalLink(sym, site) } match { + case Nil => + // (3) Look at external links + syms.flatMap { case (sym, owner) => + // reconstruct the original link + def linkName(sym: Symbol) = { + def nameString(s: Symbol) = s.nameString + (if ((s.isModule || s.isModuleClass) && !s.isPackage) "$" else "") + val packageSuffix = if (sym.isPackage) ".package" else "" + + sym.ownerChain.reverse.filterNot(isRoot(_)).map(nameString(_)).mkString(".") + packageSuffix + } + + if (sym.isClass || sym.isModule || sym.isTrait || sym.isPackage) + findExternalLink(sym, linkName(sym)) + else if (owner.isClass || owner.isModule || owner.isTrait || owner.isPackage) + findExternalLink(sym, linkName(owner) + "@" + externalSignature(sym)) + else + None + } + case links => links + } + links match { + case Nil => + if (warnNoLink) + reporter.warning(pos, "Could not find any member to link for \"" + query + "\".") + // (4) if we still haven't found anything, create a tooltip + Tooltip(query) + case List(l) => l + case links => + val chosen = chooseLink(links) + def linkToString(link: LinkTo) = { + val chosenInfo = + if (link == chosen) " [chosen]" else "" + toString(link) + chosenInfo + "\n" + } + if (warnNoLink) { + val allLinks = links.map(linkToString).mkString + reporter.warning(pos, + s"""The link target \"$query\" is ambiguous. Several members fit the target: + |$allLinks + |$explanation""".stripMargin) + } + chosen + } + } + + private sealed trait SearchStrategy + private case object BothTypeAndTerm extends SearchStrategy + private case object OnlyType extends SearchStrategy + private case object OnlyTerm extends SearchStrategy + + private def lookupInRootPackage(pos: Position, members: List[String]) = + lookupInTemplate(pos, members, EmptyPackage) ::: lookupInTemplate(pos, members, RootPackage) + + private def lookupInTemplate(pos: Position, members: List[String], container: Symbol): List[(Symbol, Symbol)] = { + // Maintaining compatibility with previous links is a bit tricky here: + // we have a preference for term names for all terms except for the last, where we prefer a class: + // How to do this: + // - at each step we do a DFS search with the prefered strategy + // - if the search doesn't return any members, we backtrack on the last decision + // * we look for terms with the last member's name + // * we look for types with the same name, all the way up + val result = members match { + case Nil => Nil + case mbrName::Nil => + var syms = lookupInTemplate(pos, mbrName, container, OnlyType) map ((_, container)) + if (syms.isEmpty) + syms = lookupInTemplate(pos, mbrName, container, OnlyTerm) map ((_, container)) + syms + + case tplName::rest => + def completeSearch(syms: List[Symbol]) = + syms flatMap (lookupInTemplate(pos, rest, _)) + + completeSearch(lookupInTemplate(pos, tplName, container, OnlyTerm)) match { + case Nil => completeSearch(lookupInTemplate(pos, tplName, container, OnlyType)) + case syms => syms + } + } + //println("lookupInTemplate(" + members + ", " + container + ") => " + result) + result + } + + private def lookupInTemplate(pos: Position, member: String, container: Symbol, strategy: SearchStrategy): List[Symbol] = { + val name = member.stripSuffix("$").stripSuffix("!").stripSuffix("*") + def signatureMatch(sym: Symbol): Boolean = externalSignature(sym).startsWith(name) + + // We need to cleanup the bogus classes created by the .class file parser. For example, [[scala.Predef]] resolves + // to (bogus) class scala.Predef loaded by the class loader -- which we need to eliminate by looking at the info + // and removing NoType classes + def cleanupBogusClasses(syms: List[Symbol]) = { syms.filter(_.info != NoType) } + + def syms(name: Name) = container.info.nonPrivateMember(name.encodedName).alternatives + def termSyms = cleanupBogusClasses(syms(newTermName(name))) + def typeSyms = cleanupBogusClasses(syms(newTypeName(name))) + + val result = if (member.endsWith("$")) + termSyms + else if (member.endsWith("!")) + typeSyms + else if (member.endsWith("*")) + cleanupBogusClasses(container.info.nonPrivateDecls) filter signatureMatch + else + strategy match { + case BothTypeAndTerm => termSyms ::: typeSyms + case OnlyType => typeSyms + case OnlyTerm => termSyms + } + + //println("lookupInTemplate(" + member + ", " + container + ") => " + result) + result + } + + private def breakMembers(query: String): List[String] = { + // Okay, how does this work? Well: you split on . but you don't want to split on \. => thus the ugly regex + // query.split((?<=[^\\\\])\\.).map(_.replaceAll("\\.")) + // The same code, just faster: + var members = List[String]() + var index = 0 + var last_index = 0 + val length = query.length + while (index < length) { + if ((query.charAt(index) == '.' || query.charAt(index) == '#') && + ((index == 0) || (query.charAt(index-1) != '\\'))) { + + val member = query.substring(last_index, index).replaceAll("\\\\([#\\.])", "$1") + // we want to allow javadoc-style links [[#member]] -- which requires us to remove empty members from the first + // elemnt in the list + if ((member != "") || (!members.isEmpty)) + members ::= member + last_index = index + 1 + } + index += 1 + } + if (last_index < length) + members ::= query.substring(last_index, length).replaceAll("\\\\\\.", ".") + members.reverse + } + + def externalSignature(sym: Symbol) = { + sym.info // force it, otherwise we see lazy types + (sym.nameString + sym.signatureString).replaceAll("\\s", "") + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala new file mode 100755 index 0000000000..2a07547de2 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala @@ -0,0 +1,89 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Manohar Jonnalagedda + */ + +package scala.tools.nsc +package doc +package base +package comment + +import scala.collection._ + +/** A body of text. A comment has a single body, which is composed of + * at least one block. Inside every body is exactly one summary (see + * [[scala.tools.nsc.doc.model.comment.Summary]]). */ +final case class Body(blocks: Seq[Block]) { + + /** The summary text of the comment body. */ + lazy val summary: Option[Inline] = { + def summaryInBlock(block: Block): Seq[Inline] = block match { + case Title(text, _) => summaryInInline(text) + case Paragraph(text) => summaryInInline(text) + case UnorderedList(items) => items flatMap summaryInBlock + case OrderedList(items, _) => items flatMap summaryInBlock + case DefinitionList(items) => items.values.toSeq flatMap summaryInBlock + case _ => Nil + } + def summaryInInline(text: Inline): Seq[Inline] = text match { + case Summary(text) => List(text) + case Chain(items) => items flatMap summaryInInline + case Italic(text) => summaryInInline(text) + case Bold(text) => summaryInInline(text) + case Underline(text) => summaryInInline(text) + case Superscript(text) => summaryInInline(text) + case Subscript(text) => summaryInInline(text) + case Link(_, title) => summaryInInline(title) + case _ => Nil + } + (blocks flatMap { summaryInBlock(_) }).toList match { + case Nil => None + case inline :: Nil => Some(inline) + case inlines => Some(Chain(inlines)) + } + } +} + +/** A block-level element of text, such as a paragraph or code block. */ +sealed abstract class Block + +final case class Title(text: Inline, level: Int) extends Block +final case class Paragraph(text: Inline) extends Block +final case class Code(data: String) extends Block +final case class UnorderedList(items: Seq[Block]) extends Block +final case class OrderedList(items: Seq[Block], style: String) extends Block +final case class DefinitionList(items: SortedMap[Inline, Block]) extends Block +final case class HorizontalRule() extends Block + +/** An section of text inside a block, possibly with formatting. */ +sealed abstract class Inline + +final case class Chain(items: Seq[Inline]) extends Inline +final case class Italic(text: Inline) extends Inline +final case class Bold(text: Inline) extends Inline +final case class Underline(text: Inline) extends Inline +final case class Superscript(text: Inline) extends Inline +final case class Subscript(text: Inline) extends Inline +final case class Link(target: String, title: Inline) extends Inline +final case class Monospace(text: Inline) extends Inline +final case class Text(text: String) extends Inline +abstract class EntityLink(val title: Inline) extends Inline { def link: LinkTo } +object EntityLink { + def apply(title: Inline, linkTo: LinkTo) = new EntityLink(title) { def link: LinkTo = linkTo } + def unapply(el: EntityLink): Option[(Inline, LinkTo)] = Some((el.title, el.link)) +} +final case class HtmlTag(data: String) extends Inline { + def canClose(open: HtmlTag) = { + open.data.stripPrefix("<") == data.stripPrefix(" + list foreach scan + case tag: HtmlTag => { + if (stack.length > 0 && tag.canClose(stack.last)) { + stack.remove(stack.length-1) + } else { + tag.close match { + case Some(t) => + stack += t + case None => + ; + } + } + } + case _ => + ; + } + } + scan(inline) + Chain(List(inline) ++ stack.reverse) + } + + /** A shorter version of the body. Usually, this is the first sentence of the body. */ + def short: Inline = { + body.summary match { + case Some(s) => + closeHtmlTags(s) + case _ => + Text("") + } + } + + /** A list of authors. The empty list is used when no author is defined. */ + def authors: List[Body] + + /** A list of other resources to see, including links to other entities or + * to external documentation. The empty list is used when no other resource + * is mentionned. */ + def see: List[Body] + + /** A description of the result of the entity. Typically, this provides additional + * information on the domain of the result, contractual post-conditions, etc. */ + def result: Option[Body] + + /** A map of exceptions that the entity can throw when accessed, and a + * description of what they mean. */ + def throws: Map[String, Body] + + /** A map of value parameters, and a description of what they are. Typically, + * this provides additional information on the domain of the parameters, + * contractual pre-conditions, etc. */ + def valueParams: Map[String, Body] + + /** A map of type parameters, and a description of what they are. Typically, + * this provides additional information on the domain of the parameters. */ + def typeParams: Map[String, Body] + + /** The version number of the entity. There is no formatting or further + * meaning attached to this value. */ + def version: Option[Body] + + /** A version number of a containing entity where this member-entity was introduced. */ + def since: Option[Body] + + /** An annotation as to expected changes on this entity. */ + def todo: List[Body] + + /** Whether the entity is deprecated. Using the `@deprecated` Scala attribute + * is prefereable to using this Scaladoc tag. */ + def deprecated: Option[Body] + + /** An additional note concerning the contract of the entity. */ + def note: List[Body] + + /** A usage example related to the entity. */ + def example: List[Body] + + /** A description for the primary constructor */ + def constructor: Option[Body] + + /** A set of diagram directives for the inheritance diagram */ + def inheritDiagram: List[String] + + /** A set of diagram directives for the content diagram */ + def contentDiagram: List[String] + + /** The group this member is part of */ + def group: Option[String] + + /** Member group descriptions */ + def groupDesc: Map[String,Body] + + /** Member group names (overriding the short tag) */ + def groupNames: Map[String,String] + + /** Member group priorities */ + def groupPrio: Map[String,Int] + + override def toString = + body.toString + "\n" + + (authors map ("@author " + _.toString)).mkString("\n") + + (result map ("@return " + _.toString)).mkString("\n") + + (version map ("@version " + _.toString)).mkString +} diff --git a/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala b/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala new file mode 100644 index 0000000000..42b56aa927 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala @@ -0,0 +1,30 @@ +package scala.tools.nsc.doc +package doclet + +import scala.collection._ + +/** Custom Scaladoc generators must implement the `Generator` class. A custom generator can be selected in Scaladoc + * using the `-doc-generator` command line option. + * The `Generator` class does not provide data about the documented code. A number of data provider traits can be used + * to configure what data is actually available to the generator: + * - A `Universer` provides a `Universe` data structure representing the interfaces and comments of the documented + * program. + * - An `Indexer` provides precalculated indexing information about a universe. + * To implement this class only requires defining method `generateImpl`. */ +abstract class Generator { + + /** A series of tests that must be true before generation can be done. This is used by data provider traits to + * confirm that they have been correctly initialised before allowing generation to proceed. */ + protected val checks: mutable.Set[()=>Boolean] = + mutable.Set.empty[()=>Boolean] + + /** Outputs documentation (as a side effect). */ + def generate(): Unit = { + assert(checks forall { check => check() }) + generateImpl() + } + + /** Outputs documentation (as a side effect). This method is called only if all `checks` are true. */ + protected def generateImpl(): Unit + +} diff --git a/src/scaladoc/scala/tools/nsc/doc/doclet/Indexer.scala b/src/scaladoc/scala/tools/nsc/doc/doclet/Indexer.scala new file mode 100644 index 0000000000..0cdd47182f --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/doclet/Indexer.scala @@ -0,0 +1,21 @@ +package scala.tools.nsc +package doc +package doclet + +/** A `Generator` may implement the `Indexer` trait to gain access to pre-calculated indexing information */ +trait Indexer extends Generator with Universer { + + protected var indexField: Index = null + + def index: Index = indexField + + def setIndex(i: Index) { + assert(indexField == null) + indexField = i + } + + checks += { () => + indexField != null + } + +} \ No newline at end of file diff --git a/src/scaladoc/scala/tools/nsc/doc/doclet/Universer.scala b/src/scaladoc/scala/tools/nsc/doc/doclet/Universer.scala new file mode 100644 index 0000000000..ee8b7809e5 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/doclet/Universer.scala @@ -0,0 +1,21 @@ +package scala.tools.nsc +package doc +package doclet + +/** A `Generator` may implement the `Universer` trait to gain access to a model of the documented program */ +trait Universer extends Generator { + + protected var universeField: Universe = null + + def universe: Universe = universeField + + def setUniverse(u: Universe) { + assert(universeField == null) + universeField = u + } + + checks += { () => + universeField != null + } + +} \ No newline at end of file diff --git a/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala b/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala new file mode 100644 index 0000000000..21c5f6bb67 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala @@ -0,0 +1,19 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author David Bernard, Manohar Jonnalagedda + */ + +package scala.tools.nsc.doc +package html + +import doclet._ + +/** The default doclet used by the scaladoc command line tool + * when no user-provided doclet is provided. */ +class Doclet extends Generator with Universer with Indexer { + + def generateImpl() { + new html.HtmlFactory(universe, index).generate() + } + +} diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala new file mode 100644 index 0000000000..d721a96ad7 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala @@ -0,0 +1,152 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author David Bernard, Manohar Jonnalagedda + */ + +package scala.tools.nsc +package doc +package html + +import model._ +import java.io.{ File => JFile } +import io.{ Streamable, Directory } +import scala.collection._ +import page.diagram._ + +import html.page.diagram.DiagramGenerator + +/** A class that can generate Scaladoc sites to some fixed root folder. + * @author David Bernard + * @author Gilles Dubochet */ +class HtmlFactory(val universe: doc.Universe, index: doc.Index) { + + /** The character encoding to be used for generated Scaladoc sites. + * This value is currently always UTF-8. */ + def encoding: String = "UTF-8" + + def siteRoot: JFile = new JFile(universe.settings.outdir.value) + + def libResources = List( + "index.js", + "jquery-ui.js", + "jquery.js", + "jquery.layout.js", + "scheduler.js", + "diagrams.js", + "template.js", + "tools.tooltip.js", + "modernizr.custom.js", + + "index.css", + "ref-index.css", + "template.css", + "diagrams.css", + + "class.png", + "class_big.png", + "class_diagram.png", + "object.png", + "object_big.png", + "object_diagram.png", + "package.png", + "package_big.png", + "trait.png", + "trait_big.png", + "trait_diagram.png", + "type.png", + "type_big.png", + "type_diagram.png", + + "class_to_object_big.png", + "object_to_class_big.png", + "trait_to_object_big.png", + "object_to_trait_big.png", + "type_to_object_big.png", + "object_to_type_big.png", + + "arrow-down.png", + "arrow-right.png", + "filter_box_left.png", + "filter_box_left2.gif", + "filter_box_right.png", + "filterbg.gif", + "filterboxbarbg.gif", + "filterboxbg.gif", + + "constructorsbg.gif", + "defbg-blue.gif", + "defbg-green.gif", + "filterboxbarbg.png", + "fullcommenttopbg.gif", + "ownderbg2.gif", + "ownerbg.gif", + "ownerbg2.gif", + "packagesbg.gif", + "signaturebg.gif", + "signaturebg2.gif", + "typebg.gif", + "conversionbg.gif", + "valuemembersbg.gif", + + "navigation-li-a.png", + "navigation-li.png", + "remove.png", + "selected-right.png", + "selected.png", + "selected2-right.png", + "selected2.png", + "selected-right-implicits.png", + "selected-implicits.png", + "unselected.png" + ) + + /** Generates the Scaladoc site for a model into the site root. + * A scaladoc site is a set of HTML and related files + * that document a model extracted from a compiler run. + */ + def generate() { + + def copyResource(subPath: String) { + val bytes = new Streamable.Bytes { + val p = "/scala/tools/nsc/doc/html/resource/" + subPath + val inputStream = getClass.getResourceAsStream(p) + assert(inputStream != null, p) + }.toByteArray() + val dest = Directory(siteRoot) / subPath + dest.parent.createDirectory() + val out = dest.toFile.bufferedOutput() + try out.write(bytes, 0, bytes.length) + finally out.close() + } + + DiagramGenerator.initialize(universe.settings) + + libResources foreach (s => copyResource("lib/" + s)) + + new page.Index(universe, index) writeFor this + new page.IndexScript(universe, index) writeFor this + + writeTemplates(_ writeFor this) + + for (letter <- index.firstLetterIndex) { + new html.page.ReferenceIndex(letter._1, index, universe) writeFor this + } + + DiagramGenerator.cleanup() + } + + def writeTemplates(writeForThis: HtmlPage => Unit) { + val written = mutable.HashSet.empty[DocTemplateEntity] + val diagramGenerator: DiagramGenerator = new DotDiagramGenerator(universe.settings) + + def writeTemplate(tpl: DocTemplateEntity) { + if (!(written contains tpl)) { + writeForThis(new page.Template(universe, diagramGenerator, tpl)) + written += tpl + tpl.templates collect { case d: DocTemplateEntity => d } map writeTemplate + } + } + + writeTemplate(universe.rootPackage) + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala new file mode 100644 index 0000000000..229e26d699 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala @@ -0,0 +1,224 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author David Bernard, Manohar Jonnalagedda + */ + +package scala.tools.nsc +package doc +package html + +import base._ +import base.comment._ +import model._ + +import scala.xml.NodeSeq +import scala.xml.dtd.{DocType, PublicID} +import scala.collection._ +import java.io.Writer + +/** An html page that is part of a Scaladoc site. + * @author David Bernard + * @author Gilles Dubochet */ +abstract class HtmlPage extends Page { thisPage => + /** The title of this page. */ + protected def title: String + + /** The page description */ + protected def description: String = + // unless overwritten, will display the title in a spaced format, keeping - and . + title.replaceAll("[^a-zA-Z0-9\\.\\-]+", " ").replaceAll("\\-+", " - ").replaceAll(" +", " ") + + /** The page keywords */ + protected def keywords: String = + // unless overwritten, same as description, minus the " - " + description.replaceAll(" - ", " ") + + /** Additional header elements (links, scripts, meta tags, etc.) required for this page. */ + protected def headers: NodeSeq + + /** The body of this page. */ + def body: NodeSeq + + def writeFor(site: HtmlFactory) { + val doctype = + DocType("html", PublicID("-//W3C//DTD XHTML 1.1//EN", "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"), Nil) + val html = + + + { title } + + + \n") + w.write(doctype.toString + "\n") + w.write(xml.Xhtml.toXhtml(html)) + } + + if (site.universe.settings.docRawOutput.value) + writeFile(site, ".raw") { + // we're only interested in the body, as this will go into the diff + _.write(body.text) + } + + //XML.save(pageFile.getPath, html, site.encoding, xmlDecl = false, doctype = doctype) + } + + /** Transforms an optional comment into an styled HTML tree representing its body if it is defined, or into an empty + * node sequence if it is not. */ + def commentToHtml(comment: Option[Comment]): NodeSeq = + (comment map (commentToHtml(_))) getOrElse NodeSeq.Empty + + /** Transforms a comment into an styled HTML tree representing its body. */ + def commentToHtml(comment: Comment): NodeSeq = + bodyToHtml(comment.body) + + def bodyToHtml(body: Body): NodeSeq = + body.blocks flatMap (blockToHtml(_)) + + def blockToHtml(block: Block): NodeSeq = block match { + case Title(in, 1) =>

{ inlineToHtml(in) }

+ case Title(in, 2) =>

{ inlineToHtml(in) }

+ case Title(in, 3) =>
{ inlineToHtml(in) }
+ case Title(in, _) =>
{ inlineToHtml(in) }
+ case Paragraph(in) =>

{ inlineToHtml(in) }

+ case Code(data) => +
{ SyntaxHigh(data) }
//
{ scala.xml.Text(data) }
+ case UnorderedList(items) => +
    { listItemsToHtml(items) }
+ case OrderedList(items, listStyle) => +
    { listItemsToHtml(items) }
+ case DefinitionList(items) => +
{items map { case (t, d) =>
{ inlineToHtml(t) }
{ blockToHtml(d) }
} }
+ case HorizontalRule() => +
+ } + + def listItemsToHtml(items: Seq[Block]) = + items.foldLeft(xml.NodeSeq.Empty){ (xmlList, item) => + item match { + case OrderedList(_, _) | UnorderedList(_) => // html requires sub ULs to be put into the last LI + xmlList.init ++
  • { xmlList.last.child ++ blockToHtml(item) }
  • + case Paragraph(inline) => + xmlList :+
  • { inlineToHtml(inline) }
  • // LIs are blocks, no need to use Ps + case block => + xmlList :+
  • { blockToHtml(block) }
  • + } + } + + def inlineToHtml(inl: Inline): NodeSeq = inl match { + case Chain(items) => items flatMap (inlineToHtml(_)) + case Italic(in) => { inlineToHtml(in) } + case Bold(in) => { inlineToHtml(in) } + case Underline(in) => { inlineToHtml(in) } + case Superscript(in) => { inlineToHtml(in) } + case Subscript(in) => { inlineToHtml(in) } + case Link(raw, title) => { inlineToHtml(title) } + case Monospace(in) => { inlineToHtml(in) } + case Text(text) => scala.xml.Text(text) + case Summary(in) => inlineToHtml(in) + case HtmlTag(tag) => scala.xml.Unparsed(tag) + case EntityLink(target, link) => linkToHtml(target, link, hasLinks = true) + } + + def linkToHtml(text: Inline, link: LinkTo, hasLinks: Boolean) = link match { + case LinkToTpl(dtpl: TemplateEntity) => + if (hasLinks) + { inlineToHtml(text) } + else + { inlineToHtml(text) } + case LinkToMember(mbr: MemberEntity, inTpl: TemplateEntity) => + if (hasLinks) + { inlineToHtml(text) } + else + { inlineToHtml(text) } + case Tooltip(tooltip) => + { inlineToHtml(text) } + case LinkToExternal(name, url) => + { inlineToHtml(text) } + case _ => + inlineToHtml(text) + } + + def typeToHtml(tpes: List[model.TypeEntity], hasLinks: Boolean): NodeSeq = tpes match { + case Nil => + NodeSeq.Empty + case List(tpe) => + typeToHtml(tpe, hasLinks) + case tpe :: rest => + typeToHtml(tpe, hasLinks) ++ scala.xml.Text(" with ") ++ typeToHtml(rest, hasLinks) + } + + def typeToHtml(tpe: model.TypeEntity, hasLinks: Boolean): NodeSeq = { + val string = tpe.name + def toLinksOut(inPos: Int, starts: List[Int]): NodeSeq = { + if (starts.isEmpty && (inPos == string.length)) + NodeSeq.Empty + else if (starts.isEmpty) + scala.xml.Text(string.slice(inPos, string.length)) + else if (inPos == starts.head) + toLinksIn(inPos, starts) + else { + scala.xml.Text(string.slice(inPos, starts.head)) ++ toLinksIn(starts.head, starts) + } + } + def toLinksIn(inPos: Int, starts: List[Int]): NodeSeq = { + val (link, width) = tpe.refEntity(inPos) + val text = comment.Text(string.slice(inPos, inPos + width)) + linkToHtml(text, link, hasLinks) ++ toLinksOut(inPos + width, starts.tail) + } + if (hasLinks) + toLinksOut(0, tpe.refEntity.keySet.toList) + else + scala.xml.Text(string) + } + + def typesToHtml(tpess: List[model.TypeEntity], hasLinks: Boolean, sep: NodeSeq): NodeSeq = tpess match { + case Nil => NodeSeq.Empty + case tpe :: Nil => typeToHtml(tpe, hasLinks) + case tpe :: tpes => typeToHtml(tpe, hasLinks) ++ sep ++ typesToHtml(tpes, hasLinks, sep) + } + + def hasPage(e: DocTemplateEntity) = { + e.isPackage || e.isTrait || e.isClass || e.isObject || e.isCaseClass + } + + /** Returns the HTML code that represents the template in `tpl` as a hyperlinked name. */ + def templateToHtml(tpl: TemplateEntity, name: String = null) = tpl match { + case dTpl: DocTemplateEntity => + if (hasPage(dTpl)) { + { if (name eq null) dTpl.name else name } + } else { + scala.xml.Text(if (name eq null) dTpl.name else name) + } + case ndTpl: NoDocTemplate => + scala.xml.Text(if (name eq null) ndTpl.name else name) + } + + /** Returns the HTML code that represents the templates in `tpls` as a list of hyperlinked names. */ + def templatesToHtml(tplss: List[TemplateEntity], sep: NodeSeq): NodeSeq = tplss match { + case Nil => NodeSeq.Empty + case tpl :: Nil => templateToHtml(tpl) + case tpl :: tpls => templateToHtml(tpl) ++ sep ++ templatesToHtml(tpls, sep) + } + + /** Returns the _big image name corresponding to the DocTemplate Entity (upper left icon) */ + def docEntityKindToBigImage(ety: DocTemplateEntity) = + if (ety.isTrait && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None) "trait_to_object_big.png" + else if (ety.isTrait) "trait_big.png" + else if (ety.isClass && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None) "class_to_object_big.png" + else if (ety.isClass) "class_big.png" + else if ((ety.isAbstractType || ety.isAliasType) && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None) "type_to_object_big.png" + else if ((ety.isAbstractType || ety.isAliasType)) "type_big.png" + else if (ety.isObject && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None && ety.companion.get.isClass) "object_to_class_big.png" + else if (ety.isObject && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None && ety.companion.get.isTrait) "object_to_trait_big.png" + else if (ety.isObject && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None && (ety.companion.get.isAbstractType || ety.companion.get.isAliasType)) "object_to_trait_big.png" + else if (ety.isObject) "object_big.png" + else if (ety.isPackage) "package_big.png" + else "class_big.png" // FIXME: an entity *should* fall into one of the above categories, but AnyRef is somehow not +} diff --git a/src/scaladoc/scala/tools/nsc/doc/html/Page.scala b/src/scaladoc/scala/tools/nsc/doc/html/Page.scala new file mode 100644 index 0000000000..91939cf3de --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/Page.scala @@ -0,0 +1,102 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author David Bernard, Manohar Jonnalagedda + */ + +package scala.tools.nsc.doc.html + +import scala.tools.nsc.doc.model._ +import java.io.{FileOutputStream, File} +import scala.reflect.NameTransformer +import java.nio.channels.Channels +import java.io.Writer + +abstract class Page { + thisPage => + + /** The path of this page, relative to the API site. `path.tail` is a list + * of folder names leading to this page (from closest package to + * one-above-root package), `path.head` is the file name of this page. + * Note that `path` has a length of at least one. */ + def path: List[String] + + def absoluteLinkTo(path: List[String]) = path.reverse.mkString("/") + + def createFileOutputStream(site: HtmlFactory, suffix: String = "") = { + val file = new File(site.siteRoot, absoluteLinkTo(thisPage.path) + suffix) + val folder = file.getParentFile + if (! folder.exists) { + folder.mkdirs + } + new FileOutputStream(file.getPath) + } + + def writeFile(site: HtmlFactory, suffix: String = "")(fn: Writer => Unit) = { + val fos = createFileOutputStream(site, suffix) + val w = Channels.newWriter(fos.getChannel, site.encoding) + try { + fn(w) + } + finally { + w.close() + fos.close() + } + } + + /** Writes this page as a file. The file's location is relative to the + * generator's site root, and the encoding is also defined by the generator. + * @param site The generator that is writing this page. */ + def writeFor(site: HtmlFactory): Unit + + def kindToString(mbr: MemberEntity) = + mbr match { + case c: Class => if (c.isCaseClass) "case class" else "class" + case _: Trait => "trait" + case _: Package => "package" + case _: Object => "object" + case _: AbstractType => "type" + case _: AliasType => "type" + case _: Constructor => "new" + case v: Def => "def" + case v: Val if (v.isLazyVal) => "lazy val" + case v: Val if (v.isVal) => "val" + case v: Val if (v.isVar) => "var" + case _ => sys.error("Cannot create kind for: " + mbr + " of class " + mbr.getClass) + } + + def templateToPath(tpl: TemplateEntity): List[String] = { + def doName(tpl: TemplateEntity): String = + (if (tpl.inPackageObject) "package$$" else "") + NameTransformer.encode(tpl.name) + (if (tpl.isObject) "$" else "") + def downPacks(pack: Package): List[String] = + if (pack.isRootPackage) Nil else (doName(pack) :: downPacks(pack.inTemplate)) + def downInner(nme: String, tpl: TemplateEntity): (String, Package) = { + tpl.inTemplate match { + case inPkg: Package => (nme + ".html", inPkg) + case inTpl => downInner(doName(inTpl) + "$" + nme, inTpl) + } + } + val (file, pack) = + tpl match { + case p: Package => ("package.html", p) + case _ => downInner(doName(tpl), tpl) + } + file :: downPacks(pack) + } + + /** A relative link from this page to some destination class entity. + * @param destClass The class or object entity that the link will point to. */ + def relativeLinkTo(destClass: TemplateEntity): String = + relativeLinkTo(templateToPath(destClass)) + + /** A relative link from this page to some destination path. + * @param destPath The path that the link will point to. */ + def relativeLinkTo(destPath: List[String]): String = { + def relativize(from: List[String], to: List[String]): List[String] = (from, to) match { + case (f :: fs, t :: ts) if (f == t) => // both paths are identical to that point + relativize(fs, ts) + case (fss, tss) => + List.fill(fss.length - 1)("..") ::: tss + } + relativize(thisPage.path.reverse, destPath.reverse).mkString("/") + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala b/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala new file mode 100644 index 0000000000..5781e680dd --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala @@ -0,0 +1,286 @@ +/* NSC -- new Scala compiler + * Copyright 2010-2013 LAMP/EPFL + * @author Stephane Micheloud + */ + +package scala.tools.nsc.doc.html + +import scala.xml.NodeSeq + +/** Highlight the syntax of Scala code appearing in a `{{{` wiki block + * (see method `HtmlPage.blockToHtml`). + * + * @author Stephane Micheloud + * @version 1.0 + */ +private[html] object SyntaxHigh { + + /** Reserved words, sorted alphabetically + * (see [[scala.reflect.internal.StdNames]]) */ + val reserved = Array( + "abstract", "case", "catch", "class", "def", + "do", "else", "extends", "false", "final", "finally", + "for", "if", "implicit", "import", "lazy", "match", + "new", "null", "object", "override", "package", + "private", "protected", "return", "sealed", "super", + "this", "throw", "trait", "true", "try", "type", + "val", "var", "while", "with", "yield") + + /** Annotations, sorted alphabetically */ + val annotations = Array( + "BeanProperty", "SerialVersionUID", + "beanGetter", "beanSetter", "bridge", + "deprecated", "deprecatedName", "deprecatedOverriding", "deprecatedInheritance", + "elidable", "field", "getter", "inline", + "migration", "native", "noinline", "param", + "remote", "setter", "specialized", "strictfp", "switch", + "tailrec", "throws", "transient", + "unchecked", "uncheckedStable", "uncheckedVariance", + "varargs", "volatile") + + /** Standard library classes/objects, sorted alphabetically */ + val standards = Array ( + "WeakTypeTag", "Any", "AnyRef", "AnyVal", "App", "Array", + "Boolean", "Byte", "Char", "Class", "ClassTag", "ClassManifest", + "Console", "Double", "Enumeration", "Float", "Function", "Int", + "List", "Long", "Manifest", "Map", + "NoManifest", "None", "Nothing", "Null", "Object", "Option", "OptManifest", + "Pair", "Predef", + "Seq", "Set", "Short", "Some", "String", "Symbol", + "Triple", "TypeTag", "Unit") + + def apply(data: String): NodeSeq = { + val buf = data.getBytes + val out = new StringBuilder + + def compare(offset: Int, key: String): Int = { + var i = offset + var j = 0 + val l = key.length + while (i < buf.length && j < l) { + val bch = buf(i).toChar + val kch = key charAt j + if (bch < kch) return -1 + else if (bch > kch) return 1 + i += 1 + j += 1 + } + if (j < l) -1 + else if (i < buf.length && + ('A' <= buf(i) && buf(i) <= 'Z' || + 'a' <= buf(i) && buf(i) <= 'z' || + '0' <= buf(i) && buf(i) <= '9' || + buf(i) == '_')) 1 + else 0 + } + + def lookup(a: Array[String], i: Int): Int = { + var lo = 0 + var hi = a.length - 1 + while (lo <= hi) { + val m = (hi + lo) / 2 + val d = compare(i, a(m)) + if (d < 0) hi = m - 1 + else if (d > 0) lo = m + 1 + else return m + } + -1 + } + + def comment(i: Int): String = { + val out = new StringBuilder("/") + def line(i: Int): Int = + if (i == buf.length || buf(i) == '\n') i + else { + out append buf(i).toChar + line(i+1) + } + var level = 0 + def multiline(i: Int, star: Boolean): Int = { + if (i == buf.length) return i + val ch = buf(i).toChar + out append ch + ch match { + case '*' => + if (star) level += 1 + multiline(i+1, !star) + case '/' => + if (star) { + if (level > 0) level -= 1 + if (level == 0) i else multiline(i+1, star = true) + } else + multiline(i+1, star = false) + case _ => + multiline(i+1, star = false) + } + } + if (buf(i) == '/') line(i) else multiline(i, star = true) + out.toString + } + + /* e.g. `val endOfLine = '\u000A'`*/ + def charlit(j: Int): String = { + val out = new StringBuilder("'") + def charlit0(i: Int, bslash: Boolean): Int = { + if (i == buf.length) i + else if (i > j+6) { out setLength 0; j } + else { + val ch = buf(i).toChar + out append ch + ch match { + case '\\' => + charlit0(i+1, bslash = true) + case '\'' if !bslash => + i + case _ => + if (bslash && '0' <= ch && ch <= '9') charlit0(i+1, bslash = true) + else charlit0(i+1, bslash = false) + } + } + } + charlit0(j, bslash = false) + out.toString + } + + def strlit(i: Int): String = { + val out = new StringBuilder("\"") + def strlit0(i: Int, bslash: Boolean): Int = { + if (i == buf.length) return i + val ch = buf(i).toChar + out append ch + ch match { + case '\\' => + strlit0(i+1, bslash = true) + case '"' if !bslash => + i + case _ => + strlit0(i+1, bslash = false) + } + } + strlit0(i, bslash = false) + out.toString + } + + def numlit(i: Int): String = { + val out = new StringBuilder + def intg(i: Int): Int = { + if (i == buf.length) return i + val ch = buf(i).toChar + ch match { + case '.' => + out append ch + frac(i+1) + case _ => + if (Character.isDigit(ch)) { + out append ch + intg(i+1) + } else i + } + } + def frac(i: Int): Int = { + if (i == buf.length) return i + val ch = buf(i).toChar + ch match { + case 'e' | 'E' => + out append ch + expo(i+1, signed = false) + case _ => + if (Character.isDigit(ch)) { + out append ch + frac(i+1) + } else i + } + } + def expo(i: Int, signed: Boolean): Int = { + if (i == buf.length) return i + val ch = buf(i).toChar + ch match { + case '+' | '-' if !signed => + out append ch + expo(i+1, signed = true) + case _ => + if (Character.isDigit(ch)) { + out append ch + expo(i+1, signed) + } else i + } + } + intg(i) + out.toString + } + + def parse(pre: String, i: Int): Int = { + out append pre + if (i == buf.length) return i + buf(i) match { + case '\n' => + parse("\n", i+1) + case ' ' => + parse(" ", i+1) + case '&' => + parse("&", i+1) + case '<' if i+1 < buf.length => + val ch = buf(i+1).toChar + if (ch == '-' || ch == ':' || ch == '%') + parse("<"+ch+"", i+2) + else + parse("<", i+1) + case '>' => + if (i+1 < buf.length && buf(i+1) == ':') + parse(">:", i+2) + else + parse(">", i+1) + case '=' => + if (i+1 < buf.length && buf(i+1) == '>') + parse("=>", i+2) + else + parse(buf(i).toChar.toString, i+1) + case '/' => + if (i+1 < buf.length && (buf(i+1) == '/' || buf(i+1) == '*')) { + val c = comment(i+1) + parse(""+c+"", i+c.length) + } else + parse(buf(i).toChar.toString, i+1) + case '\'' => + val s = charlit(i+1) + if (s.length > 0) + parse(""+s+"", i+s.length) + else + parse(buf(i).toChar.toString, i+1) + case '"' => + val s = strlit(i+1) + parse(""+s+"", i+s.length) + case '@' => + val k = lookup(annotations, i+1) + if (k >= 0) + parse("@"+annotations(k)+"", i+annotations(k).length+1) + else + parse(buf(i).toChar.toString, i+1) + case _ => + if (i == 0 || (i >= 1 && !Character.isJavaIdentifierPart(buf(i-1).toChar))) { + if (Character.isDigit(buf(i)) || + (buf(i) == '.' && i + 1 < buf.length && Character.isDigit(buf(i+1)))) { + val s = numlit(i) + parse(""+s+"", i+s.length) + } else { + val k = lookup(reserved, i) + if (k >= 0) + parse(""+reserved(k)+"", i+reserved(k).length) + else { + val k = lookup(standards, i) + if (k >= 0) + parse(""+standards(k)+"", i+standards(k).length) + else + parse(buf(i).toChar.toString, i+1) + } + } + } else + parse(buf(i).toChar.toString, i+1) + } + i + } + + parse("", 0) + scala.xml.Unparsed(out.toString) + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala new file mode 100644 index 0000000000..c034647320 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala @@ -0,0 +1,133 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author David Bernard, Manohar Jonnalagedda + */ + +package scala.tools.nsc +package doc +package html +package page + +import model._ +import scala.collection._ +import scala.xml._ + +class Index(universe: doc.Universe, val index: doc.Index) extends HtmlPage { + + def path = List("index.html") + + def title = { + val s = universe.settings + ( if (!s.doctitle.isDefault) s.doctitle.value else "" ) + + ( if (!s.docversion.isDefault) (" " + s.docversion.value) else "" ) + } + + val headers = + + + + + + + + + + val body = + +
    + + + + +
    + { browser } +
    + ':""),e._keyEvent=!1,B},_generateMonthYearHeader:function(e,t,n,r,i,s,o,u){var a=this._get(e,"changeMonth"),f=this._get(e,"changeYear"),l=this._get(e,"showMonthAfterYear"),c='
    ',h="";if(s||!a)h+=''+o[t]+"";else{var p=r&&r.getFullYear()==n,d=i&&i.getFullYear()==n;h+='"}l||(c+=h+(s||!a||!f?" ":""));if(!e.yearshtml){e.yearshtml="";if(s||!f)c+=''+n+"";else{var m=this._get(e,"yearRange").split(":"),g=(new Date).getFullYear(),y=function(e){var t=e.match(/c[+-].*/)?n+parseInt(e.substring(1),10):e.match(/[+-].*/)?g+parseInt(e,10):parseInt(e,10);return isNaN(t)?g:t},b=y(m[0]),w=Math.max(b,y(m[1]||""));b=r?Math.max(b,r.getFullYear()):b,w=i?Math.min(w,i.getFullYear()):w,e.yearshtml+='",c+=e.yearshtml,e.yearshtml=null}}return c+=this._get(e,"yearSuffix"),l&&(c+=(s||!a||!f?" ":"")+h),c+="
    ",c},_adjustInstDate:function(e,t,n){var r=e.drawYear+(n=="Y"?t:0),i=e.drawMonth+(n=="M"?t:0),s=Math.min(e.selectedDay,this._getDaysInMonth(r,i))+(n=="D"?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(r,i,s)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),(n=="M"||n=="Y")&&this._notifyChange(e)},_restrictMinMax:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max"),i=n&&tr?r:i,i},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return t==null?[1,1]:typeof t=="number"?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return(new Date(e,t,1)).getDay()},_canAdjustMonth:function(e,t,n,r){var i=this._getNumberOfMonths(e),s=this._daylightSavingAdjust(new Date(n,r+(t<0?t:i[0]*i[1]),1));return t<0&&s.setDate(this._getDaysInMonth(s.getFullYear(),s.getMonth())),this._isInRange(e,s)},_isInRange:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max");return(!n||t.getTime()>=n.getTime())&&(!r||t.getTime()<=r.getTime())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t=typeof t!="string"?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,n,r){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var i=t?typeof t=="object"?t:this._daylightSavingAdjust(new Date(r,n,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),i,this._getFormatConfig(e))}}),$.fn.datepicker=function(e){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find(document.body).append($.datepicker.dpDiv),$.datepicker.initialized=!0);var t=Array.prototype.slice.call(arguments,1);return typeof e!="string"||e!="isDisabled"&&e!="getDate"&&e!="widget"?e=="option"&&arguments.length==2&&typeof arguments[1]=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t)):this.each(function(){typeof e=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this].concat(t)):$.datepicker._attachDatepicker(this,e)}):$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t))},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.9.0",window["DP_jQuery_"+dpuuid]=$})(jQuery);(function(e,t){var n="ui-dialog ui-widget ui-widget-content ui-corner-all ",r={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};e.widget("ui.dialog",{version:"1.9.0",options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var n=e(this).css(t).offset().top;n<0&&e(this).css("top",t.top-n)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.oldPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.options.title=this.options.title||this.originalTitle;var t=this,r=this.options,i=r.title||" ",s=(this.uiDialog=e("
    ")).addClass(n+r.dialogClass).css({display:"none",outline:0,zIndex:r.zIndex}).attr("tabIndex",-1).keydown(function(n){r.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===e.ui.keyCode.ESCAPE&&(t.close(n),n.preventDefault())}).mousedown(function(e){t.moveToTop(!1,e)}).appendTo("body"),o=this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(s),u=(this.uiDialogTitlebar=e("
    ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(s),a=e("").addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").click(function(e){e.preventDefault(),t.close(e)}).appendTo(u),f=(this.uiDialogTitlebarCloseText=e("")).addClass("ui-icon ui-icon-closethick").text(r.closeText).appendTo(a),l=e("").uniqueId().addClass("ui-dialog-title").html(i).prependTo(u),c=(this.uiDialogButtonPane=e("
    ")).addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),h=(this.uiButtonSet=e("
    ")).addClass("ui-dialog-buttonset").appendTo(c);s.attr({role:"dialog","aria-labelledby":l.attr("id")}),u.find("*").add(u).disableSelection(),this._hoverable(a),this._focusable(a),r.draggable&&e.fn.draggable&&this._makeDraggable(),r.resizable&&e.fn.resizable&&this._makeResizable(),this._createButtons(r.buttons),this._isOpen=!1,e.fn.bgiframe&&s.bgiframe(),this._on(s,{keydown:function(t){if(!r.modal||t.keyCode!==e.ui.keyCode.TAB)return;var n=e(":tabbable",s),i=n.filter(":first"),o=n.filter(":last");if(t.target===o[0]&&!t.shiftKey)return i.focus(1),!1;if(t.target===i[0]&&t.shiftKey)return o.focus(1),!1}})},_init:function(){this.options.autoOpen&&this.open()},_destroy:function(){var e,t=this.oldPosition;this.overlay&&this.overlay.destroy(),this.uiDialog.hide(),this.element.removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},close:function(t){var n=this,r,i;if(!this._isOpen)return;if(!1===this._trigger("beforeClose",t))return;return this._isOpen=!1,this.overlay&&this.overlay.destroy(),this.options.hide?this.uiDialog.hide(this.options.hide,function(){n._trigger("close",t)}):(this.uiDialog.hide(),this._trigger("close",t)),e.ui.dialog.overlay.resize(),this.options.modal&&(r=0,e(".ui-dialog").each(function(){this!==n.uiDialog[0]&&(i=e(this).css("z-index"),isNaN(i)||(r=Math.max(r,i)))}),e.ui.dialog.maxZ=r),this},isOpen:function(){return this._isOpen},moveToTop:function(t,n){var r=this.options,i;return r.modal&&!t||!r.stack&&!r.modal?this._trigger("focus",n):(r.zIndex>e.ui.dialog.maxZ&&(e.ui.dialog.maxZ=r.zIndex),this.overlay&&(e.ui.dialog.maxZ+=1,e.ui.dialog.overlay.maxZ=e.ui.dialog.maxZ,this.overlay.$el.css("z-index",e.ui.dialog.overlay.maxZ)),i={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()},e.ui.dialog.maxZ+=1,this.uiDialog.css("z-index",e.ui.dialog.maxZ),this.element.attr(i),this._trigger("focus",n),this)},open:function(){if(this._isOpen)return;var t,n=this.options,r=this.uiDialog;return this._size(),this._position(n.position),r.show(n.show),this.overlay=n.modal?new e.ui.dialog.overlay(this):null,this.moveToTop(!0),t=this.element.find(":tabbable"),t.length||(t=this.uiDialogButtonPane.find(":tabbable"),t.length||(t=r)),t.eq(0).focus(),this._isOpen=!0,this._trigger("open"),this},_createButtons:function(t){var n,r,i=this,s=!1;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),typeof t=="object"&&t!==null&&e.each(t,function(){return!(s=!0)}),s?(e.each(t,function(t,n){n=e.isFunction(n)?{click:n,text:t}:n;var r=e("
    ').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var n=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),n.containment&&this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,n){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute");if(!n){var r=this._uiHash();if(this._trigger("drag",t,r)===!1)return this._mouseUp({}),!1;this.position=r.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";return e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var n=!1;e.ui.ddmanager&&!this.options.dropBehaviour&&(n=e.ui.ddmanager.drop(this,t)),this.dropped&&(n=this.dropped,this.dropped=!1);var r=this.element[0],i=!1;while(r&&(r=r.parentNode))r==document&&(i=!0);if(!i&&this.options.helper==="original")return!1;if(this.options.revert=="invalid"&&!n||this.options.revert=="valid"&&n||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,n)){var s=this;e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){s._trigger("stop",t)!==!1&&s._clear()})}else this._trigger("stop",t)!==!1&&this._clear();return!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){var n=!this.options.handle||!e(this.options.handle,this.element).length?!0:!1;return e(this.options.handle,this.element).find("*").andSelf().each(function(){this==t.target&&(n=!0)}),n},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t])):n.helper=="clone"?this.element.clone().removeAttr("id"):this.element;return r.parents("body").length||r.appendTo(n.appendTo=="parent"?this.element[0].parentNode:n.appendTo),r[0]!=this.element[0]&&!/(fixed|absolute)/.test(r.css("position"))&&r.css("position","absolute"),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.browser.msie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[t.containment=="document"?0:e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t.containment=="document"?0:e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(t.containment=="document"?0:e(window).scrollLeft())+e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(t.containment=="document"?0:e(window).scrollTop())+(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)&&t.containment.constructor!=Array){var n=e(t.containment),r=n[0];if(!r)return;var i=n.offset(),s=e(r).css("overflow")!="hidden";this.containment=[(parseInt(e(r).css("borderLeftWidth"),10)||0)+(parseInt(e(r).css("paddingLeft"),10)||0),(parseInt(e(r).css("borderTopWidth"),10)||0)+(parseInt(e(r).css("paddingTop"),10)||0),(s?Math.max(r.scrollWidth,r.offsetWidth):r.offsetWidth)-(parseInt(e(r).css("borderLeftWidth"),10)||0)-(parseInt(e(r).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(s?Math.max(r.scrollHeight,r.offsetHeight):r.offsetHeight)-(parseInt(e(r).css("borderTopWidth"),10)||0)-(parseInt(e(r).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=n}else t.containment.constructor==Array&&(this.containment=t.containment)},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName),s=t.pageX,o=t.pageY;if(this.originalPosition){var u;if(this.containment){if(this.relative_container){var a=this.relative_container.offset();u=[this.containment[0]+a.left,this.containment[1]+a.top,this.containment[2]+a.left,this.containment[3]+a.top]}else u=this.containment;t.pageX-this.offset.click.leftu[2]&&(s=u[2]+this.offset.click.left),t.pageY-this.offset.click.top>u[3]&&(o=u[3]+this.offset.click.top)}if(n.grid){var f=n.grid[1]?this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1]:this.originalPageY;o=u?f-this.offset.click.topu[3]?f-this.offset.click.topu[2]?l-this.offset.click.left=0;l--){var c=r.snapElements[l].left,h=c+r.snapElements[l].width,p=r.snapElements[l].top,d=p+r.snapElements[l].height;if(!(c-s=l&&o<=c||u>=l&&u<=c||oc)&&(i>=a&&i<=f||s>=a&&s<=f||if);default:return!1}},e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,n){var r=e.ui.ddmanager.droppables[t.options.scope]||[],i=n?n.type:null,s=(t.currentItem||t.element).find(":data(droppable)").andSelf();e:for(var o=0;oe?0:r.max")[0],c,h=t.each;l.style.cssText="background-color:rgba(1,1,1,.5)",f.rgba=l.style.backgroundColor.indexOf("rgba")>-1,h(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),o.fn=t.extend(o.prototype,{parse:function(r,i,s,a){if(r===n)return this._rgba=[null,null,null,null],this;if(r.jquery||r.nodeType)r=t(r).css(i),i=n;var f=this,l=t.type(r),v=this._rgba=[],m;i!==n&&(r=[r,i,s,a],l="array");if(l==="string")return this.parse(d(r)||c._default);if(l==="array")return h(u.rgba.props,function(e,t){v[t.idx]=p(r[t.idx],t)}),this;if(l==="object")return r instanceof o?h(u,function(e,t){r[t.cache]&&(f[t.cache]=r[t.cache].slice())}):h(u,function(t,n){var i=n.cache;h(n.props,function(e,t){if(!f[i]&&n.to){if(e==="alpha"||r[e]==null)return;f[i]=n.to(f._rgba)}f[i][t.idx]=p(r[e],t,!0)}),f[i]&&e.inArray(null,f[i].slice(0,3))<0&&(f[i][3]=1,n.from&&(f._rgba=n.from(f[i])))}),this},is:function(e){var t=o(e),n=!0,r=this;return h(u,function(e,i){var s,o=t[i.cache];return o&&(s=r[i.cache]||i.to&&i.to(r._rgba)||[],h(i.props,function(e,t){if(o[t.idx]!=null)return n=o[t.idx]===s[t.idx],n})),n}),n},_space:function(){var e=[],t=this;return h(u,function(n,r){t[r.cache]&&e.push(n)}),e.pop()},transition:function(e,t){var n=o(e),r=n._space(),i=u[r],s=this.alpha()===0?o("transparent"):this,f=s[i.cache]||i.to(s._rgba),l=f.slice();return n=n[i.cache],h(i.props,function(e,r){var i=r.idx,s=f[i],o=n[i],u=a[r.type]||{};if(o===null)return;s===null?l[i]=o:(u.mod&&(o-s>u.mod/2?s+=u.mod:s-o>u.mod/2&&(s-=u.mod)),l[i]=p((o-s)*t+s,r))}),this[r](l)},blend:function(e){if(this._rgba[3]===1)return this;var n=this._rgba.slice(),r=n.pop(),i=o(e)._rgba;return o(t.map(n,function(e,t){return(1-r)*i[t]+r*e}))},toRgbaString:function(){var e="rgba(",n=t.map(this._rgba,function(e,t){return e==null?t>2?1:0:e});return n[3]===1&&(n.pop(),e="rgb("),e+n.join()+")"},toHslaString:function(){var e="hsla(",n=t.map(this.hsla(),function(e,t){return e==null&&(e=t>2?1:0),t&&t<3&&(e=Math.round(e*100)+"%"),e});return n[3]===1&&(n.pop(),e="hsl("),e+n.join()+")"},toHexString:function(e){var n=this._rgba.slice(),r=n.pop();return e&&n.push(~~(r*255)),"#"+t.map(n,function(e,t){return e=(e||0).toString(16),e.length===1?"0"+e:e}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),o.fn.parse.prototype=o.fn,u.hsla.to=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/255,n=e[1]/255,r=e[2]/255,i=e[3],s=Math.max(t,n,r),o=Math.min(t,n,r),u=s-o,a=s+o,f=a*.5,l,c;return o===s?l=0:t===s?l=60*(n-r)/u+360:n===s?l=60*(r-t)/u+120:l=60*(t-n)/u+240,f===0||f===1?c=f:f<=.5?c=u/a:c=u/(2-a),[Math.round(l)%360,c,f,i==null?1:i]},u.hsla.from=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/360,n=e[1],r=e[2],i=e[3],s=r<=.5?r*(1+n):r+n-r*n,o=2*r-s,u,a,f;return[Math.round(v(o,s,t+1/3)*255),Math.round(v(o,s,t)*255),Math.round(v(o,s,t-1/3)*255),i]},h(u,function(e,r){var s=r.props,u=r.cache,a=r.to,f=r.from;o.fn[e]=function(e){a&&!this[u]&&(this[u]=a(this._rgba));if(e===n)return this[u].slice();var r,i=t.type(e),l=i==="array"||i==="object"?e:arguments,c=this[u].slice();return h(s,function(e,t){var n=l[i==="object"?e:t.idx];n==null&&(n=c[t.idx]),c[t.idx]=p(n,t)}),f?(r=o(f(c)),r[u]=c,r):o(c)},h(s,function(n,r){if(o.fn[n])return;o.fn[n]=function(s){var o=t.type(s),u=n==="alpha"?this._hsla?"hsla":"rgba":e,a=this[u](),f=a[r.idx],l;return o==="undefined"?f:(o==="function"&&(s=s.call(this,f),o=t.type(s)),s==null&&r.empty?this:(o==="string"&&(l=i.exec(s),l&&(s=f+parseFloat(l[2])*(l[1]==="+"?1:-1))),a[r.idx]=s,this[u](a)))}})}),h(r,function(e,n){t.cssHooks[n]={set:function(e,r){var i,s,u="";if(t.type(r)!=="string"||(i=d(r))){r=o(i||r);if(!f.rgba&&r._rgba[3]!==1){s=n==="backgroundColor"?e.parentNode:e;while((u===""||u==="transparent")&&s&&s.style)try{u=t.css(s,"backgroundColor"),s=s.parentNode}catch(a){}r=r.blend(u&&u!=="transparent"?u:"_default")}r=r.toRgbaString()}try{e.style[n]=r}catch(r){}}},t.fx.step[n]=function(e){e.colorInit||(e.start=o(e.elem,n),e.end=o(e.end),e.colorInit=!0),t.cssHooks[n].set(e.elem,e.start.transition(e.end,e.pos))}}),t.cssHooks.borderColor={expand:function(e){var t={};return h(["Top","Right","Bottom","Left"],function(n,r){t["border"+r+"Color"]=e}),t}},c=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(){var t=this.ownerDocument.defaultView?this.ownerDocument.defaultView.getComputedStyle(this,null):this.currentStyle,n={},r,i,s;if(t&&t.length&&t[0]&&t[t[0]]){s=t.length;while(s--)r=t[s],typeof t[r]=="string"&&(n[e.camelCase(r)]=t[r])}else for(r in t)typeof t[r]=="string"&&(n[r]=t[r]);return n}function s(t,n){var i={},s,o;for(s in n)o=n[s],t[s]!==o&&!r[s]&&(e.fx.step[s]||!isNaN(parseFloat(o)))&&(i[s]=o);return i}var n=["add","remove","toggle"],r={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,n){e.fx.step[n]=function(e){if(e.end!=="none"&&!e.setAttr||e.pos===1&&!e.setAttr)jQuery.style(e.elem,n,e.end),e.setAttr=!0}}),e.effects.animateClass=function(t,r,o,u){var a=e.speed(r,o,u);return this.queue(function(){var r=e(this),o=r.attr("class")||"",u,f=a.children?r.find("*").andSelf():r;f=f.map(function(){var t=e(this);return{el:t,start:i.call(this)}}),u=function(){e.each(n,function(e,n){t[n]&&r[n+"Class"](t[n])})},u(),f=f.map(function(){return this.end=i.call(this.el[0]),this.diff=s(this.start,this.end),this}),r.attr("class",o),f=f.map(function(){var t=this,n=e.Deferred(),r=jQuery.extend({},a,{queue:!1,complete:function(){n.resolve(t)}});return this.el.animate(this.diff,r),n.promise()}),e.when.apply(e,f.get()).done(function(){u(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),a.complete.call(r[0])})})},e.fn.extend({_addClass:e.fn.addClass,addClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{add:t},n,r,i):this._addClass(t)},_removeClass:e.fn.removeClass,removeClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{remove:t},n,r,i):this._removeClass(t)},_toggleClass:e.fn.toggleClass,toggleClass:function(n,r,i,s,o){return typeof r=="boolean"||r===t?i?e.effects.animateClass.call(this,r?{add:n}:{remove:n},i,s,o):this._toggleClass(n,r):e.effects.animateClass.call(this,{toggle:n},r,i,s)},switchClass:function(t,n,r,i,s){return e.effects.animateClass.call(this,{add:n,remove:t},r,i,s)}})}(),function(){function i(n,r,i,s){e.isPlainObject(n)&&(r=n,n=n.effect),n={effect:n},r===t&&(r={}),e.isFunction(r)&&(s=r,i=null,r={});if(typeof r=="number"||e.fx.speeds[r])s=i,i=r,r={};return e.isFunction(i)&&(s=i,i=null),r&&e.extend(n,r),i=i||r.duration,n.duration=e.fx.off?0:typeof i=="number"?i:i in e.fx.speeds?e.fx.speeds[i]:e.fx.speeds._default,n.complete=s||r.complete,n}function s(t){return!t||typeof t=="number"||e.fx.speeds[t]?!0:typeof t=="string"&&!e.effects.effect[t]?n&&e.effects[t]?!1:!0:!1}e.extend(e.effects,{version:"1.9.0",save:function(e,t){for(var n=0;n
    ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),i={width:t.width(),height:t.height()},s=document.activeElement;try{s.id}catch(o){s=document.body}return t.wrap(r),(t[0]===s||e.contains(t[0],s))&&e(s).focus(),r=t.parent(),t.css("position")==="static"?(r.css({position:"relative"}),t.css({position:"relative"})):(e.extend(n,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,r){n[r]=t.css(r),isNaN(parseInt(n[r],10))&&(n[r]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(i),r.css(n).show()},removeWrapper:function(t){var n=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===n||e.contains(t[0],n))&&e(n).focus()),t},setTransition:function(t,n,r,i){return i=i||{},e.each(n,function(e,n){var s=t.cssUnit(n);s[0]>0&&(i[n]=s[0]*r+s[1])}),i}}),e.fn.extend({effect:function(t,r,s,o){function h(t){function s(){e.isFunction(r)&&r.call(n[0]),e.isFunction(t)&&t()}var n=e(this),r=u.complete,i=u.mode;(n.is(":hidden")?i==="hide":i==="show")?s():l.call(n[0],u,s)}var u=i.apply(this,arguments),a=u.mode,f=u.queue,l=e.effects.effect[u.effect],c=!l&&n&&e.effects[u.effect];return e.fx.off||!l&&!c?a?this[a](u.duration,u.complete):this.each(function(){u.complete&&u.complete.call(this)}):l?f===!1?this.each(h):this.queue(f||"fx",h):c.call(this,{options:u,duration:u.duration,callback:u.complete,mode:u.mode})},_show:e.fn.show,show:function(e){if(s(e))return this._show.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="show",this.effect.call(this,t)},_hide:e.fn.hide,hide:function(e){if(s(e))return this._hide.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="hide",this.effect.call(this,t)},__toggle:e.fn.toggle,toggle:function(t){if(s(t)||typeof t=="boolean"||e.isFunction(t))return this.__toggle.apply(this,arguments);var n=i.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)},cssUnit:function(t){var n=this.css(t),r=[];return e.each(["em","px","%","pt"],function(e,t){n.indexOf(t)>0&&(r=[parseFloat(n),t])}),r}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,n){t[n]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return e===0||e===1?e:-Math.pow(2,8*(e-1))*Math.sin(((e-1)*80-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){var t,n=4;while(e<((t=Math.pow(2,--n))-1)/11);return 1/Math.pow(4,3-n)-7.5625*Math.pow((t*3-2)/22-e,2)}}),e.each(t,function(t,n){e.easing["easeIn"+t]=n,e.easing["easeOut"+t]=function(e){return 1-n(1-e)},e.easing["easeInOut"+t]=function(e){return e<.5?n(e*2)/2:1-n(e*-2+2)/2}})}()}(jQuery);(function(e,t){var n=/up|down|vertical/,r=/up|left|vertical|horizontal/;e.effects.effect.blind=function(t,i){var s=e(this),o=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(s,t.mode||"hide"),a=t.direction||"up",f=n.test(a),l=f?"height":"width",c=f?"top":"left",h=r.test(a),p={},d=u==="show",v,m,g;s.parent().is(".ui-effects-wrapper")?e.effects.save(s.parent(),o):e.effects.save(s,o),s.show(),v=e.effects.createWrapper(s).css({overflow:"hidden"}),m=v[l](),g=parseFloat(v.css(c))||0,p[l]=d?m:0,h||(s.css(f?"bottom":"right",0).css(f?"top":"left","auto").css({position:"absolute"}),p[c]=d?g:m+g),d&&(v.css(l,0),h||v.css(c,g+m)),v.animate(p,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){u==="hide"&&s.hide(),e.effects.restore(s,o),e.effects.removeWrapper(s),i()}})}})(jQuery);(function(e,t){e.effects.effect.bounce=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=s==="hide",u=s==="show",a=t.direction||"up",f=t.distance,l=t.times||5,c=l*2+(u||o?1:0),h=t.duration/c,p=t.easing,d=a==="up"||a==="down"?"top":"left",v=a==="up"||a==="left",m,g,y,b=r.queue(),w=b.length;(u||o)&&i.push("opacity"),e.effects.save(r,i),r.show(),e.effects.createWrapper(r),f||(f=r[d==="top"?"outerHeight":"outerWidth"]()/3),u&&(y={opacity:1},y[d]=0,r.css("opacity",0).css(d,v?-f*2:f*2).animate(y,h,p)),o&&(f/=Math.pow(2,l-1)),y={},y[d]=0;for(m=0;m1&&b.splice.apply(b,[1,0].concat(b.splice(w,c+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.clip=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"vertical",a=u==="vertical",f=a?"height":"width",l=a?"top":"left",c={},h,p,d;e.effects.save(r,i),r.show(),h=e.effects.createWrapper(r).css({overflow:"hidden"}),p=r[0].tagName==="IMG"?h:r,d=p[f](),o&&(p.css(f,0),p.css(l,d/2)),c[f]=o?d:0,c[l]=o?0:d/2,p.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o||r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.drop=function(t,n){var r=e(this),i=["position","top","bottom","left","right","opacity","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left"?"pos":"neg",l={opacity:o?1:0},c;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),c=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0)/2,o&&r.css("opacity",0).css(a,f==="pos"?-c:c),l[a]=(o?f==="pos"?"+=":"-=":f==="pos"?"-=":"+=")+c,r.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.explode=function(t,n){function y(){c.push(this),c.length===r*i&&b()}function b(){s.css({visibility:"visible"}),e(c).remove(),u||s.hide(),n()}var r=t.pieces?Math.round(Math.sqrt(t.pieces)):3,i=r,s=e(this),o=e.effects.setMode(s,t.mode||"hide"),u=o==="show",a=s.show().css("visibility","hidden").offset(),f=Math.ceil(s.outerWidth()/i),l=Math.ceil(s.outerHeight()/r),c=[],h,p,d,v,m,g;for(h=0;h
    ").css({position:"absolute",visibility:"visible",left:-p*f,top:-h*l}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:f,height:l,left:d+(u?m*f:0),top:v+(u?g*l:0),opacity:u?0:1}).animate({left:d+(u?0:m*f),top:v+(u?0:g*l),opacity:u?1:0},t.duration||500,t.easing,y)}}})(jQuery);(function(e,t){e.effects.effect.fade=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"toggle");r.animate({opacity:i},{queue:!1,duration:t.duration,easing:t.easing,complete:n})}})(jQuery);(function(e,t){e.effects.effect.fold=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=s==="hide",a=t.size||15,f=/([0-9]+)%/.exec(a),l=!!t.horizFirst,c=o!==l,h=c?["width","height"]:["height","width"],p=t.duration/2,d,v,m={},g={};e.effects.save(r,i),r.show(),d=e.effects.createWrapper(r).css({overflow:"hidden"}),v=c?[d.width(),d.height()]:[d.height(),d.width()],f&&(a=parseInt(f[1],10)/100*v[u?0:1]),o&&d.css(l?{height:0,width:a}:{height:a,width:0}),m[h[0]]=o?v[0]:a,g[h[1]]=o?v[1]:0,d.animate(m,p,t.easing).animate(g,p,t.easing,function(){u&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()})}})(jQuery);(function(e,t){e.effects.effect.highlight=function(t,n){var r=e(this),i=["backgroundImage","backgroundColor","opacity"],s=e.effects.setMode(r,t.mode||"show"),o={backgroundColor:r.css("backgroundColor")};s==="hide"&&(o.opacity=0),e.effects.save(r,i),r.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),n()}})}})(jQuery);(function(e,t){e.effects.effect.pulsate=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"show"),s=i==="show",o=i==="hide",u=s||i==="hide",a=(t.times||5)*2+(u?1:0),f=t.duration/a,l=0,c=r.queue(),h=c.length,p;if(s||!r.is(":visible"))r.css("opacity",0).show(),l=1;for(p=1;p1&&c.splice.apply(c,[1,0].concat(c.splice(h,a+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.puff=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"hide"),s=i==="hide",o=parseInt(t.percent,10)||150,u=o/100,a={height:r.height(),width:r.width()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:i,complete:n,percent:s?o:100,from:s?a:{height:a.height*u,width:a.width*u}}),r.effect(t)},e.effects.effect.scale=function(t,n){var r=e(this),i=e.extend(!0,{},t),s=e.effects.setMode(r,t.mode||"effect"),o=parseInt(t.percent,10)||(parseInt(t.percent,10)===0?0:s==="hide"?0:100),u=t.direction||"both",a=t.origin,f={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},l={y:u!=="horizontal"?o/100:1,x:u!=="vertical"?o/100:1};i.effect="size",i.queue=!1,i.complete=n,s!=="effect"&&(i.origin=a||["middle","center"],i.restore=!0),i.from=t.from||(s==="show"?{height:0,width:0}:f),i.to={height:f.height*l.y,width:f.width*l.x,outerHeight:f.outerHeight*l.y,outerWidth:f.outerWidth*l.x},i.fade&&(s==="show"&&(i.from.opacity=0,i.to.opacity=1),s==="hide"&&(i.from.opacity=1,i.to.opacity=0)),r.effect(i)},e.effects.effect.size=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height","overflow","opacity"],s=["position","top","bottom","left","right","overflow","opacity"],o=["width","height","overflow"],u=["fontSize"],a=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],f=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],l=e.effects.setMode(r,t.mode||"effect"),c=t.restore||l!=="effect",h=t.scale||"both",p=t.origin||["middle","center"],d,v,m,g=r.css("position");l==="show"&&r.show(),d={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},r.from=t.from||d,r.to=t.to||d,m={from:{y:r.from.height/d.height,x:r.from.width/d.width},to:{y:r.to.height/d.height,x:r.to.width/d.width}};if(h==="box"||h==="both")m.from.y!==m.to.y&&(i=i.concat(a),r.from=e.effects.setTransition(r,a,m.from.y,r.from),r.to=e.effects.setTransition(r,a,m.to.y,r.to)),m.from.x!==m.to.x&&(i=i.concat(f),r.from=e.effects.setTransition(r,f,m.from.x,r.from),r.to=e.effects.setTransition(r,f,m.to.x,r.to));(h==="content"||h==="both")&&m.from.y!==m.to.y&&(i=i.concat(u),r.from=e.effects.setTransition(r,u,m.from.y,r.from),r.to=e.effects.setTransition(r,u,m.to.y,r.to)),e.effects.save(r,c?i:s),r.show(),e.effects.createWrapper(r),r.css("overflow","hidden").css(r.from),p&&(v=e.effects.getBaseline(p,d),r.from.top=(d.outerHeight-r.outerHeight())*v.y,r.from.left=(d.outerWidth-r.outerWidth())*v.x,r.to.top=(d.outerHeight-r.to.outerHeight)*v.y,r.to.left=(d.outerWidth-r.to.outerWidth)*v.x),r.css(r.from);if(h==="content"||h==="both")a=a.concat(["marginTop","marginBottom"]).concat(u),f=f.concat(["marginLeft","marginRight"]),o=i.concat(a).concat(f),r.find("*[width]").each(function(){var n=e(this),r={height:n.height(),width:n.width()};c&&e.effects.save(n,o),n.from={height:r.height*m.from.y,width:r.width*m.from.x},n.to={height:r.height*m.to.y,width:r.width*m.to.x},m.from.y!==m.to.y&&(n.from=e.effects.setTransition(n,a,m.from.y,n.from),n.to=e.effects.setTransition(n,a,m.to.y,n.to)),m.from.x!==m.to.x&&(n.from=e.effects.setTransition(n,f,m.from.x,n.from),n.to=e.effects.setTransition(n,f,m.to.x,n.to)),n.css(n.from),n.animate(n.to,t.duration,t.easing,function(){c&&e.effects.restore(n,o)})});r.animate(r.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){r.to.opacity===0&&r.css("opacity",r.from.opacity),l==="hide"&&r.hide(),e.effects.restore(r,c?i:s),c||(g==="static"?r.css({position:"relative",top:r.to.top,left:r.to.left}):e.each(["top","left"],function(e,t){r.css(t,function(t,n){var i=parseInt(n,10),s=e?r.to.left:r.to.top;return n==="auto"?s+"px":i+s+"px"})})),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.shake=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=t.direction||"left",u=t.distance||20,a=t.times||3,f=a*2+1,l=Math.round(t.duration/f),c=o==="up"||o==="down"?"top":"left",h=o==="up"||o==="left",p={},d={},v={},m,g=r.queue(),y=g.length;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),p[c]=(h?"-=":"+=")+u,d[c]=(h?"+=":"-=")+u*2,v[c]=(h?"-=":"+=")+u*2,r.animate(p,l,t.easing);for(m=1;m1&&g.splice.apply(g,[1,0].concat(g.splice(y,f+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.slide=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height"],s=e.effects.setMode(r,t.mode||"show"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left",l,c={};e.effects.save(r,i),r.show(),l=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(r).css({overflow:"hidden"}),o&&r.css(a,f?isNaN(l)?"-"+l:-l:l),c[a]=(o?f?"+=":"-=":f?"-=":"+=")+l,r.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.transfer=function(t,n){var r=e(this),i=e(t.to),s=i.css("position")==="fixed",o=e("body"),u=s?o.scrollTop():0,a=s?o.scrollLeft():0,f=i.offset(),l={top:f.top-u,left:f.left-a,height:i.innerHeight(),width:i.innerWidth()},c=r.offset(),h=e('
    ').appendTo(document.body).addClass(t.className).css({top:c.top-u,left:c.left-a,height:r.innerHeight(),width:r.innerWidth(),position:s?"fixed":"absolute"}).animate(l,t.duration,t.easing,function(){h.remove(),n()})}})(jQuery);(function(e,t){var n=!1;e.widget("ui.menu",{version:"1.9.0",defaultElement:"
      ",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,e.proxy(function(e){this.options.disabled&&e.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(e){e.preventDefault()},"click .ui-state-disabled > a":function(e){e.preventDefault()},"click .ui-menu-item:has(a)":function(t){var r=e(t.target).closest(".ui-menu-item");!n&&r.not(".ui-state-disabled").length&&(n=!0,this.select(t),r.has(".ui-menu").length?this.expand(t):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&this.active.parents(".ui-menu").length===1&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){var n=e(t.currentTarget);n.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(t,n)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var n=this.active||this.element.children(".ui-menu-item").eq(0);t||this.focus(e,n)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){e(t.target).closest(".ui-menu").length||this.collapseAll(t),n=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").andSelf().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){function a(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var n,r,i,s,o,u=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:u=!1,r=this.previousFilter||"",i=String.fromCharCode(t.keyCode),s=!1,clearTimeout(this.filterTimer),i===r?s=!0:i=r+i,o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())}),n=s&&n.index(this.active.next())!==-1?this.active.nextAll(".ui-menu-item"):n,n.length||(i=String.fromCharCode(t.keyCode),o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())})),n.length?(this.focus(t,n),n.length>1?(this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}u&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(e):this.select(e))},refresh:function(){var t,n=this.options.icons.submenu,r=this.element.find(this.options.menus+":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"});t=r.add(this.element),t.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),t.children(":not(.ui-menu-item)").each(function(){var t=e(this);/[^\-—–\s]/.test(t.text())||t.addClass("ui-widget-content ui-menu-divider")}),t.children(".ui-state-disabled").attr("aria-disabled","true"),r.each(function(){var t=e(this),r=t.prev("a"),i=e("").addClass("ui-menu-icon ui-icon "+n).data("ui-menu-submenu-carat",!0);r.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",r.attr("id"))}),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},focus:function(e,t){var n,r;this.blur(e,e&&e.type==="focus"),this._scrollIntoView(t),this.active=t.first(),r=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",r.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),e&&e.type==="keydown"?this._close():this.timer=this._delay(function(){this._close()},this.delay),n=t.children(".ui-menu"),n.length&&/^mouse/.test(e.type)&&this._startOpening(n),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var n,r,i,s,o,u;this._hasScroll()&&(n=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,r=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,i=t.offset().top-this.activeMenu.offset().top-n-r,s=this.activeMenu.scrollTop(),o=this.activeMenu.height(),u=t.height(),i<0?this.activeMenu.scrollTop(s+i):i+u>o&&this.activeMenu.scrollTop(s+i-o+u))},blur:function(e,t){t||clearTimeout(this.timer);if(!this.active)return;this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active})},_startOpening:function(e){clearTimeout(this.timer);if(e.attr("aria-hidden")!=="true")return;this.timer=this._delay(function(){this._close(),this._open(e)},this.delay)},_open:function(t){var n=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(n)},collapseAll:function(t,n){clearTimeout(this.timer),this.timer=this._delay(function(){var r=n?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));r.length||(r=this.element),this._close(r),this.blur(t),this.activeMenu=r},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,n){var r;this.active&&(e==="first"||e==="last"?r=this.active[e==="first"?"prevAll":"nextAll"](".ui-menu-item").eq(-1):r=this.active[e+"All"](".ui-menu-item").eq(0));if(!r||!r.length||!this.active)r=this.activeMenu.children(".ui-menu-item")[t]();this.focus(n,r)},nextPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isLastItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r-i<0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())},previousPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isFirstItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r+i>0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item").first())},_hasScroll:function(){return this.element.outerHeight()
    ").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(e){return e===t?this._value():(this._setOption("value",e),this)},_setOption:function(e,t){e==="value"&&(this.options.value=t,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),this._super(e,t)},_value:function(){var e=this.options.value;return typeof e!="number"&&(e=0),Math.min(this.options.max,Math.max(this.min,e))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var e=this.value(),t=this._percentage();this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),this.valueDiv.toggle(e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(t.toFixed(0)+"%"),this.element.attr("aria-valuenow",e)}})})(jQuery);(function(e,t){e.widget("ui.resizable",e.ui.mouse,{version:"1.9.0",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1e3},_create:function(){var t=this,n=this.options;this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!n.aspectRatio,aspectRatio:n.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:n.helper||n.ghost||n.animate?n.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(e('
    ').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=n.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var r=this.handles.split(",");this.handles={};for(var i=0;i
    ');u.css({zIndex:n.zIndex}),"se"==s&&u.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(u)}}this._renderAxis=function(t){t=t||this.element;for(var n in this.handles){this.handles[n].constructor==String&&(this.handles[n]=e(this.handles[n],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var r=e(this.handles[n],this.element),i=0;i=/sw|ne|nw|se|n|s/.test(n)?r.outerHeight():r.outerWidth();var s=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");t.css(s,i),this._proportionallyResize()}if(!e(this.handles[n]).length)continue}},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!t.resizing){if(this.className)var e=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);t.axis=e&&e[1]?e[1]:"se"}}),n.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){if(n.disabled)return;e(this).removeClass("ui-resizable-autohide"),t._handles.show()}).mouseleave(function(){if(n.disabled)return;t.resizing||(e(this).addClass("ui-resizable-autohide"),t._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){t(this.element);var n=this.element;n.after(this.originalElement.css({position:n.css("position"),width:n.outerWidth(),height:n.outerHeight(),top:n.css("top"),left:n.css("left")})).remove()}return this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_mouseCapture:function(t){var n=!1;for(var r in this.handles)e(this.handles[r])[0]==t.target&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(t){var r=this.options,i=this.element.position(),s=this.element;this.resizing=!0,this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()},(s.is(".ui-draggable")||/absolute/.test(s.css("position")))&&s.css({position:"absolute",top:i.top,left:i.left}),this._renderProxy();var o=n(this.helper.css("left")),u=n(this.helper.css("top"));r.containment&&(o+=e(r.containment).scrollLeft()||0,u+=e(r.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:o,top:u},this.size=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalSize=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalPosition={left:o,top:u},this.sizeDiff={width:s.outerWidth()-s.width(),height:s.outerHeight()-s.height()},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio=typeof r.aspectRatio=="number"?r.aspectRatio:this.originalSize.width/this.originalSize.height||1;var a=e(".ui-resizable-"+this.axis).css("cursor");return e("body").css("cursor",a=="auto"?this.axis+"-resize":a),s.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(e){var t=this.helper,n=this.options,r={},i=this,s=this.originalMousePosition,o=this.axis,u=e.pageX-s.left||0,a=e.pageY-s.top||0,f=this._change[o];if(!f)return!1;var l=f.apply(this,[e,u,a]);this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey)l=this._updateRatio(l,e);return l=this._respectSize(l,e),this._propagate("resize",e),t.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",e,this.ui()),!1},_mouseStop:function(t){this.resizing=!1;var n=this.options,r=this;if(this._helper){var i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),o=s&&e.ui.hasScroll(i[0],"left")?0:r.sizeDiff.height,u=s?0:r.sizeDiff.width,a={width:r.helper.width()-u,height:r.helper.height()-o},f=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,l=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;n.animate||this.element.css(e.extend(a,{top:l,left:f})),r.helper.height(r.size.height),r.helper.width(r.size.width),this._helper&&!n.animate&&this._proportionallyResize()}return e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t=this.options,n,i,s,o,u;u={minWidth:r(t.minWidth)?t.minWidth:0,maxWidth:r(t.maxWidth)?t.maxWidth:Infinity,minHeight:r(t.minHeight)?t.minHeight:0,maxHeight:r(t.maxHeight)?t.maxHeight:Infinity};if(this._aspectRatio||e)n=u.minHeight*this.aspectRatio,s=u.minWidth/this.aspectRatio,i=u.maxHeight*this.aspectRatio,o=u.maxWidth/this.aspectRatio,n>u.minWidth&&(u.minWidth=n),s>u.minHeight&&(u.minHeight=s),ie.width,l=r(e.height)&&i.minHeight&&i.minHeight>e.height;f&&(e.width=i.minWidth),l&&(e.height=i.minHeight),u&&(e.width=i.maxWidth),a&&(e.height=i.maxHeight);var c=this.originalPosition.left+this.originalSize.width,h=this.position.top+this.size.height,p=/sw|nw|w/.test(o),d=/nw|ne|n/.test(o);f&&p&&(e.left=c-i.minWidth),u&&p&&(e.left=c-i.maxWidth),l&&d&&(e.top=h-i.minHeight),a&&d&&(e.top=h-i.maxHeight);var v=!e.width&&!e.height;return v&&!e.left&&e.top?e.top=null:v&&!e.top&&e.left&&(e.left=null),e},_proportionallyResize:function(){var t=this.options;if(!this._proportionallyResizeElements.length)return;var n=this.helper||this.element;for(var r=0;r');var r=e.browser.msie&&e.browser.version<7,i=r?1:0,s=r?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+s,height:this.element.outerHeight()+s,position:"absolute",left:this.elementOffset.left-i+"px",top:this.elementOffset.top-i+"px",zIndex:++n.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(e,t,n){return{width:this.originalSize.width+t}},w:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{top:s.top+n,height:i.height-n}},s:function(e,t,n){return{height:this.originalSize.height+n}},se:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},sw:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,n,r]))},ne:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},nw:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,n,r]))}},_propagate:function(t,n){e.ui.plugin.call(this,t,[n,this.ui()]),t!="resize"&&this._trigger(t,n,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","alsoResize",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=function(t){e(t).each(function(){var t=e(this);t.data("resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};typeof i.alsoResize=="object"&&!i.alsoResize.parentNode?i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)}):s(i.alsoResize)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.originalSize,o=r.originalPosition,u={height:r.size.height-s.height||0,width:r.size.width-s.width||0,top:r.position.top-o.top||0,left:r.position.left-o.left||0},a=function(t,r){e(t).each(function(){var t=e(this),i=e(this).data("resizable-alsoresize"),s={},o=r&&r.length?r:t.parents(n.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var n=(i[t]||0)+(u[t]||0);n&&n>=0&&(s[t]=n||null)}),t.css(s)})};typeof i.alsoResize=="object"&&!i.alsoResize.nodeType?e.each(i.alsoResize,function(e,t){a(e,t)}):a(i.alsoResize)},stop:function(t,n){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","animate",{stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r._proportionallyResizeElements,o=s.length&&/textarea/i.test(s[0].nodeName),u=o&&e.ui.hasScroll(s[0],"left")?0:r.sizeDiff.height,a=o?0:r.sizeDiff.width,f={width:r.size.width-a,height:r.size.height-u},l=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,c=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;r.element.animate(e.extend(f,c&&l?{top:c,left:l}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var n={width:parseInt(r.element.css("width"),10),height:parseInt(r.element.css("height"),10),top:parseInt(r.element.css("top"),10),left:parseInt(r.element.css("left"),10)};s&&s.length&&e(s[0]).css({width:n.width,height:n.height}),r._updateCache(n),r._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(t,r){var i=e(this).data("resizable"),s=i.options,o=i.element,u=s.containment,a=u instanceof e?u.get(0):/parent/.test(u)?o.parent().get(0):u;if(!a)return;i.containerElement=e(a);if(/document/.test(u)||u==document)i.containerOffset={left:0,top:0},i.containerPosition={left:0,top:0},i.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight};else{var f=e(a),l=[];e(["Top","Right","Left","Bottom"]).each(function(e,t){l[e]=n(f.css("padding"+t))}),i.containerOffset=f.offset(),i.containerPosition=f.position(),i.containerSize={height:f.innerHeight()-l[3],width:f.innerWidth()-l[1]};var c=i.containerOffset,h=i.containerSize.height,p=i.containerSize.width,d=e.ui.hasScroll(a,"left")?a.scrollWidth:p,v=e.ui.hasScroll(a)?a.scrollHeight:h;i.parentData={element:a,left:c.left,top:c.top,width:d,height:v}}},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.containerSize,o=r.containerOffset,u=r.size,a=r.position,f=r._aspectRatio||t.shiftKey,l={top:0,left:0},c=r.containerElement;c[0]!=document&&/static/.test(c.css("position"))&&(l=o),a.left<(r._helper?o.left:0)&&(r.size.width=r.size.width+(r._helper?r.position.left-o.left:r.position.left-l.left),f&&(r.size.height=r.size.width/r.aspectRatio),r.position.left=i.helper?o.left:0),a.top<(r._helper?o.top:0)&&(r.size.height=r.size.height+(r._helper?r.position.top-o.top:r.position.top),f&&(r.size.width=r.size.height*r.aspectRatio),r.position.top=r._helper?o.top:0),r.offset.left=r.parentData.left+r.position.left,r.offset.top=r.parentData.top+r.position.top;var h=Math.abs((r._helper?r.offset.left-l.left:r.offset.left-l.left)+r.sizeDiff.width),p=Math.abs((r._helper?r.offset.top-l.top:r.offset.top-o.top)+r.sizeDiff.height),d=r.containerElement.get(0)==r.element.parent().get(0),v=/relative|absolute/.test(r.containerElement.css("position"));d&&v&&(h-=r.parentData.left),h+r.size.width>=r.parentData.width&&(r.size.width=r.parentData.width-h,f&&(r.size.height=r.size.width/r.aspectRatio)),p+r.size.height>=r.parentData.height&&(r.size.height=r.parentData.height-p,f&&(r.size.width=r.size.height*r.aspectRatio))},stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.position,o=r.containerOffset,u=r.containerPosition,a=r.containerElement,f=e(r.helper),l=f.offset(),c=f.outerWidth()-r.sizeDiff.width,h=f.outerHeight()-r.sizeDiff.height;r._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h}),r._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h})}}),e.ui.plugin.add("resizable","ghost",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size;r.ghost=r.originalElement.clone(),r.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:""),r.ghost.appendTo(r.helper)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.ghost.css({position:"relative",height:r.size.height,width:r.size.width})},stop:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.helper&&r.helper.get(0).removeChild(r.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size,o=r.originalSize,u=r.originalPosition,a=r.axis,f=i._aspectRatio||t.shiftKey;i.grid=typeof i.grid=="number"?[i.grid,i.grid]:i.grid;var l=Math.round((s.width-o.width)/(i.grid[0]||1))*(i.grid[0]||1),c=Math.round((s.height-o.height)/(i.grid[1]||1))*(i.grid[1]||1);/^(se|s|e)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c):/^(ne)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c):/^(sw)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.left=u.left-l):(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c,r.position.left=u.left-l)}});var n=function(e){return parseInt(e,10)||0},r=function(e){return!isNaN(parseInt(e,10))}})(jQuery);(function(e,t){e.widget("ui.selectable",e.ui.mouse,{version:"1.9.0",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var t=this;this.element.addClass("ui-selectable"),this.dragged=!1;var n;this.refresh=function(){n=e(t.options.filter,t.element[0]),n.addClass("ui-selectee"),n.each(function(){var t=e(this),n=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:n.left,top:n.top,right:n.left+t.outerWidth(),bottom:n.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=n.addClass("ui-selectee"),this._mouseInit(),this.helper=e("
    ")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var n=this;this.opos=[t.pageX,t.pageY];if(this.options.disabled)return;var r=this.options;this.selectees=e(r.filter,this.element[0]),this._trigger("start",t),e(r.appendTo).append(this.helper),this.helper.css({left:t.clientX,top:t.clientY,width:0,height:0}),r.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var r=e.data(this,"selectable-item");r.startselected=!0,!t.metaKey&&!t.ctrlKey&&(r.$element.removeClass("ui-selected"),r.selected=!1,r.$element.addClass("ui-unselecting"),r.unselecting=!0,n._trigger("unselecting",t,{unselecting:r.element}))}),e(t.target).parents().andSelf().each(function(){var r=e.data(this,"selectable-item");if(r){var i=!t.metaKey&&!t.ctrlKey||!r.$element.hasClass("ui-selected");return r.$element.removeClass(i?"ui-unselecting":"ui-selected").addClass(i?"ui-selecting":"ui-unselecting"),r.unselecting=!i,r.selecting=i,r.selected=i,i?n._trigger("selecting",t,{selecting:r.element}):n._trigger("unselecting",t,{unselecting:r.element}),!1}})},_mouseDrag:function(t){var n=this;this.dragged=!0;if(this.options.disabled)return;var r=this.options,i=this.opos[0],s=this.opos[1],o=t.pageX,u=t.pageY;if(i>o){var a=o;o=i,i=a}if(s>u){var a=u;u=s,s=a}return this.helper.css({left:i,top:s,width:o-i,height:u-s}),this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!a||a.element==n.element[0])return;var f=!1;r.tolerance=="touch"?f=!(a.left>o||a.rightu||a.bottomi&&a.rights&&a.bottom").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(r.range==="min"||r.range==="max"?" ui-slider-range-"+r.range:"")));for(t=i.length;tn&&(i=n,s=e(this),o=t)}),c.range===!0&&this.values(1)===c.min&&(o+=1,s=e(this.handles[o])),u=this._start(t,o),u===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,s.addClass("ui-state-active").focus(),a=s.offset(),f=!e(t.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=f?{left:0,top:0}:{left:t.pageX-a.left-s.width()/2,top:t.pageY-a.top-s.height()/2-(parseInt(s.css("borderTopWidth"),10)||0)-(parseInt(s.css("borderBottomWidth"),10)||0)+(parseInt(s.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,r),this._animateOff=!0,!0))},_mouseStart:function(e){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},n=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,n),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,n,r,i,s;return this.orientation==="horizontal"?(t=this.elementSize.width,n=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,n=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),r=n/t,r>1&&(r=1),r<0&&(r=0),this.orientation==="vertical"&&(r=1-r),i=this._valueMax()-this._valueMin(),s=this._valueMin()+r*i,this._trimAlignValue(s)},_start:function(e,t){var n={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("start",e,n)},_slide:function(e,t,n){var r,i,s;this.options.values&&this.options.values.length?(r=this.values(t?0:1),this.options.values.length===2&&this.options.range===!0&&(t===0&&n>r||t===1&&n1){this.options.values[t]=this._trimAlignValue(n),this._refreshValue(),this._change(null,t);return}if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();r=this.options.values,i=arguments[0];for(s=0;s=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,n=(e-this._valueMin())%t,r=e-n;return Math.abs(n)*2>=t&&(r+=n>0?t:-t),parseFloat(r.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,n,r,i,s,o=this.options.range,u=this.options,a=this,f=this._animateOff?!1:u.animate,l={};this.options.values&&this.options.values.length?this.handles.each(function(r,i){n=(a.values(r)-a._valueMin())/(a._valueMax()-a._valueMin())*100,l[a.orientation==="horizontal"?"left":"bottom"]=n+"%",e(this).stop(1,1)[f?"animate":"css"](l,u.animate),a.options.range===!0&&(a.orientation==="horizontal"?(r===0&&a.range.stop(1,1)[f?"animate":"css"]({left:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({width:n-t+"%"},{queue:!1,duration:u.animate})):(r===0&&a.range.stop(1,1)[f?"animate":"css"]({bottom:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({height:n-t+"%"},{queue:!1,duration:u.animate}))),t=n}):(r=this.value(),i=this._valueMin(),s=this._valueMax(),n=s!==i?(r-i)/(s-i)*100:0,l[this.orientation==="horizontal"?"left":"bottom"]=n+"%",this.handle.stop(1,1)[f?"animate":"css"](l,u.animate),o==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[f?"animate":"css"]({width:n+"%"},u.animate),o==="max"&&this.orientation==="horizontal"&&this.range[f?"animate":"css"]({width:100-n+"%"},{queue:!1,duration:u.animate}),o==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[f?"animate":"css"]({height:n+"%"},u.animate),o==="max"&&this.orientation==="vertical"&&this.range[f?"animate":"css"]({height:100-n+"%"},{queue:!1,duration:u.animate}))}})})(jQuery);(function(e,t){e.widget("ui.sortable",e.ui.mouse,{version:"1.9.0",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?e.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,n){t==="disabled"?(this.options[t]=n,this.widget().toggleClass("ui-sortable-disabled",!!n)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,n){var r=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(t);var i=null,s=e(t.target).parents().each(function(){if(e.data(this,r.widgetName+"-item")==r)return i=e(this),!1});e.data(t.target,r.widgetName+"-item")==r&&(i=e(t.target));if(!i)return!1;if(this.options.handle&&!n){var o=!1;e(this.options.handle,i).find("*").andSelf().each(function(){this==t.target&&(o=!0)});if(!o)return!1}return this.currentItem=i,this._removeCurrentsFromItems(),!0},_mouseStart:function(t,n,r){var i=this.options;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),i.containment&&this._setContainment(),i.cursor&&(e("body").css("cursor")&&(this._storedCursor=e("body").css("cursor")),e("body").css("cursor",i.cursor)),i.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",i.opacity)),i.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",i.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!r)for(var s=this.containers.length-1;s>=0;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var n=this.options,r=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY=0;i--){var s=this.items[i],o=s.item[0],u=this._intersectsWithPointer(s);if(!u)continue;if(s.instance!==this.currentContainer)continue;if(o!=this.currentItem[0]&&this.placeholder[u==1?"next":"prev"]()[0]!=o&&!e.contains(this.placeholder[0],o)&&(this.options.type=="semi-dynamic"?!e.contains(this.element[0],o):!0)){this.direction=u==1?"down":"up";if(this.options.tolerance!="pointer"&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,n){if(!t)return;e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t);if(this.options.revert){var r=this,i=this.placeholder.offset();this.reverting=!0,e(this.helper).animate({left:i.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:i.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){r._clear(t)})}else this._clear(t,n);return!1},cancel:function(){if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},e(n).each(function(){var n=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[-=_](.+)/);n&&r.push((t.key||n[1]+"[]")+"="+(t.key&&t.expression?n[1]:n[2]))}),!r.length&&t.key&&r.push(t.key+"="),r.join("&")},toArray:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},n.each(function(){r.push(e(t.item||this).attr(t.attribute||"id")||"")}),r},_intersectsWith:function(e){var t=this.positionAbs.left,n=t+this.helperProportions.width,r=this.positionAbs.top,i=r+this.helperProportions.height,s=e.left,o=s+e.width,u=e.top,a=u+e.height,f=this.offset.click.top,l=this.offset.click.left,c=r+f>u&&r+fs&&t+le[this.floating?"width":"height"]?c:s0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return e!=0&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor==String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){var n=[],r=[],i=this._connectWith();if(i&&t)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&r.push([e.isFunction(a.options.items)?a.options.items.call(a.element):e(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a])}}r.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var s=r.length-1;s>=0;s--)r[s][0].each(function(){n.push(this)});return e(n)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");for(var t=0;t=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&(r.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a))}}for(var s=r.length-1;s>=0;s--){var f=r[s][1],l=r[s][0];for(var u=0,c=l.length;u=0;n--){var r=this.items[n];if(r.instance!=this.currentContainer&&this.currentContainer&&r.item[0]!=this.currentItem[0])continue;var i=this.options.toleranceElement?e(this.options.toleranceElement,r.item):r.item;t||(r.width=i.outerWidth(),r.height=i.outerHeight());var s=i.offset();r.left=s.left,r.top=s.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var n=this.containers.length-1;n>=0;n--){var s=this.containers[n].element.offset();this.containers[n].containerCache.left=s.left,this.containers[n].containerCache.top=s.top,this.containers[n].containerCache.width=this.containers[n].element.outerWidth(),this.containers[n].containerCache.height=this.containers[n].element.outerHeight()}return this},_createPlaceholder:function(t){t=t||this;var n=t.options;if(!n.placeholder||n.placeholder.constructor==String){var r=n.placeholder;n.placeholder={element:function(){var n=e(document.createElement(t.currentItem[0].nodeName)).addClass(r||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return r||(n.style.visibility="hidden"),n},update:function(e,i){if(r&&!n.forcePlaceholderSize)return;i.height()||i.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),i.width()||i.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10))}}}t.placeholder=e(n.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),n.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var n=null,r=null;for(var i=this.containers.length-1;i>=0;i--){if(e.contains(this.currentItem[0],this.containers[i].element[0]))continue;if(this._intersectsWith(this.containers[i].containerCache)){if(n&&e.contains(this.containers[i].element[0],n.element[0]))continue;n=this.containers[i],r=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0)}if(!n)return;if(this.containers.length===1)this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1;else if(this.currentContainer!=this.containers[r]){var s=1e4,o=null,u=this.positionAbs[this.containers[r].floating?"left":"top"];for(var a=this.items.length-1;a>=0;a--){if(!e.contains(this.containers[r].element[0],this.items[a].item[0]))continue;var f=this.containers[r].floating?this.items[a].item.offset().left:this.items[a].item.offset().top;Math.abs(f-u)0?"down":"up")}if(!o&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[r],o?this._rearrange(t,o,null,!0):this._rearrange(t,null,this.containers[r].element,!0),this._trigger("change",t,this._uiHash()),this.containers[r]._trigger("change",t,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1}},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t,this.currentItem])):n.helper=="clone"?this.currentItem.clone():this.currentItem;return r.parents("body").length||e(n.appendTo!="parent"?n.appendTo:this.currentItem[0].parentNode)[0].appendChild(r[0]),r[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(r[0].style.width==""||n.forceHelperSize)&&r.width(this.currentItem.width()),(r[0].style.height==""||n.forceHelperSize)&&r.height(this.currentItem.height()),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.browser.msie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)){var n=e(t.containment)[0],r=e(t.containment).offset(),i=e(n).css("overflow")!="hidden";this.containment=[r.left+(parseInt(e(n).css("borderLeftWidth"),10)||0)+(parseInt(e(n).css("paddingLeft"),10)||0)-this.margins.left,r.top+(parseInt(e(n).css("borderTopWidth"),10)||0)+(parseInt(e(n).css("paddingTop"),10)||0)-this.margins.top,r.left+(i?Math.max(n.scrollWidth,n.offsetWidth):n.offsetWidth)-(parseInt(e(n).css("borderLeftWidth"),10)||0)-(parseInt(e(n).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,r.top+(i?Math.max(n.scrollHeight,n.offsetHeight):n.offsetHeight)-(parseInt(e(n).css("borderTopWidth"),10)||0)-(parseInt(e(n).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var s=t.pageX,o=t.pageY;if(this.originalPosition){this.containment&&(t.pageX-this.offset.click.leftthis.containment[2]&&(s=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top));if(n.grid){var u=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1];o=this.containment?u-this.offset.click.topthis.containment[3]?u-this.offset.click.topthis.containment[2]?a-this.offset.click.left=0;i--)n||r.push(function(e){return function(t){e._trigger("deactivate",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(r.push(function(e){return function(t){e._trigger("out",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);this._storedCursor&&e("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!n){this._trigger("beforeStop",t,this._uiHash());for(var i=0;i",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},n=this.element;return e.each(["min","max","step"],function(e,r){var i=n.attr(r);i!==undefined&&i.length&&(t[r]=i)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.uiSpinner.addClass("ui-state-active"),this.previous=this.element.val()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}this._refresh(),this.uiSpinner.removeClass("ui-state-active"),this.previous!==this.element.val()&&this._trigger("change",e)},mousewheel:function(e,t){if(!t)return;if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()},"mousedown .ui-spinner-button":function(t){function r(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=n,this._delay(function(){this.previous=n}))}var n;n=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),r.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,r.call(this)});if(this._start(t)===!1)return;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){if(!e(t.currentTarget).hasClass("ui-state-active"))return;if(this._start(t)===!1)return!1;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this._hoverable(e),this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(e.height()*.5)&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var n=this.options,r=e.ui.keyCode;switch(t.keyCode){case r.UP:return this._repeat(null,1,t),!0;case r.DOWN:return this._repeat(null,-1,t),!0;case r.PAGE_UP:return this._repeat(null,n.page,t),!0;case r.PAGE_DOWN:return this._repeat(null,-n.page,t),!0}return!1},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""+""+""+""+""},_start:function(e){return!this.spinning&&this._trigger("start",e)===!1?!1:(this.counter||(this.counter=1),this.spinning=!0,!0)},_repeat:function(e,t,n){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,n)},e),this._spin(t*this.options.step,n)},_spin:function(e,t){var n=this.value()||0;this.counter||(this.counter=1),n=this._adjustValue(n+e*this._increment(this.counter));if(!this.spinning||this._trigger("spin",t,{value:n})!==!1)this._value(n),this.counter++},_increment:function(t){var n=this.options.incremental;return n?e.isFunction(n)?n(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return this.options.min!==null&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=e.toString(),n=t.indexOf(".");return n===-1?0:t.length-n-1},_adjustValue:function(e){var t,n,r=this.options;return t=r.min!==null?r.min:0,n=e-t,n=Math.round(n/r.step)*r.step,e=t+n,e=parseFloat(e.toFixed(this._precision())),r.max!==null&&e>r.max?r.max:r.min!==null&&e1&&e.href.replace(r,"")===location.href.replace(r,"")}var n=0,r=/#.*$/;e.widget("ui.tabs",{version:"1.9.0",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t,n=this,r=this.options,i=r.active;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",r.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs();if(i===null){location.hash&&this.anchors.each(function(e,t){if(t.hash===location.hash)return i=e,!1}),i===null&&(i=this.tabs.filter(".ui-tabs-active").index());if(i===null||i===-1)i=this.tabs.length?0:!1}i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),i===-1&&(i=r.collapsible?!1:0)),r.active=i,!r.collapsible&&r.active===!1&&this.anchors.length&&(r.active=0),e.isArray(r.disabled)&&(r.disabled=e.unique(r.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return n.tabs.index(e)}))).sort()),this.options.active!==!1&&this.anchors.length?this.active=this._findActive(this.options.active):this.active=e(),this._refresh(),this.active.length&&this.load(r.active)},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var n=e(this.document[0].activeElement).closest("li"),r=this.tabs.index(n),i=!0;if(this._handlePageNav(t))return;switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:r++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:i=!1,r--;break;case e.ui.keyCode.END:r=this.anchors.length-1;break;case e.ui.keyCode.HOME:r=0;break;case e.ui.keyCode.SPACE:t.preventDefault(),clearTimeout(this.activating),this._activate(r);return;case e.ui.keyCode.ENTER:t.preventDefault(),clearTimeout(this.activating),this._activate(r===this.options.active?!1:r);return;default:return}t.preventDefault(),clearTimeout(this.activating),r=this._focusNextTab(r,i),t.ctrlKey||(n.attr("aria-selected","false"),this.tabs.eq(r).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",r)},this.delay))},_panelKeydown:function(t){if(this._handlePageNav(t))return;t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP)return this._activate(this._focusNextTab(this.options.active-1,!1)),!0;if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN)return this._activate(this._focusNextTab(this.options.active+1,!0)),!0},_findNextTab:function(t,n){function i(){return t>r&&(t=0),t<0&&(t=r),t}var r=this.tabs.length-1;while(e.inArray(i(),this.options.disabled)!==-1)t=n?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){if(e==="active"){this._activate(t);return}if(e==="disabled"){this._setupDisabled(t);return}this._super(e,t),e==="collapsible"&&(this.element.toggleClass("ui-tabs-collapsible",t),!t&&this.options.active===!1&&this._activate(0)),e==="event"&&this._setupEvents(t),e==="heightStyle"&&this._setupHeightStyle(t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t,n=this.options,r=this.tablist.children(":has(a[href])");n.disabled=e.map(r.filter(".ui-state-disabled"),function(e){return r.index(e)}),this._processTabs(),n.active===!1||!this.anchors.length?(n.active=!1,this.active=e()):this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===n.disabled.length?(n.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,n.active-1),!1)):n.active=this.tabs.index(this.active),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(n,r){var i,o,u,a=e(r).uniqueId().attr("id"),f=e(r).closest("li"),l=f.attr("aria-controls");s(r)?(i=r.hash,o=t.element.find(t._sanitizeSelector(i))):(u=t._tabId(f),i="#"+u,o=t.element.find(i),o.length||(o=t._createPanel(u),o.insertAfter(t.panels[n-1]||t.tablist)),o.attr("aria-live","polite")),o.length&&(t.panels=t.panels.add(o)),l&&f.data("ui-tabs-aria-controls",l),f.attr({"aria-controls":i.substring(1),"aria-labelledby":a}),o.attr("aria-labelledby",a)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("
    ").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var n=0,r;r=this.tabs[n];n++)t===!0||e.inArray(n,t)!==-1?e(r).addClass("ui-state-disabled").attr("aria-disabled","true"):e(r).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var n={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,n),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var n,r,i=this.element.parent();t==="fill"?(e.support.minHeight||(r=i.css("overflow"),i.css("overflow","hidden")),n=i.height(),this.element.siblings(":visible").each(function(){var t=e(this),r=t.css("position");if(r==="absolute"||r==="fixed")return;n-=t.outerHeight(!0)}),r&&i.css("overflow",r),this.element.children().not(this.panels).each(function(){n-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,n-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):t==="auto"&&(n=0,this.panels.each(function(){n=Math.max(n,e(this).height("").height())}).height(n))},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i.closest("li"),o=s[0]===r[0],u=o&&n.collapsible,a=u?e():this._getPanelForTab(s),f=r.length?this._getPanelForTab(r):e(),l={oldTab:r,oldPanel:f,newTab:u?e():s,newPanel:a};t.preventDefault();if(s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||o&&!n.collapsible||this._trigger("beforeActivate",t,l)===!1)return;n.active=u?!1:this.tabs.index(s),this.active=o?e():s,this.xhr&&this.xhr.abort(),!f.length&&!a.length&&e.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,l)},_toggle:function(t,n){function o(){r.running=!1,r._trigger("activate",t,n)}function u(){n.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),i.length&&r.options.show?r._show(i,r.options.show,o):(i.show(),o())}var r=this,i=n.newPanel,s=n.oldPanel;this.running=!0,s.length&&this.options.hide?this._hide(s,this.options.hide,function(){n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),s.hide(),u()),s.attr({"aria-expanded":"false","aria-hidden":"true"}),n.oldTab.attr("aria-selected","false"),i.length&&s.length?n.oldTab.attr("tabIndex",-1):i.length&&this.tabs.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}),n.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var n,r=this._findActive(t);if(r[0]===this.active[0])return;r.length||(r=this.active),n=r.find(".ui-tabs-anchor")[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return typeof e=="string"&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeData("href.tabs").removeData("load.tabs").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),n=t.data("ui-tabs-aria-controls");n?t.attr("aria-controls",n):t.removeAttr("aria-controls")}),this.options.heightStyle!=="content"&&this.panels.css("height","")},enable:function(n){var r=this.options.disabled;if(r===!1)return;n===t?r=!1:(n=this._getIndex(n),e.isArray(r)?r=e.map(r,function(e){return e!==n?e:null}):r=e.map(this.tabs,function(e,t){return t!==n?t:null})),this._setupDisabled(r)},disable:function(n){var r=this.options.disabled;if(r===!0)return;if(n===t)r=!0;else{n=this._getIndex(n);if(e.inArray(n,r)!==-1)return;e.isArray(r)?r=e.merge([n],r).sort():r=[n]}this._setupDisabled(r)},load:function(t,n){t=this._getIndex(t);var r=this,i=this.tabs.eq(t),o=i.find(".ui-tabs-anchor"),u=this._getPanelForTab(i),a={tab:i,panel:u};if(s(o[0]))return;this.xhr=e.ajax(this._ajaxSettings(o,n,a)),this.xhr&&this.xhr.statusText!=="canceled"&&(i.addClass("ui-tabs-loading"),u.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){u.html(e),r._trigger("load",n,a)},1)}).complete(function(e,t){setTimeout(function(){t==="abort"&&r.panels.stop(!1,!0),i.removeClass("ui-tabs-loading"),u.removeAttr("aria-busy"),e===r.xhr&&delete r.xhr},1)}))},_ajaxSettings:function(t,n,r){var i=this;return{url:t.attr("href"),beforeSend:function(t,s){return i._trigger("beforeLoad",n,e.extend({jqXHR:t,ajaxSettings:s},r))}}},_getPanelForTab:function(t){var n=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+n))}}),e.uiBackCompat!==!1&&(e.ui.tabs.prototype._ui=function(e,t){return{tab:e,panel:t,index:this.anchors.index(e)}},e.widget("ui.tabs",e.ui.tabs,{url:function(e,t){this.anchors.eq(e).attr("href",t)}}),e.widget("ui.tabs",e.ui.tabs,{options:{ajaxOptions:null,cache:!1},_create:function(){this._super();var t=this;this._on({tabsbeforeload:function(n,r){if(e.data(r.tab[0],"cache.tabs")){n.preventDefault();return}r.jqXHR.success(function(){t.options.cache&&e.data(r.tab[0],"cache.tabs",!0)})}})},_ajaxSettings:function(t,n,r){var i=this.options.ajaxOptions;return e.extend({},i,{error:function(e,t,n){try{i.error(e,t,r.tab.closest("li").index(),r.tab[0])}catch(n){}}},this._superApply(arguments))},_setOption:function(e,t){e==="cache"&&t===!1&&this.anchors.removeData("cache.tabs"),this._super(e,t)},_destroy:function(){this.anchors.removeData("cache.tabs"),this._super()},url:function(e,t){this.anchors.eq(e).removeData("cache.tabs"),this._superApply(arguments)}}),e.widget("ui.tabs",e.ui.tabs,{abort:function(){this.xhr&&this.xhr.abort()}}),e.widget("ui.tabs",e.ui.tabs,{options:{spinner:"Loading…"},_create:function(){this._super(),this._on({tabsbeforeload:function(e,t){if(e.target!==this.element[0]||!this.options.spinner)return;var n=t.tab.find("span"),r=n.html();n.html(this.options.spinner),t.jqXHR.complete(function(){n.html(r)})}})}}),e.widget("ui.tabs",e.ui.tabs,{options:{enable:null,disable:null},enable:function(t){var n=this.options,r;if(t&&n.disabled===!0||e.isArray(n.disabled)&&e.inArray(t,n.disabled)!==-1)r=!0;this._superApply(arguments),r&&this._trigger("enable",null,this._ui(this.anchors[t],this.panels[t]))},disable:function(t){var n=this.options,r;if(t&&n.disabled===!1||e.isArray(n.disabled)&&e.inArray(t,n.disabled)===-1)r=!0;this._superApply(arguments),r&&this._trigger("disable",null,this._ui(this.anchors[t],this.panels[t]))}}),e.widget("ui.tabs",e.ui.tabs,{options:{add:null,remove:null,tabTemplate:"
  • #{label}
  • "},add:function(n,r,i){i===t&&(i=this.anchors.length);var s,o,u=this.options,a=e(u.tabTemplate.replace(/#\{href\}/g,n).replace(/#\{label\}/g,r)),f=n.indexOf("#")?this._tabId(a):n.replace("#","");return a.addClass("ui-state-default ui-corner-top").data("ui-tabs-destroy",!0),a.attr("aria-controls",f),s=i>=this.tabs.length,o=this.element.find("#"+f),o.length||(o=this._createPanel(f),s?i>0?o.insertAfter(this.panels.eq(-1)):o.appendTo(this.element):o.insertBefore(this.panels[i])),o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide(),s?a.appendTo(this.tablist):a.insertBefore(this.tabs[i]),u.disabled=e.map(u.disabled,function(e){return e>=i?++e:e}),this.refresh(),this.tabs.length===1&&u.active===!1&&this.option("active",0),this._trigger("add",null,this._ui(this.anchors[i],this.panels[i])),this},remove:function(t){t=this._getIndex(t);var n=this.options,r=this.tabs.eq(t).remove(),i=this._getPanelForTab(r).remove();return r.hasClass("ui-tabs-active")&&this.anchors.length>2&&this._activate(t+(t+1=t?--e:e}),this.refresh(),this._trigger("remove",null,this._ui(r.find("a")[0],i[0])),this}}),e.widget("ui.tabs",e.ui.tabs,{length:function(){return this.anchors.length}}),e.widget("ui.tabs",e.ui.tabs,{options:{idPrefix:"ui-tabs-"},_tabId:function(t){var n=t.is("li")?t.find("a[href]"):t;return n=n[0],e(n).closest("li").attr("aria-controls")||n.title&&n.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF\-]/g,"")||this.options.idPrefix+i()}}),e.widget("ui.tabs",e.ui.tabs,{options:{panelTemplate:"
    "},_createPanel:function(t){return e(this.options.panelTemplate).attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)}}),e.widget("ui.tabs",e.ui.tabs,{_create:function(){var e=this.options;e.active===null&&e.selected!==t&&(e.active=e.selected===-1?!1:e.selected),this._super(),e.selected=e.active,e.selected===!1&&(e.selected=-1)},_setOption:function(e,t){if(e!=="selected")return this._super(e,t);var n=this.options;this._super("active",t===-1?!1:t),n.selected=n.active,n.selected===!1&&(n.selected=-1)},_eventHandler:function(e){this._superApply(arguments),this.options.selected=this.options.active,this.options.selected===!1&&(this.options.selected=-1)}}),e.widget("ui.tabs",e.ui.tabs,{options:{show:null,select:null},_create:function(){this._super(),this.options.active!==!1&&this._trigger("show",null,this._ui(this.active.find(".ui-tabs-anchor")[0],this._getPanelForTab(this.active)[0]))},_trigger:function(e,t,n){var r=this._superApply(arguments);return r?(e==="beforeActivate"&&n.newTab.length?r=this._super("select",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()}):e==="activate"&&n.newTab.length&&(r=this._super("show",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()})),r):!1}}),e.widget("ui.tabs",e.ui.tabs,{select:function(e){e=this._getIndex(e);if(e===-1){if(!this.options.collapsible||this.options.selected===-1)return;e=this.options.selected}this.anchors.eq(e).trigger(this.options.event+this.eventNamespace)}}),function(){var t=0;e.widget("ui.tabs",e.ui.tabs,{options:{cookie:null},_create:function(){var e=this.options,t;e.active==null&&e.cookie&&(t=parseInt(this._cookie(),10),t===-1&&(t=!1),e.active=t),this._super()},_cookie:function(n){var r=[this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++t)];return arguments.length&&(r.push(n===!1?-1:n),r.push(this.options.cookie)),e.cookie.apply(null,r)},_refresh:function(){this._super(),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_eventHandler:function(e){this._superApply(arguments),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_destroy:function(){this._super(),this.options.cookie&&this._cookie(null,this.options.cookie)}})}(),e.widget("ui.tabs",e.ui.tabs,{_trigger:function(t,n,r){var i=e.extend({},r);return t==="load"&&(i.panel=i.panel[0],i.tab=i.tab.find(".ui-tabs-anchor")[0]),this._super(t,n,i)}}),e.widget("ui.tabs",e.ui.tabs,{options:{fx:null},_getFx:function(){var t,n,r=this.options.fx;return r&&(e.isArray(r)?(t=r[0],n=r[1]):t=n=r),r?{show:n,hide:t}:null},_toggle:function(e,t){function o(){n.running=!1,n._trigger("activate",e,t)}function u(){t.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&s.show?r.animate(s.show,s.show.duration,function(){o()}):(r.show(),o())}var n=this,r=t.newPanel,i=t.oldPanel,s=this._getFx();if(!s)return this._super(e,t);n.running=!0,i.length&&s.hide?i.animate(s.hide,s.hide.duration,function(){t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),i.hide(),u())}}))})(jQuery);(function(e){function n(t,n){var r=(t.attr("aria-describedby")||"").split(/\s+/);r.push(n),t.data("ui-tooltip-id",n).attr("aria-describedby",e.trim(r.join(" ")))}function r(t){var n=t.data("ui-tooltip-id"),r=(t.attr("aria-describedby")||"").split(/\s+/),i=e.inArray(n,r);i!==-1&&r.splice(i,1),t.removeData("ui-tooltip-id"),r=e.trim(r.join(" ")),r?t.attr("aria-describedby",r):t.removeAttr("aria-describedby")}var t=0;e.widget("ui.tooltip",{version:"1.9.0",options:{content:function(){return e(this).attr("title")},hide:!0,items:"[title]",position:{my:"left+15 center",at:"right center",collision:"flipfit flipfit"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={}},_setOption:function(t,n){var r=this;if(t==="disabled"){this[n?"_disable":"_enable"](),this.options[t]=n;return}this._super(t,n),t==="content"&&e.each(this.tooltips,function(e,t){r._updateContent(t)})},_disable:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0)}),this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var n=e(t?t.target:this.element).closest(this.options.items);if(!n.length)return;if(this.options.track&&n.data("ui-tooltip-id")){this._find(n).position(e.extend({of:n},this.options.position)),this._off(this.document,"mousemove");return}n.attr("title")&&n.data("ui-tooltip-title",n.attr("title")),n.data("tooltip-open",!0),this._updateContent(n,t)},_updateContent:function(e,t){var n,r=this.options.content,i=this;if(typeof r=="string")return this._open(t,e,r);n=r.call(e[0],function(n){if(!e.data("tooltip-open"))return;i._delay(function(){this._open(t,e,n)})}),n&&this._open(t,e,n)},_open:function(t,r,i){function u(e){o.of=e,s.position(o)}var s,o;if(!i)return;s=this._find(r);if(s.length){s.find(".ui-tooltip-content").html(i);return}r.is("[title]")&&(t&&t.type==="mouseover"?r.attr("title",""):r.removeAttr("title")),s=this._tooltip(r),n(r,s.attr("id")),s.find(".ui-tooltip-content").html(i),this.options.track&&t&&/^mouse/.test(t.originalEvent.type)?(o=e.extend({},this.options.position),this._on(this.document,{mousemove:u}),u(t)):s.position(e.extend({of:r},this.options.position)),s.hide(),this._show(s,this.options.show),this._trigger("open",t,{tooltip:s}),this._on(r,{mouseleave:"close",focusout:"close",keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var n=e.Event(t);n.currentTarget=r[0],this.close(n,!0)}}})},close:function(t,n){var i=this,s=e(t?t.currentTarget:this.element),o=this._find(s);if(this.closing)return;if(!n&&t&&t.type!=="focusout"&&this.document[0].activeElement===s[0])return;s.data("ui-tooltip-title")&&s.attr("title",s.data("ui-tooltip-title")),r(s),o.stop(!0),this._hide(o,this.options.hide,function(){e(this).remove(),delete i.tooltips[this.id]}),s.removeData("tooltip-open"),this._off(s,"mouseleave focusout keyup"),this._off(this.document,"mousemove"),this.closing=!0,this._trigger("close",t,{tooltip:o}),this.closing=!1},_tooltip:function(n){var r="ui-tooltip-"+t++,i=e("
    ").attr({id:r,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return e("
    ").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),e.fn.bgiframe&&i.bgiframe(),this.tooltips[r]=n,i},_find:function(t){var n=t.data("ui-tooltip-id");return n?e("#"+n):e()},_destroy:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0),e("#"+n).remove(),r.data("ui-tooltip-title")&&(r.attr("title",r.data("ui-tooltip-title")),r.removeData("ui-tooltip-title"))})}})})(jQuery); \ No newline at end of file diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.js new file mode 100644 index 0000000000..bc3fbc81b2 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.2 jquery.com | jquery.org/license */ +(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write(""),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bS[a]=c,c}function ci(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||ce.test(a)?d(a,e):ci(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ci(a+"["+e+"]",b[e],c,d);else d(a,b)}function cz(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:function(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.2",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);return d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("Invalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callbacks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return a!=null?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b
    a",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="
    t
    ",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="
    ",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||p.guid++:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.length,e=c.shift(),f=p._queueHooks(a,b),g=function(){p.dequeue(a,b)};e==="inprogress"&&(e=c.shift(),d--),e&&(b==="fx"&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.prop,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c=0)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c=0)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.val()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,d+""),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arguments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;j=0:p.find(m,this,null,[f]).length),h[m]&&j.push(l);j.length&&u.push({elem:f,matches:j})}o.length>q&&u.push({elem:this,matches:o.slice(q)});for(d=0;d0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bc(a,b,c,d){c=c||[],b=b||r;var e,f,i,j,k=b.nodeType;if(!a||typeof a!="string")return c;if(k!==1&&k!==9)return[];i=g(b);if(!i&&!d)if(e=P.exec(a))if(j=e[1]){if(k===9){f=b.getElementById(j);if(!f||!f.parentNode)return c;if(f.id===j)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(j))&&h(b,f)&&f.id===j)return c.push(f),c}else{if(e[2])return w.apply(c,x.call(b.getElementsByTagName(a),0)),c;if((j=e[3])&&_&&b.getElementsByClassName)return w.apply(c,x.call(b.getElementsByClassName(j),0)),c}return bp(a.replace(L,"$1"),b,c,d,i)}function bd(a){return function(b){var c=b.nodeName.toLowerCase();return c==="input"&&b.type===a}}function be(a){return function(b){var c=b.nodeName.toLowerCase();return(c==="input"||c==="button")&&b.type===a}}function bf(a){return z(function(b){return b=+b,z(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function bg(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}function bh(a,b){var c,d,f,g,h,i,j,k=C[o][a];if(k)return b?0:k.slice(0);h=a,i=[],j=e.preFilter;while(h){if(!c||(d=M.exec(h)))d&&(h=h.slice(d[0].length)),i.push(f=[]);c=!1;if(d=N.exec(h))f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=d[0].replace(L," ");for(g in e.filter)(d=W[g].exec(h))&&(!j[g]||(d=j[g](d,r,!0)))&&(f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=g,c.matches=d);if(!c)break}return b?h.length:h?bc.error(a):C(a,i).slice(0)}function bi(a,b,d){var e=b.dir,f=d&&b.dir==="parentNode",g=u++;return b.first?function(b,c,d){while(b=b[e])if(f||b.nodeType===1)return a(b,c,d)}:function(b,d,h){if(!h){var i,j=t+" "+g+" ",k=j+c;while(b=b[e])if(f||b.nodeType===1){if((i=b[o])===k)return b.sizset;if(typeof i=="string"&&i.indexOf(j)===0){if(b.sizset)return b}else{b[o]=k;if(a(b,d,h))return b.sizset=!0,b;b.sizset=!1}}}else while(b=b[e])if(f||b.nodeType===1)if(a(b,d,h))return b}}function bj(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function bk(a,b,c,d,e){var f,g=[],h=0,i=a.length,j=b!=null;for(;h-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==l)||((b=c).nodeType?j(a,c,d):k(a,c,d))}];for(;i1&&bj(m),i>1&&a.slice(0,i-1).join("").replace(L,"$1"),c,i0,f=a.length>0,g=function(h,i,j,k,m){var n,o,p,q=[],s=0,u="0",x=h&&[],y=m!=null,z=l,A=h||f&&e.find.TAG("*",m&&i.parentNode||i),B=t+=z==null?1:Math.E;y&&(l=i!==r&&i,c=g.el);for(;(n=A[u])!=null;u++){if(f&&n){for(o=0;p=a[o];o++)if(p(n,i,j)){k.push(n);break}y&&(t=B,c=++g.el)}d&&((n=!p&&n)&&s--,h&&x.push(n))}s+=u;if(d&&u!==s){for(o=0;p=b[o];o++)p(x,q,i,j);if(h){if(s>0)while(u--)!x[u]&&!q[u]&&(q[u]=v.call(k));q=bk(q)}w.apply(k,q),y&&!h&&q.length>0&&s+b.length>1&&bc.uniqueSort(k)}return y&&(t=B,l=z),x};return g.el=0,d?z(g):g}function bo(a,b,c,d){var e=0,f=b.length;for(;e2&&(j=h[0]).type==="ID"&&b.nodeType===9&&!f&&e.relative[h[1].type]){b=e.find.ID(j.matches[0].replace(V,""),b,f)[0];if(!b)return c;a=a.slice(h.shift().length)}for(g=W.POS.test(a)?-1:h.length-1;g>=0;g--){j=h[g];if(e.relative[k=j.type])break;if(l=e.find[k])if(d=l(j.matches[0].replace(V,""),R.test(h[0].type)&&b.parentNode||b,f)){h.splice(g,1),a=d.length&&h.join("");if(!a)return w.apply(c,x.call(d,0)),c;break}}}return i(a,m)(d,b,f,c,R.test(a)),c}function bq(){}var c,d,e,f,g,h,i,j,k,l,m=!0,n="undefined",o=("sizcache"+Math.random()).replace(".",""),q=String,r=a.document,s=r.documentElement,t=0,u=0,v=[].pop,w=[].push,x=[].slice,y=[].indexOf||function(a){var b=0,c=this.length;for(;be.cacheLength&&delete a[b.shift()],a[c]=d},a)},B=A(),C=A(),D=A(),E="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",G=F.replace("w","w#"),H="([*^$|!~]?=)",I="\\["+E+"*("+F+")"+E+"*(?:"+H+E+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+G+")|)|)"+E+"*\\]",J=":("+F+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+I+")|[^:]|\\\\.)*|.*))\\)|)",K=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+E+"*((?:-\\d)?\\d*)"+E+"*\\)|)(?=[^-]|$)",L=new RegExp("^"+E+"+|((?:^|[^\\\\])(?:\\\\.)*)"+E+"+$","g"),M=new RegExp("^"+E+"*,"+E+"*"),N=new RegExp("^"+E+"*([\\x20\\t\\r\\n\\f>+~])"+E+"*"),O=new RegExp(J),P=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,Q=/^:not/,R=/[\x20\t\r\n\f]*[+~]/,S=/:not\($/,T=/h\d/i,U=/input|select|textarea|button/i,V=/\\(?!\\)/g,W={ID:new RegExp("^#("+F+")"),CLASS:new RegExp("^\\.("+F+")"),NAME:new RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:new RegExp("^("+F.replace("w","w*")+")"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+J),POS:new RegExp(K,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+E+"*(even|odd|(([+-]|)(\\d*)n|)"+E+"*(?:([+-]|)"+E+"*(\\d+)|))"+E+"*\\)|)","i"),needsContext:new RegExp("^"+E+"*[>+~]|"+K,"i")},X=function(a){var b=r.createElement("div");try{return a(b)}catch(c){return!1}finally{b=null}},Y=X(function(a){return a.appendChild(r.createComment("")),!a.getElementsByTagName("*").length}),Z=X(function(a){return a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!==n&&a.firstChild.getAttribute("href")==="#"}),$=X(function(a){a.innerHTML="";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),_=X(function(a){return a.innerHTML="",!a.getElementsByClassName||!a.getElementsByClassName("e").length?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length===2)}),ba=X(function(a){a.id=o+0,a.innerHTML="
    ",s.insertBefore(a,s.firstChild);var b=r.getElementsByName&&r.getElementsByName(o).length===2+r.getElementsByName(o+0).length;return d=!r.getElementById(o),s.removeChild(a),b});try{x.call(s.childNodes,0)[0].nodeType}catch(bb){x=function(a){var b,c=[];for(;b=this[a];a++)c.push(b);return c}}bc.matches=function(a,b){return bc(a,null,null,b)},bc.matchesSelector=function(a,b){return bc(b,null,null,[a]).length>0},f=bc.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(e===1||e===9||e===11){if(typeof a.textContent=="string")return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=f(a)}else if(e===3||e===4)return a.nodeValue}else for(;b=a[d];d++)c+=f(b);return c},g=bc.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?b.nodeName!=="HTML":!1},h=bc.contains=s.contains?function(a,b){var c=a.nodeType===9?a.documentElement:a,d=b&&b.parentNode;return a===d||!!(d&&d.nodeType===1&&c.contains&&c.contains(d))}:s.compareDocumentPosition?function(a,b){return b&&!!(a.compareDocumentPosition(b)&16)}:function(a,b){while(b=b.parentNode)if(b===a)return!0;return!1},bc.attr=function(a,b){var c,d=g(a);return d||(b=b.toLowerCase()),(c=e.attrHandle[b])?c(a):d||$?a.getAttribute(b):(c=a.getAttributeNode(b),c?typeof a[b]=="boolean"?a[b]?b:null:c.specified?c.value:null:null)},e=bc.selectors={cacheLength:50,createPseudo:z,match:W,attrHandle:Z?{}:{href:function(a){return a.getAttribute("href",2)},type:function(a){return a.getAttribute("type")}},find:{ID:d?function(a,b,c){if(typeof b.getElementById!==n&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==n&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==n&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:Y?function(a,b){if(typeof b.getElementsByTagName!==n)return b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c},NAME:ba&&function(a,b){if(typeof b.getElementsByName!==n)return b.getElementsByName(name)},CLASS:_&&function(a,b,c){if(typeof b.getElementsByClassName!==n&&!c)return b.getElementsByClassName(a)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(V,""),a[3]=(a[4]||a[5]||"").replace(V,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||bc.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&bc.error(a[0]),a},PSEUDO:function(a){var b,c;if(W.CHILD.test(a[0]))return null;if(a[3])a[2]=a[3];else if(b=a[4])O.test(b)&&(c=bh(b,!0))&&(c=b.indexOf(")",b.length-c)-b.length)&&(b=b.slice(0,c),a[0]=a[0].slice(0,c)),a[2]=b;return a.slice(0,3)}},filter:{ID:d?function(a){return a=a.replace(V,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(V,""),function(b){var c=typeof b.getAttributeNode!==n&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(V,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=B[o][a];return b||(b=B(a,new RegExp("(^|"+E+")"+a+"("+E+"|$)"))),function(a){return b.test(a.className||typeof a.getAttribute!==n&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return function(d,e){var f=bc.attr(d,a);return f==null?b==="!=":b?(f+="",b==="="?f===c:b==="!="?f!==c:b==="^="?c&&f.indexOf(c)===0:b==="*="?c&&f.indexOf(c)>-1:b==="$="?c&&f.substr(f.length-c.length)===c:b==="~="?(" "+f+" ").indexOf(c)>-1:b==="|="?f===c||f.substr(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d){return a==="nth"?function(a){var b,e,f=a.parentNode;if(c===1&&d===0)return!0;if(f){e=0;for(b=f.firstChild;b;b=b.nextSibling)if(b.nodeType===1){e++;if(a===b)break}}return e-=d,e===c||e%c===0&&e/c>=0}:function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b){var c,d=e.pseudos[a]||e.setFilters[a.toLowerCase()]||bc.error("unsupported pseudo: "+a);return d[o]?d(b):d.length>1?(c=[a,a,"",b],e.setFilters.hasOwnProperty(a.toLowerCase())?z(function(a,c){var e,f=d(a,b),g=f.length;while(g--)e=y.call(a,f[g]),a[e]=!(c[e]=f[g])}):function(a){return d(a,0,c)}):d}},pseudos:{not:z(function(a){var b=[],c=[],d=i(a.replace(L,"$1"));return d[o]?z(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)if(f=g[h])a[h]=!(b[h]=f)}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:z(function(a){return function(b){return bc(a,b).length>0}}),contains:z(function(a){return function(b){return(b.textContent||b.innerText||f(b)).indexOf(a)>-1}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!e.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.nodeType)===3||b===4)return!1;a=a.nextSibling}return!0},header:function(a){return T.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:bd("radio"),checkbox:bd("checkbox"),file:bd("file"),password:bd("password"),image:bd("image"),submit:be("submit"),reset:be("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return U.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement},first:bf(function(a,b,c){return[0]}),last:bf(function(a,b,c){return[b-1]}),eq:bf(function(a,b,c){return[c<0?c+b:c]}),even:bf(function(a,b,c){for(var d=0;d=0;)a.push(d);return a}),gt:bf(function(a,b,c){for(var d=c<0?c+b:c;++d",a.querySelectorAll("[selected]").length||e.push("\\["+E+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),X(function(a){a.innerHTML="

    ",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+E+"*(?:\"\"|'')"),a.innerHTML="",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=new RegExp(e.join("|")),bp=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a))){var i,j,k=!0,l=o,m=d,n=d.nodeType===9&&a;if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){i=bh(a),(k=d.getAttribute("id"))?l=k.replace(c,"\\$&"):d.setAttribute("id",l),l="[id='"+l+"'] ",j=i.length;while(j--)i[j]=l+i[j].join("");m=R.test(a)&&d.parentNode||d,n=i.join(",")}if(n)try{return w.apply(f,x.call(m.querySelectorAll(n),0)),f}catch(p){}finally{k||d.removeAttribute("id")}}return b(a,d,f,g,h)},h&&(X(function(b){a=h.call(b,"div");try{h.call(b,"[test!='']:sizzle"),f.push("!=",J)}catch(c){}}),f=new RegExp(f.join("|")),bc.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!g(b)&&!f.test(c)&&(!e||!e.test(c)))try{var i=h.call(b,c);if(i||a||b.document&&b.document.nodeType!==11)return i}catch(j){}return bc(c,null,null,[b]).length>0})}(),e.pseudos.nth=e.pseudos.eq,e.filters=bq.prototype=e.pseudos,e.setFilters=new bq,bc.attr=p.attr,p.find=bc,p.expr=bc.selectors,p.expr[":"]=p.expr.pseudos,p.unique=bc.uniqueSort,p.text=bc.getText,p.isXMLDoc=bc.isXML,p.contains=bc.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b0)for(e=d;e=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p.map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/]","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*\s*$/g,bz={option:[1,""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X
    ","
    "]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this[0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1>");try{for(;d1&&typeof j=="string"&&bw.test(j))return this.each(function(){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=b===e&&bA,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(f=0;(h=a[f])!=null;f++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{s=s||bk(b),l=b.createElement("div"),s.appendChild(l),h=h.replace(bo,"<$1>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]===""&&!m?l.childNodes:[];for(g=n.length-1;g>=0;--g)p.nodeName(n[g],"tbody")&&!n[g].childNodes.length&&n[g].parentNode.removeChild(n[g])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l.parentNode.removeChild(l)}h.nodeType?t.push(h):p.merge(t,h)}l&&(h=l=s=null);if(!p.support.appendChecked)for(f=0;(h=t[f])!=null;f++)p.nodeName(h,"input")?bG(h):typeof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(f=0;(h=t[f])!=null;f++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[f+1,0].concat(r)),f+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.chrome?b.webkit=!0:b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^(none|table(?!-c[ea]).+)/,bO=/^margin/,bP=new RegExp("^("+q+")(.*)$","i"),bQ=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bR=new RegExp("^([-+])=("+q+")","i"),bS={},bT={position:"absolute",visibility:"hidden",display:"block"},bU={letterSpacing:0,fontWeight:400},bV=["Top","Right","Bottom","Left"],bW=["Webkit","O","Moz","ms"],bX=p.fn.toggle;p.fn.extend({css:function(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return b$(this,!0)},hide:function(){return b$(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bX.apply(this,arguments):this.each(function(){(c?a:bZ(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bY(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bR.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&isNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bY(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bU&&(f=bU[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(b,c){var d,e,f,g,h=a.getComputedStyle(b,null),i=b.style;return h&&(d=h[c],d===""&&!p.contains(b.ownerDocument,b)&&(d=p.style(b,c)),bQ.test(d)&&bO.test(c)&&(e=i.width,f=i.minWidth,g=i.maxWidth,i.minWidth=i.maxWidth=i.width=d,d=h.width,i.width=e,i.minWidth=f,i.maxWidth=g)),d}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bQ.test(e)&&!bM.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth===0&&bN.test(bH(a,"display"))?p.swap(a,bT,function(){return cb(a,b,d)}):cb(a,b,d)},set:function(a,c,d){return b_(a,c,d?ca(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMarginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bQ.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bV[d]+b]=e[d]||e[d-2]||e[0];return f}},bO.test(a)||(p.cssHooks[a+b].set=b_)});var cd=/%20/g,ce=/\[\]$/,cf=/\r?\n/g,cg=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,ch=/^(?:select|textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ch.test(this.nodeName)||cg.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(cf,"\r\n")}}):{name:b.name,value:c.replace(cf,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ci(d,a[d],c,f);return e.join("&").replace(cd,"+")};var cj,ck,cl=/#.*$/,cm=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,co=/^(?:GET|HEAD)$/,cp=/^\/\//,cq=/\?/,cr=/)<[^<]*)*<\/script>/gi,cs=/([?&])_=[^&]*/,ct=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,cu=p.fn.load,cv={},cw={},cx=["*/"]+["*"];try{ck=f.href}catch(cy){ck=e.createElement("a"),ck.href="",ck=ck.href}cj=ct.exec(ck.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&cu)return cu.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):c&&typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("
    ").append(a.replace(cr,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cB(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cB(a,b),a},ajaxSettings:{url:ck,isLocal:cn.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cx},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cz(cv),ajaxTransport:cz(cw),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cC(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cD(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=(c||y)+"",k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cm.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(cl,"").replace(cp,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=ct.exec(l.url.toLowerCase())||!1,l.crossDomain=i&&i.join(":")+(i[3]?"":i[1]==="http:"?80:443)!==cj.join(":")+(cj[3]?"":cj[1]==="http:"?80:443)),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cA(cv,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!co.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cq.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cs,"$1_="+z);l.url=A+(A===l.url?(cq.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cx+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cA(cw,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cE=[],cF=/\?/,cG=/(=)\?(?=&|$)|\?\?/,cH=p.now();p.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=cE.pop()||p.expando+"_"+cH++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cG.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cG.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cG,"$1"+f):m?c.data=i.replace(cG,"$1"+f):k&&(c.url+=(cF.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cE.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cI,cJ=a.ActiveXObject?function(){for(var a in cI)cI[a](0,1)}:!1,cK=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cL()||cM()}:cL,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cJ&&delete cI[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cK,cJ&&(cI||(cI={},p(a).unload(cJ)),cI[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var cN,cO,cP=/^(?:toggle|show|hide)$/,cQ=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cR=/queueHooks$/,cS=[cY],cT={"*":[function(a,b){var c,d,e=this.createTween(a,b),f=cQ.exec(b),g=e.cur(),h=+g||0,i=1,j=20;if(f){c=+f[2],d=f[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&h){h=p.css(e.elem,a,!0)||c||1;do i=i||".5",h=h/i,p.style(e.elem,a,h+d);while(i!==(i=e.cur()/g)&&i!==1&&--j)}e.unit=d,e.start=h,e.end=f[1]?h+(f[1]+1)*c:c}return e}]};p.Animation=p.extend(cW,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),p.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},p.fn.extend({position:function(){if(!this[0])return;var a=this[0],b=this.offsetParent(),c=this.offset(),d=c_.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(p.css(a,"marginTop"))||0,c.left-=parseFloat(p.css(a,"marginLeft"))||0,d.top+=parseFloat(p.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(p.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||e.body;while(a&&!c_.test(a.nodeName)&&p.css(a,"position")==="static")a=a.offsetParent;return a||e.body})}}),p.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);p.fn[a]=function(e){return p.access(this,function(a,e,f){var g=da(a);if(f===b)return g?c in g?g[c]:g.document.documentElement[e]:a[e];g?g.scrollTo(d?p(g).scrollLeft():f,d?f:p(g).scrollTop()):a[e]=f},a,e,arguments.length,null)}}),p.each({Height:"height",Width:"width"},function(a,c){p.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){p.fn[e]=function(e,f){var g=arguments.length&&(d||typeof e!="boolean"),h=d||(e===!0||f===!0?"margin":"border");return p.access(this,function(c,d,e){var f;return p.isWindow(c)?c.document.documentElement["client"+a]:c.nodeType===9?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?p.css(c,d,e,h):p.style(c,d,e,h)},c,g?e:b,g,null)}})}),a.jQuery=a.$=p,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return p})})(window); \ No newline at end of file diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js new file mode 100644 index 0000000000..4dd48675b7 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js @@ -0,0 +1,5486 @@ +/** + * @preserve jquery.layout 1.3.0 - Release Candidate 30.62 + * $Date: 2012-08-04 08:00:00 (Thu, 23 Aug 2012) $ + * $Rev: 303006 $ + * + * Copyright (c) 2012 + * Fabrizio Balliano (http://www.fabrizioballiano.net) + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * Changelog: http://layout.jquery-dev.net/changelog.cfm#1.3.0.rc30.62 + * NOTE: This is a short-term release to patch a couple of bugs. + * These bugs are listed as officially fixed in RC30.7, which will be released shortly. + * + * Docs: http://layout.jquery-dev.net/documentation.html + * Tips: http://layout.jquery-dev.net/tips.html + * Help: http://groups.google.com/group/jquery-ui-layout + */ + +/* JavaDoc Info: http://code.google.com/closure/compiler/docs/js-for-compiler.html + * {!Object} non-nullable type (never NULL) + * {?string} nullable type (sometimes NULL) - default for {Object} + * {number=} optional parameter + * {*} ALL types + */ + +// NOTE: For best readability, view with a fixed-width font and tabs equal to 4-chars + +;(function ($) { + +// alias Math methods - used a lot! +var min = Math.min +, max = Math.max +, round = Math.floor + +, isStr = function (v) { return $.type(v) === "string"; } + +, runPluginCallbacks = function (Instance, a_fn) { + if ($.isArray(a_fn)) + for (var i=0, c=a_fn.length; i
    ').appendTo("body"); + var d = { width: $c.width() - $c[0].clientWidth, height: $c.height() - $c[0].clientHeight }; + $c.remove(); + window.scrollbarWidth = d.width; + window.scrollbarHeight = d.height; + return dim.match(/^(width|height)$/) ? d[dim] : d; + } + + + /** + * Returns hash container 'display' and 'visibility' + * + * @see $.swap() - swaps CSS, runs callback, resets CSS + */ +, showInvisibly: function ($E, force) { + if ($E && $E.length && (force || $E.css('display') === "none")) { // only if not *already hidden* + var s = $E[0].style + // save ONLY the 'style' props because that is what we must restore + , CSS = { display: s.display || '', visibility: s.visibility || '' }; + // show element 'invisibly' so can be measured + $E.css({ display: "block", visibility: "hidden" }); + return CSS; + } + return {}; + } + + /** + * Returns data for setting size of an element (container or a pane). + * + * @see _create(), onWindowResize() for container, plus others for pane + * @return JSON Returns a hash of all dimensions: top, bottom, left, right, outerWidth, innerHeight, etc + */ +, getElementDimensions: function ($E) { + var + d = {} // dimensions hash + , x = d.css = {} // CSS hash + , i = {} // TEMP insets + , b, p // TEMP border, padding + , N = $.layout.cssNum + , off = $E.offset() + ; + d.offsetLeft = off.left; + d.offsetTop = off.top; + + $.each("Left,Right,Top,Bottom".split(","), function (idx, e) { // e = edge + b = x["border" + e] = $.layout.borderWidth($E, e); + p = x["padding"+ e] = $.layout.cssNum($E, "padding"+e); + i[e] = b + p; // total offset of content from outer side + d["inset"+ e] = p; // eg: insetLeft = paddingLeft + }); + + d.offsetWidth = $E.innerWidth(); // offsetWidth is used in calc when doing manual resize + d.offsetHeight = $E.innerHeight(); // ditto + d.outerWidth = $E.outerWidth(); + d.outerHeight = $E.outerHeight(); + d.innerWidth = max(0, d.outerWidth - i.Left - i.Right); + d.innerHeight = max(0, d.outerHeight - i.Top - i.Bottom); + + x.width = $E.width(); + x.height = $E.height(); + x.top = N($E,"top",true); + x.bottom = N($E,"bottom",true); + x.left = N($E,"left",true); + x.right = N($E,"right",true); + + //d.visible = $E.is(":visible");// && x.width > 0 && x.height > 0; + + return d; + } + +, getElementCSS: function ($E, list) { + var + CSS = {} + , style = $E[0].style + , props = list.split(",") + , sides = "Top,Bottom,Left,Right".split(",") + , attrs = "Color,Style,Width".split(",") + , p, s, a, i, j, k + ; + for (i=0; i < props.length; i++) { + p = props[i]; + if (p.match(/(border|padding|margin)$/)) + for (j=0; j < 4; j++) { + s = sides[j]; + if (p === "border") + for (k=0; k < 3; k++) { + a = attrs[k]; + CSS[p+s+a] = style[p+s+a]; + } + else + CSS[p+s] = style[p+s]; + } + else + CSS[p] = style[p]; + }; + return CSS + } + + /** + * Return the innerWidth for the current browser/doctype + * + * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {number=} outerWidth (optional) Can pass a width, allowing calculations BEFORE element is resized + * @return {number} Returns the innerWidth of the elem by subtracting padding and borders + */ +, cssWidth: function ($E, outerWidth) { + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerWidth <= 0) return 0; + + if (!$.layout.browser.boxModel) return outerWidth; + + // strip border and padding from outerWidth to get CSS Width + var b = $.layout.borderWidth + , n = $.layout.cssNum + , W = outerWidth + - b($E, "Left") + - b($E, "Right") + - n($E, "paddingLeft") + - n($E, "paddingRight"); + + return max(0,W); + } + + /** + * Return the innerHeight for the current browser/doctype + * + * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {number=} outerHeight (optional) Can pass a width, allowing calculations BEFORE element is resized + * @return {number} Returns the innerHeight of the elem by subtracting padding and borders + */ +, cssHeight: function ($E, outerHeight) { + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerHeight <= 0) return 0; + + if (!$.layout.browser.boxModel) return outerHeight; + + // strip border and padding from outerHeight to get CSS Height + var b = $.layout.borderWidth + , n = $.layout.cssNum + , H = outerHeight + - b($E, "Top") + - b($E, "Bottom") + - n($E, "paddingTop") + - n($E, "paddingBottom"); + + return max(0,H); + } + + /** + * Returns the 'current CSS numeric value' for a CSS property - 0 if property does not exist + * + * @see Called by many methods + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {string} prop The name of the CSS property, eg: top, width, etc. + * @param {boolean=} [allowAuto=false] true = return 'auto' if that is value; false = return 0 + * @return {(string|number)} Usually used to get an integer value for position (top, left) or size (height, width) + */ +, cssNum: function ($E, prop, allowAuto) { + if (!$E.jquery) $E = $($E); + var CSS = $.layout.showInvisibly($E) + , p = $.css($E[0], prop, true) + , v = allowAuto && p=="auto" ? p : (parseInt(p, 10) || 0); + $E.css( CSS ); // RESET + return v; + } + +, borderWidth: function (el, side) { + if (el.jquery) el = el[0]; + var b = "border"+ side.substr(0,1).toUpperCase() + side.substr(1); // left => Left + return $.css(el, b+"Style", true) === "none" ? 0 : (parseInt($.css(el, b+"Width", true), 10) || 0); + } + + /** + * Mouse-tracking utility - FUTURE REFERENCE + * + * init: if (!window.mouse) { + * window.mouse = { x: 0, y: 0 }; + * $(document).mousemove( $.layout.trackMouse ); + * } + * + * @param {Object} evt + * +, trackMouse: function (evt) { + window.mouse = { x: evt.clientX, y: evt.clientY }; + } + */ + + /** + * SUBROUTINE for preventPrematureSlideClose option + * + * @param {Object} evt + * @param {Object=} el + */ +, isMouseOverElem: function (evt, el) { + var + $E = $(el || this) + , d = $E.offset() + , T = d.top + , L = d.left + , R = L + $E.outerWidth() + , B = T + $E.outerHeight() + , x = evt.pageX // evt.clientX ? + , y = evt.pageY // evt.clientY ? + ; + // if X & Y are < 0, probably means is over an open SELECT + return ($.layout.browser.msie && x < 0 && y < 0) || ((x >= L && x <= R) && (y >= T && y <= B)); + } + + /** + * Message/Logging Utility + * + * @example $.layout.msg("My message"); // log text + * @example $.layout.msg("My message", true); // alert text + * @example $.layout.msg({ foo: "bar" }, "Title"); // log hash-data, with custom title + * @example $.layout.msg({ foo: "bar" }, true, "Title", { sort: false }); -OR- + * @example $.layout.msg({ foo: "bar" }, "Title", { sort: false, display: true }); // alert hash-data + * + * @param {(Object|string)} info String message OR Hash/Array + * @param {(Boolean|string|Object)=} [popup=false] True means alert-box - can be skipped + * @param {(Object|string)=} [debugTitle=""] Title for Hash data - can be skipped + * @param {Object=} [debugOpts] Extra options for debug output + */ +, msg: function (info, popup, debugTitle, debugOpts) { + if ($.isPlainObject(info) && window.debugData) { + if (typeof popup === "string") { + debugOpts = debugTitle; + debugTitle = popup; + } + else if (typeof debugTitle === "object") { + debugOpts = debugTitle; + debugTitle = null; + } + var t = debugTitle || "log( )" + , o = $.extend({ sort: false, returnHTML: false, display: false }, debugOpts); + if (popup === true || o.display) + debugData( info, t, o ); + else if (window.console) + console.log(debugData( info, t, o )); + } + else if (popup) + alert(info); + else if (window.console) + console.log(info); + else { + var id = "#layoutLogger" + , $l = $(id); + if (!$l.length) + $l = createLog(); + $l.children("ul").append('
  • '+ info.replace(/\/g,">") +'
  • '); + } + + function createLog () { + var pos = $.support.fixedPosition ? 'fixed' : 'absolute' + , $e = $('
    ' + + '
    ' + + 'XLayout console.log
    ' + + '
      ' + + '
      ' + ).appendTo("body"); + $e.css('left', $(window).width() - $e.outerWidth() - 5) + if ($.ui.draggable) $e.draggable({ handle: ':first-child' }); + return $e; + }; + } + +}; + +// DEFAULT OPTIONS +$.layout.defaults = { +/* + * LAYOUT & LAYOUT-CONTAINER OPTIONS + * - none of these options are applicable to individual panes + */ + name: "" // Not required, but useful for buttons and used for the state-cookie +, containerSelector: "" // ONLY used when specifying a childOptions - to find container-element that is NOT directly-nested +, containerClass: "ui-layout-container" // layout-container element +, scrollToBookmarkOnLoad: true // after creating a layout, scroll to bookmark in URL (.../page.htm#myBookmark) +, resizeWithWindow: true // bind thisLayout.resizeAll() to the window.resize event +, resizeWithWindowDelay: 200 // delay calling resizeAll because makes window resizing very jerky +, resizeWithWindowMaxDelay: 0 // 0 = none - force resize every XX ms while window is being resized +, onresizeall_start: null // CALLBACK when resizeAll() STARTS - NOT pane-specific +, onresizeall_end: null // CALLBACK when resizeAll() ENDS - NOT pane-specific +, onload_start: null // CALLBACK when Layout inits - after options initialized, but before elements +, onload_end: null // CALLBACK when Layout inits - after EVERYTHING has been initialized +, onunload_start: null // CALLBACK when Layout is destroyed OR onWindowUnload +, onunload_end: null // CALLBACK when Layout is destroyed OR onWindowUnload +, initPanes: true // false = DO NOT initialize the panes onLoad - will init later +, showErrorMessages: true // enables fatal error messages to warn developers of common errors +, showDebugMessages: false // display console-and-alert debug msgs - IF this Layout version _has_ debugging code! +// Changing this zIndex value will cause other zIndex values to automatically change +, zIndex: null // the PANE zIndex - resizers and masks will be +1 +// DO NOT CHANGE the zIndex values below unless you clearly understand their relationships +, zIndexes: { // set _default_ z-index values here... + pane_normal: 0 // normal z-index for panes + , content_mask: 1 // applied to overlays used to mask content INSIDE panes during resizing + , resizer_normal: 2 // normal z-index for resizer-bars + , pane_sliding: 100 // applied to *BOTH* the pane and its resizer when a pane is 'slid open' + , pane_animate: 1000 // applied to the pane when being animated - not applied to the resizer + , resizer_drag: 10000 // applied to the CLONED resizer-bar when being 'dragged' + } +, errors: { + pane: "pane" // description of "layout pane element" - used only in error messages + , selector: "selector" // description of "jQuery-selector" - used only in error messages + , addButtonError: "Error Adding Button \n\nInvalid " + , containerMissing: "UI Layout Initialization Error\n\nThe specified layout-container does not exist." + , centerPaneMissing: "UI Layout Initialization Error\n\nThe center-pane element does not exist.\n\nThe center-pane is a required element." + , noContainerHeight: "UI Layout Initialization Warning\n\nThe layout-container \"CONTAINER\" has no height.\n\nTherefore the layout is 0-height and hence 'invisible'!" + , callbackError: "UI Layout Callback Error\n\nThe EVENT callback is not a valid function." + } +/* + * PANE DEFAULT SETTINGS + * - settings under the 'panes' key become the default settings for *all panes* + * - ALL pane-options can also be set specifically for each panes, which will override these 'default values' + */ +, panes: { // default options for 'all panes' - will be overridden by 'per-pane settings' + applyDemoStyles: false // NOTE: renamed from applyDefaultStyles for clarity + , closable: true // pane can open & close + , resizable: true // when open, pane can be resized + , slidable: true // when closed, pane can 'slide open' over other panes - closes on mouse-out + , initClosed: false // true = init pane as 'closed' + , initHidden: false // true = init pane as 'hidden' - no resizer-bar/spacing + // SELECTORS + //, paneSelector: "" // MUST be pane-specific - jQuery selector for pane + , contentSelector: ".ui-layout-content" // INNER div/element to auto-size so only it scrolls, not the entire pane! + , contentIgnoreSelector: ".ui-layout-ignore" // element(s) to 'ignore' when measuring 'content' + , findNestedContent: false // true = $P.find(contentSelector), false = $P.children(contentSelector) + // GENERIC ROOT-CLASSES - for auto-generated classNames + , paneClass: "ui-layout-pane" // Layout Pane + , resizerClass: "ui-layout-resizer" // Resizer Bar + , togglerClass: "ui-layout-toggler" // Toggler Button + , buttonClass: "ui-layout-button" // CUSTOM Buttons - eg: '[ui-layout-button]-toggle/-open/-close/-pin' + // ELEMENT SIZE & SPACING + //, size: 100 // MUST be pane-specific -initial size of pane + , minSize: 0 // when manually resizing a pane + , maxSize: 0 // ditto, 0 = no limit + , spacing_open: 6 // space between pane and adjacent panes - when pane is 'open' + , spacing_closed: 6 // ditto - when pane is 'closed' + , togglerLength_open: 50 // Length = WIDTH of toggler button on north/south sides - HEIGHT on east/west sides + , togglerLength_closed: 50 // 100% OR -1 means 'full height/width of resizer bar' - 0 means 'hidden' + , togglerAlign_open: "center" // top/left, bottom/right, center, OR... + , togglerAlign_closed: "center" // 1 => nn = offset from top/left, -1 => -nn == offset from bottom/right + , togglerContent_open: "" // text or HTML to put INSIDE the toggler + , togglerContent_closed: "" // ditto + // RESIZING OPTIONS + , resizerDblClickToggle: true // + , autoResize: true // IF size is 'auto' or a percentage, then recalc 'pixel size' whenever the layout resizes + , autoReopen: true // IF a pane was auto-closed due to noRoom, reopen it when there is room? False = leave it closed + , resizerDragOpacity: 1 // option for ui.draggable + //, resizerCursor: "" // MUST be pane-specific - cursor when over resizer-bar + , maskContents: false // true = add DIV-mask over-or-inside this pane so can 'drag' over IFRAMES + , maskObjects: false // true = add IFRAME-mask over-or-inside this pane to cover objects/applets - content-mask will overlay this mask + , maskZindex: null // will override zIndexes.content_mask if specified - not applicable to iframe-panes + , resizingGrid: false // grid size that the resizers will snap-to during resizing, eg: [20,20] + , livePaneResizing: false // true = LIVE Resizing as resizer is dragged + , liveContentResizing: false // true = re-measure header/footer heights as resizer is dragged + , liveResizingTolerance: 1 // how many px change before pane resizes, to control performance + // SLIDING OPTIONS + , sliderCursor: "pointer" // cursor when resizer-bar will trigger 'sliding' + , slideTrigger_open: "click" // click, dblclick, mouseenter + , slideTrigger_close: "mouseleave"// click, mouseleave + , slideDelay_open: 300 // applies only for mouseenter event - 0 = instant open + , slideDelay_close: 300 // applies only for mouseleave event (300ms is the minimum!) + , hideTogglerOnSlide: false // when pane is slid-open, should the toggler show? + , preventQuickSlideClose: $.layout.browser.webkit // Chrome triggers slideClosed as it is opening + , preventPrematureSlideClose: false // handle incorrect mouseleave trigger, like when over a SELECT-list in IE + // PANE-SPECIFIC TIPS & MESSAGES + , tips: { + Open: "Open" // eg: "Open Pane" + , Close: "Close" + , Resize: "Resize" + , Slide: "Slide Open" + , Pin: "Pin" + , Unpin: "Un-Pin" + , noRoomToOpen: "Not enough room to show this panel." // alert if user tries to open a pane that cannot + , minSizeWarning: "Panel has reached its minimum size" // displays in browser statusbar + , maxSizeWarning: "Panel has reached its maximum size" // ditto + } + // HOT-KEYS & MISC + , showOverflowOnHover: false // will bind allowOverflow() utility to pane.onMouseOver + , enableCursorHotkey: true // enabled 'cursor' hotkeys + //, customHotkey: "" // MUST be pane-specific - EITHER a charCode OR a character + , customHotkeyModifier: "SHIFT" // either 'SHIFT', 'CTRL' or 'CTRL+SHIFT' - NOT 'ALT' + // PANE ANIMATION + // NOTE: fxSss_open, fxSss_close & fxSss_size options (eg: fxName_open) are auto-generated if not passed + , fxName: "slide" // ('none' or blank), slide, drop, scale -- only relevant to 'open' & 'close', NOT 'size' + , fxSpeed: null // slow, normal, fast, 200, nnn - if passed, will OVERRIDE fxSettings.duration + , fxSettings: {} // can be passed, eg: { easing: "easeOutBounce", duration: 1500 } + , fxOpacityFix: true // tries to fix opacity in IE to restore anti-aliasing after animation + , animatePaneSizing: false // true = animate resizing after dragging resizer-bar OR sizePane() is called + /* NOTE: Action-specific FX options are auto-generated from the options above if not specifically set: + fxName_open: "slide" // 'Open' pane animation + fnName_close: "slide" // 'Close' pane animation + fxName_size: "slide" // 'Size' pane animation - when animatePaneSizing = true + fxSpeed_open: null + fxSpeed_close: null + fxSpeed_size: null + fxSettings_open: {} + fxSettings_close: {} + fxSettings_size: {} + */ + // CHILD/NESTED LAYOUTS + , childOptions: null // Layout-options for nested/child layout - even {} is valid as options + , initChildLayout: true // true = child layout will be created as soon as _this_ layout completes initialization + , destroyChildLayout: true // true = destroy child-layout if this pane is destroyed + , resizeChildLayout: true // true = trigger child-layout.resizeAll() when this pane is resized + // EVENT TRIGGERING + , triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes + , triggerEventsDuringLiveResize: true // true = trigger onresize callback REPEATEDLY if livePaneResizing==true + // PANE CALLBACKS + , onshow_start: null // CALLBACK when pane STARTS to Show - BEFORE onopen/onhide_start + , onshow_end: null // CALLBACK when pane ENDS being Shown - AFTER onopen/onhide_end + , onhide_start: null // CALLBACK when pane STARTS to Close - BEFORE onclose_start + , onhide_end: null // CALLBACK when pane ENDS being Closed - AFTER onclose_end + , onopen_start: null // CALLBACK when pane STARTS to Open + , onopen_end: null // CALLBACK when pane ENDS being Opened + , onclose_start: null // CALLBACK when pane STARTS to Close + , onclose_end: null // CALLBACK when pane ENDS being Closed + , onresize_start: null // CALLBACK when pane STARTS being Resized ***FOR ANY REASON*** + , onresize_end: null // CALLBACK when pane ENDS being Resized ***FOR ANY REASON*** + , onsizecontent_start: null // CALLBACK when sizing of content-element STARTS + , onsizecontent_end: null // CALLBACK when sizing of content-element ENDS + , onswap_start: null // CALLBACK when pane STARTS to Swap + , onswap_end: null // CALLBACK when pane ENDS being Swapped + , ondrag_start: null // CALLBACK when pane STARTS being ***MANUALLY*** Resized + , ondrag_end: null // CALLBACK when pane ENDS being ***MANUALLY*** Resized + } +/* + * PANE-SPECIFIC SETTINGS + * - options listed below MUST be specified per-pane - they CANNOT be set under 'panes' + * - all options under the 'panes' key can also be set specifically for any pane + * - most options under the 'panes' key apply only to 'border-panes' - NOT the the center-pane + */ +, north: { + paneSelector: ".ui-layout-north" + , size: "auto" // eg: "auto", "30%", .30, 200 + , resizerCursor: "n-resize" // custom = url(myCursor.cur) + , customHotkey: "" // EITHER a charCode (43) OR a character ("o") + } +, south: { + paneSelector: ".ui-layout-south" + , size: "auto" + , resizerCursor: "s-resize" + , customHotkey: "" + } +, east: { + paneSelector: ".ui-layout-east" + , size: 200 + , resizerCursor: "e-resize" + , customHotkey: "" + } +, west: { + paneSelector: ".ui-layout-west" + , size: 200 + , resizerCursor: "w-resize" + , customHotkey: "" + } +, center: { + paneSelector: ".ui-layout-center" + , minWidth: 0 + , minHeight: 0 + } +}; + +$.layout.optionsMap = { + // layout/global options - NOT pane-options + layout: ("stateManagement,effects,zIndexes,errors," + + "name,zIndex,scrollToBookmarkOnLoad,showErrorMessages," + + "resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay," + + "onresizeall,onresizeall_start,onresizeall_end,onload,onunload").split(",") +// borderPanes: [ ALL options that are NOT specified as 'layout' ] + // default.panes options that apply to the center-pane (most options apply _only_ to border-panes) +, center: ("paneClass,contentSelector,contentIgnoreSelector,findNestedContent,applyDemoStyles,triggerEventsOnLoad," + + "showOverflowOnHover,maskContents,maskObjects,liveContentResizing," + + "childOptions,initChildLayout,resizeChildLayout,destroyChildLayout," + + "onresize,onresize_start,onresize_end,onsizecontent,onsizecontent_start,onsizecontent_end").split(",") + // options that MUST be specifically set 'per-pane' - CANNOT set in the panes (defaults) key +, noDefault: ("paneSelector,resizerCursor,customHotkey").split(",") +}; + +/** + * Processes options passed in converts flat-format data into subkey (JSON) format + * In flat-format, subkeys are _currently_ separated with 2 underscores, like north__optName + * Plugins may also call this method so they can transform their own data + * + * @param {!Object} hash Data/options passed by user - may be a single level or nested levels + * @return {Object} Returns hash of minWidth & minHeight + */ +$.layout.transformData = function (hash) { + var json = { panes: {}, center: {} } // init return object + , data, branch, optKey, keys, key, val, i, c; + + if (typeof hash !== "object") return json; // no options passed + + // convert all 'flat-keys' to 'sub-key' format + for (optKey in hash) { + branch = json; + data = $.layout.optionsMap.layout; + val = hash[ optKey ]; + keys = optKey.split("__"); // eg: west__size or north__fxSettings__duration + c = keys.length - 1; + // convert underscore-delimited to subkeys + for (i=0; i <= c; i++) { + key = keys[i]; + if (i === c) + branch[key] = val; + else if (!branch[key]) + branch[key] = {}; // create the subkey + // recurse to sub-key for next loop - if not done + branch = branch[key]; + } + } + + return json; +}; + +// INTERNAL CONFIG DATA - DO NOT CHANGE THIS! +$.layout.backwardCompatibility = { + // data used by renameOldOptions() + map: { + // OLD Option Name: NEW Option Name + applyDefaultStyles: "applyDemoStyles" + , resizeNestedLayout: "resizeChildLayout" + , resizeWhileDragging: "livePaneResizing" + , resizeContentWhileDragging: "liveContentResizing" + , triggerEventsWhileDragging: "triggerEventsDuringLiveResize" + , maskIframesOnResize: "maskContents" + , useStateCookie: "stateManagement.enabled" + , "cookie.autoLoad": "stateManagement.autoLoad" + , "cookie.autoSave": "stateManagement.autoSave" + , "cookie.keys": "stateManagement.stateKeys" + , "cookie.name": "stateManagement.cookie.name" + , "cookie.domain": "stateManagement.cookie.domain" + , "cookie.path": "stateManagement.cookie.path" + , "cookie.expires": "stateManagement.cookie.expires" + , "cookie.secure": "stateManagement.cookie.secure" + // OLD Language options + , noRoomToOpenTip: "tips.noRoomToOpen" + , togglerTip_open: "tips.Close" // open = Close + , togglerTip_closed: "tips.Open" // closed = Open + , resizerTip: "tips.Resize" + , sliderTip: "tips.Slide" + } + +/** +* @param {Object} opts +*/ +, renameOptions: function (opts) { + var map = $.layout.backwardCompatibility.map + , oldData, newData, value + ; + for (var itemPath in map) { + oldData = getBranch( itemPath ); + value = oldData.branch[ oldData.key ]; + if (value !== undefined) { + newData = getBranch( map[itemPath], true ); + newData.branch[ newData.key ] = value; + delete oldData.branch[ oldData.key ]; + } + } + + /** + * @param {string} path + * @param {boolean=} [create=false] Create path if does not exist + */ + function getBranch (path, create) { + var a = path.split(".") // split keys into array + , c = a.length - 1 + , D = { branch: opts, key: a[c] } // init branch at top & set key (last item) + , i = 0, k, undef; + for (; i 0) { + if (autoHide && $E.data('autoHidden') && $E.innerHeight() > 0) { + $E.show().data('autoHidden', false); + if (!browser.mozilla) // FireFox refreshes iframes - IE does not + // make hidden, then visible to 'refresh' display after animation + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + } + + /** + * @param {(string|!Object)} el + * @param {number=} outerHeight + * @param {boolean=} [autoHide=false] + */ +, setOuterHeight = function (el, outerHeight, autoHide) { + var $E = el, h; + if (isStr(el)) $E = $Ps[el]; // west + else if (!el.jquery) $E = $(el); + h = cssH($E, outerHeight); + $E.css({ height: h, visibility: "visible" }); // may have been 'hidden' by sizeContent + if (h > 0 && $E.innerWidth() > 0) { + if (autoHide && $E.data('autoHidden')) { + $E.show().data('autoHidden', false); + if (!browser.mozilla) // FireFox refreshes iframes - IE does not + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + } + + /** + * @param {(string|!Object)} el + * @param {number=} outerSize + * @param {boolean=} [autoHide=false] + */ +, setOuterSize = function (el, outerSize, autoHide) { + if (_c[pane].dir=="horz") // pane = north or south + setOuterHeight(el, outerSize, autoHide); + else // pane = east or west + setOuterWidth(el, outerSize, autoHide); + } + + + /** + * Converts any 'size' params to a pixel/integer size, if not already + * If 'auto' or a decimal/percentage is passed as 'size', a pixel-size is calculated + * + /** + * @param {string} pane + * @param {(string|number)=} size + * @param {string=} [dir] + * @return {number} + */ +, _parseSize = function (pane, size, dir) { + if (!dir) dir = _c[pane].dir; + + if (isStr(size) && size.match(/%/)) + size = (size === '100%') ? -1 : parseInt(size, 10) / 100; // convert % to decimal + + if (size === 0) + return 0; + else if (size >= 1) + return parseInt(size, 10); + + var o = options, avail = 0; + if (dir=="horz") // north or south or center.minHeight + avail = sC.innerHeight - ($Ps.north ? o.north.spacing_open : 0) - ($Ps.south ? o.south.spacing_open : 0); + else if (dir=="vert") // east or west or center.minWidth + avail = sC.innerWidth - ($Ps.west ? o.west.spacing_open : 0) - ($Ps.east ? o.east.spacing_open : 0); + + if (size === -1) // -1 == 100% + return avail; + else if (size > 0) // percentage, eg: .25 + return round(avail * size); + else if (pane=="center") + return 0; + else { // size < 0 || size=='auto' || size==Missing || size==Invalid + // auto-size the pane + var dim = (dir === "horz" ? "height" : "width") + , $P = $Ps[pane] + , $C = dim === 'height' ? $Cs[pane] : false + , vis = $.layout.showInvisibly($P) // show pane invisibly if hidden + , szP = $P.css(dim) // SAVE current pane size + , szC = $C ? $C.css(dim) : 0 // SAVE current content size + ; + $P.css(dim, "auto"); + if ($C) $C.css(dim, "auto"); + size = (dim === "height") ? $P.outerHeight() : $P.outerWidth(); // MEASURE + $P.css(dim, szP).css(vis); // RESET size & visibility + if ($C) $C.css(dim, szC); + return size; + } + } + + /** + * Calculates current 'size' (outer-width or outer-height) of a border-pane - optionally with 'pane-spacing' added + * + * @param {(string|!Object)} pane + * @param {boolean=} [inclSpace=false] + * @return {number} Returns EITHER Width for east/west panes OR Height for north/south panes + */ +, getPaneSize = function (pane, inclSpace) { + var + $P = $Ps[pane] + , o = options[pane] + , s = state[pane] + , oSp = (inclSpace ? o.spacing_open : 0) + , cSp = (inclSpace ? o.spacing_closed : 0) + ; + if (!$P || s.isHidden) + return 0; + else if (s.isClosed || (s.isSliding && inclSpace)) + return cSp; + else if (_c[pane].dir === "horz") + return $P.outerHeight() + oSp; + else // dir === "vert" + return $P.outerWidth() + oSp; + } + + /** + * Calculate min/max pane dimensions and limits for resizing + * + * @param {string} pane + * @param {boolean=} [slide=false] + */ +, setSizeLimits = function (pane, slide) { + if (!isInitialized()) return; + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , dir = c.dir + , side = c.side.toLowerCase() + , type = c.sizeType.toLowerCase() + , isSliding = (slide != undefined ? slide : s.isSliding) // only open() passes 'slide' param + , $P = $Ps[pane] + , paneSpacing = o.spacing_open + // measure the pane on the *opposite side* from this pane + , altPane = _c.oppositeEdge[pane] + , altS = state[altPane] + , $altP = $Ps[altPane] + , altPaneSize = (!$altP || altS.isVisible===false || altS.isSliding ? 0 : (dir=="horz" ? $altP.outerHeight() : $altP.outerWidth())) + , altPaneSpacing = ((!$altP || altS.isHidden ? 0 : options[altPane][ altS.isClosed !== false ? "spacing_closed" : "spacing_open" ]) || 0) + // limitSize prevents this pane from 'overlapping' opposite pane + , containerSize = (dir=="horz" ? sC.innerHeight : sC.innerWidth) + , minCenterDims = cssMinDims("center") + , minCenterSize = dir=="horz" ? max(options.center.minHeight, minCenterDims.minHeight) : max(options.center.minWidth, minCenterDims.minWidth) + // if pane is 'sliding', then ignore center and alt-pane sizes - because 'overlays' them + , limitSize = (containerSize - paneSpacing - (isSliding ? 0 : (_parseSize("center", minCenterSize, dir) + altPaneSize + altPaneSpacing))) + , minSize = s.minSize = max( _parseSize(pane, o.minSize), cssMinDims(pane).minSize ) + , maxSize = s.maxSize = min( (o.maxSize ? _parseSize(pane, o.maxSize) : 100000), limitSize ) + , r = s.resizerPosition = {} // used to set resizing limits + , top = sC.insetTop + , left = sC.insetLeft + , W = sC.innerWidth + , H = sC.innerHeight + , rW = o.spacing_open // subtract resizer-width to get top/left position for south/east + ; + switch (pane) { + case "north": r.min = top + minSize; + r.max = top + maxSize; + break; + case "west": r.min = left + minSize; + r.max = left + maxSize; + break; + case "south": r.min = top + H - maxSize - rW; + r.max = top + H - minSize - rW; + break; + case "east": r.min = left + W - maxSize - rW; + r.max = left + W - minSize - rW; + break; + }; + } + + /** + * Returns data for setting the size/position of center pane. Also used to set Height for east/west panes + * + * @return JSON Returns a hash of all dimensions: top, bottom, left, right, (outer) width and (outer) height + */ +, calcNewCenterPaneDims = function () { + var d = { + top: getPaneSize("north", true) // true = include 'spacing' value for pane + , bottom: getPaneSize("south", true) + , left: getPaneSize("west", true) + , right: getPaneSize("east", true) + , width: 0 + , height: 0 + }; + + // NOTE: sC = state.container + // calc center-pane outer dimensions + d.width = sC.innerWidth - d.left - d.right; // outerWidth + d.height = sC.innerHeight - d.bottom - d.top; // outerHeight + // add the 'container border/padding' to get final positions relative to the container + d.top += sC.insetTop; + d.bottom += sC.insetBottom; + d.left += sC.insetLeft; + d.right += sC.insetRight; + + return d; + } + + + /** + * @param {!Object} el + * @param {boolean=} [allStates=false] + */ +, getHoverClasses = function (el, allStates) { + var + $El = $(el) + , type = $El.data("layoutRole") + , pane = $El.data("layoutEdge") + , o = options[pane] + , root = o[type +"Class"] + , _pane = "-"+ pane // eg: "-west" + , _open = "-open" + , _closed = "-closed" + , _slide = "-sliding" + , _hover = "-hover " // NOTE the trailing space + , _state = $El.hasClass(root+_closed) ? _closed : _open + , _alt = _state === _closed ? _open : _closed + , classes = (root+_hover) + (root+_pane+_hover) + (root+_state+_hover) + (root+_pane+_state+_hover) + ; + if (allStates) // when 'removing' classes, also remove alternate-state classes + classes += (root+_alt+_hover) + (root+_pane+_alt+_hover); + + if (type=="resizer" && $El.hasClass(root+_slide)) + classes += (root+_slide+_hover) + (root+_pane+_slide+_hover); + + return $.trim(classes); + } +, addHover = function (evt, el) { + var $E = $(el || this); + if (evt && $E.data("layoutRole") === "toggler") + evt.stopPropagation(); // prevent triggering 'slide' on Resizer-bar + $E.addClass( getHoverClasses($E) ); + } +, removeHover = function (evt, el) { + var $E = $(el || this); + $E.removeClass( getHoverClasses($E, true) ); + } + +, onResizerEnter = function (evt) { // ALSO called by toggler.mouseenter + if ($.fn.disableSelection) + $("body").disableSelection(); + } +, onResizerLeave = function (evt, el) { + var + e = el || this // el is only passed when called by the timer + , pane = $(e).data("layoutEdge") + , name = pane +"ResizerLeave" + ; + timer.clear(pane+"_openSlider"); // cancel slideOpen timer, if set + timer.clear(name); // cancel enableSelection timer - may re/set below + // this method calls itself on a timer because it needs to allow + // enough time for dragging to kick-in and set the isResizing flag + // dragging has a 100ms delay set, so this delay must be >100 + if (!el) // 1st call - mouseleave event + timer.set(name, function(){ onResizerLeave(evt, e); }, 200); + // if user is resizing, then dragStop will enableSelection(), so can skip it here + else if (!state[pane].isResizing && $.fn.enableSelection) // 2nd call - by timer + $("body").enableSelection(); + } + +/* + * ########################### + * INITIALIZATION METHODS + * ########################### + */ + + /** + * Initialize the layout - called automatically whenever an instance of layout is created + * + * @see none - triggered onInit + * @return mixed true = fully initialized | false = panes not initialized (yet) | 'cancel' = abort + */ +, _create = function () { + // initialize config/options + initOptions(); + var o = options; + + // TEMP state so isInitialized returns true during init process + state.creatingLayout = true; + + // init plugins for this layout, if there are any (eg: stateManagement) + runPluginCallbacks( Instance, $.layout.onCreate ); + + // options & state have been initialized, so now run beforeLoad callback + // onload will CANCEL layout creation if it returns false + if (false === _runCallbacks("onload_start")) + return 'cancel'; + + // initialize the container element + _initContainer(); + + // bind hotkey function - keyDown - if required + initHotkeys(); + + // bind window.onunload + $(window).bind("unload."+ sID, unload); + + // init plugins for this layout, if there are any (eg: customButtons) + runPluginCallbacks( Instance, $.layout.onLoad ); + + // if layout elements are hidden, then layout WILL NOT complete initialization! + // initLayoutElements will set initialized=true and run the onload callback IF successful + if (o.initPanes) _initLayoutElements(); + + delete state.creatingLayout; + + return state.initialized; + } + + /** + * Initialize the layout IF not already + * + * @see All methods in Instance run this test + * @return boolean true = layoutElements have been initialized | false = panes are not initialized (yet) + */ +, isInitialized = function () { + if (state.initialized || state.creatingLayout) return true; // already initialized + else return _initLayoutElements(); // try to init panes NOW + } + + /** + * Initialize the layout - called automatically whenever an instance of layout is created + * + * @see _create() & isInitialized + * @return An object pointer to the instance created + */ +, _initLayoutElements = function (retry) { + // initialize config/options + var o = options; + + // CANNOT init panes inside a hidden container! + if (!$N.is(":visible")) { + // handle Chrome bug where popup window 'has no height' + // if layout is BODY element, try again in 50ms + // SEE: http://layout.jquery-dev.net/samples/test_popup_window.html + if ( !retry && browser.webkit && $N[0].tagName === "BODY" ) + setTimeout(function(){ _initLayoutElements(true); }, 50); + return false; + } + + // a center pane is required, so make sure it exists + if (!getPane("center").length) { + return _log( o.errors.centerPaneMissing ); + } + + // TEMP state so isInitialized returns true during init process + state.creatingLayout = true; + + // update Container dims + $.extend(sC, elDims( $N )); + + // initialize all layout elements + initPanes(); // size & position panes - calls initHandles() - which calls initResizable() + + if (o.scrollToBookmarkOnLoad) { + var l = self.location; + if (l.hash) l.replace( l.hash ); // scrollTo Bookmark + } + + // check to see if this layout 'nested' inside a pane + if (Instance.hasParentLayout) + o.resizeWithWindow = false; + // bind resizeAll() for 'this layout instance' to window.resize event + else if (o.resizeWithWindow) + $(window).bind("resize."+ sID, windowResize); + + delete state.creatingLayout; + state.initialized = true; + + // init plugins for this layout, if there are any + runPluginCallbacks( Instance, $.layout.onReady ); + + // now run the onload callback, if exists + _runCallbacks("onload_end"); + + return true; // elements initialized successfully + } + + /** + * Initialize nested layouts - called when _initLayoutElements completes + * + * NOT CURRENTLY USED + * + * @see _initLayoutElements + * @return An object pointer to the instance created + */ +, _initChildLayouts = function () { + $.each(_c.allPanes, function (idx, pane) { + if (options[pane].initChildLayout) + createChildLayout( pane ); + }); + } + + /** + * Initialize nested layouts for a specific pane - can optionally pass layout-options + * + * @see _initChildLayouts + * @param {string|Object} evt_or_pane The pane being opened, ie: north, south, east, or west + * @param {Object=} [opts] Layout-options - if passed, will OVERRRIDE options[pane].childOptions + * @return An object pointer to the layout instance created - or null + */ +, createChildLayout = function (evt_or_pane, opts) { + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + , C = children + ; + if ($P) { + var $C = $Cs[pane] + , o = opts || options[pane].childOptions + , d = "layout" + // determine which element is supposed to be the 'child container' + // if pane has a 'containerSelector' OR a 'content-div', use those instead of the pane + , $Cont = o.containerSelector ? $P.find( o.containerSelector ) : ($C || $P) + , containerFound = $Cont.length + // see if a child-layout ALREADY exists on this element + , child = containerFound ? (C[pane] = $Cont.data(d) || null) : null + ; + // if no layout exists, but childOptions are set, try to create the layout now + if (!child && containerFound && o) + child = C[pane] = $Cont.eq(0).layout(o) || null; + if (child) + child.hasParentLayout = true; // set parent-flag in child + } + Instance[pane].child = C[pane]; // ALWAYS set pane-object pointer, even if null + } + +, windowResize = function () { + var delay = Number(options.resizeWithWindowDelay); + if (delay < 10) delay = 100; // MUST have a delay! + // resizing uses a delay-loop because the resize event fires repeatly - except in FF, but delay anyway + timer.clear("winResize"); // if already running + timer.set("winResize", function(){ + timer.clear("winResize"); + timer.clear("winResizeRepeater"); + var dims = elDims( $N ); + // only trigger resizeAll() if container has changed size + if (dims.innerWidth !== sC.innerWidth || dims.innerHeight !== sC.innerHeight) + resizeAll(); + }, delay); + // ALSO set fixed-delay timer, if not already running + if (!timer.data["winResizeRepeater"]) setWindowResizeRepeater(); + } + +, setWindowResizeRepeater = function () { + var delay = Number(options.resizeWithWindowMaxDelay); + if (delay > 0) + timer.set("winResizeRepeater", function(){ setWindowResizeRepeater(); resizeAll(); }, delay); + } + +, unload = function () { + var o = options; + + _runCallbacks("onunload_start"); + + // trigger plugin callabacks for this layout (eg: stateManagement) + runPluginCallbacks( Instance, $.layout.onUnload ); + + _runCallbacks("onunload_end"); + } + + /** + * Validate and initialize container CSS and events + * + * @see _create() + */ +, _initContainer = function () { + var + N = $N[0] + , tag = sC.tagName = N.tagName + , id = sC.id = N.id + , cls = sC.className = N.className + , o = options + , name = o.name + , fullPage= (tag === "BODY") + , props = "overflow,position,margin,padding,border" + , css = "layoutCSS" + , CSS = {} + , hid = "hidden" // used A LOT! + // see if this container is a 'pane' inside an outer-layout + , parent = $N.data("parentLayout") // parent-layout Instance + , pane = $N.data("layoutEdge") // pane-name in parent-layout + , isChild = parent && pane + ; + // sC -> state.container + sC.selector = $N.selector.split(".slice")[0]; + sC.ref = (o.name ? o.name +' layout / ' : '') + tag + (id ? "#"+id : cls ? '.['+cls+']' : ''); // used in messages + + $N .data({ + layout: Instance + , layoutContainer: sID // FLAG to indicate this is a layout-container - contains unique internal ID + }) + .addClass(o.containerClass) + ; + var layoutMethods = { + destroy: '' + , initPanes: '' + , resizeAll: 'resizeAll' + , resize: 'resizeAll' + }; + // loop hash and bind all methods - include layoutID namespacing + for (name in layoutMethods) { + $N.bind("layout"+ name.toLowerCase() +"."+ sID, Instance[ layoutMethods[name] || name ]); + } + + // if this container is another layout's 'pane', then set child/parent pointers + if (isChild) { + // update parent flag + Instance.hasParentLayout = true; + // set pointers to THIS child-layout (Instance) in parent-layout + // NOTE: parent.PANE.child is an ALIAS to parent.children.PANE + parent[pane].child = parent.children[pane] = $N.data("layout"); + } + + // SAVE original container CSS for use in destroy() + if (!$N.data(css)) { + // handle props like overflow different for BODY & HTML - has 'system default' values + if (fullPage) { + CSS = $.extend( elCSS($N, props), { + height: $N.css("height") + , overflow: $N.css("overflow") + , overflowX: $N.css("overflowX") + , overflowY: $N.css("overflowY") + }); + // ALSO SAVE CSS + var $H = $("html"); + $H.data(css, { + height: "auto" // FF would return a fixed px-size! + , overflow: $H.css("overflow") + , overflowX: $H.css("overflowX") + , overflowY: $H.css("overflowY") + }); + } + else // handle props normally for non-body elements + CSS = elCSS($N, props+",top,bottom,left,right,width,height,overflow,overflowX,overflowY"); + + $N.data(css, CSS); + } + + try { // format html/body if this is a full page layout + if (fullPage) { + $("html").css({ + height: "100%" + , overflow: hid + , overflowX: hid + , overflowY: hid + }); + $("body").css({ + position: "relative" + , height: "100%" + , overflow: hid + , overflowX: hid + , overflowY: hid + , margin: 0 + , padding: 0 // TODO: test whether body-padding could be handled? + , border: "none" // a body-border creates problems because it cannot be measured! + }); + + // set current layout-container dimensions + $.extend(sC, elDims( $N )); + } + else { // set required CSS for overflow and position + // ENSURE container will not 'scroll' + CSS = { overflow: hid, overflowX: hid, overflowY: hid } + var + p = $N.css("position") + , h = $N.css("height") + ; + // if this is a NESTED layout, then container/outer-pane ALREADY has position and height + if (!isChild) { + if (!p || !p.match(/fixed|absolute|relative/)) + CSS.position = "relative"; // container MUST have a 'position' + /* + if (!h || h=="auto") + CSS.height = "100%"; // container MUST have a 'height' + */ + } + $N.css( CSS ); + + // set current layout-container dimensions + if ( $N.is(":visible") ) { + $.extend(sC, elDims( $N )); + if (sC.innerHeight < 1) + _log( o.errors.noContainerHeight.replace(/CONTAINER/, sC.ref) ); + } + } + } catch (ex) {} + } + + /** + * Bind layout hotkeys - if options enabled + * + * @see _create() and addPane() + * @param {string=} [panes=""] The edge(s) to process + */ +, initHotkeys = function (panes) { + panes = panes ? panes.split(",") : _c.borderPanes; + // bind keyDown to capture hotkeys, if option enabled for ANY pane + $.each(panes, function (i, pane) { + var o = options[pane]; + if (o.enableCursorHotkey || o.customHotkey) { + $(document).bind("keydown."+ sID, keyDown); // only need to bind this ONCE + return false; // BREAK - binding was done + } + }); + } + + /** + * Build final OPTIONS data + * + * @see _create() + */ +, initOptions = function () { + var data, d, pane, key, val, i, c, o; + + // reprocess user's layout-options to have correct options sub-key structure + opts = $.layout.transformData( opts ); // panes = default subkey + + // auto-rename old options for backward compatibility + opts = $.layout.backwardCompatibility.renameAllOptions( opts ); + + // if user-options has 'panes' key (pane-defaults), clean it... + if (!$.isEmptyObject(opts.panes)) { + // REMOVE any pane-defaults that MUST be set per-pane + data = $.layout.optionsMap.noDefault; + for (i=0, c=data.length; i 0) { + z.pane_normal = zo; + z.content_mask = max(zo+1, z.content_mask); // MIN = +1 + z.resizer_normal = max(zo+2, z.resizer_normal); // MIN = +2 + } + + // DELETE 'panes' key now that we are done - values were copied to EACH pane + delete options.panes; + + + function createFxOptions ( pane ) { + var o = options[pane] + , d = options.panes; + // ensure fxSettings key to avoid errors + if (!o.fxSettings) o.fxSettings = {}; + if (!d.fxSettings) d.fxSettings = {}; + + $.each(["_open","_close","_size"], function (i,n) { + var + sName = "fxName"+ n + , sSpeed = "fxSpeed"+ n + , sSettings = "fxSettings"+ n + // recalculate fxName according to specificity rules + , fxName = o[sName] = + o[sName] // options.west.fxName_open + || d[sName] // options.panes.fxName_open + || o.fxName // options.west.fxName + || d.fxName // options.panes.fxName + || "none" // MEANS $.layout.defaults.panes.fxName == "" || false || null || 0 + ; + // validate fxName to ensure is valid effect - MUST have effect-config data in options.effects + if (fxName === "none" || !$.effects || !$.effects[fxName] || !options.effects[fxName]) + fxName = o[sName] = "none"; // effect not loaded OR unrecognized fxName + + // set vars for effects subkeys to simplify logic + var fx = options.effects[fxName] || {} // effects.slide + , fx_all = fx.all || null // effects.slide.all + , fx_pane = fx[pane] || null // effects.slide.west + ; + // create fxSpeed[_open|_close|_size] + o[sSpeed] = + o[sSpeed] // options.west.fxSpeed_open + || d[sSpeed] // options.west.fxSpeed_open + || o.fxSpeed // options.west.fxSpeed + || d.fxSpeed // options.panes.fxSpeed + || null // DEFAULT - let fxSetting.duration control speed + ; + // create fxSettings[_open|_close|_size] + o[sSettings] = $.extend( + true + , {} + , fx_all // effects.slide.all + , fx_pane // effects.slide.west + , d.fxSettings // options.panes.fxSettings + , o.fxSettings // options.west.fxSettings + , d[sSettings] // options.panes.fxSettings_open + , o[sSettings] // options.west.fxSettings_open + ); + }); + + // DONE creating action-specific-settings for this pane, + // so DELETE generic options - are no longer meaningful + delete o.fxName; + delete o.fxSpeed; + delete o.fxSettings; + } + } + + /** + * Initialize module objects, styling, size and position for all panes + * + * @see _initElements() + * @param {string} pane The pane to process + */ +, getPane = function (pane) { + var sel = options[pane].paneSelector + if (sel.substr(0,1)==="#") // ID selector + // NOTE: elements selected 'by ID' DO NOT have to be 'children' + return $N.find(sel).eq(0); + else { // class or other selector + var $P = $N.children(sel).eq(0); + // look for the pane nested inside a 'form' element + return $P.length ? $P : $N.children("form:first").children(sel).eq(0); + } + } + +, initPanes = function (evt) { + // stopPropagation if called by trigger("layoutinitpanes") - use evtPane utility + evtPane(evt); + + // NOTE: do north & south FIRST so we can measure their height - do center LAST + $.each(_c.allPanes, function (idx, pane) { + addPane( pane, true ); + }); + + // init the pane-handles NOW in case we have to hide or close the pane below + initHandles(); + + // now that all panes have been initialized and initially-sized, + // make sure there is really enough space available for each pane + $.each(_c.borderPanes, function (i, pane) { + if ($Ps[pane] && state[pane].isVisible) { // pane is OPEN + setSizeLimits(pane); + makePaneFit(pane); // pane may be Closed, Hidden or Resized by makePaneFit() + } + }); + // size center-pane AGAIN in case we 'closed' a border-pane in loop above + sizeMidPanes("center"); + + // Chrome/Webkit sometimes fires callbacks BEFORE it completes resizing! + // Before RC30.3, there was a 10ms delay here, but that caused layout + // to load asynchrously, which is BAD, so try skipping delay for now + + // process pane contents and callbacks, and init/resize child-layout if exists + $.each(_c.allPanes, function (i, pane) { + var o = options[pane]; + if ($Ps[pane]) { + if (state[pane].isVisible) { // pane is OPEN + sizeContent(pane); + // trigger pane.onResize if triggerEventsOnLoad = true + if (o.triggerEventsOnLoad) + _runCallbacks("onresize_end", pane); + else // automatic if onresize called, otherwise call it specifically + // resize child - IF inner-layout already exists (created before this layout) + resizeChildLayout(pane); + } + // init childLayout - even if pane is not visible + if (o.initChildLayout && o.childOptions) + createChildLayout(pane); + } + }); + } + + /** + * Add a pane to the layout - subroutine of initPanes() + * + * @see initPanes() + * @param {string} pane The pane to process + * @param {boolean=} [force=false] Size content after init + */ +, addPane = function (pane, force) { + if (!force && !isInitialized()) return; + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , fx = s.fx + , dir = c.dir + , spacing = o.spacing_open || 0 + , isCenter = (pane === "center") + , CSS = {} + , $P = $Ps[pane] + , size, minSize, maxSize + ; + // if pane-pointer already exists, remove the old one first + if ($P) + removePane( pane, false, true, false ); + else + $Cs[pane] = false; // init + + $P = $Ps[pane] = getPane(pane); + if (!$P.length) { + $Ps[pane] = false; // logic + return; + } + + // SAVE original Pane CSS + if (!$P.data("layoutCSS")) { + var props = "position,top,left,bottom,right,width,height,overflow,zIndex,display,backgroundColor,padding,margin,border"; + $P.data("layoutCSS", elCSS($P, props)); + } + + // create alias for pane data in Instance - initHandles will add more + Instance[pane] = { name: pane, pane: $Ps[pane], content: $Cs[pane], options: options[pane], state: state[pane], child: children[pane] }; + + // add classes, attributes & events + $P .data({ + parentLayout: Instance // pointer to Layout Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "pane" + }) + .css(c.cssReq).css("zIndex", options.zIndexes.pane_normal) + .css(o.applyDemoStyles ? c.cssDemo : {}) // demo styles + .addClass( o.paneClass +" "+ o.paneClass+"-"+pane ) // default = "ui-layout-pane ui-layout-pane-west" - may be a dupe of 'paneSelector' + .bind("mouseenter."+ sID, addHover ) + .bind("mouseleave."+ sID, removeHover ) + ; + var paneMethods = { + hide: '' + , show: '' + , toggle: '' + , close: '' + , open: '' + , slideOpen: '' + , slideClose: '' + , slideToggle: '' + , size: 'sizePane' + , sizePane: 'sizePane' + , sizeContent: '' + , sizeHandles: '' + , enableClosable: '' + , disableClosable: '' + , enableSlideable: '' + , disableSlideable: '' + , enableResizable: '' + , disableResizable: '' + , swapPanes: 'swapPanes' + , swap: 'swapPanes' + , move: 'swapPanes' + , removePane: 'removePane' + , remove: 'removePane' + , createChildLayout: '' + , resizeChildLayout: '' + , resizeAll: 'resizeAll' + , resizeLayout: 'resizeAll' + } + , name; + // loop hash and bind all methods - include layoutID namespacing + for (name in paneMethods) { + $P.bind("layoutpane"+ name.toLowerCase() +"."+ sID, Instance[ paneMethods[name] || name ]); + } + + // see if this pane has a 'scrolling-content element' + initContent(pane, false); // false = do NOT sizeContent() - called later + + if (!isCenter) { + // call _parseSize AFTER applying pane classes & styles - but before making visible (if hidden) + // if o.size is auto or not valid, then MEASURE the pane and use that as its 'size' + size = s.size = _parseSize(pane, o.size); + minSize = _parseSize(pane,o.minSize) || 1; + maxSize = _parseSize(pane,o.maxSize) || 100000; + if (size > 0) size = max(min(size, maxSize), minSize); + + // state for border-panes + s.isClosed = false; // true = pane is closed + s.isSliding = false; // true = pane is currently open by 'sliding' over adjacent panes + s.isResizing= false; // true = pane is in process of being resized + s.isHidden = false; // true = pane is hidden - no spacing, resizer or toggler is visible! + + // array for 'pin buttons' whose classNames are auto-updated on pane-open/-close + if (!s.pins) s.pins = []; + } + // states common to ALL panes + s.tagName = $P[0].tagName; + s.edge = pane; // useful if pane is (or about to be) 'swapped' - easy find out where it is (or is going) + s.noRoom = false; // true = pane 'automatically' hidden due to insufficient room - will unhide automatically + s.isVisible = true; // false = pane is invisible - closed OR hidden - simplify logic + + // set css-position to account for container borders & padding + switch (pane) { + case "north": CSS.top = sC.insetTop; + CSS.left = sC.insetLeft; + CSS.right = sC.insetRight; + break; + case "south": CSS.bottom = sC.insetBottom; + CSS.left = sC.insetLeft; + CSS.right = sC.insetRight; + break; + case "west": CSS.left = sC.insetLeft; // top, bottom & height set by sizeMidPanes() + break; + case "east": CSS.right = sC.insetRight; // ditto + break; + case "center": // top, left, width & height set by sizeMidPanes() + } + + if (dir === "horz") // north or south pane + CSS.height = cssH($P, size); + else if (dir === "vert") // east or west pane + CSS.width = cssW($P, size); + //else if (isCenter) {} + + $P.css(CSS); // apply size -- top, bottom & height will be set by sizeMidPanes + if (dir != "horz") sizeMidPanes(pane, true); // true = skipCallback + + // close or hide the pane if specified in settings + if (o.initClosed && o.closable && !o.initHidden) + close(pane, true, true); // true, true = force, noAnimation + else if (o.initHidden || o.initClosed) + hide(pane); // will be completely invisible - no resizer or spacing + else if (!s.noRoom) + // make the pane visible - in case was initially hidden + $P.css("display","block"); + // ELSE setAsOpen() - called later by initHandles() + + // RESET visibility now - pane will appear IF display:block + $P.css("visibility","visible"); + + // check option for auto-handling of pop-ups & drop-downs + if (o.showOverflowOnHover) + $P.hover( allowOverflow, resetOverflow ); + + // if manually adding a pane AFTER layout initialization, then... + if (state.initialized) { + initHandles( pane ); + initHotkeys( pane ); + resizeAll(); // will sizeContent if pane is visible + if (s.isVisible) { // pane is OPEN + if (o.triggerEventsOnLoad) + _runCallbacks("onresize_end", pane); + else // automatic if onresize called, otherwise call it specifically + // resize child - IF inner-layout already exists (created before this layout) + resizeChildLayout(pane); // a previously existing childLayout + } + if (o.initChildLayout && o.childOptions) + createChildLayout(pane); + } + } + + /** + * Initialize module objects, styling, size and position for all resize bars and toggler buttons + * + * @see _create() + * @param {string=} [panes=""] The edge(s) to process + */ +, initHandles = function (panes) { + panes = panes ? panes.split(",") : _c.borderPanes; + + // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV + $.each(panes, function (i, pane) { + var $P = $Ps[pane]; + $Rs[pane] = false; // INIT + $Ts[pane] = false; + if (!$P) return; // pane does not exist - skip + + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , paneId = o.paneSelector.substr(0,1) === "#" ? o.paneSelector.substr(1) : "" + , rClass = o.resizerClass + , tClass = o.togglerClass + , side = c.side.toLowerCase() + , spacing = (s.isVisible ? o.spacing_open : o.spacing_closed) + , _pane = "-"+ pane // used for classNames + , _state = (s.isVisible ? "-open" : "-closed") // used for classNames + , I = Instance[pane] + // INIT RESIZER BAR + , $R = I.resizer = $Rs[pane] = $("
      ") + // INIT TOGGLER BUTTON + , $T = I.toggler = (o.closable ? $Ts[pane] = $("
      ") : false) + ; + + //if (s.isVisible && o.resizable) ... handled by initResizable + if (!s.isVisible && o.slidable) + $R.attr("title", o.tips.Slide).css("cursor", o.sliderCursor); + + $R // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "paneLeft-resizer" + .attr("id", paneId ? paneId +"-resizer" : "" ) + .data({ + parentLayout: Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "resizer" + }) + .css(_c.resizers.cssReq).css("zIndex", options.zIndexes.resizer_normal) + .css(o.applyDemoStyles ? _c.resizers.cssDemo : {}) // add demo styles + .addClass(rClass +" "+ rClass+_pane) + .hover(addHover, removeHover) // ALWAYS add hover-classes, even if resizing is not enabled - handle with CSS instead + .hover(onResizerEnter, onResizerLeave) // ALWAYS NEED resizer.mouseleave to balance toggler.mouseenter + .appendTo($N) // append DIV to container + ; + + if ($T) { + $T // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "#paneLeft-toggler" + .attr("id", paneId ? paneId +"-toggler" : "" ) + .data({ + parentLayout: Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "toggler" + }) + .css(_c.togglers.cssReq) // add base/required styles + .css(o.applyDemoStyles ? _c.togglers.cssDemo : {}) // add demo styles + .addClass(tClass +" "+ tClass+_pane) + .hover(addHover, removeHover) // ALWAYS add hover-classes, even if toggling is not enabled - handle with CSS instead + .bind("mouseenter", onResizerEnter) // NEED toggler.mouseenter because mouseenter MAY NOT fire on resizer + .appendTo($R) // append SPAN to resizer DIV + ; + // ADD INNER-SPANS TO TOGGLER + if (o.togglerContent_open) // ui-layout-open + $(""+ o.togglerContent_open +"") + .data({ + layoutEdge: pane + , layoutRole: "togglerContent" + }) + .data("layoutRole", "togglerContent") + .data("layoutEdge", pane) + .addClass("content content-open") + .css("display","none") + .appendTo( $T ) + //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-open instead! + ; + if (o.togglerContent_closed) // ui-layout-closed + $(""+ o.togglerContent_closed +"") + .data({ + layoutEdge: pane + , layoutRole: "togglerContent" + }) + .addClass("content content-closed") + .css("display","none") + .appendTo( $T ) + //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-closed instead! + ; + // ADD TOGGLER.click/.hover + enableClosable(pane); + } + + // add Draggable events + initResizable(pane); + + // ADD CLASSNAMES & SLIDE-BINDINGS - eg: class="resizer resizer-west resizer-open" + if (s.isVisible) + setAsOpen(pane); // onOpen will be called, but NOT onResize + else { + setAsClosed(pane); // onClose will be called + bindStartSlidingEvent(pane, true); // will enable events IF option is set + } + + }); + + // SET ALL HANDLE DIMENSIONS + sizeHandles(); + } + + + /** + * Initialize scrolling ui-layout-content div - if exists + * + * @see initPane() - or externally after an Ajax injection + * @param {string} [pane] The pane to process + * @param {boolean=} [resize=true] Size content after init + */ +, initContent = function (pane, resize) { + if (!isInitialized()) return; + var + o = options[pane] + , sel = o.contentSelector + , I = Instance[pane] + , $P = $Ps[pane] + , $C + ; + if (sel) $C = I.content = $Cs[pane] = (o.findNestedContent) + ? $P.find(sel).eq(0) // match 1-element only + : $P.children(sel).eq(0) + ; + if ($C && $C.length) { + $C.data("layoutRole", "content"); + // SAVE original Pane CSS + if (!$C.data("layoutCSS")) + $C.data("layoutCSS", elCSS($C, "height")); + $C.css( _c.content.cssReq ); + if (o.applyDemoStyles) { + $C.css( _c.content.cssDemo ); // add padding & overflow: auto to content-div + $P.css( _c.content.cssDemoPane ); // REMOVE padding/scrolling from pane + } + state[pane].content = {}; // init content state + if (resize !== false) sizeContent(pane); + // sizeContent() is called AFTER init of all elements + } + else + I.content = $Cs[pane] = false; + } + + + /** + * Add resize-bars to all panes that specify it in options + * -dependancy: $.fn.resizable - will skip if not found + * + * @see _create() + * @param {string=} [panes=""] The edge(s) to process + */ +, initResizable = function (panes) { + var draggingAvailable = $.layout.plugins.draggable + , side // set in start() + ; + panes = panes ? panes.split(",") : _c.borderPanes; + + $.each(panes, function (idx, pane) { + var o = options[pane]; + if (!draggingAvailable || !$Ps[pane] || !o.resizable) { + o.resizable = false; + return true; // skip to next + } + + var s = state[pane] + , z = options.zIndexes + , c = _c[pane] + , side = c.dir=="horz" ? "top" : "left" + , opEdge = _c.oppositeEdge[pane] + , masks = pane +",center,"+ opEdge + (c.dir=="horz" ? ",west,east" : "") + , $P = $Ps[pane] + , $R = $Rs[pane] + , base = o.resizerClass + , lastPos = 0 // used when live-resizing + , r, live // set in start because may change + // 'drag' classes are applied to the ORIGINAL resizer-bar while dragging is in process + , resizerClass = base+"-drag" // resizer-drag + , resizerPaneClass = base+"-"+pane+"-drag" // resizer-north-drag + // 'helper' class is applied to the CLONED resizer-bar while it is being dragged + , helperClass = base+"-dragging" // resizer-dragging + , helperPaneClass = base+"-"+pane+"-dragging" // resizer-north-dragging + , helperLimitClass = base+"-dragging-limit" // resizer-drag + , helperPaneLimitClass = base+"-"+pane+"-dragging-limit" // resizer-north-drag + , helperClassesSet = false // logic var + ; + + if (!s.isClosed) + $R.attr("title", o.tips.Resize) + .css("cursor", o.resizerCursor); // n-resize, s-resize, etc + + $R.draggable({ + containment: $N[0] // limit resizing to layout container + , axis: (c.dir=="horz" ? "y" : "x") // limit resizing to horz or vert axis + , delay: 0 + , distance: 1 + , grid: o.resizingGrid + // basic format for helper - style it using class: .ui-draggable-dragging + , helper: "clone" + , opacity: o.resizerDragOpacity + , addClasses: false // avoid ui-state-disabled class when disabled + //, iframeFix: o.draggableIframeFix // TODO: consider using when bug is fixed + , zIndex: z.resizer_drag + + , start: function (e, ui) { + // REFRESH options & state pointers in case we used swapPanes + o = options[pane]; + s = state[pane]; + // re-read options + live = o.livePaneResizing; + + // ondrag_start callback - will CANCEL hide if returns false + // TODO: dragging CANNOT be cancelled like this, so see if there is a way? + if (false === _runCallbacks("ondrag_start", pane)) return false; + + s.isResizing = true; // prevent pane from closing while resizing + timer.clear(pane+"_closeSlider"); // just in case already triggered + + // SET RESIZER LIMITS - used in drag() + setSizeLimits(pane); // update pane/resizer state + r = s.resizerPosition; + lastPos = ui.position[ side ] + + $R.addClass( resizerClass +" "+ resizerPaneClass ); // add drag classes + helperClassesSet = false; // reset logic var - see drag() + + // DISABLE TEXT SELECTION (probably already done by resizer.mouseOver) + $('body').disableSelection(); + + // MASK PANES CONTAINING IFRAMES, APPLETS OR OTHER TROUBLESOME ELEMENTS + showMasks( masks ); + } + + , drag: function (e, ui) { + if (!helperClassesSet) { // can only add classes after clone has been added to the DOM + //$(".ui-draggable-dragging") + ui.helper + .addClass( helperClass +" "+ helperPaneClass ) // add helper classes + .css({ right: "auto", bottom: "auto" }) // fix dir="rtl" issue + .children().css("visibility","hidden") // hide toggler inside dragged resizer-bar + ; + helperClassesSet = true; + // draggable bug!? RE-SET zIndex to prevent E/W resize-bar showing through N/S pane! + if (s.isSliding) $Ps[pane].css("zIndex", z.pane_sliding); + } + // CONTAIN RESIZER-BAR TO RESIZING LIMITS + var limit = 0; + if (ui.position[side] < r.min) { + ui.position[side] = r.min; + limit = -1; + } + else if (ui.position[side] > r.max) { + ui.position[side] = r.max; + limit = 1; + } + // ADD/REMOVE dragging-limit CLASS + if (limit) { + ui.helper.addClass( helperLimitClass +" "+ helperPaneLimitClass ); // at dragging-limit + window.defaultStatus = (limit>0 && pane.match(/(north|west)/)) || (limit<0 && pane.match(/(south|east)/)) ? o.tips.maxSizeWarning : o.tips.minSizeWarning; + } + else { + ui.helper.removeClass( helperLimitClass +" "+ helperPaneLimitClass ); // not at dragging-limit + window.defaultStatus = ""; + } + // DYNAMICALLY RESIZE PANES IF OPTION ENABLED + // won't trigger unless resizer has actually moved! + if (live && Math.abs(ui.position[side] - lastPos) >= o.liveResizingTolerance) { + lastPos = ui.position[side]; + resizePanes(e, ui, pane) + } + } + + , stop: function (e, ui) { + $('body').enableSelection(); // RE-ENABLE TEXT SELECTION + window.defaultStatus = ""; // clear 'resizing limit' message from statusbar + $R.removeClass( resizerClass +" "+ resizerPaneClass ); // remove drag classes from Resizer + s.isResizing = false; + resizePanes(e, ui, pane, true, masks); // true = resizingDone + } + + }); + }); + + /** + * resizePanes + * + * Sub-routine called from stop() - and drag() if livePaneResizing + * + * @param {!Object} evt + * @param {!Object} ui + * @param {string} pane + * @param {boolean=} [resizingDone=false] + */ + var resizePanes = function (evt, ui, pane, resizingDone, masks) { + var dragPos = ui.position + , c = _c[pane] + , o = options[pane] + , s = state[pane] + , resizerPos + ; + switch (pane) { + case "north": resizerPos = dragPos.top; break; + case "west": resizerPos = dragPos.left; break; + case "south": resizerPos = sC.offsetHeight - dragPos.top - o.spacing_open; break; + case "east": resizerPos = sC.offsetWidth - dragPos.left - o.spacing_open; break; + }; + // remove container margin from resizer position to get the pane size + var newSize = resizerPos - sC["inset"+ c.side]; + + // Disable OR Resize Mask(s) created in drag.start + if (!resizingDone) { + // ensure we meet liveResizingTolerance criteria + if (Math.abs(newSize - s.size) < o.liveResizingTolerance) + return; // SKIP resize this time + // resize the pane + manualSizePane(pane, newSize, false, true); // true = noAnimation + sizeMasks(); // resize all visible masks + } + else { // resizingDone + // ondrag_end callback + if (false !== _runCallbacks("ondrag_end", pane)) + manualSizePane(pane, newSize, false, true); // true = noAnimation + hideMasks(); // hide all masks, which include panes with 'content/iframe-masks' + if (s.isSliding && masks) // RE-SHOW only 'object-masks' so objects won't show through sliding pane + showMasks( masks, true ); // true = onlyForObjects + } + }; + } + + /** + * sizeMask + * + * Needed to overlay a DIV over an IFRAME-pane because mask CANNOT be *inside* the pane + * Called when mask created, and during livePaneResizing + */ +, sizeMask = function () { + var $M = $(this) + , pane = $M.data("layoutMask") // eg: "west" + , s = state[pane] + ; + // only masks over an IFRAME-pane need manual resizing + if (s.tagName == "IFRAME" && s.isVisible) // no need to mask closed/hidden panes + $M.css({ + top: s.offsetTop + , left: s.offsetLeft + , width: s.outerWidth + , height: s.outerHeight + }); + /* ALT Method... + var $P = $Ps[pane]; + $M.css( $P.position() ).css({ width: $P[0].offsetWidth, height: $P[0].offsetHeight }); + */ + } +, sizeMasks = function () { + $Ms.each( sizeMask ); // resize all 'visible' masks + } + +, showMasks = function (panes, onlyForObjects) { + var a = panes ? panes.split(",") : $.layout.config.allPanes + , z = options.zIndexes + , o, s; + $.each(a, function(i,p){ + s = state[p]; + o = options[p]; + if (s.isVisible && ( (!onlyForObjects && o.maskContents) || o.maskObjects )) { + getMasks(p).each(function(){ + sizeMask.call(this); + this.style.zIndex = s.isSliding ? z.pane_sliding+1 : z.pane_normal+1 + this.style.display = "block"; + }); + } + }); + } + +, hideMasks = function () { + // ensure no pane is resizing - could be a timing issue + var skip; + $.each( $.layout.config.borderPanes, function(i,p){ + if (state[p].isResizing) { + skip = true; + return false; // BREAK + } + }); + if (!skip) + $Ms.hide(); // hide ALL masks + } + +, getMasks = function (pane) { + var $Masks = $([]) + , $M, i = 0, c = $Ms.length + ; + for (; i CSS + if (sC.tagName === "BODY" && ($N = $("html")).data(css)) // RESET CSS + $N.css( $N.data(css) ).removeData(css); + + // trigger plugins for this layout, if there are any + runPluginCallbacks( Instance, $.layout.onDestroy ); + + // trigger state-management and onunload callback + unload(); + + // clear the Instance of everything except for container & options (so could recreate) + // RE-CREATE: myLayout = myLayout.container.layout( myLayout.options ); + for (n in Instance) + if (!n.match(/^(container|options)$/)) delete Instance[ n ]; + // add a 'destroyed' flag to make it easy to check + Instance.destroyed = true; + + // if this is a child layout, CLEAR the child-pointer in the parent + /* for now the pointer REMAINS, but with only container, options and destroyed keys + if (parentPane) { + var layout = parentPane.pane.data("parentLayout"); + parentPane.child = layout.children[ parentPane.name ] = null; + } + */ + + return Instance; // for coding convenience + } + + /** + * Remove a pane from the layout - subroutine of destroy() + * + * @see destroy() + * @param {string|Object} evt_or_pane The pane to process + * @param {boolean=} [remove=false] Remove the DOM element? + * @param {boolean=} [skipResize=false] Skip calling resizeAll()? + * @param {boolean=} [destroyChild=true] Destroy Child-layouts? If not passed, obeys options setting + */ +, removePane = function (evt_or_pane, remove, skipResize, destroyChild) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + , $C = $Cs[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + ; + // NOTE: elements can still exist even after remove() + // so check for missing data(), which is cleared by removed() + if ($P && $.isEmptyObject( $P.data() )) $P = false; + if ($C && $.isEmptyObject( $C.data() )) $C = false; + if ($R && $.isEmptyObject( $R.data() )) $R = false; + if ($T && $.isEmptyObject( $T.data() )) $T = false; + + if ($P) $P.stop(true, true); + + // check for a child layout + var o = options[pane] + , s = state[pane] + , d = "layout" + , css = "layoutCSS" + , child = children[pane] || ($P ? $P.data(d) : 0) || ($C ? $C.data(d) : 0) || null + , destroy = destroyChild !== undefined ? destroyChild : o.destroyChildLayout + ; + + // FIRST destroy the child-layout(s) + if (destroy && child && !child.destroyed) { + child.destroy(true); // tell child-layout to destroy ALL its child-layouts too + if (child.destroyed) // destroy was successful + child = null; // clear pointer for logic below + } + + if ($P && remove && !child) + $P.remove(); + else if ($P && $P[0]) { + // create list of ALL pane-classes that need to be removed + var root = o.paneClass // default="ui-layout-pane" + , pRoot = root +"-"+ pane // eg: "ui-layout-pane-west" + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + , classes = [ root, root+_open, root+_closed, root+_sliding, // generic classes + pRoot, pRoot+_open, pRoot+_closed, pRoot+_sliding ] // pane-specific classes + ; + $.merge(classes, getHoverClasses($P, true)); // ADD hover-classes + // remove all Layout classes from pane-element + $P .removeClass( classes.join(" ") ) // remove ALL pane-classes + .removeData("parentLayout") + .removeData("layoutPane") + .removeData("layoutRole") + .removeData("layoutEdge") + .removeData("autoHidden") // in case set + .unbind("."+ sID) // remove ALL Layout events + // TODO: remove these extra unbind commands when jQuery is fixed + //.unbind("mouseenter"+ sID) + //.unbind("mouseleave"+ sID) + ; + // do NOT reset CSS if this pane/content is STILL the container of a nested layout! + // the nested layout will reset its 'container' CSS when/if it is destroyed + if ($C && $C.data(d)) { + // a content-div may not have a specific width, so give it one to contain the Layout + $C.width( $C.width() ); + child.resizeAll(); // now resize the Layout + } + else if ($C) + $C.css( $C.data(css) ).removeData(css).removeData("layoutRole"); + // remove pane AFTER content in case there was a nested layout + if (!$P.data(d)) + $P.css( $P.data(css) ).removeData(css); + } + + // REMOVE pane resizer and toggler elements + if ($T) $T.remove(); + if ($R) $R.remove(); + + // CLEAR all pointers and state data + Instance[pane] = $Ps[pane] = $Cs[pane] = $Rs[pane] = $Ts[pane] = children[pane] = false; + s = { removed: true }; + + if (!skipResize) + resizeAll(); + } + + +/* + * ########################### + * ACTION METHODS + * ########################### + */ + +, _hidePane = function (pane) { + var $P = $Ps[pane] + , o = options[pane] + , s = $P[0].style + ; + if (o.useOffscreenClose) { + if (!$P.data(_c.offscreenReset)) + $P.data(_c.offscreenReset, { left: s.left, right: s.right }); + $P.css( _c.offscreenCSS ); + } + else + $P.hide().removeData(_c.offscreenReset); + } + +, _showPane = function (pane) { + var $P = $Ps[pane] + , o = options[pane] + , off = _c.offscreenCSS + , old = $P.data(_c.offscreenReset) + , s = $P[0].style + ; + $P .show() // ALWAYS show, just in case + .removeData(_c.offscreenReset); + if (o.useOffscreenClose && old) { + if (s.left == off.left) + s.left = old.left; + if (s.right == off.right) + s.right = old.right; + } + } + + + /** + * Completely 'hides' a pane, including its spacing - as if it does not exist + * The pane is not actually 'removed' from the source, so can use 'show' to un-hide it + * + * @param {string|Object} evt_or_pane The pane being hidden, ie: north, south, east, or west + * @param {boolean=} [noAnimation=false] + */ +, hide = function (evt_or_pane, noAnimation) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (!$P || s.isHidden) return; // pane does not exist OR is already hidden + + // onhide_start callback - will CANCEL hide if returns false + if (state.initialized && false === _runCallbacks("onhide_start", pane)) return; + + s.isSliding = false; // just in case + + // now hide the elements + if ($R) $R.hide(); // hide resizer-bar + if (!state.initialized || s.isClosed) { + s.isClosed = true; // to trigger open-animation on show() + s.isHidden = true; + s.isVisible = false; + if (!state.initialized) + _hidePane(pane); // no animation when loading page + sizeMidPanes(_c[pane].dir === "horz" ? "" : "center"); + if (state.initialized || o.triggerEventsOnLoad) + _runCallbacks("onhide_end", pane); + } + else { + s.isHiding = true; // used by onclose + close(pane, false, noAnimation); // adjust all panes to fit + } + } + + /** + * Show a hidden pane - show as 'closed' by default unless openPane = true + * + * @param {string|Object} evt_or_pane The pane being opened, ie: north, south, east, or west + * @param {boolean=} [openPane=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [noAlert=false] + */ +, show = function (evt_or_pane, openPane, noAnimation, noAlert) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (!$P || !s.isHidden) return; // pane does not exist OR is not hidden + + // onshow_start callback - will CANCEL show if returns false + if (false === _runCallbacks("onshow_start", pane)) return; + + s.isSliding = false; // just in case + s.isShowing = true; // used by onopen/onclose + //s.isHidden = false; - will be set by open/close - if not cancelled + + // now show the elements + //if ($R) $R.show(); - will be shown by open/close + if (openPane === false) + close(pane, true); // true = force + else + open(pane, false, noAnimation, noAlert); // adjust all panes to fit + } + + + /** + * Toggles a pane open/closed by calling either open or close + * + * @param {string|Object} evt_or_pane The pane being toggled, ie: north, south, east, or west + * @param {boolean=} [slide=false] + */ +, toggle = function (evt_or_pane, slide) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , s = state[pane] + ; + if (evt) // called from to $R.dblclick OR triggerPaneEvent + evt.stopImmediatePropagation(); + if (s.isHidden) + show(pane); // will call 'open' after unhiding it + else if (s.isClosed) + open(pane, !!slide); + else + close(pane); + } + + + /** + * Utility method used during init or other auto-processes + * + * @param {string} pane The pane being closed + * @param {boolean=} [setHandles=false] + */ +, _closePane = function (pane, setHandles) { + var + $P = $Ps[pane] + , s = state[pane] + ; + _hidePane(pane); + s.isClosed = true; + s.isVisible = false; + // UNUSED: if (setHandles) setAsClosed(pane, true); // true = force + } + + /** + * Close the specified pane (animation optional), and resize all other panes as needed + * + * @param {string|Object} evt_or_pane The pane being closed, ie: north, south, east, or west + * @param {boolean=} [force=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [skipCallback=false] + */ +, close = function (evt_or_pane, force, noAnimation, skipCallback) { + var pane = evtPane.call(this, evt_or_pane); + // if pane has been initialized, but NOT the complete layout, close pane instantly + if (!state.initialized && $Ps[pane]) { + _closePane(pane); // INIT pane as closed + return; + } + if (!isInitialized()) return; + + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , c = _c[pane] + , doFX, isShowing, isHiding, wasSliding; + + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + + if ( !$P + || (!o.closable && !s.isShowing && !s.isHiding) // invalid request // (!o.resizable && !o.closable) ??? + || (!force && s.isClosed && !s.isShowing) // already closed + ) return queueNext(); + + // onclose_start callback - will CANCEL hide if returns false + // SKIP if just 'showing' a hidden pane as 'closed' + var abort = !s.isShowing && false === _runCallbacks("onclose_start", pane); + + // transfer logic vars to temp vars + isShowing = s.isShowing; + isHiding = s.isHiding; + wasSliding = s.isSliding; + // now clear the logic vars (REQUIRED before aborting) + delete s.isShowing; + delete s.isHiding; + + if (abort) return queueNext(); + + doFX = !noAnimation && !s.isClosed && (o.fxName_close != "none"); + s.isMoving = true; + s.isClosed = true; + s.isVisible = false; + // update isHidden BEFORE sizing panes + if (isHiding) s.isHidden = true; + else if (isShowing) s.isHidden = false; + + if (s.isSliding) // pane is being closed, so UNBIND trigger events + bindStopSlidingEvents(pane, false); // will set isSliding=false + else // resize panes adjacent to this one + sizeMidPanes(_c[pane].dir === "horz" ? "" : "center", false); // false = NOT skipCallback + + // if this pane has a resizer bar, move it NOW - before animation + setAsClosed(pane); + + // CLOSE THE PANE + if (doFX) { // animate the close + // mask panes with objects + var masks = "center"+ (c.dir=="horz" ? ",west,east" : ""); + showMasks( masks, true ); // true = ONLY mask panes with maskObjects=true + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.hide( o.fxName_close, o.fxSettings_close, o.fxSpeed_close, function () { + lockPaneForFX(pane, false); // undo + if (s.isClosed) close_2(); + queueNext(); + }); + } + else { // hide the pane without animation + _hidePane(pane); + close_2(); + queueNext(); + }; + }); + + // SUBROUTINE + function close_2 () { + s.isMoving = false; + bindStartSlidingEvent(pane, true); // will enable if o.slidable = true + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.oppositeEdge[pane]; + if (state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane ); + } + + // hide any masks shown while closing + hideMasks(); + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad)) { + // onclose callback - UNLESS just 'showing' a hidden pane as 'closed' + if (!isShowing) _runCallbacks("onclose_end", pane); + // onhide OR onshow callback + if (isShowing) _runCallbacks("onshow_end", pane); + if (isHiding) _runCallbacks("onhide_end", pane); + } + } + } + + /** + * @param {string} pane The pane just closed, ie: north, south, east, or west + */ +, setAsClosed = function (pane) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side.toLowerCase() + , inset = "inset"+ _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + ; + $R + .css(side, sC[inset]) // move the resizer + .removeClass( rClass+_open +" "+ rClass+_pane+_open ) + .removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + .addClass( rClass+_closed +" "+ rClass+_pane+_closed ) + .unbind("dblclick."+ sID) + ; + // DISABLE 'resizing' when closed - do this BEFORE bindStartSlidingEvent? + if (o.resizable && $.layout.plugins.draggable) + $R + .draggable("disable") + .removeClass("ui-state-disabled") // do NOT apply disabled styling - not suitable here + .css("cursor", "default") + .attr("title","") + ; + + // if pane has a toggler button, adjust that too + if ($T) { + $T + .removeClass( tClass+_open +" "+ tClass+_pane+_open ) + .addClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .attr("title", o.tips.Open) // may be blank + ; + // toggler-content - if exists + $T.children(".content-open").hide(); + $T.children(".content-closed").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, false); + + if (state.initialized) { + // resize 'length' and position togglers for adjacent panes + sizeHandles(); + } + } + + /** + * Open the specified pane (animation optional), and resize all other panes as needed + * + * @param {string|Object} evt_or_pane The pane being opened, ie: north, south, east, or west + * @param {boolean=} [slide=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [noAlert=false] + */ +, open = function (evt_or_pane, slide, noAnimation, noAlert) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , c = _c[pane] + , doFX, isShowing + ; + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + + if ( !$P + || (!o.resizable && !o.closable && !s.isShowing) // invalid request + || (s.isVisible && !s.isSliding) // already open + ) return queueNext(); + + // pane can ALSO be unhidden by just calling show(), so handle this scenario + if (s.isHidden && !s.isShowing) { + queueNext(); // call before show() because it needs the queue free + show(pane, true); + return; + } + + if (o.autoResize && s.size != o.size) // resize pane to original size set in options + sizePane(pane, o.size, true, true, true); // true=skipCallback/forceResize/noAnimation + else + // make sure there is enough space available to open the pane + setSizeLimits(pane, slide); + + // onopen_start callback - will CANCEL open if returns false + var cbReturn = _runCallbacks("onopen_start", pane); + + if (cbReturn === "abort") + return queueNext(); + + // update pane-state again in case options were changed in onopen_start + if (cbReturn !== "NC") // NC = "No Callback" + setSizeLimits(pane, slide); + + if (s.minSize > s.maxSize) { // INSUFFICIENT ROOM FOR PANE TO OPEN! + syncPinBtns(pane, false); // make sure pin-buttons are reset + if (!noAlert && o.tips.noRoomToOpen) + alert(o.tips.noRoomToOpen); + return queueNext(); // ABORT + } + + if (slide) // START Sliding - will set isSliding=true + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + else if (s.isSliding) // PIN PANE (stop sliding) - open pane 'normally' instead + bindStopSlidingEvents(pane, false); // UNBIND trigger events - will set isSliding=false + else if (o.slidable) + bindStartSlidingEvent(pane, false); // UNBIND trigger events + + s.noRoom = false; // will be reset by makePaneFit if 'noRoom' + makePaneFit(pane); + + // transfer logic var to temp var + isShowing = s.isShowing; + // now clear the logic var + delete s.isShowing; + + doFX = !noAnimation && s.isClosed && (o.fxName_open != "none"); + s.isMoving = true; + s.isVisible = true; + s.isClosed = false; + // update isHidden BEFORE sizing panes - WHY??? Old? + if (isShowing) s.isHidden = false; + + if (doFX) { // ANIMATE + // mask panes with objects + var masks = "center"+ (c.dir=="horz" ? ",west,east" : ""); + if (s.isSliding) masks += ","+ _c.oppositeEdge[pane]; + showMasks( masks, true ); // true = ONLY mask panes with maskObjects=true + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.show( o.fxName_open, o.fxSettings_open, o.fxSpeed_open, function() { + lockPaneForFX(pane, false); // undo + if (s.isVisible) open_2(); // continue + queueNext(); + }); + } + else { // no animation + _showPane(pane);// just show pane and... + open_2(); // continue + queueNext(); + }; + }); + + // SUBROUTINE + function open_2 () { + s.isMoving = false; + + // cure iframe display issues + _fixIframe(pane); + + // NOTE: if isSliding, then other panes are NOT 'resized' + if (!s.isSliding) { // resize all panes adjacent to this one + hideMasks(); // remove any masks shown while opening + sizeMidPanes(_c[pane].dir=="vert" ? "center" : "", false); // false = NOT skipCallback + } + + // set classes, position handles and execute callbacks... + setAsOpen(pane); + }; + + } + + /** + * @param {string} pane The pane just opened, ie: north, south, east, or west + * @param {boolean=} [skipCallback=false] + */ +, setAsOpen = function (pane, skipCallback) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side.toLowerCase() + , inset = "inset"+ _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _closed = "-closed" + , _sliding= "-sliding" + ; + $R + .css(side, sC[inset] + getPaneSize(pane)) // move the resizer + .removeClass( rClass+_closed +" "+ rClass+_pane+_closed ) + .addClass( rClass+_open +" "+ rClass+_pane+_open ) + ; + if (s.isSliding) + $R.addClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + else // in case 'was sliding' + $R.removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + + if (o.resizerDblClickToggle) + $R.bind("dblclick", toggle ); + removeHover( 0, $R ); // remove hover classes + if (o.resizable && $.layout.plugins.draggable) + $R .draggable("enable") + .css("cursor", o.resizerCursor) + .attr("title", o.tips.Resize); + else if (!s.isSliding) + $R.css("cursor", "default"); // n-resize, s-resize, etc + + // if pane also has a toggler button, adjust that too + if ($T) { + $T .removeClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .addClass( tClass+_open +" "+ tClass+_pane+_open ) + .attr("title", o.tips.Close); // may be blank + removeHover( 0, $T ); // remove hover classes + // toggler-content - if exists + $T.children(".content-closed").hide(); + $T.children(".content-open").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, !s.isSliding); + + // update pane-state dimensions - BEFORE resizing content + $.extend(s, elDims($P)); + + if (state.initialized) { + // resize resizer & toggler sizes for all panes + sizeHandles(); + // resize content every time pane opens - to be sure + sizeContent(pane, true); // true = remeasure headers/footers, even if 'pane.isMoving' + } + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad) && $P.is(":visible")) { + // onopen callback + _runCallbacks("onopen_end", pane); + // onshow callback - TODO: should this be here? + if (s.isShowing) _runCallbacks("onshow_end", pane); + + // ALSO call onresize because layout-size *may* have changed while pane was closed + if (state.initialized) + _runCallbacks("onresize_end", pane); + } + + // TODO: Somehow sizePane("north") is being called after this point??? + } + + + /** + * slideOpen / slideClose / slideToggle + * + * Pass-though methods for sliding + */ +, slideOpen = function (evt_or_pane) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , s = state[pane] + , delay = options[pane].slideDelay_open + ; + // prevent event from triggering on NEW resizer binding created below + if (evt) evt.stopImmediatePropagation(); + + if (s.isClosed && evt && evt.type === "mouseenter" && delay > 0) + // trigger = mouseenter - use a delay + timer.set(pane+"_openSlider", open_NOW, delay); + else + open_NOW(); // will unbind events if is already open + + /** + * SUBROUTINE for timed open + */ + function open_NOW () { + if (!s.isClosed) // skip if no longer closed! + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + else if (!s.isMoving) + open(pane, true); // true = slide - open() will handle binding + }; + } + +, slideClose = function (evt_or_pane) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , delay = s.isMoving ? 1000 : 300 // MINIMUM delay - option may override + ; + if (s.isClosed || s.isResizing) + return; // skip if already closed OR in process of resizing + else if (o.slideTrigger_close === "click") + close_NOW(); // close immediately onClick + else if (o.preventQuickSlideClose && s.isMoving) + return; // handle Chrome quick-close on slide-open + else if (o.preventPrematureSlideClose && evt && $.layout.isMouseOverElem(evt, $Ps[pane])) + return; // handle incorrect mouseleave trigger, like when over a SELECT-list in IE + else if (evt) // trigger = mouseleave - use a delay + // 1 sec delay if 'opening', else .3 sec + timer.set(pane+"_closeSlider", close_NOW, max(o.slideDelay_close, delay)); + else // called programically + close_NOW(); + + /** + * SUBROUTINE for timed close + */ + function close_NOW () { + if (s.isClosed) // skip 'close' if already closed! + bindStopSlidingEvents(pane, false); // UNBIND trigger events - TODO: is this needed here? + else if (!s.isMoving) + close(pane); // close will handle unbinding + }; + } + + /** + * @param {string|Object} evt_or_pane The pane being opened, ie: north, south, east, or west + */ +, slideToggle = function (evt_or_pane) { + var pane = evtPane.call(this, evt_or_pane); + toggle(pane, true); + } + + + /** + * Must set left/top on East/South panes so animation will work properly + * + * @param {string} pane The pane to lock, 'east' or 'south' - any other is ignored! + * @param {boolean} doLock true = set left/top, false = remove + */ +, lockPaneForFX = function (pane, doLock) { + var $P = $Ps[pane] + , s = state[pane] + , o = options[pane] + , z = options.zIndexes + ; + if (doLock) { + $P.css({ zIndex: z.pane_animate }); // overlay all elements during animation + if (pane=="south") + $P.css({ top: sC.insetTop + sC.innerHeight - $P.outerHeight() }); + else if (pane=="east") + $P.css({ left: sC.insetLeft + sC.innerWidth - $P.outerWidth() }); + } + else { // animation DONE - RESET CSS + // TODO: see if this can be deleted. It causes a quick-close when sliding in Chrome + $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); + if (pane=="south") + $P.css({ top: "auto" }); + // if pane is positioned 'off-screen', then DO NOT screw with it! + else if (pane=="east" && !$P.css("left").match(/\-99999/)) + $P.css({ left: "auto" }); + // fix anti-aliasing in IE - only needed for animations that change opacity + if (browser.msie && o.fxOpacityFix && o.fxName_open != "slide" && $P.css("filter") && $P.css("opacity") == 1) + $P[0].style.removeAttribute('filter'); + } + } + + + /** + * Toggle sliding functionality of a specific pane on/off by adding removing 'slide open' trigger + * + * @see open(), close() + * @param {string} pane The pane to enable/disable, 'north', 'south', etc. + * @param {boolean} enable Enable or Disable sliding? + */ +, bindStartSlidingEvent = function (pane, enable) { + var o = options[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , evtName = o.slideTrigger_open.toLowerCase() + ; + if (!$R || (enable && !o.slidable)) return; + + // make sure we have a valid event + if (evtName.match(/mouseover/)) + evtName = o.slideTrigger_open = "mouseenter"; + else if (!evtName.match(/(click|dblclick|mouseenter)/)) + evtName = o.slideTrigger_open = "click"; + + $R + // add or remove event + [enable ? "bind" : "unbind"](evtName +'.'+ sID, slideOpen) + // set the appropriate cursor & title/tip + .css("cursor", enable ? o.sliderCursor : "default") + .attr("title", enable ? o.tips.Slide : "") + ; + } + + /** + * Add or remove 'mouseleave' events to 'slide close' when pane is 'sliding' open or closed + * Also increases zIndex when pane is sliding open + * See bindStartSlidingEvent for code to control 'slide open' + * + * @see slideOpen(), slideClose() + * @param {string} pane The pane to process, 'north', 'south', etc. + * @param {boolean} enable Enable or Disable events? + */ +, bindStopSlidingEvents = function (pane, enable) { + var o = options[pane] + , s = state[pane] + , c = _c[pane] + , z = options.zIndexes + , evtName = o.slideTrigger_close.toLowerCase() + , action = (enable ? "bind" : "unbind") + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + s.isSliding = enable; // logic + timer.clear(pane+"_closeSlider"); // just in case + + // remove 'slideOpen' event from resizer + // ALSO will raise the zIndex of the pane & resizer + if (enable) bindStartSlidingEvent(pane, false); + + // RE/SET zIndex - increases when pane is sliding-open, resets to normal when not + $P.css("zIndex", enable ? z.pane_sliding : z.pane_normal); + $R.css("zIndex", enable ? z.pane_sliding+2 : z.resizer_normal); // NOTE: mask = pane_sliding+1 + + // make sure we have a valid event + if (!evtName.match(/(click|mouseleave)/)) + evtName = o.slideTrigger_close = "mouseleave"; // also catches 'mouseout' + + // add/remove slide triggers + $R[action](evtName, slideClose); // base event on resize + // need extra events for mouseleave + if (evtName === "mouseleave") { + // also close on pane.mouseleave + $P[action]("mouseleave."+ sID, slideClose); + // cancel timer when mouse moves between 'pane' and 'resizer' + $R[action]("mouseenter."+ sID, cancelMouseOut); + $P[action]("mouseenter."+ sID, cancelMouseOut); + } + + if (!enable) + timer.clear(pane+"_closeSlider"); + else if (evtName === "click" && !o.resizable) { + // IF pane is not resizable (which already has a cursor and tip) + // then set the a cursor & title/tip on resizer when sliding + $R.css("cursor", enable ? o.sliderCursor : "default"); + $R.attr("title", enable ? o.tips.Close : ""); // use Toggler-tip, eg: "Close Pane" + } + + // SUBROUTINE for mouseleave timer clearing + function cancelMouseOut (evt) { + timer.clear(pane+"_closeSlider"); + evt.stopPropagation(); + } + } + + + /** + * Hides/closes a pane if there is insufficient room - reverses this when there is room again + * MUST have already called setSizeLimits() before calling this method + * + * @param {string} pane The pane being resized + * @param {boolean=} [isOpening=false] Called from onOpen? + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [force=false] + */ +, makePaneFit = function (pane, isOpening, skipCallback, force) { + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isSidePane = c.dir==="vert" + , hasRoom = false + ; + // special handling for center & east/west panes + if (pane === "center" || (isSidePane && s.noVerticalRoom)) { + // see if there is enough room to display the pane + // ERROR: hasRoom = s.minHeight <= s.maxHeight && (isSidePane || s.minWidth <= s.maxWidth); + hasRoom = (s.maxHeight >= 0); + if (hasRoom && s.noRoom) { // previously hidden due to noRoom, so show now + _showPane(pane); + if ($R) $R.show(); + s.isVisible = true; + s.noRoom = false; + if (isSidePane) s.noVerticalRoom = false; + _fixIframe(pane); + } + else if (!hasRoom && !s.noRoom) { // not currently hidden, so hide now + _hidePane(pane); + if ($R) $R.hide(); + s.isVisible = false; + s.noRoom = true; + } + } + + // see if there is enough room to fit the border-pane + if (pane === "center") { + // ignore center in this block + } + else if (s.minSize <= s.maxSize) { // pane CAN fit + hasRoom = true; + if (s.size > s.maxSize) // pane is too big - shrink it + sizePane(pane, s.maxSize, skipCallback, force, true); // true = noAnimation + else if (s.size < s.minSize) // pane is too small - enlarge it + sizePane(pane, s.minSize, skipCallback, force, true); + // need s.isVisible because new pseudoClose method keeps pane visible, but off-screen + else if ($R && s.isVisible && $P.is(":visible")) { + // make sure resizer-bar is positioned correctly + // handles situation where nested layout was 'hidden' when initialized + var side = c.side.toLowerCase() + , pos = s.size + sC["inset"+ c.side] + ; + if ($.layout.cssNum($R, side) != pos) $R.css( side, pos ); + } + + // if was previously hidden due to noRoom, then RESET because NOW there is room + if (s.noRoom) { + // s.noRoom state will be set by open or show + if (s.wasOpen && o.closable) { + if (o.autoReopen) + open(pane, false, true, true); // true = noAnimation, true = noAlert + else // leave the pane closed, so just update state + s.noRoom = false; + } + else + show(pane, s.wasOpen, true, true); // true = noAnimation, true = noAlert + } + } + else { // !hasRoom - pane CANNOT fit + if (!s.noRoom) { // pane not set as noRoom yet, so hide or close it now... + s.noRoom = true; // update state + s.wasOpen = !s.isClosed && !s.isSliding; + if (s.isClosed){} // SKIP + else if (o.closable) // 'close' if possible + close(pane, true, true); // true = force, true = noAnimation + else // 'hide' pane if cannot just be closed + hide(pane, true); // true = noAnimation + } + } + } + + + /** + * sizePane / manualSizePane + * sizePane is called only by internal methods whenever a pane needs to be resized + * manualSizePane is an exposed flow-through method allowing extra code when pane is 'manually resized' + * + * @param {string|Object} evt_or_pane The pane being resized + * @param {number} size The *desired* new size for this pane - will be validated + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [noAnimation=false] + */ +, manualSizePane = function (evt_or_pane, size, skipCallback, noAnimation) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + // if resizing callbacks have been delayed and resizing is now DONE, force resizing to complete... + , forceResize = o.livePaneResizing && !s.isResizing + ; + // ANY call to manualSizePane disables autoResize - ie, percentage sizing + o.autoResize = false; + // flow-through... + sizePane(pane, size, skipCallback, forceResize, noAnimation); // will animate resize if option enabled + } + + /** + * @param {string|Object} evt_or_pane The pane being resized + * @param {number} size The *desired* new size for this pane - will be validated + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [force=false] Force resizing even if does not seem necessary + * @param {boolean=} [noAnimation=false] + */ +, sizePane = function (evt_or_pane, size, skipCallback, force, noAnimation) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) // probably NEVER called from event? + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , side = _c[pane].side.toLowerCase() + , dimName = _c[pane].sizeType.toLowerCase() + , inset = "inset"+ _c[pane].side + , skipResizeWhileDragging = s.isResizing && !o.triggerEventsDuringLiveResize + , doFX = noAnimation !== true && o.animatePaneSizing + , oldSize, newSize + ; + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + // calculate 'current' min/max sizes + setSizeLimits(pane); // update pane-state + oldSize = s.size; + size = _parseSize(pane, size); // handle percentages & auto + size = max(size, _parseSize(pane, o.minSize)); + size = min(size, s.maxSize); + if (size < s.minSize) { // not enough room for pane! + queueNext(); // call before makePaneFit() because it needs the queue free + makePaneFit(pane, false, skipCallback); // will hide or close pane + return; + } + + // IF newSize is same as oldSize, then nothing to do - abort + if (!force && size === oldSize) + return queueNext(); + + // onresize_start callback CANNOT cancel resizing because this would break the layout! + if (!skipCallback && state.initialized && s.isVisible) + _runCallbacks("onresize_start", pane); + + // resize the pane, and make sure its visible + newSize = cssSize(pane, size); + + if (doFX && $P.is(":visible")) { // ANIMATE + var fx = $.layout.effects.size[pane] || $.layout.effects.size.all + , easing = o.fxSettings_size.easing || fx.easing + , z = options.zIndexes + , props = {}; + props[ dimName ] = newSize +'px'; + s.isMoving = true; + // overlay all elements during animation + $P.css({ zIndex: z.pane_animate }) + .show().animate( props, o.fxSpeed_size, easing, function(){ + // reset zIndex after animation + $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); + s.isMoving = false; + sizePane_2(); // continue + queueNext(); + }); + } + else { // no animation + $P.css( dimName, newSize ); // resize pane + // if pane is visible, then + if ($P.is(":visible")) + sizePane_2(); // continue + else { + // pane is NOT VISIBLE, so just update state data... + // when pane is *next opened*, it will have the new size + s.size = size; // update state.size + $.extend(s, elDims($P)); // update state dimensions + } + queueNext(); + }; + + }); + + // SUBROUTINE + function sizePane_2 () { + /* Panes are sometimes not sized precisely in some browsers!? + * This code will resize the pane up to 3 times to nudge the pane to the correct size + */ + var actual = dimName==='width' ? $P.outerWidth() : $P.outerHeight() + , tries = [{ + pane: pane + , count: 1 + , target: size + , actual: actual + , correct: (size === actual) + , attempt: size + , cssSize: newSize + }] + , lastTry = tries[0] + , thisTry = {} + , msg = 'Inaccurate size after resizing the '+ pane +'-pane.' + ; + while ( !lastTry.correct ) { + thisTry = { pane: pane, count: lastTry.count+1, target: size }; + + if (lastTry.actual > size) + thisTry.attempt = max(0, lastTry.attempt - (lastTry.actual - size)); + else // lastTry.actual < size + thisTry.attempt = max(0, lastTry.attempt + (size - lastTry.actual)); + + thisTry.cssSize = cssSize(pane, thisTry.attempt); + $P.css( dimName, thisTry.cssSize ); + + thisTry.actual = dimName=='width' ? $P.outerWidth() : $P.outerHeight(); + thisTry.correct = (size === thisTry.actual); + + // log attempts and alert the user of this *non-fatal error* (if showDebugMessages) + if ( tries.length === 1) { + _log(msg, false, true); + _log(lastTry, false, true); + } + _log(thisTry, false, true); + // after 4 tries, is as close as its gonna get! + if (tries.length > 3) break; + + tries.push( thisTry ); + lastTry = tries[ tries.length - 1 ]; + } + // END TESTING CODE + + // update pane-state dimensions + s.size = size; + $.extend(s, elDims($P)); + + if (s.isVisible && $P.is(":visible")) { + // reposition the resizer-bar + if ($R) $R.css( side, size + sC[inset] ); + // resize the content-div + sizeContent(pane); + } + + if (!skipCallback && !skipResizeWhileDragging && state.initialized && s.isVisible) + _runCallbacks("onresize_end", pane); + + // resize all the adjacent panes, and adjust their toggler buttons + // when skipCallback passed, it means the controlling method will handle 'other panes' + if (!skipCallback) { + // also no callback if live-resize is in progress and NOT triggerEventsDuringLiveResize + if (!s.isSliding) sizeMidPanes(_c[pane].dir=="horz" ? "" : "center", skipResizeWhileDragging, force); + sizeHandles(); + } + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.oppositeEdge[pane]; + if (size < oldSize && state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane, false, skipCallback ); + } + + // DEBUG - ALERT user/developer so they know there was a sizing problem + if (tries.length > 1) + _log(msg +'\nSee the Error Console for details.', true, true); + } + } + + /** + * @see initPanes(), sizePane(), resizeAll(), open(), close(), hide() + * @param {Array.|string} panes The pane(s) being resized, comma-delmited string + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [force=false] + */ +, sizeMidPanes = function (panes, skipCallback, force) { + panes = (panes ? panes : "east,west,center").split(","); + + $.each(panes, function (i, pane) { + if (!$Ps[pane]) return; // NO PANE - skip + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isCenter= (pane=="center") + , hasRoom = true + , CSS = {} + , newCenter = calcNewCenterPaneDims() + ; + // update pane-state dimensions + $.extend(s, elDims($P)); + + if (pane === "center") { + if (!force && s.isVisible && newCenter.width === s.outerWidth && newCenter.height === s.outerHeight) + return true; // SKIP - pane already the correct size + // set state for makePaneFit() logic + $.extend(s, cssMinDims(pane), { + maxWidth: newCenter.width + , maxHeight: newCenter.height + }); + CSS = newCenter; + // convert OUTER width/height to CSS width/height + CSS.width = cssW($P, CSS.width); + // NEW - allow pane to extend 'below' visible area rather than hide it + CSS.height = cssH($P, CSS.height); + hasRoom = CSS.width >= 0 && CSS.height >= 0; // height >= 0 = ALWAYS TRUE NOW + // during layout init, try to shrink east/west panes to make room for center + if (!state.initialized && o.minWidth > s.outerWidth) { + var + reqPx = o.minWidth - s.outerWidth + , minE = options.east.minSize || 0 + , minW = options.west.minSize || 0 + , sizeE = state.east.size + , sizeW = state.west.size + , newE = sizeE + , newW = sizeW + ; + if (reqPx > 0 && state.east.isVisible && sizeE > minE) { + newE = max( sizeE-minE, sizeE-reqPx ); + reqPx -= sizeE-newE; + } + if (reqPx > 0 && state.west.isVisible && sizeW > minW) { + newW = max( sizeW-minW, sizeW-reqPx ); + reqPx -= sizeW-newW; + } + // IF we found enough extra space, then resize the border panes as calculated + if (reqPx === 0) { + if (sizeE && sizeE != minE) + sizePane('east', newE, true, force, true); // true = skipCallback/noAnimation - initPanes will handle when done + if (sizeW && sizeW != minW) + sizePane('west', newW, true, force, true); + // now start over! + sizeMidPanes('center', skipCallback, force); + return; // abort this loop + } + } + } + else { // for east and west, set only the height, which is same as center height + // set state.min/maxWidth/Height for makePaneFit() logic + if (s.isVisible && !s.noVerticalRoom) + $.extend(s, elDims($P), cssMinDims(pane)) + if (!force && !s.noVerticalRoom && newCenter.height === s.outerHeight) + return true; // SKIP - pane already the correct size + // east/west have same top, bottom & height as center + CSS.top = newCenter.top; + CSS.bottom = newCenter.bottom; + // NEW - allow pane to extend 'below' visible area rather than hide it + CSS.height = cssH($P, newCenter.height); + s.maxHeight = CSS.height; + hasRoom = (s.maxHeight >= 0); // ALWAYS TRUE NOW + if (!hasRoom) s.noVerticalRoom = true; // makePaneFit() logic + } + + if (hasRoom) { + // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized + if (!skipCallback && state.initialized) + _runCallbacks("onresize_start", pane); + + $P.css(CSS); // apply the CSS to pane + if (pane !== "center") + sizeHandles(pane); // also update resizer length + if (s.noRoom && !s.isClosed && !s.isHidden) + makePaneFit(pane); // will re-open/show auto-closed/hidden pane + if (s.isVisible) { + $.extend(s, elDims($P)); // update pane dimensions + if (state.initialized) sizeContent(pane); // also resize the contents, if exists + } + } + else if (!s.noRoom && s.isVisible) // no room for pane + makePaneFit(pane); // will hide or close pane + + if (!s.isVisible) + return true; // DONE - next pane + + /* + * Extra CSS for IE6 or IE7 in Quirks-mode - add 'width' to NORTH/SOUTH panes + * Normally these panes have only 'left' & 'right' positions so pane auto-sizes + * ALSO required when pane is an IFRAME because will NOT default to 'full width' + * TODO: Can I use width:100% for a north/south iframe? + * TODO: Sounds like a job for $P.outerWidth( sC.innerWidth ) SETTER METHOD + */ + if (pane === "center") { // finished processing midPanes + var fix = browser.isIE6 || !browser.boxModel; + if ($Ps.north && (fix || state.north.tagName=="IFRAME")) + $Ps.north.css("width", cssW($Ps.north, sC.innerWidth)); + if ($Ps.south && (fix || state.south.tagName=="IFRAME")) + $Ps.south.css("width", cssW($Ps.south, sC.innerWidth)); + } + + // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized + if (!skipCallback && state.initialized) + _runCallbacks("onresize_end", pane); + }); + } + + + /** + * @see window.onresize(), callbacks or custom code + */ +, resizeAll = function (evt) { + // stopPropagation if called by trigger("layoutdestroy") - use evtPane utility + evtPane(evt); + + if (!state.initialized) { + _initLayoutElements(); + return; // no need to resize since we just initialized! + } + var oldW = sC.innerWidth + , oldH = sC.innerHeight + ; + // cannot size layout when 'container' is hidden or collapsed + if (!$N.is(":visible") ) return; + $.extend(state.container, elDims( $N )); // UPDATE container dimensions + if (!sC.outerHeight) return; + + // onresizeall_start will CANCEL resizing if returns false + // state.container has already been set, so user can access this info for calcuations + if (false === _runCallbacks("onresizeall_start")) return false; + + var // see if container is now 'smaller' than before + shrunkH = (sC.innerHeight < oldH) + , shrunkW = (sC.innerWidth < oldW) + , $P, o, s, dir + ; + // NOTE special order for sizing: S-N-E-W + $.each(["south","north","east","west"], function (i, pane) { + if (!$Ps[pane]) return; // no pane - SKIP + s = state[pane]; + o = options[pane]; + dir = _c[pane].dir; + + if (o.autoResize && s.size != o.size) // resize pane to original size set in options + sizePane(pane, o.size, true, true, true); // true=skipCallback/forceResize/noAnimation + else { + setSizeLimits(pane); + makePaneFit(pane, false, true, true); // true=skipCallback/forceResize + } + }); + + sizeMidPanes("", true, true); // true=skipCallback, true=forceResize + sizeHandles(); // reposition the toggler elements + + // trigger all individual pane callbacks AFTER layout has finished resizing + o = options; // reuse alias + $.each(_c.allPanes, function (i, pane) { + $P = $Ps[pane]; + if (!$P) return; // SKIP + if (state[pane].isVisible) // undefined for non-existent panes + _runCallbacks("onresize_end", pane); // callback - if exists + }); + + _runCallbacks("onresizeall_end"); + //_triggerLayoutEvent(pane, 'resizeall'); + } + + /** + * Whenever a pane resizes or opens that has a nested layout, trigger resizeAll + * + * @param {string|Object} evt_or_pane The pane just resized or opened + */ +, resizeChildLayout = function (evt_or_pane) { + var pane = evtPane.call(this, evt_or_pane); + if (!options[pane].resizeChildLayout) return; + var $P = $Ps[pane] + , $C = $Cs[pane] + , d = "layout" + , P = Instance[pane] + , L = children[pane] + ; + // user may have manually set EITHER instance pointer, so handle that + if (P.child && !L) { + // have to reverse the pointers! + var el = P.child.container; + L = children[pane] = (el ? el.data(d) : 0) || null; // set pointer _directly_ to layout instance + } + + // if a layout-pointer exists, see if child has been destroyed + if (L && L.destroyed) + L = children[pane] = null; // clear child pointers + // no child layout pointer is set - see if there is a child layout NOW + if (!L) L = children[pane] = $P.data(d) || ($C ? $C.data(d) : 0) || null; // set/update child pointers + + // ALWAYS refresh the pane.child alias + P.child = children[pane]; + + if (L) L.resizeAll(); + } + + + /** + * IF pane has a content-div, then resize all elements inside pane to fit pane-height + * + * @param {string|Object} evt_or_panes The pane(s) being resized + * @param {boolean=} [remeasure=false] Should the content (header/footer) be remeasured? + */ +, sizeContent = function (evt_or_panes, remeasure) { + if (!isInitialized()) return; + + var panes = evtPane.call(this, evt_or_panes); + panes = panes ? panes.split(",") : _c.allPanes; + + $.each(panes, function (idx, pane) { + var + $P = $Ps[pane] + , $C = $Cs[pane] + , o = options[pane] + , s = state[pane] + , m = s.content // m = measurements + ; + if (!$P || !$C || !$P.is(":visible")) return true; // NOT VISIBLE - skip + + // if content-element was REMOVED, update OR remove the pointer + if (!$C.length) { + initContent(pane, false); // false = do NOT sizeContent() - already there! + if (!$C) return; // no replacement element found - pointer have been removed + } + + // onsizecontent_start will CANCEL resizing if returns false + if (false === _runCallbacks("onsizecontent_start", pane)) return; + + // skip re-measuring offsets if live-resizing + if ((!s.isMoving && !s.isResizing) || o.liveContentResizing || remeasure || m.top == undefined) { + _measure(); + // if any footers are below pane-bottom, they may not measure correctly, + // so allow pane overflow and re-measure + if (m.hiddenFooters > 0 && $P.css("overflow") === "hidden") { + $P.css("overflow", "visible"); + _measure(); // remeasure while overflowing + $P.css("overflow", "hidden"); + } + } + // NOTE: spaceAbove/Below *includes* the pane paddingTop/Bottom, but not pane.borders + var newH = s.innerHeight - (m.spaceAbove - s.css.paddingTop) - (m.spaceBelow - s.css.paddingBottom); + + if (!$C.is(":visible") || m.height != newH) { + // size the Content element to fit new pane-size - will autoHide if not enough room + setOuterHeight($C, newH, true); // true=autoHide + m.height = newH; // save new height + }; + + if (state.initialized) + _runCallbacks("onsizecontent_end", pane); + + function _below ($E) { + return max(s.css.paddingBottom, (parseInt($E.css("marginBottom"), 10) || 0)); + }; + + function _measure () { + var + ignore = options[pane].contentIgnoreSelector + , $Fs = $C.nextAll().not(ignore || ':lt(0)') // not :lt(0) = ALL + , $Fs_vis = $Fs.filter(':visible') + , $F = $Fs_vis.filter(':last') + ; + m = { + top: $C[0].offsetTop + , height: $C.outerHeight() + , numFooters: $Fs.length + , hiddenFooters: $Fs.length - $Fs_vis.length + , spaceBelow: 0 // correct if no content footer ($E) + } + m.spaceAbove = m.top; // just for state - not used in calc + m.bottom = m.top + m.height; + if ($F.length) + //spaceBelow = (LastFooter.top + LastFooter.height) [footerBottom] - Content.bottom + max(LastFooter.marginBottom, pane.paddingBotom) + m.spaceBelow = ($F[0].offsetTop + $F.outerHeight()) - m.bottom + _below($F); + else // no footer - check marginBottom on Content element itself + m.spaceBelow = _below($C); + }; + }); + } + + + /** + * Called every time a pane is opened, closed, or resized to slide the togglers to 'center' and adjust their length if necessary + * + * @see initHandles(), open(), close(), resizeAll() + * @param {string|Object} evt_or_panes The pane(s) being resized + */ +, sizeHandles = function (evt_or_panes) { + var panes = evtPane.call(this, evt_or_panes) + panes = panes ? panes.split(",") : _c.borderPanes; + + $.each(panes, function (i, pane) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , $TC + ; + if (!$P || !$R) return; + + var + dir = _c[pane].dir + , _state = (s.isClosed ? "_closed" : "_open") + , spacing = o["spacing"+ _state] + , togAlign = o["togglerAlign"+ _state] + , togLen = o["togglerLength"+ _state] + , paneLen + , left + , offset + , CSS = {} + ; + + if (spacing === 0) { + $R.hide(); + return; + } + else if (!s.noRoom && !s.isHidden) // skip if resizer was hidden for any reason + $R.show(); // in case was previously hidden + + // Resizer Bar is ALWAYS same width/height of pane it is attached to + if (dir === "horz") { // north/south + //paneLen = $P.outerWidth(); // s.outerWidth || + paneLen = sC.innerWidth; // handle offscreen-panes + s.resizerLength = paneLen; + left = $.layout.cssNum($P, "left") + $R.css({ + width: cssW($R, paneLen) // account for borders & padding + , height: cssH($R, spacing) // ditto + , left: left > -9999 ? left : sC.insetLeft // handle offscreen-panes + }); + } + else { // east/west + paneLen = $P.outerHeight(); // s.outerHeight || + s.resizerLength = paneLen; + $R.css({ + height: cssH($R, paneLen) // account for borders & padding + , width: cssW($R, spacing) // ditto + , top: sC.insetTop + getPaneSize("north", true) // TODO: what if no North pane? + //, top: $.layout.cssNum($Ps["center"], "top") + }); + } + + // remove hover classes + removeHover( o, $R ); + + if ($T) { + if (togLen === 0 || (s.isSliding && o.hideTogglerOnSlide)) { + $T.hide(); // always HIDE the toggler when 'sliding' + return; + } + else + $T.show(); // in case was previously hidden + + if (!(togLen > 0) || togLen === "100%" || togLen > paneLen) { + togLen = paneLen; + offset = 0; + } + else { // calculate 'offset' based on options.PANE.togglerAlign_open/closed + if (isStr(togAlign)) { + switch (togAlign) { + case "top": + case "left": offset = 0; + break; + case "bottom": + case "right": offset = paneLen - togLen; + break; + case "middle": + case "center": + default: offset = round((paneLen - togLen) / 2); // 'default' catches typos + } + } + else { // togAlign = number + var x = parseInt(togAlign, 10); // + if (togAlign >= 0) offset = x; + else offset = paneLen - togLen + x; // NOTE: x is negative! + } + } + + if (dir === "horz") { // north/south + var width = cssW($T, togLen); + $T.css({ + width: width // account for borders & padding + , height: cssH($T, spacing) // ditto + , left: offset // TODO: VERIFY that toggler positions correctly for ALL values + , top: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginLeft", round((width-$TC.outerWidth())/2)); // could be negative + }); + } + else { // east/west + var height = cssH($T, togLen); + $T.css({ + height: height // account for borders & padding + , width: cssW($T, spacing) // ditto + , top: offset // POSITION the toggler + , left: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginTop", round((height-$TC.outerHeight())/2)); // could be negative + }); + } + + // remove ALL hover classes + removeHover( 0, $T ); + } + + // DONE measuring and sizing this resizer/toggler, so can be 'hidden' now + if (!state.initialized && (o.initHidden || s.noRoom)) { + $R.hide(); + if ($T) $T.hide(); + } + }); + } + + + /** + * @param {string|Object} evt_or_pane + */ +, enableClosable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $T = $Ts[pane] + , o = options[pane] + ; + if (!$T) return; + o.closable = true; + $T .bind("click."+ sID, function(evt){ evt.stopPropagation(); toggle(pane); }) + .css("visibility", "visible") + .css("cursor", "pointer") + .attr("title", state[pane].isClosed ? o.tips.Open : o.tips.Close) // may be blank + .show(); + } + /** + * @param {string|Object} evt_or_pane + * @param {boolean=} [hide=false] + */ +, disableClosable = function (evt_or_pane, hide) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $T = $Ts[pane] + ; + if (!$T) return; + options[pane].closable = false; + // is closable is disable, then pane MUST be open! + if (state[pane].isClosed) open(pane, false, true); + $T .unbind("."+ sID) + .css("visibility", hide ? "hidden" : "visible") // instead of hide(), which creates logic issues + .css("cursor", "default") + .attr("title", ""); + } + + + /** + * @param {string|Object} evt_or_pane + */ +, enableSlidable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R || !$R.data('draggable')) return; + options[pane].slidable = true; + if (state[pane].isClosed) + bindStartSlidingEvent(pane, true); + } + /** + * @param {string|Object} evt_or_pane + */ +, disableSlidable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R) return; + options[pane].slidable = false; + if (state[pane].isSliding) + close(pane, false, true); + else { + bindStartSlidingEvent(pane, false); + $R .css("cursor", "default") + .attr("title", ""); + removeHover(null, $R[0]); // in case currently hovered + } + } + + + /** + * @param {string|Object} evt_or_pane + */ +, enableResizable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + , o = options[pane] + ; + if (!$R || !$R.data('draggable')) return; + o.resizable = true; + $R.draggable("enable"); + if (!state[pane].isClosed) + $R .css("cursor", o.resizerCursor) + .attr("title", o.tips.Resize); + } + /** + * @param {string|Object} evt_or_pane + */ +, disableResizable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R || !$R.data('draggable')) return; + options[pane].resizable = false; + $R .draggable("disable") + .css("cursor", "default") + .attr("title", ""); + removeHover(null, $R[0]); // in case currently hovered + } + + + /** + * Move a pane from source-side (eg, west) to target-side (eg, east) + * If pane exists on target-side, move that to source-side, ie, 'swap' the panes + * + * @param {string|Object} evt_or_pane1 The pane/edge being swapped + * @param {string} pane2 ditto + */ +, swapPanes = function (evt_or_pane1, pane2) { + if (!isInitialized()) return; + var pane1 = evtPane.call(this, evt_or_pane1); + // change state.edge NOW so callbacks can know where pane is headed... + state[pane1].edge = pane2; + state[pane2].edge = pane1; + // run these even if NOT state.initialized + if (false === _runCallbacks("onswap_start", pane1) + || false === _runCallbacks("onswap_start", pane2) + ) { + state[pane1].edge = pane1; // reset + state[pane2].edge = pane2; + return; + } + + var + oPane1 = copy( pane1 ) + , oPane2 = copy( pane2 ) + , sizes = {} + ; + sizes[pane1] = oPane1 ? oPane1.state.size : 0; + sizes[pane2] = oPane2 ? oPane2.state.size : 0; + + // clear pointers & state + $Ps[pane1] = false; + $Ps[pane2] = false; + state[pane1] = {}; + state[pane2] = {}; + + // ALWAYS remove the resizer & toggler elements + if ($Ts[pane1]) $Ts[pane1].remove(); + if ($Ts[pane2]) $Ts[pane2].remove(); + if ($Rs[pane1]) $Rs[pane1].remove(); + if ($Rs[pane2]) $Rs[pane2].remove(); + $Rs[pane1] = $Rs[pane2] = $Ts[pane1] = $Ts[pane2] = false; + + // transfer element pointers and data to NEW Layout keys + move( oPane1, pane2 ); + move( oPane2, pane1 ); + + // cleanup objects + oPane1 = oPane2 = sizes = null; + + // make panes 'visible' again + if ($Ps[pane1]) $Ps[pane1].css(_c.visible); + if ($Ps[pane2]) $Ps[pane2].css(_c.visible); + + // fix any size discrepancies caused by swap + resizeAll(); + + // run these even if NOT state.initialized + _runCallbacks("onswap_end", pane1); + _runCallbacks("onswap_end", pane2); + + return; + + function copy (n) { // n = pane + var + $P = $Ps[n] + , $C = $Cs[n] + ; + return !$P ? false : { + pane: n + , P: $P ? $P[0] : false + , C: $C ? $C[0] : false + , state: $.extend(true, {}, state[n]) + , options: $.extend(true, {}, options[n]) + } + }; + + function move (oPane, pane) { + if (!oPane) return; + var + P = oPane.P + , C = oPane.C + , oldPane = oPane.pane + , c = _c[pane] + , side = c.side.toLowerCase() + , inset = "inset"+ c.side + // save pane-options that should be retained + , s = $.extend(true, {}, state[pane]) + , o = options[pane] + // RETAIN side-specific FX Settings - more below + , fx = { resizerCursor: o.resizerCursor } + , re, size, pos + ; + $.each("fxName,fxSpeed,fxSettings".split(","), function (i, k) { + fx[k +"_open"] = o[k +"_open"]; + fx[k +"_close"] = o[k +"_close"]; + fx[k +"_size"] = o[k +"_size"]; + }); + + // update object pointers and attributes + $Ps[pane] = $(P) + .data({ + layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + }) + .css(_c.hidden) + .css(c.cssReq) + ; + $Cs[pane] = C ? $(C) : false; + + // set options and state + options[pane] = $.extend(true, {}, oPane.options, fx); + state[pane] = $.extend(true, {}, oPane.state); + + // change classNames on the pane, eg: ui-layout-pane-east ==> ui-layout-pane-west + re = new RegExp(o.paneClass +"-"+ oldPane, "g"); + P.className = P.className.replace(re, o.paneClass +"-"+ pane); + + // ALWAYS regenerate the resizer & toggler elements + initHandles(pane); // create the required resizer & toggler + + // if moving to different orientation, then keep 'target' pane size + if (c.dir != _c[oldPane].dir) { + size = sizes[pane] || 0; + setSizeLimits(pane); // update pane-state + size = max(size, state[pane].minSize); + // use manualSizePane to disable autoResize - not useful after panes are swapped + manualSizePane(pane, size, true, true); // true/true = skipCallback/noAnimation + } + else // move the resizer here + $Rs[pane].css(side, sC[inset] + (state[pane].isVisible ? getPaneSize(pane) : 0)); + + + // ADD CLASSNAMES & SLIDE-BINDINGS + if (oPane.state.isVisible && !s.isVisible) + setAsOpen(pane, true); // true = skipCallback + else { + setAsClosed(pane); + bindStartSlidingEvent(pane, true); // will enable events IF option is set + } + + // DESTROY the object + oPane = null; + }; + } + + + /** + * INTERNAL method to sync pin-buttons when pane is opened or closed + * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes + * + * @see open(), setAsOpen(), setAsClosed() + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin True means set the pin 'down', False means 'up' + */ +, syncPinBtns = function (pane, doPin) { + if ($.layout.plugins.buttons) + $.each(state[pane].pins, function (i, selector) { + $.layout.buttons.setPinState(Instance, $(selector), pane, doPin); + }); + } + +; // END var DECLARATIONS + + /** + * Capture keys when enableCursorHotkey - toggle pane if hotkey pressed + * + * @see document.keydown() + */ + function keyDown (evt) { + if (!evt) return true; + var code = evt.keyCode; + if (code < 33) return true; // ignore special keys: ENTER, TAB, etc + + var + PANE = { + 38: "north" // Up Cursor - $.ui.keyCode.UP + , 40: "south" // Down Cursor - $.ui.keyCode.DOWN + , 37: "west" // Left Cursor - $.ui.keyCode.LEFT + , 39: "east" // Right Cursor - $.ui.keyCode.RIGHT + } + , ALT = evt.altKey // no worky! + , SHIFT = evt.shiftKey + , CTRL = evt.ctrlKey + , CURSOR = (CTRL && code >= 37 && code <= 40) + , o, k, m, pane + ; + + if (CURSOR && options[PANE[code]].enableCursorHotkey) // valid cursor-hotkey + pane = PANE[code]; + else if (CTRL || SHIFT) // check to see if this matches a custom-hotkey + $.each(_c.borderPanes, function (i, p) { // loop each pane to check its hotkey + o = options[p]; + k = o.customHotkey; + m = o.customHotkeyModifier; // if missing or invalid, treated as "CTRL+SHIFT" + if ((SHIFT && m=="SHIFT") || (CTRL && m=="CTRL") || (CTRL && SHIFT)) { // Modifier matches + if (k && code === (isNaN(k) || k <= 9 ? k.toUpperCase().charCodeAt(0) : k)) { // Key matches + pane = p; + return false; // BREAK + } + } + }); + + // validate pane + if (!pane || !$Ps[pane] || !options[pane].closable || state[pane].isHidden) + return true; + + toggle(pane); + + evt.stopPropagation(); + evt.returnValue = false; // CANCEL key + return false; + }; + + +/* + * ###################################### + * UTILITY METHODS + * called externally or by initButtons + * ###################################### + */ + + /** + * Change/reset a pane overflow setting & zIndex to allow popups/drop-downs to work + * + * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event + */ + function allowOverflow (el) { + if (!isInitialized()) return; + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (isStr(el)) + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents().each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + ; + + // if pane is already raised, then reset it before doing it again! + // this would happen if allowOverflow is attached to BOTH the pane and an element + if (s.cssSaved) + resetOverflow(pane); // reset previous CSS before continuing + + // if pane is raised by sliding or resizing, or its closed, then abort + if (s.isSliding || s.isResizing || s.isClosed) { + s.cssSaved = false; + return; + } + + var + newCSS = { zIndex: (options.zIndexes.resizer_normal + 1) } + , curCSS = {} + , of = $P.css("overflow") + , ofX = $P.css("overflowX") + , ofY = $P.css("overflowY") + ; + // determine which, if any, overflow settings need to be changed + if (of != "visible") { + curCSS.overflow = of; + newCSS.overflow = "visible"; + } + if (ofX && !ofX.match(/(visible|auto)/)) { + curCSS.overflowX = ofX; + newCSS.overflowX = "visible"; + } + if (ofY && !ofY.match(/(visible|auto)/)) { + curCSS.overflowY = ofX; + newCSS.overflowY = "visible"; + } + + // save the current overflow settings - even if blank! + s.cssSaved = curCSS; + + // apply new CSS to raise zIndex and, if necessary, make overflow 'visible' + $P.css( newCSS ); + + // make sure the zIndex of all other panes is normal + $.each(_c.allPanes, function(i, p) { + if (p != pane) resetOverflow(p); + }); + + }; + /** + * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event + */ + function resetOverflow (el) { + if (!isInitialized()) return; + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (isStr(el)) + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents().each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + , CSS = s.cssSaved || {} + ; + // reset the zIndex + if (!s.isSliding && !s.isResizing) + $P.css("zIndex", options.zIndexes.pane_normal); + + // reset Overflow - if necessary + $P.css( CSS ); + + // clear var + s.cssSaved = false; + }; + +/* + * ##################### + * CREATE/RETURN LAYOUT + * ##################### + */ + + // validate that container exists + var $N = $(this).eq(0); // FIRST matching Container element + if (!$N.length) { + return _log( options.errors.containerMissing ); + }; + + // Users retrieve Instance of a layout with: $N.layout() OR $N.data("layout") + // return the Instance-pointer if layout has already been initialized + if ($N.data("layoutContainer") && $N.data("layout")) + return $N.data("layout"); // cached pointer + + // init global vars + var + $Ps = {} // Panes x5 - set in initPanes() + , $Cs = {} // Content x5 - set in initPanes() + , $Rs = {} // Resizers x4 - set in initHandles() + , $Ts = {} // Togglers x4 - set in initHandles() + , $Ms = $([]) // Masks - up to 2 masks per pane (IFRAME + DIV) + // aliases for code brevity + , sC = state.container // alias for easy access to 'container dimensions' + , sID = state.id // alias for unique layout ID/namespace - eg: "layout435" + ; + + // create Instance object to expose data & option Properties, and primary action Methods + var Instance = { + // layout data + options: options // property - options hash + , state: state // property - dimensions hash + // object pointers + , container: $N // property - object pointers for layout container + , panes: $Ps // property - object pointers for ALL Panes: panes.north, panes.center + , contents: $Cs // property - object pointers for ALL Content: contents.north, contents.center + , resizers: $Rs // property - object pointers for ALL Resizers, eg: resizers.north + , togglers: $Ts // property - object pointers for ALL Togglers, eg: togglers.north + // border-pane open/close + , hide: hide // method - ditto + , show: show // method - ditto + , toggle: toggle // method - pass a 'pane' ("north", "west", etc) + , open: open // method - ditto + , close: close // method - ditto + , slideOpen: slideOpen // method - ditto + , slideClose: slideClose // method - ditto + , slideToggle: slideToggle // method - ditto + // pane actions + , setSizeLimits: setSizeLimits // method - pass a 'pane' - update state min/max data + , _sizePane: sizePane // method -intended for user by plugins only! + , sizePane: manualSizePane // method - pass a 'pane' AND an 'outer-size' in pixels or percent, or 'auto' + , sizeContent: sizeContent // method - pass a 'pane' + , swapPanes: swapPanes // method - pass TWO 'panes' - will swap them + , showMasks: showMasks // method - pass a 'pane' OR list of panes - default = all panes with mask option set + , hideMasks: hideMasks // method - ditto' + // pane element methods + , initContent: initContent // method - ditto + , addPane: addPane // method - pass a 'pane' + , removePane: removePane // method - pass a 'pane' to remove from layout, add 'true' to delete the pane-elem + , createChildLayout: createChildLayout// method - pass a 'pane' and (optional) layout-options (OVERRIDES options[pane].childOptions + // special pane option setting + , enableClosable: enableClosable // method - pass a 'pane' + , disableClosable: disableClosable // method - ditto + , enableSlidable: enableSlidable // method - ditto + , disableSlidable: disableSlidable // method - ditto + , enableResizable: enableResizable // method - ditto + , disableResizable: disableResizable// method - ditto + // utility methods for panes + , allowOverflow: allowOverflow // utility - pass calling element (this) + , resetOverflow: resetOverflow // utility - ditto + // layout control + , destroy: destroy // method - no parameters + , initPanes: isInitialized // method - no parameters + , resizeAll: resizeAll // method - no parameters + // callback triggering + , runCallbacks: _runCallbacks // method - pass evtName & pane (if a pane-event), eg: trigger("onopen", "west") + // alias collections of options, state and children - created in addPane and extended elsewhere + , hasParentLayout: false // set by initContainer() + , children: children // pointers to child-layouts, eg: Instance.children["west"] + , north: false // alias group: { name: pane, pane: $Ps[pane], options: options[pane], state: state[pane], child: children[pane] } + , south: false // ditto + , west: false // ditto + , east: false // ditto + , center: false // ditto + }; + + // create the border layout NOW + if (_create() === 'cancel') // onload_start callback returned false to CANCEL layout creation + return null; + else // true OR false -- if layout-elements did NOT init (hidden or do not exist), can auto-init later + return Instance; // return the Instance object + +} + + +/* OLD versions of jQuery only set $.support.boxModel after page is loaded + * so if this is IE, use support.boxModel to test for quirks-mode (ONLY IE changes boxModel). + */ +$(function(){ + var b = $.layout.browser; + if (b.msie) b.boxModel = $.support.boxModel; +}); + + +/** + * jquery.layout.state 1.0 + * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $ + * + * Copyright (c) 2010 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @dependancies: UI Layout 1.3.0.rc30.1 or higher + * @dependancies: $.ui.cookie (above) + * + * @support: http://groups.google.com/group/jquery-ui-layout + */ +/* + * State-management options stored in options.stateManagement, which includes a .cookie hash + * Default options saves ALL KEYS for ALL PANES, ie: pane.size, pane.isClosed, pane.isHidden + * + * // STATE/COOKIE OPTIONS + * @example $(el).layout({ + stateManagement: { + enabled: true + , stateKeys: "east.size,west.size,east.isClosed,west.isClosed" + , cookie: { name: "appLayout", path: "/" } + } + }) + * @example $(el).layout({ stateManagement__enabled: true }) // enable auto-state-management using cookies + * @example $(el).layout({ stateManagement__cookie: { name: "appLayout", path: "/" } }) + * @example $(el).layout({ stateManagement__cookie__name: "appLayout", stateManagement__cookie__path: "/" }) + * + * // STATE/COOKIE METHODS + * @example myLayout.saveCookie( "west.isClosed,north.size,south.isHidden", {expires: 7} ); + * @example myLayout.loadCookie(); + * @example myLayout.deleteCookie(); + * @example var JSON = myLayout.readState(); // CURRENT Layout State + * @example var JSON = myLayout.readCookie(); // SAVED Layout State (from cookie) + * @example var JSON = myLayout.state.stateData; // LAST LOADED Layout State (cookie saved in layout.state hash) + * + * CUSTOM STATE-MANAGEMENT (eg, saved in a database) + * @example var JSON = myLayout.readState( "west.isClosed,north.size,south.isHidden" ); + * @example myLayout.loadState( JSON ); + */ + +/** + * UI COOKIE UTILITY + * + * A $.cookie OR $.ui.cookie namespace *should be standard*, but until then... + * This creates $.ui.cookie so Layout does not need the cookie.jquery.js plugin + * NOTE: This utility is REQUIRED by the layout.state plugin + * + * Cookie methods in Layout are created as part of State Management + */ +if (!$.ui) $.ui = {}; +$.ui.cookie = { + + // cookieEnabled is not in DOM specs, but DOES works in all browsers,including IE6 + acceptsCookies: !!navigator.cookieEnabled + +, read: function (name) { + var + c = document.cookie + , cs = c ? c.split(';') : [] + , pair // loop var + ; + for (var i=0, n=cs.length; i < n; i++) { + pair = $.trim(cs[i]).split('='); // name=value pair + if (pair[0] == name) // found the layout cookie + return decodeURIComponent(pair[1]); + + } + return null; + } + +, write: function (name, val, cookieOpts) { + var + params = '' + , date = '' + , clear = false + , o = cookieOpts || {} + , x = o.expires + ; + if (x && x.toUTCString) + date = x; + else if (x === null || typeof x === 'number') { + date = new Date(); + if (x > 0) + date.setDate(date.getDate() + x); + else { + date.setFullYear(1970); + clear = true; + } + } + if (date) params += ';expires='+ date.toUTCString(); + if (o.path) params += ';path='+ o.path; + if (o.domain) params += ';domain='+ o.domain; + if (o.secure) params += ';secure'; + document.cookie = name +'='+ (clear ? "" : encodeURIComponent( val )) + params; // write or clear cookie + } + +, clear: function (name) { + $.ui.cookie.write(name, '', {expires: -1}); + } + +}; +// if cookie.jquery.js is not loaded, create an alias to replicate it +// this may be useful to other plugins or code dependent on that plugin +if (!$.cookie) $.cookie = function (k, v, o) { + var C = $.ui.cookie; + if (v === null) + C.clear(k); + else if (v === undefined) + return C.read(k); + else + C.write(k, v, o); +}; + + +// tell Layout that the state plugin is available +$.layout.plugins.stateManagement = true; + +// Add State-Management options to layout.defaults +$.layout.config.optionRootKeys.push("stateManagement"); +$.layout.defaults.stateManagement = { + enabled: false // true = enable state-management, even if not using cookies +, autoSave: true // Save a state-cookie when page exits? +, autoLoad: true // Load the state-cookie when Layout inits? + // List state-data to save - must be pane-specific +, stateKeys: "north.size,south.size,east.size,west.size,"+ + "north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+ + "north.isHidden,south.isHidden,east.isHidden,west.isHidden" +, cookie: { + name: "" // If not specified, will use Layout.name, else just "Layout" + , domain: "" // blank = current domain + , path: "" // blank = current page, '/' = entire website + , expires: "" // 'days' to keep cookie - leave blank for 'session cookie' + , secure: false + } +}; +// Set stateManagement as a layout-option, NOT a pane-option +$.layout.optionsMap.layout.push("stateManagement"); + +/* + * State Management methods + */ +$.layout.state = { + + /** + * Get the current layout state and save it to a cookie + * + * myLayout.saveCookie( keys, cookieOpts ) + * + * @param {Object} inst + * @param {(string|Array)=} keys + * @param {Object=} cookieOpts + */ + saveCookie: function (inst, keys, cookieOpts) { + var o = inst.options + , oS = o.stateManagement + , oC = $.extend(true, {}, oS.cookie, cookieOpts || null) + , data = inst.state.stateData = inst.readState( keys || oS.stateKeys ) // read current panes-state + ; + $.ui.cookie.write( oC.name || o.name || "Layout", $.layout.state.encodeJSON(data), oC ); + return $.extend(true, {}, data); // return COPY of state.stateData data + } + + /** + * Remove the state cookie + * + * @param {Object} inst + */ +, deleteCookie: function (inst) { + var o = inst.options; + $.ui.cookie.clear( o.stateManagement.cookie.name || o.name || "Layout" ); + } + + /** + * Read & return data from the cookie - as JSON + * + * @param {Object} inst + */ +, readCookie: function (inst) { + var o = inst.options; + var c = $.ui.cookie.read( o.stateManagement.cookie.name || o.name || "Layout" ); + // convert cookie string back to a hash and return it + return c ? $.layout.state.decodeJSON(c) : {}; + } + + /** + * Get data from the cookie and USE IT to loadState + * + * @param {Object} inst + */ +, loadCookie: function (inst) { + var c = $.layout.state.readCookie(inst); // READ the cookie + if (c) { + inst.state.stateData = $.extend(true, {}, c); // SET state.stateData + inst.loadState(c); // LOAD the retrieved state + } + return c; + } + + /** + * Update layout options from the cookie, if one exists + * + * @param {Object} inst + * @param {Object=} stateData + * @param {boolean=} animate + */ +, loadState: function (inst, stateData, animate) { + stateData = $.layout.transformData( stateData ); // panes = default subkey + if ($.isEmptyObject( stateData )) return; + $.extend(true, inst.options, stateData); // update layout options + // if layout has already been initialized, then UPDATE layout state + if (inst.state.initialized) { + var pane, vis, o, s, h, c + , noAnimate = (animate===false) + ; + $.each($.layout.config.borderPanes, function (idx, pane) { + state = inst.state[pane]; + o = stateData[ pane ]; + if (typeof o != 'object') return; // no key, continue + s = o.size; + c = o.initClosed; + h = o.initHidden; + vis = state.isVisible; + // resize BEFORE opening + if (!vis) + inst.sizePane(pane, s, false, false); + if (h === true) inst.hide(pane, noAnimate); + else if (c === false) inst.open (pane, false, noAnimate); + else if (c === true) inst.close(pane, false, noAnimate); + else if (h === false) inst.show (pane, false, noAnimate); + // resize AFTER any other actions + if (vis) + inst.sizePane(pane, s, false, noAnimate); // animate resize if option passed + }); + }; + } + + /** + * Get the *current layout state* and return it as a hash + * + * @param {Object=} inst + * @param {(string|Array)=} keys + */ +, readState: function (inst, keys) { + var + data = {} + , alt = { isClosed: 'initClosed', isHidden: 'initHidden' } + , state = inst.state + , panes = $.layout.config.allPanes + , pair, pane, key, val + ; + if (!keys) keys = inst.options.stateManagement.stateKeys; // if called by user + if ($.isArray(keys)) keys = keys.join(","); + // convert keys to an array and change delimiters from '__' to '.' + keys = keys.replace(/__/g, ".").split(','); + // loop keys and create a data hash + for (var i=0, n=keys.length; i < n; i++) { + pair = keys[i].split("."); + pane = pair[0]; + key = pair[1]; + if ($.inArray(pane, panes) < 0) continue; // bad pane! + val = state[ pane ][ key ]; + if (val == undefined) continue; + if (key=="isClosed" && state[pane]["isSliding"]) + val = true; // if sliding, then *really* isClosed + ( data[pane] || (data[pane]={}) )[ alt[key] ? alt[key] : key ] = val; + } + return data; + } + + /** + * Stringify a JSON hash so can save in a cookie or db-field + */ +, encodeJSON: function (JSON) { + return parse(JSON); + function parse (h) { + var D=[], i=0, k, v, t; // k = key, v = value + for (k in h) { + v = h[k]; + t = typeof v; + if (t == 'string') // STRING - add quotes + v = '"'+ v +'"'; + else if (t == 'object') // SUB-KEY - recurse into it + v = parse(v); + D[i++] = '"'+ k +'":'+ v; + } + return '{'+ D.join(',') +'}'; + }; + } + + /** + * Convert stringified JSON back to a hash object + * @see $.parseJSON(), adding in jQuery 1.4.1 + */ +, decodeJSON: function (str) { + try { return $.parseJSON ? $.parseJSON(str) : window["eval"]("("+ str +")") || {}; } + catch (e) { return {}; } + } + + +, _create: function (inst) { + var _ = $.layout.state; + // ADD State-Management plugin methods to inst + $.extend( inst, { + // readCookie - update options from cookie - returns hash of cookie data + readCookie: function () { return _.readCookie(inst); } + // deleteCookie + , deleteCookie: function () { _.deleteCookie(inst); } + // saveCookie - optionally pass keys-list and cookie-options (hash) + , saveCookie: function (keys, cookieOpts) { return _.saveCookie(inst, keys, cookieOpts); } + // loadCookie - readCookie and use to loadState() - returns hash of cookie data + , loadCookie: function () { return _.loadCookie(inst); } + // loadState - pass a hash of state to use to update options + , loadState: function (stateData, animate) { _.loadState(inst, stateData, animate); } + // readState - returns hash of current layout-state + , readState: function (keys) { return _.readState(inst, keys); } + // add JSON utility methods too... + , encodeJSON: _.encodeJSON + , decodeJSON: _.decodeJSON + }); + + // init state.stateData key, even if plugin is initially disabled + inst.state.stateData = {}; + + // read and load cookie-data per options + var oS = inst.options.stateManagement; + if (oS.enabled) { + if (oS.autoLoad) // update the options from the cookie + inst.loadCookie(); + else // don't modify options - just store cookie data in state.stateData + inst.state.stateData = inst.readCookie(); + } + } + +, _unload: function (inst) { + var oS = inst.options.stateManagement; + if (oS.enabled) { + if (oS.autoSave) // save a state-cookie automatically + inst.saveCookie(); + else // don't save a cookie, but do store state-data in state.stateData key + inst.state.stateData = inst.readState(); + } + } + +}; + +// add state initialization method to Layout's onCreate array of functions +$.layout.onCreate.push( $.layout.state._create ); +$.layout.onUnload.push( $.layout.state._unload ); + + + + +/** + * jquery.layout.buttons 1.0 + * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $ + * + * Copyright (c) 2010 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @dependancies: UI Layout 1.3.0.rc30.1 or higher + * + * @support: http://groups.google.com/group/jquery-ui-layout + * + * Docs: [ to come ] + * Tips: [ to come ] + */ + +// tell Layout that the state plugin is available +$.layout.plugins.buttons = true; + +// Add buttons options to layout.defaults +$.layout.defaults.autoBindCustomButtons = false; +// Specify autoBindCustomButtons as a layout-option, NOT a pane-option +$.layout.optionsMap.layout.push("autoBindCustomButtons"); + +/* + * Button methods + */ +$.layout.buttons = { + + /** + * Searches for .ui-layout-button-xxx elements and auto-binds them as layout-buttons + * + * @see _create() + * + * @param {Object} inst Layout Instance object + */ + init: function (inst) { + var pre = "ui-layout-button-" + , layout = inst.options.name || "" + , name; + $.each("toggle,open,close,pin,toggle-slide,open-slide".split(","), function (i, action) { + $.each($.layout.config.borderPanes, function (ii, pane) { + $("."+pre+action+"-"+pane).each(function(){ + // if button was previously 'bound', data.layoutName was set, but is blank if layout has no 'name' + name = $(this).data("layoutName") || $(this).attr("layoutName"); + if (name == undefined || name === layout) + inst.bindButton(this, action, pane); + }); + }); + }); + } + + /** + * Helper function to validate params received by addButton utilities + * + * Two classes are added to the element, based on the buttonClass... + * The type of button is appended to create the 2nd className: + * - ui-layout-button-pin // action btnClass + * - ui-layout-button-pin-west // action btnClass + pane + * - ui-layout-button-toggle + * - ui-layout-button-open + * - ui-layout-button-close + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * + * @return {Array.} If both params valid, the element matching 'selector' in a jQuery wrapper - otherwise returns null + */ +, get: function (inst, selector, pane, action) { + var $E = $(selector) + , o = inst.options + , err = o.errors.addButtonError + ; + if (!$E.length) { // element not found + $.layout.msg(err +" "+ o.errors.selector +": "+ selector, true); + } + else if ($.inArray(pane, $.layout.config.borderPanes) < 0) { // invalid 'pane' sepecified + $.layout.msg(err +" "+ o.errors.pane +": "+ pane, true); + $E = $(""); // NO BUTTON + } + else { // VALID + var btn = o[pane].buttonClass +"-"+ action; + $E .addClass( btn +" "+ btn +"-"+ pane ) + .data("layoutName", o.name); // add layout identifier - even if blank! + } + return $E; + } + + + /** + * NEW syntax for binding layout-buttons - will eventually replace addToggle, addOpen, etc. + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} action + * @param {string} pane + */ +, bind: function (inst, selector, action, pane) { + var _ = $.layout.buttons; + switch (action.toLowerCase()) { + case "toggle": _.addToggle (inst, selector, pane); break; + case "open": _.addOpen (inst, selector, pane); break; + case "close": _.addClose (inst, selector, pane); break; + case "pin": _.addPin (inst, selector, pane); break; + case "toggle-slide": _.addToggle (inst, selector, pane, true); break; + case "open-slide": _.addOpen (inst, selector, pane, true); break; + } + return inst; + } + + /** + * Add a custom Toggler button for a pane + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * @param {boolean=} slide true = slide-open, false = pin-open + */ +, addToggle: function (inst, selector, pane, slide) { + $.layout.buttons.get(inst, selector, pane, "toggle") + .click(function(evt){ + inst.toggle(pane, !!slide); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Open button for a pane + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * @param {boolean=} slide true = slide-open, false = pin-open + */ +, addOpen: function (inst, selector, pane, slide) { + $.layout.buttons.get(inst, selector, pane, "open") + .attr("title", inst.options[pane].tips.Open) + .click(function (evt) { + inst.open(pane, !!slide); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Close button for a pane + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + */ +, addClose: function (inst, selector, pane) { + $.layout.buttons.get(inst, selector, pane, "close") + .attr("title", inst.options[pane].tips.Close) + .click(function (evt) { + inst.close(pane); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Pin button for a pane + * + * Four classes are added to the element, based on the paneClass for the associated pane... + * Assuming the default paneClass and the pin is 'up', these classes are added for a west-pane pin: + * - ui-layout-pane-pin + * - ui-layout-pane-west-pin + * - ui-layout-pane-pin-up + * - ui-layout-pane-west-pin-up + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the pin is for: 'north', 'south', etc. + */ +, addPin: function (inst, selector, pane) { + var _ = $.layout.buttons + , $E = _.get(inst, selector, pane, "pin"); + if ($E.length) { + var s = inst.state[pane]; + $E.click(function (evt) { + _.setPinState(inst, $(this), pane, (s.isSliding || s.isClosed)); + if (s.isSliding || s.isClosed) inst.open( pane ); // change from sliding to open + else inst.close( pane ); // slide-closed + evt.stopPropagation(); + }); + // add up/down pin attributes and classes + _.setPinState(inst, $E, pane, (!s.isClosed && !s.isSliding)); + // add this pin to the pane data so we can 'sync it' automatically + // PANE.pins key is an array so we can store multiple pins for each pane + s.pins.push( selector ); // just save the selector string + } + return inst; + } + + /** + * Change the class of the pin button to make it look 'up' or 'down' + * + * @see addPin(), syncPins() + * + * @param {Object} inst Layout Instance object + * @param {Array.} $Pin The pin-span element in a jQuery wrapper + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin true = set the pin 'down', false = set it 'up' + */ +, setPinState: function (inst, $Pin, pane, doPin) { + var updown = $Pin.attr("pin"); + if (updown && doPin === (updown=="down")) return; // already in correct state + var + o = inst.options[pane] + , pin = o.buttonClass +"-pin" + , side = pin +"-"+ pane + , UP = pin +"-up "+ side +"-up" + , DN = pin +"-down "+side +"-down" + ; + $Pin + .attr("pin", doPin ? "down" : "up") // logic + .attr("title", doPin ? o.tips.Unpin : o.tips.Pin) + .removeClass( doPin ? UP : DN ) + .addClass( doPin ? DN : UP ) + ; + } + + /** + * INTERNAL function to sync 'pin buttons' when pane is opened or closed + * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes + * + * @see open(), close() + * + * @param {Object} inst Layout Instance object + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin True means set the pin 'down', False means 'up' + */ +, syncPinBtns: function (inst, pane, doPin) { + // REAL METHOD IS _INSIDE_ LAYOUT - THIS IS HERE JUST FOR REFERENCE + $.each(inst.state[pane].pins, function (i, selector) { + $.layout.buttons.setPinState(inst, $(selector), pane, doPin); + }); + } + + +, _load: function (inst) { + var _ = $.layout.buttons; + // ADD Button methods to Layout Instance + // Note: sel = jQuery Selector string + $.extend( inst, { + bindButton: function (sel, action, pane) { return _.bind(inst, sel, action, pane); } + // DEPRECATED METHODS + , addToggleBtn: function (sel, pane, slide) { return _.addToggle(inst, sel, pane, slide); } + , addOpenBtn: function (sel, pane, slide) { return _.addOpen(inst, sel, pane, slide); } + , addCloseBtn: function (sel, pane) { return _.addClose(inst, sel, pane); } + , addPinBtn: function (sel, pane) { return _.addPin(inst, sel, pane); } + }); + + // init state array to hold pin-buttons + for (var i=0; i<4; i++) { + var pane = $.layout.config.borderPanes[i]; + inst.state[pane].pins = []; + } + + // auto-init buttons onLoad if option is enabled + if ( inst.options.autoBindCustomButtons ) + _.init(inst); + } + +, _unload: function (inst) { + // TODO: unbind all buttons??? + } + +}; + +// add initialization method to Layout's onLoad array of functions +$.layout.onLoad.push( $.layout.buttons._load ); +//$.layout.onUnload.push( $.layout.buttons._unload ); + + + +/** + * jquery.layout.browserZoom 1.0 + * $Date: 2011-12-29 08:00:00 (Thu, 29 Dec 2011) $ + * + * Copyright (c) 2012 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @dependancies: UI Layout 1.3.0.rc30.1 or higher + * + * @support: http://groups.google.com/group/jquery-ui-layout + * + * @todo: Extend logic to handle other problematic zooming in browsers + * @todo: Add hotkey/mousewheel bindings to _instantly_ respond to these zoom event + */ + +// tell Layout that the plugin is available +$.layout.plugins.browserZoom = true; + +$.layout.defaults.browserZoomCheckInterval = 1000; +$.layout.optionsMap.layout.push("browserZoomCheckInterval"); + +/* + * browserZoom methods + */ +$.layout.browserZoom = { + + _init: function (inst) { + // abort if browser does not need this check + if ($.layout.browserZoom.ratio() !== false) + $.layout.browserZoom._setTimer(inst); + } + +, _setTimer: function (inst) { + // abort if layout destroyed or browser does not need this check + if (inst.destroyed) return; + var o = inst.options + , s = inst.state + // don't need check if inst has parentLayout, but check occassionally in case parent destroyed! + // MINIMUM 100ms interval, for performance + , ms = inst.hasParentLayout ? 5000 : Math.max( o.browserZoomCheckInterval, 100 ) + ; + // set the timer + setTimeout(function(){ + if (inst.destroyed || !o.resizeWithWindow) return; + var d = $.layout.browserZoom.ratio(); + if (d !== s.browserZoom) { + s.browserZoom = d; + inst.resizeAll(); + } + // set a NEW timeout + $.layout.browserZoom._setTimer(inst); + } + , ms ); + } + +, ratio: function () { + var w = window + , s = screen + , d = document + , dE = d.documentElement || d.body + , b = $.layout.browser + , v = b.version + , r, sW, cW + ; + // we can ignore all browsers that fire window.resize event onZoom + if ((b.msie && v > 8) + || !b.msie + ) return false; // don't need to track zoom + + if (s.deviceXDPI) + return calc(s.deviceXDPI, s.systemXDPI); + // everything below is just for future reference! + if (b.webkit && (r = d.body.getBoundingClientRect)) + return calc((r.left - r.right), d.body.offsetWidth); + if (b.webkit && (sW = w.outerWidth)) + return calc(sW, w.innerWidth); + if ((sW = s.width) && (cW = dE.clientWidth)) + return calc(sW, cW); + return false; // no match, so cannot - or don't need to - track zoom + + function calc (x,y) { return (parseInt(x,10) / parseInt(y,10) * 100).toFixed(); } + } + +}; +// add initialization method to Layout's onLoad array of functions +$.layout.onReady.push( $.layout.browserZoom._init ); + + + +})( jQuery ); \ No newline at end of file diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/modernizr.custom.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/modernizr.custom.js new file mode 100644 index 0000000000..4688d633fe --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/modernizr.custom.js @@ -0,0 +1,4 @@ +/* Modernizr 2.5.3 (Custom Build) | MIT & BSD + * Build: http://www.modernizr.com/download/#-inlinesvg + */ +;window.Modernizr=function(a,b,c){function u(a){i.cssText=a}function v(a,b){return u(prefixes.join(a+";")+(b||""))}function w(a,b){return typeof a===b}function x(a,b){return!!~(""+a).indexOf(b)}function y(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:w(f,"function")?f.bind(d||b):f}return!1}var d="2.5.3",e={},f=b.documentElement,g="modernizr",h=b.createElement(g),i=h.style,j,k={}.toString,l={svg:"http://www.w3.org/2000/svg"},m={},n={},o={},p=[],q=p.slice,r,s={}.hasOwnProperty,t;!w(s,"undefined")&&!w(s.call,"undefined")?t=function(a,b){return s.call(a,b)}:t=function(a,b){return b in a&&w(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=q.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(q.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(q.call(arguments)))};return e}),m.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==l.svg};for(var z in m)t(m,z)&&(r=z.toLowerCase(),e[r]=m[z](),p.push((e[r]?"":"no-")+r));return u(""),h=j=null,e._version=d,e}(this,this.document); \ No newline at end of file diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li-a.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li-a.png new file mode 100644 index 0000000000..9b32288e04 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li-a.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li.png new file mode 100644 index 0000000000..fd0ad06e81 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object.png new file mode 100644 index 0000000000..ad312793ea Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_big.png new file mode 100644 index 0000000000..67ffca79de Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_big.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_diagram.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_diagram.png new file mode 100644 index 0000000000..6e9f2f743f Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_diagram.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_class_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_class_big.png new file mode 100644 index 0000000000..7502942eb6 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_class_big.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_trait_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_trait_big.png new file mode 100644 index 0000000000..c777bfce8d Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_trait_big.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_type_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_type_big.png new file mode 100644 index 0000000000..7502942eb6 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_type_big.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownderbg2.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownderbg2.gif new file mode 100644 index 0000000000..848dd5963a Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownderbg2.gif differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg.gif new file mode 100644 index 0000000000..34a04249ee Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg.gif differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg2.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg2.gif new file mode 100644 index 0000000000..2ed33b0aa4 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg2.gif differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package.png new file mode 100644 index 0000000000..6ea17ac320 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package_big.png new file mode 100644 index 0000000000..529aa93188 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package_big.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/packagesbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/packagesbg.gif new file mode 100644 index 0000000000..00c3378a2a Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/packagesbg.gif differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/raphael-min.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/raphael-min.js new file mode 100644 index 0000000000..d30dbad858 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/raphael-min.js @@ -0,0 +1,10 @@ +// ┌────────────────────────────────────────────────────────────────────┐ \\ +// │ Raphaël 2.1.0 - JavaScript Vector Library │ \\ +// ├────────────────────────────────────────────────────────────────────┤ \\ +// │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ +// │ Copyright © 2008-2012 Sencha Labs (http://sencha.com) │ \\ +// ├────────────────────────────────────────────────────────────────────┤ \\ +// │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\ +// └────────────────────────────────────────────────────────────────────┘ \\ + +(function(a){var b="0.3.4",c="hasOwnProperty",d=/[\.\/]/,e="*",f=function(){},g=function(a,b){return a-b},h,i,j={n:{}},k=function(a,b){var c=j,d=i,e=Array.prototype.slice.call(arguments,2),f=k.listeners(a),l=0,m=!1,n,o=[],p={},q=[],r=h,s=[];h=a,i=0;for(var t=0,u=f.length;tf*b.top){e=b.percents[y],p=b.percents[y-1]||0,t=t/b.top*(e-p),o=b.percents[y+1],j=b.anim[e];break}f&&d.attr(b.anim[b.percents[y]])}if(!!j){if(!k){for(var A in j)if(j[g](A))if(U[g](A)||d.paper.customAttributes[g](A)){u[A]=d.attr(A),u[A]==null&&(u[A]=T[A]),v[A]=j[A];switch(U[A]){case C:w[A]=(v[A]-u[A])/t;break;case"colour":u[A]=a.getRGB(u[A]);var B=a.getRGB(v[A]);w[A]={r:(B.r-u[A].r)/t,g:(B.g-u[A].g)/t,b:(B.b-u[A].b)/t};break;case"path":var D=bR(u[A],v[A]),E=D[1];u[A]=D[0],w[A]=[];for(y=0,z=u[A].length;yd)return d;while(cf?c=e:d=e,e=(d-c)/2+c}return e}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function m(a){return((i*a+h)*a+g)*a}var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;return n(a,1/(200*f))}function cq(){return this.x+q+this.y+q+this.width+" × "+this.height}function cp(){return this.x+q+this.y}function cb(a,b,c,d,e,f){a!=null?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function bH(b,c,d){b=a._path2curve(b),c=a._path2curve(c);var e,f,g,h,i,j,k,l,m,n,o=d?0:[];for(var p=0,q=b.length;p=0&&y<=1&&A>=0&&A<=1&&(d?n++:n.push({x:x.x,y:x.y,t1:y,t2:A}))}}return n}function bF(a,b){return bG(a,b,1)}function bE(a,b){return bG(a,b)}function bD(a,b,c,d,e,f,g,h){if(!(x(a,c)x(e,g)||x(b,d)x(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(!k)return;var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(n<+y(a,c).toFixed(2)||n>+x(a,c).toFixed(2)||n<+y(e,g).toFixed(2)||n>+x(e,g).toFixed(2)||o<+y(b,d).toFixed(2)||o>+x(b,d).toFixed(2)||o<+y(f,h).toFixed(2)||o>+x(f,h).toFixed(2))return;return{x:l,y:m}}}function bC(a,b,c,d,e,f,g,h,i){if(!(i<0||bB(a,b,c,d,e,f,g,h)n)k/=2,l+=(m1?1:i<0?0:i;var j=i/2,k=12,l=[-0.1252,.1252,-0.3678,.3678,-0.5873,.5873,-0.7699,.7699,-0.9041,.9041,-0.9816,.9816],m=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],n=0;for(var o=0;od;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}function bx(){return this.hex}function bv(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),h=d.cache=d.cache||{},i=d.count=d.count||[];if(h[g](f)){bu(i,f);return c?c(h[f]):h[f]}i.length>=1e3&&delete h[i.shift()],i.push(f),h[f]=a[m](b,e);return c?c(h[f]):h[f]}return d}function bu(a,b){for(var c=0,d=a.length;c',bl=bk.firstChild,bl.style.behavior="url(#default#VML)";if(!bl||typeof bl.adj!="object")return a.type=p;bk=null}a.svg=!(a.vml=a.type=="VML"),a._Paper=j,a.fn=k=j.prototype=a.prototype,a._id=0,a._oid=0,a.is=function(a,b){b=v.call(b);if(b=="finite")return!M[g](+a);if(b=="array")return a instanceof Array;return b=="null"&&a===null||b==typeof a&&a!==null||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||H.call(a).slice(8,-1).toLowerCase()==b},a.angle=function(b,c,d,e,f,g){if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return(180+w.atan2(-i,-h)*180/B+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)},a.rad=function(a){return a%360*B/180},a.deg=function(a){return a*180/B%360},a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,E)){var e=b.length;while(e--)if(z(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(fb-d)return c-f+b}return c};var bn=a.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=w.random()*16|0,c=a=="x"?b:b&3|8;return c.toString(16)});a.setWindow=function(b){eve("raphael.setWindow",a,h.win,b),h.win=b,h.doc=h.win.document,a._engine.initWin&&a._engine.initWin(h.win)};var bo=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write(""),e.close(),d=e.body}catch(f){d=createPopup().document.body}var g=d.createTextRange();bo=bv(function(a){try{d.style.color=r(a).replace(c,p);var b=g.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=h.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",h.doc.body.appendChild(i),bo=bv(function(a){i.style.color=a;return h.doc.defaultView.getComputedStyle(i,p).getPropertyValue("color")})}return bo(b)},bp=function(){return"hsb("+[this.h,this.s,this.b]+")"},bq=function(){return"hsl("+[this.h,this.s,this.l]+")"},br=function(){return this.hex},bs=function(b,c,d){c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b&&(d=b.b,c=b.g,b=b.r);if(c==null&&a.is(b,D)){var e=a.getRGB(b);b=e.r,c=e.g,d=e.b}if(b>1||c>1||d>1)b/=255,c/=255,d/=255;return[b,c,d]},bt=function(b,c,d,e){b*=255,c*=255,d*=255;var f={r:b,g:c,b:d,hex:a.rgb(b,c,d),toString:br};a.is(e,"finite")&&(f.opacity=e);return f};a.color=function(b){var c;a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b?(c=a.hsb2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b?(c=a.hsl2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):(a.is(b,"string")&&(b=a.getRGB(b)),a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b?(c=a.rgb2hsl(b),b.h=c.h,b.s=c.s,b.l=c.l,c=a.rgb2hsb(b),b.v=c.b):(b={hex:"none"},b.r=b.g=b.b=b.h=b.s=b.v=b.l=-1)),b.toString=br;return b},a.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,a=a.h,d=a.o),a*=360;var e,f,g,h,i;a=a%360/60,i=c*b,h=i*(1-z(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return bt(e,f,g,d)},a.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h);if(a>1||b>1||c>1)a/=360,b/=100,c/=100;a*=360;var e,f,g,h,i;a=a%360/60,i=2*b*(c<.5?c:1-c),h=i*(1-z(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return bt(e,f,g,d)},a.rgb2hsb=function(a,b,c){c=bs(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;f=x(a,b,c),g=f-y(a,b,c),d=g==0?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=g==0?0:g/f;return{h:d,s:e,b:f,toString:bp}},a.rgb2hsl=function(a,b,c){c=bs(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;g=x(a,b,c),h=y(a,b,c),i=g-h,d=i==0?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=i==0?0:f<.5?i/(2*f):i/(2-2*f);return{h:d,s:e,l:f,toString:bq}},a._path2string=function(){return this.join(",").replace(Y,"$1")};var bw=a._preload=function(a,b){var c=h.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top:-9999em",c.onload=function(){b.call(this),this.onload=null,h.doc.body.removeChild(this)},c.onerror=function(){h.doc.body.removeChild(this)},h.doc.body.appendChild(c),c.src=a};a.getRGB=bv(function(b){if(!b||!!((b=r(b)).indexOf("-")+1))return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bx};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none",toString:bx};!X[g](b.toLowerCase().substring(0,2))&&b.charAt()!="#"&&(b=bo(b));var c,d,e,f,h,i,j,k=b.match(L);if(k){k[2]&&(f=R(k[2].substring(5),16),e=R(k[2].substring(3,5),16),d=R(k[2].substring(1,3),16)),k[3]&&(f=R((i=k[3].charAt(3))+i,16),e=R((i=k[3].charAt(2))+i,16),d=R((i=k[3].charAt(1))+i,16)),k[4]&&(j=k[4][s](W),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),k[1].toLowerCase().slice(0,4)=="rgba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100));if(k[5]){j=k[5][s](W),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,f,h)}if(k[6]){j=k[6][s](W),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsla"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,f,h)}k={r:d,g:e,b:f,toString:bx},k.hex="#"+(16777216|f|e<<8|d<<16).toString(16).slice(1),a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bx}},a),a.hsb=bv(function(b,c,d){return a.hsb2rgb(b,c,d).hex}),a.hsl=bv(function(b,c,d){return a.hsl2rgb(b,c,d).hex}),a.rgb=bv(function(a,b,c){return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)}),a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b}));return c.hex},a.getColor.reset=function(){delete this.start},a.parsePathString=function(b){if(!b)return null;var c=bz(b);if(c.arr)return bJ(c.arr);var d={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},e=[];a.is(b,E)&&a.is(b[0],E)&&(e=bJ(b)),e.length||r(b).replace(Z,function(a,b,c){var f=[],g=b.toLowerCase();c.replace(_,function(a,b){b&&f.push(+b)}),g=="m"&&f.length>2&&(e.push([b][n](f.splice(0,2))),g="l",b=b=="m"?"l":"L");if(g=="r")e.push([b][n](f));else while(f.length>=d[g]){e.push([b][n](f.splice(0,d[g])));if(!d[g])break}}),e.toString=a._path2string,c.arr=bJ(e);return e},a.parseTransformString=bv(function(b){if(!b)return null;var c={r:3,s:4,t:2,m:6},d=[];a.is(b,E)&&a.is(b[0],E)&&(d=bJ(b)),d.length||r(b).replace($,function(a,b,c){var e=[],f=v.call(b);c.replace(_,function(a,b){b&&e.push(+b)}),d.push([b][n](e))}),d.toString=a._path2string;return d});var bz=function(a){var b=bz.ps=bz.ps||{};b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[g](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])});return b[a]};a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=A(j,3),l=A(j,2),m=i*i,n=m*i,o=k*a+l*3*i*c+j*3*i*i*e+n*g,p=k*b+l*3*i*d+j*3*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,x=j*e+i*g,y=j*f+i*h,z=90-w.atan2(q-s,r-t)*180/B;(q>s||r=a.x&&b<=a.x2&&c>=a.y&&c<=a.y2},a.isBBoxIntersect=function(b,c){var d=a.isPointInsideBBox;return d(c,b.x,b.y)||d(c,b.x2,b.y)||d(c,b.x,b.y2)||d(c,b.x2,b.y2)||d(b,c.x,c.y)||d(b,c.x2,c.y)||d(b,c.x,c.y2)||d(b,c.x2,c.y2)||(b.xc.x||c.xb.x)&&(b.yc.y||c.yb.y)},a.pathIntersection=function(a,b){return bH(a,b)},a.pathIntersectionNumber=function(a,b){return bH(a,b,1)},a.isPointInsidePath=function(b,c,d){var e=a.pathBBox(b);return a.isPointInsideBBox(e,c,d)&&bH(b,[["M",c,d],["H",e.x2+10]],1)%2==1},a._removedFactory=function(a){return function(){eve("raphael.log",null,"Raphaël: you are calling to method “"+a+"” of removed object",a)}};var bI=a.pathBBox=function(a){var b=bz(a);if(b.bbox)return b.bbox;if(!a)return{x:0,y:0,width:0,height:0,x2:0,y2:0};a=bR(a);var c=0,d=0,e=[],f=[],g;for(var h=0,i=a.length;h1&&(v=w.sqrt(v),c=v*c,d=v*d);var x=c*c,y=d*d,A=(f==g?-1:1)*w.sqrt(z((x*y-x*u*u-y*t*t)/(x*u*u+y*t*t))),C=A*c*u/d+(a+h)/2,D=A*-d*t/c+(b+i)/2,E=w.asin(((b-D)/d).toFixed(9)),F=w.asin(((i-D)/d).toFixed(9));E=aF&&(E=E-B*2),!g&&F>E&&(F=F-B*2)}else E=j[0],F=j[1],C=j[2],D=j[3];var G=F-E;if(z(G)>k){var H=F,I=h,J=i;F=E+k*(g&&F>E?1:-1),h=C+c*w.cos(F),i=D+d*w.sin(F),m=bO(h,i,c,d,e,0,g,I,J,[F,H,C,D])}G=F-E;var K=w.cos(E),L=w.sin(E),M=w.cos(F),N=w.sin(F),O=w.tan(G/4),P=4/3*c*O,Q=4/3*d*O,R=[a,b],S=[a+P*L,b-Q*K],T=[h+P*N,i-Q*M],U=[h,i];S[0]=2*R[0]-S[0],S[1]=2*R[1]-S[1];if(j)return[S,T,U][n](m);m=[S,T,U][n](m).join()[s](",");var V=[];for(var W=0,X=m.length;W"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bP(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bP(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y)),i=f-2*d+b-(h-2*f+d),j=2*(d-b)-2*(f-d),k=b-d,l=(-j+w.sqrt(j*j-4*i*k))/2/i,n=(-j-w.sqrt(j*j-4*i*k))/2/i,z(l)>"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bP(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bP(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y));return{min:{x:y[m](0,p),y:y[m](0,o)},max:{x:x[m](0,p),y:x[m](0,o)}}}),bR=a._path2curve=bv(function(a,b){var c=!b&&bz(a);if(!b&&c.curve)return bJ(c.curve);var d=bL(a),e=b&&bL(b),f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},h=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][n](bO[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x)),d=b.y+(b.y-(b.by||b.y)),a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x)),b.qy=b.y+(b.y-(b.qy||b.y)),a=["C"][n](bN(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][n](bN(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](bM(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](bM(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](bM(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](bM(b.x,b.y,b.X,b.Y))}return a},i=function(a,b){if(a[b].length>7){a[b].shift();var c=a[b];while(c.length)a.splice(b++,0,["C"][n](c.splice(0,6)));a.splice(b,1),l=x(d.length,e&&e.length||0)}},j=function(a,b,c,f,g){a&&b&&a[g][0]=="M"&&b[g][0]!="M"&&(b.splice(g,0,["M",f.x,f.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],l=x(d.length,e&&e.length||0))};for(var k=0,l=x(d.length,e&&e.length||0);ke){if(c&&!l.start){m=cs(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),k+=["C"+m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k,k=["M"+m.x,m.y+"C"+m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!b&&!c){m=cs(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j,g=+i[5],h=+i[6]}k+=i.shift()+i}l.end=k,m=b?n:c?l:a.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},cu=ct(1),cv=ct(),cw=ct(0,1);a.getTotalLength=cu,a.getPointAtLength=cv,a.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return cw(a,b).end;var d=cw(a,c,1);return b?cw(d,b).end:d},cl.getTotalLength=function(){if(this.type=="path"){if(this.node.getTotalLength)return this.node.getTotalLength();return cu(this.attrs.path)}},cl.getPointAtLength=function(a){if(this.type=="path")return cv(this.attrs.path,a)},cl.getSubpath=function(b,c){if(this.type=="path")return a.getSubpath(this.attrs.path,b,c)};var cx=a.easing_formulas={linear:function(a){return a},"<":function(a){return A(a,1.7)},">":function(a){return A(a,.48)},"<>":function(a){var b=.48-a/1.04,c=w.sqrt(.1734+b*b),d=c-b,e=A(z(d),1/3)*(d<0?-1:1),f=-c-b,g=A(z(f),1/3)*(f<0?-1:1),h=e+g+.5;return(1-h)*3*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==!!a)return a;return A(2,-10*a)*w.sin((a-.075)*2*B/.3)+1},bounce:function(a){var b=7.5625,c=2.75,d;a<1/c?d=b*a*a:a<2/c?(a-=1.5/c,d=b*a*a+.75):a<2.5/c?(a-=2.25/c,d=b*a*a+.9375):(a-=2.625/c,d=b*a*a+.984375);return d}};cx.easeIn=cx["ease-in"]=cx["<"],cx.easeOut=cx["ease-out"]=cx[">"],cx.easeInOut=cx["ease-in-out"]=cx["<>"],cx["back-in"]=cx.backIn,cx["back-out"]=cx.backOut;var cy=[],cz=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,16)},cA=function(){var b=+(new Date),c=0;for(;c1&&!d.next){for(s in k)k[g](s)&&(r[s]=d.totalOrigin[s]);d.el.attr(r),cE(d.anim,d.el,d.anim.percents[0],null,d.totalOrigin,d.repeat-1)}d.next&&!d.stop&&cE(d.anim,d.el,d.next,null,d.totalOrigin,d.repeat)}}a.svg&&m&&m.paper&&m.paper.safari(),cy.length&&cz(cA)},cB=function(a){return a>255?255:a<0?0:a};cl.animateWith=function(b,c,d,e,f,g){var h=this;if(h.removed){g&&g.call(h);return h}var i=d instanceof cD?d:a.animation(d,e,f,g),j,k;cE(i,h,i.percents[0],null,h.attr());for(var l=0,m=cy.length;l.5)*2-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&n!=.5&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\s*\-\s*/);if(j=="linear"){var t=e.shift();t=-d(t);if(isNaN(t))return null;var u=[0,0,f.cos(a.rad(t)),f.sin(a.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=a._parseDots(e);if(!w)return null;k=k.replace(/[\(\)\s,\xb0#]/g,"_"),b.gradient&&k!=b.gradient.id&&(p.defs.removeChild(b.gradient),delete b.gradient);if(!b.gradient){s=q(j+"Gradient",{id:k}),b.gradient=s,q(s,j=="radial"?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:b.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;x1?G.opacity/100:G.opacity});case"stroke":G=a.getRGB(p),i.setAttribute(o,G.hex),o=="stroke"&&G[b]("opacity")&&q(i,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity}),o=="stroke"&&d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"gradient":(d.type=="circle"||d.type=="ellipse"||c(p).charAt()!="r")&&r(d,p);break;case"opacity":k.gradient&&!k[b]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){H=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),H&&(I=H.getElementsByTagName("stop"),q(I[I.length-1],{"stop-opacity":p}));break};default:o=="font-size"&&(p=e(p,10)+"px");var J=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[J]=p,d._.dirty=1,i.setAttribute(o,p)}}y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if(d.type=="text"&&!!(f[b]("text")||f[b]("font")||f[b]("font-size")||f[b]("x")||f[b]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(a._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;if(f[b]("text")){g.text=f.text;while(h.firstChild)h.removeChild(h.firstChild);var j=c(f.text).split("\n"),k=[],m;for(var n=0,o=j.length;n"));var $=X.getBoundingClientRect();t.W=m.w=($.right-$.left)/Y,t.H=m.h=($.bottom-$.top)/Y,t.X=m.x,t.Y=m.y+t.H/2,("x"in i||"y"in i)&&(t.path.v=a.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));var _=["x","y","text","font","font-family","font-weight","font-style","font-size"];for(var ba=0,bb=_.length;ba.25&&(c=e.sqrt(.25-i(b-.5,2))*((c>.5)*2-1)+.5),m=b+n+c);return o}),f=f.split(/\s*\-\s*/);if(l=="linear"){var p=f.shift();p=-d(p);if(isNaN(p))return null}var q=a._parseDots(f);if(!q)return null;b=b.shape||b.node;if(q.length){b.removeChild(g),g.on=!0,g.method="none",g.color=q[0].color,g.color2=q[q.length-1].color;var r=[];for(var s=0,t=q.length;s')}}catch(c){F=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},a._engine.initWin(a._g.win),a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b.container,d=b.height,e,f=b.width,g=b.x,h=b.y;if(!c)throw new Error("VML container not found.");var i=new a._Paper,j=i.canvas=a._g.doc.createElement("div"),k=j.style;g=g||0,h=h||0,f=f||512,d=d||342,i.width=f,i.height=d,f==+f&&(f+="px"),d==+d&&(d+="px"),i.coordsize=u*1e3+n+u*1e3,i.coordorigin="0 0",i.span=a._g.doc.createElement("span"),i.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",j.appendChild(i.span),k.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d),c==1?(a._g.doc.body.appendChild(j),k.left=g+"px",k.top=h+"px",k.position="absolute"):c.firstChild?c.insertBefore(j,c.firstChild):c.appendChild(j),i.renderfix=function(){};return i},a.prototype.clear=function(){a.eve("raphael.clear",this),this.canvas.innerHTML=o,this.span=a._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},a.prototype.remove=function(){a.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]=typeof this[b]=="function"?a._removedFactory(b):null;return!0};var G=a.st;for(var H in E)E[b](H)&&!G[b](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(H))}(window.Raphael) \ No newline at end of file diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css new file mode 100755 index 0000000000..7d64b9c5c5 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css @@ -0,0 +1,30 @@ +body { + font-size: 10pt; + font-family: Arial, sans-serif; +} + +a { + color:#315479; +} + +.letters { + width:100%; + text-align:center; + margin:0.6em; + padding:0.1em; + border-bottom:1px solid gray; +} + +.entry { + border-bottom: 1px solid lightgray; + padding: 5px 0 8px; +} + +.name { + /* background-color:#E5E5E5; */ +} + +.occurrences { + margin-left: 1em; + margin-top: 5px; +} \ No newline at end of file diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.png new file mode 100644 index 0000000000..4625f9df74 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.psd b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.psd new file mode 100644 index 0000000000..3764f82ccb Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.psd differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js new file mode 100644 index 0000000000..4417f5b438 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js @@ -0,0 +1,71 @@ +// © 2010 EPFL/LAMP +// code by Gilles Dubochet + +function Scheduler() { + var scheduler = this; + var resolution = 0; + this.timeout = undefined; + this.queues = new Array(0); // an array of work pacakges indexed by index in the labels table. + this.labels = new Array(0); // an indexed array of labels indexed by priority. This should be short. + this.label = function(name, priority) { + this.name = name; + this.priority = priority; + } + this.work = function(fn, self, args) { + this.fn = fn; + this.self = self; + this.args = args; + } + this.addLabel = function(name, priority) { + var idx = 0; + while (idx < scheduler.queues.length && scheduler.labels[idx].priority <= priority) { idx = idx + 1; } + scheduler.labels.splice(idx, 0, new scheduler.label(name, priority)); + scheduler.queues.splice(idx, 0, new Array(0)); + } + this.clearLabel = function(name) { + var idx = 0; + while (idx < scheduler.queues.length && scheduler.labels[idx].name != name) { idx = idx + 1; } + if (idx < scheduler.queues.length && scheduler.labels[i].name == name) { + scheduler.labels.splice(idx, 1); + scheduler.queues.splice(idx, 1); + } + } + this.nextWork = function() { + var fn = undefined; + var idx = 0; + while (idx < scheduler.queues.length && scheduler.queues[idx].length == 0) { idx = idx + 1; } + if (idx < scheduler.queues.length && scheduler.queues[idx].length > 0) { + var fn = scheduler.queues[idx].shift(); + } + return fn; + } + this.add = function(labelName, fn, self, args) { + var doWork = function() { + scheduler.timeout = setTimeout(function() { + var work = scheduler.nextWork(); + if (work != undefined) { + if (work.args == undefined) { work.args = new Array(0); } + work.fn.apply(work.self, work.args); + doWork(); + } + else { + scheduler.timeout = undefined; + } + }, resolution); + } + var idx = 0; + while (idx < scheduler.labels.length && scheduler.labels[idx].name != labelName) { idx = idx + 1; } + if (idx < scheduler.queues.length && scheduler.labels[idx].name == labelName) { + scheduler.queues[idx].push(new scheduler.work(fn, self, args)); + if (scheduler.timeout == undefined) doWork(); + } + else throw("queue for add is non existant"); + } + this.clear = function(labelName) { + var idx = 0; + while (idx < scheduler.labels.length && scheduler.labels[idx].name != labelName) { idx = idx + 1; } + if (idx < scheduler.queues.length && scheduler.labels[idx].name == labelName) { + scheduler.queues[idx] = new Array(); + } + } +}; diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png new file mode 100644 index 0000000000..bc29efb3e6 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png new file mode 100644 index 0000000000..8313f4975b Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right.png new file mode 100644 index 0000000000..04eda2f307 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected.png new file mode 100644 index 0000000000..c89765239e Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2-right.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2-right.png new file mode 100644 index 0000000000..bf984ef0ba Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2-right.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2.png new file mode 100644 index 0000000000..a790bb1169 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg.gif new file mode 100644 index 0000000000..b6ac4415e4 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg.gif differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg2.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg2.gif new file mode 100644 index 0000000000..9aae5ba0aa Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg2.gif differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css new file mode 100644 index 0000000000..b066027f04 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css @@ -0,0 +1,848 @@ +/* Reset */ + +html, body, div, span, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, code, pre, +del, dfn, em, img, q, dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, input, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; +} + +table { border-collapse: separate; border-spacing: 0; } +caption, th, td { text-align: left; font-weight: normal; } +table, td, th { vertical-align: middle; } + +blockquote:before, blockquote:after, q:before, q:after { content: ""; } +blockquote, q { quotes: none; } + +a img { border: none; } + +input { border-width: 0px; } + +/* Page */ + +body { + font-family: Arial, sans-serif; + font-size: 10pt; +} + +#footer { + font-size: 9pt; + text-align: center; + color: #858484; + bottom: 0; + width: 100%; + height: 20px; +} + +a[href] { + text-decoration: underline; + color: #315479; +} + +a[href]:hover { + text-decoration: none; +} + +#types ol li > p { + margin-top: 5px; +} + +#types ol li:last-child { + margin-bottom: 5px; +} + +/* +#definition { + padding: 6px 0 6px 6px; + min-height: 59px; + color: white; +} +*/ + +#definition { + display: block-inline; + padding: 5px 0px; + height: 61px; +} + +#definition > img { + float: left; + padding-right: 6px; + padding-left: 5px; +} + +#definition > a > img { + float: left; + padding-right: 6px; + padding-left: 5px; +} + +#definition p + h1 { + margin-top: 3px; +} + +#definition > h1 { +/* padding: 12px 0 12px 6px;*/ + color: white; + text-shadow: 3px black; + text-shadow: black 0px 2px 0px; + font-size: 24pt; + display: inline-block; + overflow: hidden; + margin-top: 10px; +} + +#definition h1 > a { + color: #ffffff; + font-size: 24pt; + text-shadow: black 0px 2px 0px; +/* text-shadow: black 0px 0px 0px;*/ +text-decoration: none; +} + +#definition #owner { + color: #ffffff; + margin-top: 4px; + font-size: 10pt; + overflow: hidden; +} + +#definition #owner > a { + color: #ffffff; +} + +#definition #owner > a:hover { + text-decoration: none; +} + +#signature { + background-image:url('signaturebg2.gif'); + background-color: #d7d7d7; + min-height: 18px; + background-repeat:repeat-x; + font-size: 11.5pt; +/* margin-bottom: 10px;*/ + padding: 8px; +} + +#signature > span.modifier_kind { + display: inline; + float: left; + text-align: left; + width: auto; + position: static; + text-shadow: 2px white; + text-shadow: white 0px 1px 0px; +} + +#signature > span.symbol { + text-align: left; + display: inline; + padding-left: 0.7em; + text-shadow: 2px white; + text-shadow: white 0px 1px 0px; +} + +/* Linear super types and known subclasses */ +.hiddenContent { + display: none; +} + +.toggleContainer .toggle { + cursor: pointer; + padding-left: 15px; + background: url("arrow-right.png") no-repeat 0 3px transparent; +} + +.toggleContainer .toggle.open { + background: url("arrow-down.png") no-repeat 0 3px transparent; +} + +.toggleContainer .hiddenContent { + margin-top: 5px; +} + +.value #definition { + background-color: #2C475C; /* blue */ + background-image:url('defbg-blue.gif'); + background-repeat:repeat-x; +} + +.type #definition { + background-color: #316555; /* green */ + background-image:url('defbg-green.gif'); + background-repeat:repeat-x; +} + +#template { + margin-bottom: 50px; +} + +h3 { + color: white; + padding: 5px 10px; + font-size: 12pt; + font-weight: bold; + text-shadow: black 1px 1px 0px; +} + +dl.attributes > dt { + display: block; + float: left; + font-style: italic; +} + +dl.attributes > dt.implicit { + font-weight: bold; + color: darkgreen; +} + +dl.attributes > dd { + display: block; + padding-left: 10em; + margin-bottom: 5px; +} + +#template .values > h3 { + background: #2C475C url("valuemembersbg.gif") repeat-x bottom left; /* grayish blue */ + height: 18px; +} + +#values ol li:last-child { + margin-bottom: 5px; +} + +#template .types > h3 { + background: #316555 url("typebg.gif") repeat-x bottom left; /* green */ + height: 18px; +} + +#constructors > h3 { + background: #4f504f url("constructorsbg.gif") repeat-x bottom left; /* gray */ + height: 18px; +} + +#inheritedMembers > div.parent > h3 { + background: #dadada url("constructorsbg.gif") repeat-x bottom left; /* gray */ + height: 17px; + font-style: italic; + font-size: 12pt; +} + +#inheritedMembers > div.parent > h3 * { + color: white; +} + +#inheritedMembers > div.conversion > h3 { + background: #dadada url("conversionbg.gif") repeat-x bottom left; /* gray */ + height: 17px; + font-style: italic; + font-size: 12pt; +} + +#inheritedMembers > div.conversion > h3 * { + color: white; +} + +#groupedMembers > div.group > h3 { + background: #dadada url("typebg.gif") repeat-x bottom left; /* green */ + height: 17px; + font-size: 12pt; +} + +#groupedMembers > div.group > h3 * { + color: white; +} + + +/* Member cells */ + +div.members > ol { + background-color: white; + list-style: none +} + +div.members > ol > li { + display: block; + border-bottom: 1px solid gray; + padding: 5px 0 6px; + margin: 0 10px; + position: relative; +} + +div.members > ol > li:last-child { + border: 0; + padding: 5px 0 5px; +} + +/* Member signatures */ + +#tooltip { + background: #EFD5B5; + border: 1px solid gray; + color: black; + display: none; + padding: 5px; + position: absolute; +} + +.signature { + font-family: monospace; + font-size: 10pt; + line-height: 18px; + clear: both; + display: block; + text-shadow: 2px white; + text-shadow: white 0px 1px 0px; +} + +.signature .modifier_kind { + position: absolute; + text-align: right; + width: 14em; +} + +.signature > a > .symbol > .name { + text-decoration: underline; +} + +.signature > a:hover > .symbol > .name { + text-decoration: none; +} + +.signature > a { + text-decoration: none; +} + +.signature > .symbol { + display: block; + padding-left: 14.7em; +} + +.signature .name { + display: inline-block; + font-weight: bold; +} + +.signature .symbol > .implicit { + display: inline-block; + font-weight: bold; + text-decoration: underline; + color: darkgreen; +} + +.signature .symbol .shadowed { + color: darkseagreen; +} + +.signature .symbol .params > .implicit { + font-style: italic; +} + +.signature .symbol .deprecated { + text-decoration: line-through; +} + +.signature .symbol .params .default { + font-style: italic; +} + +#template .signature.closed { + background: url("arrow-right.png") no-repeat 0 5px transparent; + cursor: pointer; +} + +#template .signature.opened { + background: url("arrow-down.png") no-repeat 0 5px transparent; + cursor: pointer; +} + +#template .values .signature .name { + color: darkblue; +} + +#template .types .signature .name { + color: darkgreen; +} + +.full-signature-usecase h4 span { + font-size: 10pt; +} + +.full-signature-usecase > #signature { + padding-top: 0px; +} + +#template .full-signature-usecase > .signature.closed { + background: none; +} + +#template .full-signature-usecase > .signature.opened { + background: none; +} + +.full-signature-block { + padding: 5px 0 0; + border-top: 1px solid #EBEBEB; + margin-top: 5px; + margin-bottom: 5px; +} + + +/* Comments text formating */ + +.cmt {} + +.cmt p { + margin: 0.7em 0; +} + +.cmt p:first-child { + margin-top: 0; +} + +.cmt p:last-child { + margin-bottom: 0; +} + +.cmt h3, +.cmt h4, +.cmt h5, +.cmt h6 { + margin-bottom: 0.7em; + margin-top: 1.4em; + display: block; + text-align: left; + font-weight: bold; +} + +.cmt h3 { + font-size: 14pt; +} + +.cmt h4 { + font-size: 13pt; +} + +.cmt h5 { + font-size: 12pt; +} + +.cmt h6 { + font-size: 11pt; +} + +.cmt pre { + padding: 5px; + border: 1px solid #ddd; + background-color: #eee; + margin: 5px 0; + display: block; + font-family: monospace; +} + +.cmt pre span.ano { + color: blue; +} + +.cmt pre span.cmt { + color: green; +} + +.cmt pre span.kw { + font-weight: bold; +} + +.cmt pre span.lit { + color: #c71585; +} + +.cmt pre span.num { + color: #1e90ff; /* dodgerblue */ +} + +.cmt pre span.std { + color: #008080; /* teal */ +} + +.cmt ul { + display: block; + list-style: circle; + padding-left: 20px; +} + +.cmt ol { + display: block; + padding-left:20px; +} + +.cmt ol.decimal { + list-style: decimal; +} + +.cmt ol.lowerAlpha { + list-style: lower-alpha; +} + +.cmt ol.upperAlpha { + list-style: upper-alpha; +} + +.cmt ol.lowerRoman { + list-style: lower-roman; +} + +.cmt ol.upperRoman { + list-style: upper-roman; +} + +.cmt li { + display: list-item; +} + +.cmt code { + font-family: monospace; +} + +.cmt a { + font-style: bold; +} + +.cmt em, .cmt i { + font-style: italic; +} + +.cmt strong, .cmt b { + font-weight: bold; +} + +/* Comments structured layout */ + +.group > div.comment { + padding-top: 5px; + padding-bottom: 5px; + padding-right: 5px; + padding-left: 5px; + border: 1px solid #ddd; + background-color: #eeeee; + margin-top:5px; + margin-bottom:5px; + margin-right:5px; + margin-left:5px; + display: block; +} + +p.comment { + display: block; + margin-left: 14.7em; + margin-top: 5px; +} + +.shortcomment { + display: block; + margin: 5px 10px; +} + +div.fullcommenttop { + padding: 10px 10px; + background-image:url('fullcommenttopbg.gif'); + background-repeat:repeat-x; +} + +div.fullcomment { + margin: 5px 10px; +} + +#template div.fullcommenttop, +#template div.fullcomment { + display:none; + margin: 5px 0 0 14.7em; +} + +#template .shortcomment { + margin: 5px 0 0 14.7em; + padding: 0; +} + +div.fullcomment .block { + padding: 5px 0 0; + border-top: 1px solid #EBEBEB; + margin-top: 5px; + overflow: hidden; +} + +div.fullcommenttop .block { + padding: 5px 0 0; + border-top: 1px solid #EBEBEB; + margin-top: 5px; + margin-bottom: 5px +} + +div.fullcomment div.block ol li p, +div.fullcomment div.block ol li { + display:inline +} + +div.fullcomment .block > h5 { + font-style: italic; + font-weight: normal; + display: inline-block; +} + +div.fullcomment .comment { + margin: 5px 0 10px; +} + +div.fullcommenttop .comment:last-child, +div.fullcomment .comment:last-child { + margin-bottom: 0; +} + +div.fullcommenttop dl.paramcmts { + margin-bottom: 0.8em; + padding-bottom: 0.8em; +} + +div.fullcommenttop dl.paramcmts > dt, +div.fullcomment dl.paramcmts > dt { + display: block; + float: left; + font-weight: bold; + min-width: 70px; +} + +div.fullcommenttop dl.paramcmts > dd, +div.fullcomment dl.paramcmts > dd { + display: block; + padding-left: 10px; + margin-bottom: 5px; + margin-left: 70px; +} + +/* Members filter tool */ + +#textfilter { + position: relative; + display: block; + height: 20px; + margin-bottom: 5px; +} + +#textfilter > .pre { + display: block; + position: absolute; + top: 0; + left: 0; + height: 23px; + width: 21px; + background: url("filter_box_left.png"); +} + +#textfilter > .input { + display: block; + position: absolute; + top: 0; + right: 20px; + left: 20px; +} + +#textfilter > .input > input { + height: 20px; + padding: 1px; + font-weight: bold; + color: #000000; + background: #ffffff url("filterboxbarbg.png") repeat-x top left; + width: 100%; +} + +#textfilter > .post { + display: block; + position: absolute; + top: 0; + right: 0; + height: 23px; + width: 21px; + background: url("filter_box_right.png"); +} + +#mbrsel { + padding: 5px 10px; + background-color: #ededee; /* light gray */ + background-image:url('filterboxbg.gif'); + background-repeat:repeat-x; + font-size: 9.5pt; + display: block; + margin-top: 1em; +/* margin-bottom: 1em; */ +} + +#mbrsel > div { + margin-bottom: 5px; +} + +#mbrsel > div:last-child { + margin-bottom: 0; +} + +#mbrsel > div > span.filtertype { + padding: 4px; + margin-right: 5px; + float: left; + display: inline-block; + color: #000000; + font-weight: bold; + text-shadow: white 0px 1px 0px; + width: 4.5em; +} + +#mbrsel > div > ol { + display: inline-block; +} + +#mbrsel > div > a { + position:relative; + top: -8px; + font-size: 11px; + text-shadow: #ffffff 0 1px 0; +} + +#mbrsel > div > ol#linearization { + display: table; + margin-left: 70px; +} + +#mbrsel > div > ol#linearization > li.in { + text-decoration: none; + float: left; + padding-right: 10px; + margin-right: 5px; + background: url(selected-right.png) no-repeat; + background-position: right 0px; +} + +#mbrsel > div > ol#linearization > li.in > span{ + color: #404040; + float: left; + padding: 1px 0 1px 10px; + background: url(selected.png) no-repeat; + background-position: 0px 0px; + text-shadow: #ffffff 0 1px 0; +} + +#mbrsel > div > ol#implicits { + display: table; + margin-left: 70px; +} + +#mbrsel > div > ol#implicits > li.in { + text-decoration: none; + float: left; + padding-right: 10px; + margin-right: 5px; + background: url(selected-right-implicits.png) no-repeat; + background-position: right 0px; +} + +#mbrsel > div > ol#implicits > li.in > span{ + color: #404040; + float: left; + padding: 1px 0 1px 10px; + background: url(selected-implicits.png) no-repeat; + background-position: 0px 0px; + text-shadow: #ffffff 0 1px 0; +} + +#mbrsel > div > ol > li { +/* padding: 3px 10px;*/ + line-height: 16pt; + display: inline-block; + cursor: pointer; +} + +#mbrsel > div > ol > li.in { + text-decoration: none; + float: left; + padding-right: 10px; + margin-right: 5px; + background: url(selected-right.png) no-repeat; + background-position: right 0px; +} + +#mbrsel > div > ol > li.in > span{ + color: #404040; + float: left; + padding: 1px 0 1px 10px; + background: url(selected.png) no-repeat; + background-position: 0px 0px; + text-shadow: #ffffff 0 1px 0; +} + +#mbrsel > div > ol > li.out { + text-decoration: none; + float: left; + padding-right: 10px; + margin-right: 5px; +} + +#mbrsel > div > ol > li.out > span{ + color: #747474; +/* background-color: #999; */ + float: left; + padding: 1px 0 1px 10px; +/* background: url(unselected.png) no-repeat;*/ + background-position: 0px -1px; + text-shadow: #ffffff 0 1px 0; +} +/* +#mbrsel .hideall { + color: #4C4C4C; + line-height: 16px; + font-weight: bold; +} + +#mbrsel .hideall span { + color: #4C4C4C; + font-weight: bold; +} + +#mbrsel .showall { + color: #4C4C4C; + line-height: 16px; + font-weight: bold; +} + +#mbrsel .showall span { + color: #4C4C4C; + font-weight: bold; +}*/ + +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 11.844px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + white-space: nowrap; + vertical-align: baseline; + background-color: #999999; + padding-right: 9px; + padding-left: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} + +.badge-red { + background-color: #b94a48; +} diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js new file mode 100644 index 0000000000..6d1caf6d50 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js @@ -0,0 +1,466 @@ +// © 2009–2010 EPFL/LAMP +// code by Gilles Dubochet with contributions by Pedro Furlanetto + +$(document).ready(function(){ + + // Escapes special characters and returns a valid jQuery selector + function escapeJquery(str){ + return str.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1'); + } + + // highlight and jump to selected member + if (window.location.hash) { + var temp = window.location.hash.replace('#', ''); + var elem = '#'+escapeJquery(temp); + + window.scrollTo(0, 0); + $(elem).parent().effect("highlight", {color: "#FFCC85"}, 3000); + $('html,body').animate({scrollTop:$(elem).parent().offset().top}, 1000); + } + + var isHiddenClass = function (name) { + return name == 'scala.Any' || + name == 'scala.AnyRef'; + }; + + var isHidden = function (elem) { + return $(elem).attr("data-hidden") == 'true'; + }; + + $("#linearization li:gt(0)").filter(function(){ + return isHiddenClass($(this).attr("name")); + }).removeClass("in").addClass("out"); + + $("#implicits li").filter(function(){ + return isHidden(this); + }).removeClass("in").addClass("out"); + + // Pre-filter members + filter(); + + // Member filter box + var input = $("#textfilter input"); + input.bind("keyup", function(event) { + + switch ( event.keyCode ) { + + case 27: // escape key + input.val(""); + filter(true); + break; + + case 38: // up + input.val(""); + filter(false); + window.scrollTo(0, $("body").offset().top); + input.focus(); + break; + + case 33: //page up + input.val(""); + filter(false); + break; + + case 34: //page down + input.val(""); + filter(false); + break; + + default: + window.scrollTo(0, $("#mbrsel").offset().top); + filter(true); + break; + + } + }); + input.focus(function(event) { + input.select(); + }); + $("#textfilter > .post").click(function() { + $("#textfilter input").attr("value", ""); + filter(); + }); + $(document).keydown(function(event) { + + if (event.keyCode == 9) { // tab + $("#index-input", window.parent.document).focus(); + input.attr("value", ""); + return false; + } + }); + + $("#linearization li").click(function(){ + if ($(this).hasClass("in")) { + $(this).removeClass("in"); + $(this).addClass("out"); + } + else if ($(this).hasClass("out")) { + $(this).removeClass("out"); + $(this).addClass("in"); + }; + filter(); + }); + + $("#implicits li").click(function(){ + if ($(this).hasClass("in")) { + $(this).removeClass("in"); + $(this).addClass("out"); + } + else if ($(this).hasClass("out")) { + $(this).removeClass("out"); + $(this).addClass("in"); + }; + filter(); + }); + + $("#mbrsel > div[id=ancestors] > ol > li.hideall").click(function() { + $("#linearization li.in").removeClass("in").addClass("out"); + $("#linearization li:first").removeClass("out").addClass("in"); + $("#implicits li.in").removeClass("in").addClass("out"); + + if ($(this).hasClass("out") && $("#mbrsel > div[id=ancestors] > ol > li.showall").hasClass("in")) { + $(this).removeClass("out").addClass("in"); + $("#mbrsel > div[id=ancestors] > ol > li.showall").removeClass("in").addClass("out"); + } + + filter(); + }) + $("#mbrsel > div[id=ancestors] > ol > li.showall").click(function() { + var filteredLinearization = + $("#linearization li.out").filter(function() { + return ! isHiddenClass($(this).attr("name")); + }); + filteredLinearization.removeClass("out").addClass("in"); + + var filteredImplicits = + $("#implicits li.out").filter(function() { + return ! isHidden(this); + }); + filteredImplicits.removeClass("out").addClass("in"); + + if ($(this).hasClass("out") && $("#mbrsel > div[id=ancestors] > ol > li.hideall").hasClass("in")) { + $(this).removeClass("out").addClass("in"); + $("#mbrsel > div[id=ancestors] > ol > li.hideall").removeClass("in").addClass("out"); + } + + filter(); + }); + $("#visbl > ol > li.public").click(function() { + if ($(this).hasClass("out")) { + $(this).removeClass("out").addClass("in"); + $("#visbl > ol > li.all").removeClass("in").addClass("out"); + filter(); + }; + }) + $("#visbl > ol > li.all").click(function() { + if ($(this).hasClass("out")) { + $(this).removeClass("out").addClass("in"); + $("#visbl > ol > li.public").removeClass("in").addClass("out"); + filter(); + }; + }); + $("#order > ol > li.alpha").click(function() { + if ($(this).hasClass("out")) { + orderAlpha(); + }; + }) + $("#order > ol > li.inherit").click(function() { + if ($(this).hasClass("out")) { + orderInherit(); + }; + }); + $("#order > ol > li.group").click(function() { + if ($(this).hasClass("out")) { + orderGroup(); + }; + }); + $("#groupedMembers").hide(); + + initInherit(); + + // Create tooltips + $(".extype").add(".defval").tooltip({ + tip: "#tooltip", + position:"top center", + predelay: 500, + onBeforeShow: function(ev) { + $(this.getTip()).text(this.getTrigger().attr("name")); + } + }); + + /* Add toggle arrows */ + //var docAllSigs = $("#template li").has(".fullcomment").find(".signature"); + // trying to speed things up a little bit + var docAllSigs = $("#template li[fullComment=yes] .signature"); + + function commentToggleFct(signature){ + var parent = signature.parent(); + var shortComment = $(".shortcomment", parent); + var fullComment = $(".fullcomment", parent); + var vis = $(":visible", fullComment); + signature.toggleClass("closed").toggleClass("opened"); + if (vis.length > 0) { + shortComment.slideDown(100); + fullComment.slideUp(100); + } + else { + shortComment.slideUp(100); + fullComment.slideDown(100); + } + }; + docAllSigs.addClass("closed"); + docAllSigs.click(function() { + commentToggleFct($(this)); + }); + + /* Linear super types and known subclasses */ + function toggleShowContentFct(e){ + e.toggleClass("open"); + var content = $(".hiddenContent", e.parent().get(0)); + if (content.is(':visible')) { + content.slideUp(100); + } + else { + content.slideDown(100); + } + }; + + $(".toggle:not(.diagram-link)").click(function() { + toggleShowContentFct($(this)); + }); + + // Set parent window title + windowTitle(); + + if ($("#order > ol > li.group").length == 1) { orderGroup(); }; +}); + +function orderAlpha() { + $("#order > ol > li.alpha").removeClass("out").addClass("in"); + $("#order > ol > li.inherit").removeClass("in").addClass("out"); + $("#order > ol > li.group").removeClass("in").addClass("out"); + $("#template > div.parent").hide(); + $("#template > div.conversion").hide(); + $("#mbrsel > div[id=ancestors]").show(); + filter(); +}; + +function orderInherit() { + $("#order > ol > li.inherit").removeClass("out").addClass("in"); + $("#order > ol > li.alpha").removeClass("in").addClass("out"); + $("#order > ol > li.group").removeClass("in").addClass("out"); + $("#template > div.parent").show(); + $("#template > div.conversion").show(); + $("#mbrsel > div[id=ancestors]").hide(); + filter(); +}; + +function orderGroup() { + $("#order > ol > li.group").removeClass("out").addClass("in"); + $("#order > ol > li.alpha").removeClass("in").addClass("out"); + $("#order > ol > li.inherit").removeClass("in").addClass("out"); + $("#template > div.parent").hide(); + $("#template > div.conversion").hide(); + $("#mbrsel > div[id=ancestors]").show(); + filter(); +}; + +/** Prepares the DOM for inheritance-based display. To do so it will: + * - hide all statically-generated parents headings; + * - copy all members from the value and type members lists (flat members) to corresponding lists nested below the + * parent headings (inheritance-grouped members); + * - initialises a control variable used by the filter method to control whether filtering happens on flat members + * or on inheritance-grouped members. */ +function initInherit() { + // inheritParents is a map from fully-qualified names to the DOM node of parent headings. + var inheritParents = new Object(); + var groupParents = new Object(); + $("#inheritedMembers > div.parent").each(function(){ + inheritParents[$(this).attr("name")] = $(this); + }); + $("#inheritedMembers > div.conversion").each(function(){ + inheritParents[$(this).attr("name")] = $(this); + }); + $("#groupedMembers > div.group").each(function(){ + groupParents[$(this).attr("name")] = $(this); + }); + + $("#types > ol > li").each(function(){ + var mbr = $(this); + this.mbrText = mbr.find("> .fullcomment .cmt").text(); + var qualName = mbr.attr("name"); + var owner = qualName.slice(0, qualName.indexOf("#")); + var name = qualName.slice(qualName.indexOf("#") + 1); + var inheritParent = inheritParents[owner]; + if (inheritParent != undefined) { + var types = $("> .types > ol", inheritParent); + if (types.length == 0) { + inheritParent.append("

      Type Members

        "); + types = $("> .types > ol", inheritParent); + } + var clone = mbr.clone(); + clone[0].mbrText = this.mbrText; + types.append(clone); + } + var group = mbr.attr("group") + var groupParent = groupParents[group]; + if (groupParent != undefined) { + var types = $("> .types > ol", groupParent); + if (types.length == 0) { + groupParent.append("
          "); + types = $("> .types > ol", groupParent); + } + var clone = mbr.clone(); + clone[0].mbrText = this.mbrText; + types.append(clone); + } + }); + + $("#values > ol > li").each(function(){ + var mbr = $(this); + this.mbrText = mbr.find("> .fullcomment .cmt").text(); + var qualName = mbr.attr("name"); + var owner = qualName.slice(0, qualName.indexOf("#")); + var name = qualName.slice(qualName.indexOf("#") + 1); + var inheritParent = inheritParents[owner]; + if (inheritParent != undefined) { + var values = $("> .values > ol", inheritParent); + if (values.length == 0) { + inheritParent.append("

          Value Members

            "); + values = $("> .values > ol", inheritParent); + } + var clone = mbr.clone(); + clone[0].mbrText = this.mbrText; + values.append(clone); + } + var group = mbr.attr("group") + var groupParent = groupParents[group]; + if (groupParent != undefined) { + var values = $("> .values > ol", groupParent); + if (values.length == 0) { + groupParent.append("
              "); + values = $("> .values > ol", groupParent); + } + var clone = mbr.clone(); + clone[0].mbrText = this.mbrText; + values.append(clone); + } + }); + $("#inheritedMembers > div.parent").each(function() { + if ($("> div.members", this).length == 0) { $(this).remove(); }; + }); + $("#inheritedMembers > div.conversion").each(function() { + if ($("> div.members", this).length == 0) { $(this).remove(); }; + }); + $("#groupedMembers > div.group").each(function() { + if ($("> div.members", this).length == 0) { $(this).remove(); }; + }); +}; + +/* filter used to take boolean scrollToMember */ +function filter() { + var query = $.trim($("#textfilter input").val()).toLowerCase(); + query = query.replace(/[-[\]{}()*+?.,\\^$|#]/g, "\\$&").replace(/\s+/g, "|"); + var queryRegExp = new RegExp(query, "i"); + var privateMembersHidden = $("#visbl > ol > li.public").hasClass("in"); + var orderingAlphabetic = $("#order > ol > li.alpha").hasClass("in"); + var orderingInheritance = $("#order > ol > li.inherit").hasClass("in"); + var orderingGroups = $("#order > ol > li.group").hasClass("in"); + var hiddenSuperclassElementsLinearization = orderingInheritance ? $("#linearization > li:gt(0)") : $("#linearization > li.out"); + var hiddenSuperclassesLinearization = hiddenSuperclassElementsLinearization.map(function() { + return $(this).attr("name"); + }).get(); + var hiddenSuperclassElementsImplicits = orderingInheritance ? $("#implicits > li") : $("#implicits > li.out"); + var hiddenSuperclassesImplicits = hiddenSuperclassElementsImplicits.map(function() { + return $(this).attr("name"); + }).get(); + + var hideInheritedMembers; + + if (orderingAlphabetic) { + $("#allMembers").show(); + $("#inheritedMembers").hide(); + $("#groupedMembers").hide(); + hideInheritedMembers = true; + $("#allMembers > .members").each(filterFunc); + } else if (orderingGroups) { + $("#groupedMembers").show(); + $("#inheritedMembers").hide(); + $("#allMembers").hide(); + hideInheritedMembers = true; + $("#groupedMembers > .group > .members").each(filterFunc); + $("#groupedMembers > div.group").each(function() { + $(this).show(); + if ($("> div.members", this).not(":hidden").length == 0) { + $(this).hide(); + } else { + $(this).show(); + } + }); + } else if (orderingInheritance) { + $("#inheritedMembers").show(); + $("#groupedMembers").hide(); + $("#allMembers").hide(); + hideInheritedMembers = false; + $("#inheritedMembers > .parent > .members").each(filterFunc); + $("#inheritedMembers > .conversion > .members").each(filterFunc); + } + + + function filterFunc() { + var membersVisible = false; + var members = $(this); + members.find("> ol > li").each(function() { + var mbr = $(this); + if (privateMembersHidden && mbr.attr("visbl") == "prt") { + mbr.hide(); + return; + } + var name = mbr.attr("name"); + // Owner filtering must not happen in "inherited from" member lists + if (hideInheritedMembers) { + var ownerIndex = name.indexOf("#"); + if (ownerIndex < 0) { + ownerIndex = name.lastIndexOf("."); + } + var owner = name.slice(0, ownerIndex); + for (var i = 0; i < hiddenSuperclassesLinearization.length; i++) { + if (hiddenSuperclassesLinearization[i] == owner) { + mbr.hide(); + return; + } + }; + for (var i = 0; i < hiddenSuperclassesImplicits.length; i++) { + if (hiddenSuperclassesImplicits[i] == owner) { + mbr.hide(); + return; + } + }; + } + if (query && !(queryRegExp.test(name) || queryRegExp.test(this.mbrText))) { + mbr.hide(); + return; + } + mbr.show(); + membersVisible = true; + }); + + if (membersVisible) + members.show(); + else + members.hide(); + }; + + return false; +}; + +function windowTitle() +{ + try { + parent.document.title=document.title; + } + catch(e) { + // Chrome doesn't allow settings the parent's title when + // used on the local file system. + } +}; diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/tools.tooltip.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/tools.tooltip.js new file mode 100644 index 0000000000..0af34eca4c --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/tools.tooltip.js @@ -0,0 +1,14 @@ +/* + * tools.tooltip 1.1.3 - Tooltips done right. + * + * Copyright (c) 2009 Tero Piirainen + * http://flowplayer.org/tools/tooltip.html + * + * Dual licensed under MIT and GPL 2+ licenses + * http://www.opensource.org/licenses + * + * Launch : November 2008 + * Date: ${date} + * Revision: ${revision} + */ +(function(c){var d=[];c.tools=c.tools||{};c.tools.tooltip={version:"1.1.3",conf:{effect:"toggle",fadeOutSpeed:"fast",tip:null,predelay:0,delay:30,opacity:1,lazy:undefined,position:["top","center"],offset:[0,0],cancelDefault:true,relative:false,oneInstance:true,events:{def:"mouseover,mouseout",input:"focus,blur",widget:"focus mouseover,blur mouseout",tooltip:"mouseover,mouseout"},api:false},addEffect:function(e,g,f){b[e]=[g,f]}};var b={toggle:[function(e){var f=this.getConf(),g=this.getTip(),h=f.opacity;if(h<1){g.css({opacity:h})}g.show();e.call()},function(e){this.getTip().hide();e.call()}],fade:[function(e){this.getTip().fadeIn(this.getConf().fadeInSpeed,e)},function(e){this.getTip().fadeOut(this.getConf().fadeOutSpeed,e)}]};function a(f,g){var p=this,k=c(this);f.data("tooltip",p);var l=f.next();if(g.tip){l=c(g.tip);if(l.length>1){l=f.nextAll(g.tip).eq(0);if(!l.length){l=f.parent().nextAll(g.tip).eq(0)}}}function o(u){var t=g.relative?f.position().top:f.offset().top,s=g.relative?f.position().left:f.offset().left,v=g.position[0];t-=l.outerHeight()-g.offset[0];s+=f.outerWidth()+g.offset[1];var q=l.outerHeight()+f.outerHeight();if(v=="center"){t+=q/2}if(v=="bottom"){t+=q}v=g.position[1];var r=l.outerWidth()+f.outerWidth();if(v=="center"){s-=r/2}if(v=="left"){s-=r}return{top:t,left:s}}var i=f.is(":input"),e=i&&f.is(":checkbox, :radio, select, :button"),h=f.attr("type"),n=g.events[h]||g.events[i?(e?"widget":"input"):"def"];n=n.split(/,\s*/);if(n.length!=2){throw"Tooltip: bad events configuration for "+h}f.bind(n[0],function(r){if(g.oneInstance){c.each(d,function(){this.hide()})}var q=l.data("trigger");if(q&&q[0]!=this){l.hide().stop(true,true)}r.target=this;p.show(r);n=g.events.tooltip.split(/,\s*/);l.bind(n[0],function(){p.show(r)});if(n[1]){l.bind(n[1],function(){p.hide(r)})}});f.bind(n[1],function(q){p.hide(q)});if(!c.browser.msie&&!i&&!g.predelay){f.mousemove(function(){if(!p.isShown()){f.triggerHandler("mouseover")}})}if(g.opacity<1){l.css("opacity",g.opacity)}var m=0,j=f.attr("title");if(j&&g.cancelDefault){f.removeAttr("title");f.data("title",j)}c.extend(p,{show:function(r){if(r){f=c(r.target)}clearTimeout(l.data("timer"));if(l.is(":animated")||l.is(":visible")){return p}function q(){l.data("trigger",f);var t=o(r);if(g.tip&&j){l.html(f.data("title"))}r=r||c.Event();r.type="onBeforeShow";k.trigger(r,[t]);if(r.isDefaultPrevented()){return p}t=o(r);l.css({position:"absolute",top:t.top,left:t.left});var s=b[g.effect];if(!s){throw'Nonexistent effect "'+g.effect+'"'}s[0].call(p,function(){r.type="onShow";k.trigger(r)})}if(g.predelay){clearTimeout(m);m=setTimeout(q,g.predelay)}else{q()}return p},hide:function(r){clearTimeout(l.data("timer"));clearTimeout(m);if(!l.is(":visible")){return}function q(){r=r||c.Event();r.type="onBeforeHide";k.trigger(r);if(r.isDefaultPrevented()){return}b[g.effect][1].call(p,function(){r.type="onHide";k.trigger(r)})}if(g.delay&&r){l.data("timer",setTimeout(q,g.delay))}else{q()}return p},isShown:function(){return l.is(":visible, :animated")},getConf:function(){return g},getTip:function(){return l},getTrigger:function(){return f},bind:function(q,r){k.bind(q,r);return p},onHide:function(q){return this.bind("onHide",q)},onBeforeShow:function(q){return this.bind("onBeforeShow",q)},onShow:function(q){return this.bind("onShow",q)},onBeforeHide:function(q){return this.bind("onBeforeHide",q)},unbind:function(q){k.unbind(q);return p}});c.each(g,function(q,r){if(c.isFunction(r)){p.bind(q,r)}})}c.prototype.tooltip=function(e){var f=this.eq(typeof e=="number"?e:0).data("tooltip");if(f){return f}var g=c.extend(true,{},c.tools.tooltip.conf);if(c.isFunction(e)){e={onBeforeShow:e}}else{if(typeof e=="string"){e={tip:e}}}e=c.extend(true,g,e);if(typeof e.position=="string"){e.position=e.position.split(/,?\s/)}if(e.lazy!==false&&(e.lazy===true||this.length>20)){this.one("mouseover",function(h){f=new a(c(this),e);f.show(h);d.push(f)})}else{this.each(function(){f=new a(c(this),e);d.push(f)})}return e.api?f:this}})(jQuery); \ No newline at end of file diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait.png new file mode 100644 index 0000000000..fb961a2eda Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_big.png new file mode 100644 index 0000000000..625d9251cb Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_big.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_diagram.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_diagram.png new file mode 100644 index 0000000000..88983254ce Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_diagram.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_to_object_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_to_object_big.png new file mode 100644 index 0000000000..d0cd7fd512 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_to_object_big.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type.png new file mode 100644 index 0000000000..6c6e1fe2f5 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_big.png new file mode 100644 index 0000000000..04c8794e92 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_big.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_diagram.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_diagram.png new file mode 100644 index 0000000000..d8152529fd Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_diagram.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_tags.ai b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_tags.ai new file mode 100644 index 0000000000..3b5c47c9e3 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_tags.ai @@ -0,0 +1,6376 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[15 0 R 27 0 R 37 0 R 65 0 R 78 0 R 90 0 R 116 0 R 129 0 R 141 0 R 167 0 R 180 0 R 192 0 R 218 0 R 237 0 R 255 0 R 287 0 R 306 0 R 324 0 R 356 0 R 375 0 R 393 0 R 425 0 R 444 0 R 462 0 R 480 0 R 515 0 R 534 0 R 552 0 R 570 0 R 605 0 R 624 0 R 642 0 R 660 0 R 695 0 R 699 0 R 718 0 R 735 0 R 753 0 R 785 0 R 789 0 R 808 0 R 825 0 R 843 0 R 878 0 R 882 0 R 901 0 R 918 0 R 936 0 R 971 0 R 975 0 R 994 0 R 1011 0 R 1029 0 R 1056 0 R 1057 0 R 1058 0 R 1059 0 R 1060 0 R 1138 0 R 1139 0 R 1140 0 R 1141 0 R 1142 0 R 1143 0 R 1223 0 R 1224 0 R 1225 0 R 1226 0 R 1227 0 R 1228 0 R 1308 0 R 1309 0 R 1310 0 R 1311 0 R 1312 0 R 1313 0 R]>>/Pages 2 0 R/Type/Catalog>> endobj 1054 0 obj <>stream + + + + + application/pdf + + + Print + + + + + Adobe Illustrator CS3 + 2009-11-23T17:10:12+01:00 + 2011-04-04T19:44:30+02:00 + 2011-04-04T19:44:30+02:00 + + + + 256 + 208 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA0AEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXlX54yWv13ynbe YJ5YPIt1eTJ5h9NiqPIsYezSUp+84F0cmm21eoXMnT8jX1dGrJ0vkgvyquNDj/MTVdO8mS8/KaaZ FPqUNu8k1lHqzShR6Mko5fFCrbj7VP8AJFJ5yTAGX1X9jHH9W3J7FmG3uxV2KuxV2KuxV2KuxV2K pD5s89eU/KUNvN5h1FLFbpylupWSV3KirFY4ld+K7ValBUeIycMcpcgxlIDmivLfmfQfMumDU9Dv FvbIu0ZkUMhV06q6OFdDuDRgNiD0IxnjlE0UxkDuE0yCXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY q7FXYq7FXYq7FVO5tre6t5ba5iSe3mUxzQyKHR0YUZWVqggjqDhBpVPT9N07TbRLLTrWGys4q+nb W8axRLyJZuKIFUVJJOJJO5QBSIwJdirsVdirsVdirsVdirsVeb+cdC1a0/MF/OMdvNdaYnl24030 7FPXuxdCYyxqkPCSvqep8LcSoIPOgpXIxyHDw9eJrkDd+SL/AC10zWH1nzL5r1LTH0VfMMlobTTJ uHrrFbQEetNwJ4vK0p5IQGUjfHNIUI3dLAbk97Pcx2x2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ku xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kux V2KuxV2KuxVxIAqemKvMfPn59+V/LN1Pptqjanq0JKPDER6aOOP25Og/aBA+IEfZoa5lYdLKe/Rq nlAeb3X/ADkl5xub1JrWwgtbVaVteQk5UNTV2Su422zOj2cKcc6ksw8s/wDOSGmXc4h1/T207lQL NC3qxiin7RPEjk1ANqDqWynL2dIDbdsjqQeb2K2ura6t47i2lWaCVQ8UqEMrKdwQR1BzXEU5KpgV 2KuxV2KuxV2KuxV2KsA88/nX5P8AKcv1WSQ6hqFFb6palXYK4JBZq8V/ZPxEVBqK5kYtNKbXPKA8 5H/OUOsOV4eXoOIPxk3D1YdqAJ8P45mjs2+rQdV5Mm8rf85GaDfzCDXrR9Kd2/dzKfVgApQBn2at e/ED7t6svZ847jdlDUg83rdtcwXMEdxbyLLBKoeORTUMrCoI+jMAinJVMCuxV2KuxV2KuxV2KsOn /vpP9Y/rzYDk45WYVdiqf+Xv95ZP9f8AgMxc/NthyTXKGbsVdirsVePf85C/mZd+W9Ii0TSJxHqm qKyyypQyQwinJga1RmrQbd6g7ZlabDxGy05Z0HgfkPyNr3m3VPqWlxepIBzuLiQkRRKT9qR6Hqe3 U5tpZI443JxBEyNB7VZ/84ykW/8ApOvhbgjpFbckU/NpFLfcMx/5VrlH7W38p5sM89/lHr/lOH63 KyX2lkhTeQgjgTsBKhrxr2NSPeuZ2m1sMu3KTRlwyhv0Tj8j/wAwbnR9ai8tX8/+4i+ZvqxkO0Mx BPFSSOKyH/hvmTmL2jpQRxjm26bLvRfR2aNznYq7FXYq7FXYq7FXlv5+fmRL5S8uR2Wntx1jVuSW 770jjX+8k6UNKgAV6ncEVGZOmxcR8mrLOg8P/Lf8ptc892t7qVtfwRvBNxuGujIXd5BzL8lV6171 zZT1EcVAhxo4zNlll/zj35wk1a4smlt4rS24A6gxf05CyB6RLx5tx5UJ2Fe+T/lHGIg733Mfy0iV vmr8ivM+h6bJqEUkOpW0Cl7hYOSyIo6twYfEoHWhr7ZZh7QxzPCdixnp5RF80T+SP5hXWja1F5bv pS+k6g/G1Lkn0Zz0Vd9lkO1Kfa+ZOU9oaUEcY5s9Pl3ovo/NG57sVdirsVdirsVdirDp/wC+k/1j +vNgOTjlZhV2Kp/5e/3lk/1/4DMXPzbYcmHa9+Y+raf5i8xWMLWQk0Oze407y/IjnUtXZbE3XqWb etHSNJP3bBYJD8DdDTKGbz/zB+dHnC88gag73GnaQ91Zav8AVteikjZZXtbSF4rW1+pX92Le+d7m QpynYgRcuFSVRVJL7zN56mv9Zt7XX7mGeS5+qzAz3UskcU2t2NnCJrZZoRYH0p2Fu8BDXEXJyyvR gq9X8gah5wP5mebdM1y3u4rCGy019Jjlnimt44EmvLdJVpPNLzuxD6jFxzqpVzshZV4B+fupXd5+ ampxXD8/qIjtoTSlI+PqqtB4erT8c22lAEQ4eU7vfP8AnHbSbWz/AC0tL2JR6+pzTzTv3PpytAor 4ARfjmJrZE5K7m7APSxD81fzU81aL+YxstOuTDYaV6HO0AHCcyRrM/qbVNVk4+1KjfM3SaSE8Vkb lozZpCe3R7jqen2uq6Xc2FyvO2vImikUj9l1pWh7jNTCRjIEcw5khYp8VNezWF3DeQtxuLSVJomB rR42DKQR7jOqzAGNOphsX2zYPI9jbvI3ORokLuQAWYqKmgoN/bOUPN2wV8CXYq7FXYq7FXYq+QP+ citYXUfzMnjQMkdlClvxNBV0Zg77E9dhXwAza6WNRcTKbL1H/nFn/lHdZ/5io/8Ak3lXaHMe5lp+ RTn85PzT1zyjqGn6fpEUPqTxm5nmnUuCvMoqKAVp9k8j8qYdFpI5ATJc+YxIAZ75R19PMXlnT9Y9 MR/XYQ8kXUK4qrqK9QGBpmHmx8EzHuboS4gC+U/zAtk0LztqkNgfSFletJa8duFG9RAP9XbOixy4 8QJ6h10hwzNPr2wfnY271J5RI1WqW3UHevfOZPN2YV8CXYq7FXYq7FXYqw6f++k/1j+vNgOTjlZh V2Kp/wCXv95ZP9f+AzFz822HJNcoZuxV2KuxV8n/APOTXlk6Z54i1eFKW2qQhpG5cj66Ehq9eIYU 4/I06ZstLO413OLmjuz3/nGj8wdNn0H/AAjeTrDqFpI8mno5p60MpLsqV6ujliR4H2OV6zEb4gyw y2pmXm78mtD8y+a4NfuLmSGnpi+tFRWWf0tl+In4aqAp2Ow7YMOtljhwgJngEpWmv5lee9O8o+XL i5lmUalNGyabbVHN5SKBuPXghNWP0dSMq02A5JV06s8uThD5Q8q6VN5h81abpMUfrCedTMlVFYkP KQVYhalRQVO5oM3mpy1ElwMULL7XtoFt7eKBSzLEiorMasQopUnxznCbdmqYFdirsVdirsVdir5Z /wCcpPL89p5ws9bVALW/txEStT+9hJJLdgWDbD2JzY6SXppxsw3Zp/zinJz8ua37Xcf/ACbyGuNk JwDYs2/Mn8p7LztcWV0181hdWimJnEYlDxE8uNCyUINaGvfpkdLqziBFXbLLh42S2kGjeUvLEULz C30vSbcK88p/ZQbs3+Ux8O52zHkZZJ31LYAIjyD5H1C4ufPHn+RbdH56zfMyogLOkLMSTReRPpxC poO2b6Uhjx13B14HFJ9l2sTQ20MLMGaNFRmAoCVFKgb0zni7JUwK7FXYq7FXYq7FXx5rf/OQfny1 1m/to47H04LmaNKwuTxRyor+89s28cYoOIZG0H/0MZ+YH++7D/kS/wD1UyXhBHEXf9DGfmB/vuw/ 5Ev/ANVMfCC8Re9/849eeda84eWdSvtWWFZre99CMQIUXj6SNuCzb1bMDVxqQb8RsPVMxW12KuxV 2Ksc8/8AkfTPOfl2bRr+qBj6lvMAC0cqghXFfCvb5dKjLMeQxNhjKNh8d+b/ACB5u8lX9NQtpUgV 62+oRhvSajEKeY+y1VO30io3zaY8olycSUCERafm7+YdvbC2j8w3wiAoA0zMwA7Bmqw+/J+Hj7gj il3oCzXzX5u1b0rVLrWNTmIDuzNK+54gySOfhFT1Y0yZyxiO4MREkvp78l/ykTydZHU9RYS69eJS UgUWKM7+mtQG/wBb9W22r1GoMzXRy8ePheoZitrsVdirsVdirsVdirHPP3kjTfOflybRr8lAx9SC YAFo5VB4uKjtXt8ulRlmPIYm2Mo2GFfkD5I13yfbeYNM1aLiTdo1tOv2JYwhXmtd+o7/AKqE26jI JUQwxRItjP8AzkB+YHmvyn5z039BajJZibTw0sYCyRsRNIKmOQOhPvTL9JCMoniF7sM0iDs8h1fz 5+YPne4jsbu8udUkJrHZQoFSo/a9KFUTYftEbZmREMe4FNBMpc3vn5J/k3P5Y5a15gjjfWZkAih2 cW6mjUUg8eVR8Rp1Hw7Cra/U6nj2HJycWKub2DMNudirsVdirsVdirsVfnh5m/5SPVf+Yy4/5Otm 7jyDhHmluSQ7FX1Z/wA4jf8AKFaz/wBtI/8AJiPNdrPqHucjDyeo6j5wk0/zrYeX7mzWOwvtPvL9 dXedVVDYtCJUaIrsoW4VuZcfLMNuYy35u6jN5d13zDY6AraZoF1JHcC7uzbTzWi2lveQzwRCCWst wl2PShcr25MrHiFV11+cHop5quFtdONt5ZLRPC+plL0yiSONWubb6swtoGZ2/emRvs/ZPZVUufze tLe80HSpH0Y6vrUX1ssNYQaets05hiaC7kgR7mSanwRpBuQwqAORVeiYqpz21vcJ6c8Sypv8LqGG 4Knr7EjEFWMn8q/y3Jq3lrT2buzW6MSfEkipPzyzxp97HgHcnekaBouj262+l2UNnCteKRIFA5Uq B4DbpkZSJ5pAAR+RS7FXYq7FXYq7FXYq7FXYqteJHFGG9COQJDAHrRhQj6MVYx5o/LPyh5o1C0vt ZtPrM9mOCcjUMnLlwflU8a16U6nLIZZRFBjKAKZ6J5R8saEGGj6Zb2Afjy9CMJUqCAdu+/XqcjKZ PMpEQE2yKXYq7FXYq7FXYq7FXYq/PDzN/wApHqv/ADGXH/J1s3ceQcI80tySHYq+rP8AnEb/AJQr Wf8AtpH/AJMR5rtZ9Q9zkYeT13VvKekatrNnql+hnaztL2wFo4R7eWDUfR9dZo2Vue1soArShNQe 2G3MVuPyQ8qJcSS6LcXHl2OW/j1OS10qHTo7dp4II4IA0M1pOjJCYmljUigld3+1x4qpvL5AaXVp 9YfzBqZ1UwyWtheUsOVlBPNHPLHAv1TgwcwIv79ZCF6UqcVSib8kvLElo1ql9fwxXVvJaazwa3rq EM11LeSJccoG4cp7mVq2/pEcqCgAoq9CxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2K uxV2KuxV2KuxV2KvkXWv+cafzQu9Yv7qGC0MNxcSyxk3Kg8XcsKingc2cdVABxjiKC/6Ff8AzW/5 Z7P/AKSV/ph/NwR4Rd/0K/8Amt/yz2f/AEkr/TH83BfCL3f8gPy+8x+SPLWo6frqRJcXN59YiEMg kHD0kTcj3U5h6nIJmw3Y4kDd6hmO2OxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kux V2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV 2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2 KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2K uxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ku xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVDHUrEEgzKCNiMHEGzwpdzv0nYf7/XHiC+DLud+k 7D/f648QXwZdyrDcQzKWicOAaEjxxBYyiRzVMLF2KuxV2KqdxcQ20DzzuI4YwWdz0AGKCaeQeav+ cjdJsbyWz8v2Y1Vo2Km7LlIDt1U0JajV6bEbhsBLg5tfGPLdiMH5+fmCzDlHZmIdQIiHI/1uXH/h cjxOCe1JBn3lP8+NJ1K5W01u2/Rc0jBY5g3OCpIFGc049SakUphEnLwdpQmaOz1JWVlDKaqdwRkn ZN4q7FXYq7FXYq7FXYq7FXYqhr/UtP0+3a4vriO2hQFmeRgoABAJ3+YwgWgyA5pEfzN8gCX0/wBO 2paoFVeq7/5QHH8cn4Uu5q/MY+8J1pus6TqcQm067iuojUB4nDA8aA9PCoyBiRzbIzEuRRmBk7FX Yq7FXYq7FXYqxCf++k/1j+vKC7WPJZiydiqfeX/95pP9f+AyyHJwdV9QTTJuM7FXYq7FXzr/AM5E /mHcz6n/AIP0+Qx28IDamylgXZqFYiCF/wBY9ailD1rEl1utzfwhg/kLyHrfmi7NtpkIKR0NxcyE rFED05MAetNgBXBTq4YZ5ZVF69af848IsI+s63SWm6x2/wAIPzaSp+4YeFyx2P3y+x5z5x8sxaBr 1zo31kXbWwTlME9PeRA4HHk/Zh3yJdTqcPhZDG7p6J+R/ni6eZvK2oTc0iQvp0jncKCAYuRI2X9k UP0AZKJdz2ZqjIcBezZJ3DsVdirsVdirsVdirsVYl+ZPn6x8naE125WS/mPp2dqGHN2IPxUo3wim 5O3zNFNmOHEWnNlEA+c3vfNXnzzBH9clN1e3clLe2DCOFCRQBFY8VoopU7mm5OZ8YCIt0+TJLJKu pZte/k1qmj+X7nVtRuYENsqt9Wi5SMeTBaMxCgfa7VxhqIykAAjLopxgZSPJjOny3+mXK3mmXD21 whBDodjxNQGU/CwqOhGZMsYkN3Bx55QNgvdfy58/p5ltHt7wpDq9vT1YgacwannGD22+Y79idVnw 8B8nodJqhlHmzTKHMdirsVdirsVdirEJ/wC+k/1j+vKC7WPJZiydiqfeX/8AeaT/AF/4DLIcnB1X 1B5r5t8m+c9Y/MTXrzTAHi/R2mWdu18/1SEWk8l0dQisr2O0upopmEUatwP2ZKtuIuM3GS3yTqP5 m6f5Ut9Pntb+x1bS/LtsnlrQ47NpLC7ki0oEG/u5LTlBcLcKVMDTRUYBfjryKqL8k+Y/zPutXtIf NFzqNtprFW0+a00ydjczmQB7XU5JtKt2t40FKSpBEpVv7xipOKp/+T+sfmRqSam/nRTFKogKWskE 0LQXBMnrxxu1lZQyQiicPTknpvWVuQoq+ZfOFxNP551ySZ2kcX1wnNyWbjHIUWpO5oqjIF0OfmX1 R+S+kWun/l5pjwqPVvVa6uJAN2d2IFf9VAFyQdnooCOMebAPzL/NXzZaearvS9JufqFpYMIvgRGe RqAszM6t3OwGRJdbrNdkGQxiaAeb3+sX+q6jPqF/L613cENNLQLyIAHRQANh2GB1OWZmeI8yivKe qy6b5x0m9gAMsU2ynoQylSD9BxDkaGRjkBfWuWPVuxV2KuxV2KuxV2KuxV8rfnpr1xqn5i3Fk7Vt 9KVbeFFYsvJlDu1D0Y1CtT+XM3BGg6nVzuXuZf8AkDo2h3N3eXl8im+s2t205mkZCGcS8+KhlD/Z HUHJamRAAHJjoYxlIk8xVfa9u1ix02+02e01MK1jKAJwzmMUDAirKVI3A75hQkQbHN2uSMZRIlye CefbHRdM8zPZ6OqrYiKNlCSNKOTA8viZnP45ttPOUo+rm83rcUIzqHJLfKurzaR5t0y8hbiHmSCY FiqmOVgp5EdgSG+jHURuJXRZDHIH0zmnendirsVdirsVdirEJ/76T/WP68oLtY8lmLJ2Kp95f/3m k/1/4DLIcnB1X1BNMm4zsVdirsVfGv5weXJvL35g6jGwYwXchu4JGIJYS/E5bjsDzqaeFNhkC6bU 46kXuH/OP3nzTtT8sQ+XZ5lTVdN5LFExo0sBYurJXrwrxIHQAZIOXosoMeE8wyPzd+UflnzLqR1K d57S9cATvbsvGTiKAsrq3xUAFRiQuo0EMsuI2C8G/MLQ7Tyx5rvdItWdra3ERheUguVeJXqxAUdS e2QIdHqtPwZDEckX+TOiz675+tZxGJLPSwbi5LAlNwVRSQDuSaivWmEOX2fhud9z6lybv3Yq7FXY q7FXYq7FXYq+QvzgtpLT8zta514yzLKjEUqrop2r4Go+jM7EfSHUakesp1+U06v5w0da7+uD/wAK cvyH92XEwD99H3vfPzNUnyJq4AqfTQ7eAlUnMDT/AFh3Gt/upPnBCFNTm4eZKppxa78waZaxk8pb qFagFqD1BVqDwG+U5pekuTpoXMe99ZZp3p3Yq7FXYq7FXYq+DfMPnrztHr+pxx+YdTSNLudURby4 AAEjAAAP0GYpL0cIDhGyX/4+89f9THqn/Sbcf814LZcA7nf4+89f9THqn/Sbcf8ANeNrwDufTP8A zizrOsar5Q1abVL64v5k1Aokl1K8zKvoRniC5YgVOXYuTqe0ABIe57TlrgOxV2KuxVhP5p/lrY+d 9FELMYdStAz2FwADRj1U1ps1PEfgKAhpz4RMeb5S1/yt5q8o6iYdStpLZ4XAjukr6bNQMpSQd+JD UNGHcDIuoyYjE7o+D81fPsUaxrr9/wAVFBWeQ7fMknFHiZP5xV9B8v8Anrz7qfK2S4vXkYLcandM 7RoNh8czciaV6Cp9saWGCWQ976k/L3yBpXkzRUsbX99dv8V5esAHkkNK+PFdtl/Wd8kA7jDhEBQZ ThbnYq7FXYq7FXYq7FXYq8b/AOcgfy6uNYtIvMemI0t/ZKIp7dQzNJDUn4dyKoei0FanqxAy/DOt nD1WK9w8J8q+ZJtE1qx1JBzaznjm9M7BgjAlfpG2ZZ3FOtG0ge59X6X+Z35favp6zjWbOFJVpJbX kscEi1G6skpWvhtUZgnHIHk7iOeEhzDwb81td0WXzhdto8sEtgEhWN7biYqiNQ3Hh8PXwzPwyIju 6fVQichMeTLfyI8j3dzfjzXqKNFDCKabGwYFy4IMtRx2psOtQTUUKk4+oy3s5ei09eovd8xHZuxV 2KuxV2KuxV+ePmX/AJSPVf8AmMuP+TrZiHm9LD6QluBk7FX1X/ziN/yhWs/9tI/8mI8vxcnUdo/W Pcyfzh501vyv5rv77VJNQXQYrOaTRLO2XT3sry4tNPmvJ4Z24SahHJxiLJQqnw9d6G116Rr5685D ytLPPqV5Z+ZbK/0KfVLO5tdO9A2esXkdsIrQ27XIELgyUMkjTDjvxqMVTtfO/mXU/wA1p/LURvNI 0uTTtSgsTNpk/wAV5Zy2gF+LiWIQvFSeRECuU2UtvJGuKsek/NfzdH5M8gXZF2bjU10e81/WItNn uYZorq9gtpbWM28EkMc0qyO1Nm2CoC7rRV7hiqjdWVndoUuoEmQqUIdQ3wtTkN/GmKCAWPD8sfy+ Dcx5fshJ/v0RASV8eY+KvvXGmvwYdzJIbeCBeEMaxJt8KKFGwoNh7DFtpfirsVdirsVdirsVdirs VdirTojoyOoZGBVlYVBB2IIOKvNfPH5E+V/MlzNqFsW03Upas8kIHpu5pu6Up4kkbknrlsMxDjZN NGW/Vgp/5xf1kS0TX4DD/OYHDU/1eRH/AA2W/mPJo/JHvZZ5R/5x58uaTPHd6vcNq1zE1VjdQtvU EFSY969CCGJG+QlnJ5NuPSRHPd6vHFHEgSNQiCpCqKCpNT08TlDl0uxV2KuxV2KuxV2Kvzx8y/8A KR6r/wAxlx/ydbMQ83pYfSEtwMnYq+q/+cRv+UK1n/tpH/kxHl+Lk6jtH6x7nsg8teXBq8utDSrM axcJ6U+pC3i+syR8QvB5uPqMvFQKE9MtdepWPlDynYWUljY6JYWljLMlzLawWsMcTTxOskcrIqhS 6OisrUqCAe2Kpi1patdR3jQxtdwxvDFcFQZEjlKNIivTkFdokLAdeI8BiqjHo+kR6fBp0djbpp9q Yja2axIIYjbuskBjjA4r6TorJQfCQCOmKovFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F XYq7FXYq7FXYq7FXYq+eNT/5xH+vald3v+K/T+tTSTen+j+XH1GLUr9ZFaV8MqOLzdlHtGhXD9v7 EN/0J3/393/cu/7OsHhebL+Uv6P2/sd/0J3/AN/d/wBy7/s6x8LzX+Uv6P2/serflH+V/wDyrzRb zTP0n+lPrdz9Z9b0Pq/H92qcePqTV+xWtcsjGnD1GfxDdUzrJOO7FXYq7FXYq7FXYq7FXYq7FXYq 7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXhPnm HT9e/MDzVY+ZdTf6toltZyeXtEku0sYJmlg5TSBnHFnR2O/U1pWg2iXXZwJSkD05C6Zp+RfmDXNd 8iJdau0kzxXMsFpdzcjJPAgUh2difUIdnTkP5aHcHCG7RzlKHqehYXLdirsVdirsVdirsVdirsVd irHfOHnax8tCxga2mv8AVNVkaDTNPtwOUsigfadiFRAzKGbcitaHfLMePi8gGjNnEKFWTyW+U/O1 pr011YTW0mm61Yn/AEzTZypdRWnONl2kSu3Knh4issuEwo84nqw0+qGQmPKQ5hkmUuU7FXYq7FXY q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FUt1Xyx5a1eVJdW0my1CWNeEcl3bxTsq1rRTIrECuLGU InmEdb29vbW8VtbRJDbwoscMMahEREFFVVFAAAKADFIFKmKXYq7FXYq7FXYq7FXYq7FXYqwf8yfJ uta3d6DrOiSxDUvL1y1zHbTs0aTIxR2TmoahJhC77UJqcvw5AAQeri6nDKRjKPOKn5F8k6rZeZNV 82ayfq99qi+nDpaTG5W3ico7iSYqvNuaAKF+FR3NdpZs1xERyDDTabhmch2MunNnmYzmuxV2KuxV 2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV//2Q== + + + + + + uuid:89B13A64E5D9DE11BB37992E5642CB24 + uuid:c9fc39ea-7338-234e-90fd-9c707322e008 + proof:pdf + + uuid:1052650b-0efc-4cb2-a32e-387095575b05 + uuid:6120892493BFDB11914A8590D31508C8 + + + + Document + Print + + + 1 + False + False + + 841.889648 + 595.275391 + Pixels + + + + + MyriadPro-Regular + Myriad Pro + Regular + Open Type + Version 2.062;PS 2.000;hotconv 1.0.57;makeotf.lib2.0.21895 + False + MyriadPro-Regular.otf + + + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + White + RGB + PROCESS + 255 + 255 + 255 + + + Black + RGB + PROCESS + 35 + 31 + 32 + + + CMYK Red + RGB + PROCESS + 236 + 28 + 36 + + + CMYK Yellow + RGB + PROCESS + 255 + 241 + 0 + + + CMYK Green + RGB + PROCESS + 0 + 165 + 81 + + + CMYK Cyan + RGB + PROCESS + 0 + 173 + 238 + + + CMYK Blue + RGB + PROCESS + 46 + 49 + 145 + + + CMYK Magenta + RGB + PROCESS + 235 + 0 + 139 + + + C=16 M=98 Y=92 K=7 + RGB + PROCESS + 194 + 39 + 45 + + + C=0 M=99 Y=97 K=0 + RGB + PROCESS + 236 + 32 + 39 + + + C=0 M=79 Y=96 K=0 + RGB + PROCESS + 240 + 92 + 39 + + + C=0 M=50 Y=98 K=0 + RGB + PROCESS + 246 + 146 + 33 + + + C=0 M=35 Y=87 K=0 + RGB + PROCESS + 250 + 175 + 59 + + + C=5 M=0 Y=93 K=0 + RGB + PROCESS + 249 + 236 + 35 + + + C=19 M=0 Y=98 K=0 + RGB + PROCESS + 216 + 223 + 39 + + + C=50 M=0 Y=99 K=0 + RGB + PROCESS + 139 + 197 + 64 + + + C=74 M=0 Y=99 K=0 + RGB + PROCESS + 61 + 180 + 74 + + + C=86 M=12 Y=100 K=9 + RGB + PROCESS + 0 + 146 + 69 + + + C=88 M=28 Y=95 K=32 + RGB + PROCESS + 0 + 104 + 55 + + + C=76 M=0 Y=75 K=0 + RGB + PROCESS + 34 + 180 + 115 + + + C=78 M=9 Y=46 K=0 + RGB + PROCESS + 3 + 168 + 156 + + + C=70 M=15 Y=0 K=0 + RGB + PROCESS + 37 + 169 + 224 + + + C=87 M=52 Y=0 K=0 + RGB + PROCESS + 16 + 114 + 185 + + + C=99 M=96 Y=4 K=0 + RGB + PROCESS + 46 + 55 + 143 + + + C=100 M=100 Y=26 K=25 + RGB + PROCESS + 38 + 34 + 97 + + + C=74 M=98 Y=1 K=0 + RGB + PROCESS + 103 + 48 + 144 + + + C=49 M=99 Y=1 K=0 + RGB + PROCESS + 146 + 41 + 141 + + + C=34 M=100 Y=37 K=11 + RGB + PROCESS + 157 + 30 + 96 + + + C=12 M=100 Y=49 K=1 + RGB + PROCESS + 211 + 28 + 92 + + + C=0 M=96 Y=20 K=0 + RGB + PROCESS + 236 + 37 + 122 + + + C=23 M=27 Y=40 K=0 + RGB + PROCESS + 198 + 178 + 152 + + + C=40 M=43 Y=52 K=7 + RGB + PROCESS + 152 + 133 + 118 + + + C=50 M=53 Y=61 K=23 + RGB + PROCESS + 117 + 101 + 88 + + + C=57 M=60 Y=64 K=42 + RGB + PROCESS + 85 + 72 + 65 + + + C=23 M=38 Y=63 K=1 + RGB + PROCESS + 197 + 156 + 110 + + + C=32 M=49 Y=74 K=10 + RGB + PROCESS + 165 + 124 + 82 + + + C=36 M=57 Y=84 K=23 + RGB + PROCESS + 139 + 99 + 57 + + + C=39 M=64 Y=93 K=36 + RGB + PROCESS + 117 + 77 + 36 + + + C=41 M=70 Y=96 K=49 + RGB + PROCESS + 97 + 57 + 23 + + + C=47 M=73 Y=83 K=68 + RGB + PROCESS + 65 + 35 + 18 + + + + + + Print Color Group + 1 + + + + C=2 M=28 Y=72 K=0 + RGB + PROCESS + 246 + 187 + 96 + + + C=5 M=70 Y=90 K=0 + RGB + PROCESS + 231 + 110 + 52 + + + C=4 M=92 Y=77 K=0 + RGB + PROCESS + 229 + 59 + 65 + + + C=29 M=2 Y=92 K=0 + RGB + PROCESS + 191 + 210 + 65 + + + C=62 M=4 Y=93 K=0 + RGB + PROCESS + 109 + 182 + 78 + + + C=30 M=2 Y=7 K=0 + RGB + PROCESS + 174 + 218 + 230 + + + C=60 M=8 Y=5 K=0 + RGB + PROCESS + 85 + 185 + 223 + + + C=78 M=4 Y=11 K=0 + RGB + PROCESS + 0 + 178 + 215 + + + + + + Grayscale + 1 + + + + K=100 + GRAY + PROCESS + 255 + + + K=90 + GRAY + PROCESS + 229 + + + K=80 + GRAY + PROCESS + 203 + + + K=70 + GRAY + PROCESS + 178 + + + K=60 + GRAY + PROCESS + 152 + + + K=50 + GRAY + PROCESS + 127 + + + K=40 + GRAY + PROCESS + 101 + + + K=30 + GRAY + PROCESS + 76 + + + K=20 + GRAY + PROCESS + 50 + + + K=10 + GRAY + PROCESS + 25 + + + K=5 + GRAY + PROCESS + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + endstream endobj 2 0 obj <> endobj 5 0 obj <>/Resources<>/ExtGState<>/Font<>/ProcSet[/PDF/Text]/Properties<>/XObject<>>>/Thumb 1327 0 R/TrimBox[0.0 0.0 841.89 595.275]/Type/Page>> endobj 1315 0 obj <>stream +HWɎ7W(}10f 9e ƌ"Tٲ *`06h>:՛G|?JJzx|q5,`ǏKfSlь~X!Ư9Po0=SZL)T[Q)}b۔]ƯgG|9ⓐIMvO'|xu}]^}{N}'$\0yz)\^?Lr ë$L)W.>D byY,גˊq_dɏ?^yNy%$G3/E,ߋ6o9ٶ咢Β˾cy|WX:x}p:'?-P5=qм9]݋;1hNhլCYm} +zM[ױΥš  *8e&ieg#j779vL^0  @6g6%ǁBӥnk0XĞ ESEjc3a7 %495[݇s~rFzB:Aa$)s% .%<7Ɛ)08عB,:(d%O/IϸPxǢ4C')\@mBjQc4\.#d(7(;uQK9/Av7bdA{OCEH|T0ŒpFHFܤ@Lc$L 1K.ȅĸHʬ03IǸH X8Fd(DXeD$ iqH +]eaECa(pK(n=GJY1H*E:"lx/tHs,~|eG-T@iBQA-_*A*rҵ띁̀'E_q^b3UDxG'5#Qru84A`׺-n5gHR)?V4AHR6 'p% L)kdk +T>admәr)WHR{o+#@~"}bXv ]N`hy9cN9Sn; f%D)F@c2ubq,;TblXzGi&6̼CL| R^R\sd]PCa1ȿSƑr4T>d٥B62NN3^b*i7/ |]ix_" cUrE=Qc=nQ0>[e7<ޝ/U-I -RB(7x6KJ +q\F=wl.ϔDA~lzKE!בRc Rr@H `]^H8RneH,^Mؔ cX)G8dLf`ׂ9;ֈt;<ܙ#E6~uHl1(z>_-uS!}QLU*U{Cg;Hh3mn/R=r8)3(XW~S}h 7e6:ywsmL-g18Zܑ6qf7BM ;rSCt:\Aax墌tl1.@Y|UT4׻<5BRdD#uU@jw!(5`$WtƝy~utKW>޵ A>ʧU&o"28 &| endstream endobj 1327 0 obj <>stream +8;Z]!0oj-o&4Mq#BXZ(r-qRjZg"d;e'fX2?:$%:pb1G;i=ZP,(M5$Ct>Pr+OM%Sb3 +$Z$YM!!)e4pih!i-MB:^dR_nsi+[p*`^+#SD`bS0lt>(HO8LDNEmrh`0uV.i4u*`_ + endstream endobj 1328 0 obj [/Indexed/DeviceRGB 255 1329 0 R] endobj 1329 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 1319 0 obj <>/ExtGState<>/XObject<>>>/Subtype/Form>>stream +/CS0 cs 0.173 0.522 0.345 scn +/GS0 gs +q 1 0 0 1 183 308.2725 cm +0 0 m +6.607 0.011 12.01 -5.392 11.999 -11.999 c +12.01 -18.606 6.607 -24.009 0 -23.998 c +-6.607 -24.009 -12.01 -18.606 -11.999 -11.999 c +-12.01 -5.392 -6.607 0.011 0 0 c +f +Q +q +0 g +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q + endstream endobj 1320 0 obj <>/ExtGState<>/XObject<>>>/Subtype/Form>>stream +/CS0 cs 0.173 0.522 0.345 scn +/GS0 gs +q 1 0 0 1 186.627 218.2744 cm +0 0 m +0.544 0.003 0.995 -0.445 0.994 -1.003 c +0.997 -1.549 0.546 -1.999 0 -1.997 c +-0.55 -2 -1.007 -1.543 -1.003 -1.003 c +-1.005 -0.451 -0.549 0.003 0 0 c +f +Q +q +0 g +1 w 4 M 0 j 0 J []0 d +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q + endstream endobj 1321 0 obj <>/ExtGState<>/XObject<>>>/Subtype/Form>>stream +/CS0 cs 0.243 0.533 0.643 scn +/GS0 gs +q 1 0 0 1 334.002 303.2773 cm +0 0 m +6.607 0.011 12.01 -5.392 11.999 -11.999 c +12.008 -18.614 6.61 -24.008 0 -23.998 c +-6.61 -24.008 -12.008 -18.614 -11.999 -11.999 c +-12.01 -5.392 -6.607 0.011 0 0 c +f +Q +q +0 g +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q + endstream endobj 1322 0 obj <>/ExtGState<>/XObject<>>>/Subtype/Form>>stream +/CS0 cs 0.212 0.624 0.78 scn +/GS0 gs +q 1 0 0 1 327.999 212.2715 cm +0 0 m +0.55 0.003 1.007 -0.454 1.003 -0.994 c +1.008 -1.537 0.543 -2.002 0 -1.997 c +-0.543 -2.002 -1.008 -1.537 -1.003 -0.994 c +-1.007 -0.454 -0.55 0.003 0 0 c +f +Q +q +0 g +1 w 4 M 0 j 0 J []0 d +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q + endstream endobj 1323 0 obj <>/ExtGState<>/XObject<>>>/Subtype/Form>>stream +/CS0 cs 0.196 0.322 0.616 scn +/GS0 gs +q 1 0 0 1 323.6699 445.7744 cm +0 0 m +6.607 0.011 12.01 -5.392 11.999 -11.999 c +12.01 -18.606 6.607 -24.009 0 -23.998 c +-6.615 -24.007 -12.009 -18.609 -11.999 -11.999 c +-12.009 -5.389 -6.615 0.009 0 0 c +f +Q +q +0 g +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q + endstream endobj 1324 0 obj <>/ExtGState<>/XObject<>>>/Subtype/Form>>stream +/CS0 cs 0.196 0.322 0.616 scn +/GS0 gs +q 1 0 0 1 315.165 487.2754 cm +0 0 m +0.548 0.003 1.005 -0.451 1.003 -1.003 c +1.007 -1.542 0.55 -2 0 -1.997 c +-0.546 -2 -0.997 -1.549 -0.994 -1.003 c +-0.995 -0.445 -0.544 0.003 0 0 c +f +Q +q +0 g +1 w 4 M 0 j 0 J []0 d +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q + endstream endobj 1325 0 obj <>/ExtGState<>/XObject<>>>/Subtype/Form>>stream +/CS0 cs 0.196 0.322 0.616 scn +/GS0 gs +q 1 0 0 1 184.8359 446.2783 cm +0 0 m +6.607 0.011 12.01 -5.392 11.999 -11.999 c +12.008 -18.617 6.606 -24.018 0 -24.007 c +-6.606 -24.018 -12.008 -18.617 -11.999 -11.999 c +-12.01 -5.392 -6.607 0.011 0 0 c +f +Q +q +0 g +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q + endstream endobj 1326 0 obj <>/ExtGState<>/XObject<>>>/Subtype/Form>>stream +/CS0 cs 0.196 0.322 0.616 scn +/GS0 gs +q 1 0 0 1 189.876 496.0234 cm +0 0 m +0.55 0.003 1.007 -0.455 1.003 -0.994 c +1.005 -1.546 0.548 -2 0 -1.997 c +-0.548 -2 -1.005 -1.546 -1.003 -0.994 c +-1.007 -0.455 -0.55 0.003 0 0 c +f +Q +q +0 g +1 w 4 M 0 j 0 J []0 d +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q + endstream endobj 1344 0 obj <> endobj 1345 0 obj <>/XObject<>>>/Subtype/Form>>stream +q +189.876 496.023 m +189.876 501.023 l +193.188 501.023 195.879 498.341 195.879 495.029 c +195.879 491.708 193.188 489.026 189.876 489.026 c +186.564 489.026 183.873 491.708 183.873 495.029 c +183.873 498.341 186.564 501.023 189.876 501.023 c +189.876 496.023 l +189.326 496.026 188.869 495.569 188.873 495.029 c +188.871 494.478 189.328 494.023 189.876 494.026 c +190.424 494.023 190.881 494.478 190.879 495.029 c +190.883 495.569 190.426 496.026 189.876 496.023 c +W n +q +1 w 4 M 0 j 0 J []0 d +/GS0 gs +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q +Q + endstream endobj 1346 0 obj <> endobj 1347 0 obj <>/ExtGState<>>>/Subtype/Form>>stream +/CS0 cs 0.2 0.325 0.624 scn +/GS0 gs +q 1 0 0 1 189.876 496.0234 cm +0 0 m +0 5 l +3.312 5 6.003 2.318 6.003 -0.994 c +6.003 -4.315 3.312 -6.997 0 -6.997 c +-3.312 -6.997 -6.003 -4.315 -6.003 -0.994 c +-6.003 2.318 -3.312 5 0 5 c +0 0 l +-0.55 0.003 -1.007 -0.455 -1.003 -0.994 c +-1.005 -1.546 -0.548 -2 0 -1.997 c +0.548 -2 1.005 -1.546 1.003 -0.994 c +1.007 -0.455 0.55 0.003 0 0 c +f +Q +q 1 0 0 1 189.876 496.9482 cm +0 0 m +-0.013 -0.041 -0.073 -0.074 -0.083 -0.116 c +-0.111 -0.248 -0.02 -0.426 0 -0.56 c +0 -0.925 l +-0.55 -0.922 -1.007 -1.379 -1.003 -1.919 c +-1.005 -2.471 -0.548 -2.925 0 -2.922 c +0.548 -2.925 1.005 -2.471 1.003 -1.919 c +1.007 -1.379 0.55 -0.922 0 -0.925 c +0 -0.56 l +0.034 -0.557 0.079 -0.553 0.113 -0.55 c +0.142 -0.55 0.184 -0.537 0.21 -0.549 c +1.046 -1.473 l +1.442 -2.154 1.79 -2.107 1.805 -2.105 c +2.057 -2.065 3.182 -0.618 1.901 0.191 c +1.598 0.383 1.274 0.41 1.132 0.395 c +0 0 l +0 4.075 l +3.312 4.075 6.003 1.393 6.003 -1.919 c +6.003 -5.24 3.312 -7.922 0 -7.922 c +-3.312 -7.922 -6.003 -5.24 -6.003 -1.919 c +-6.003 1.393 -3.312 4.075 0 4.075 c +0 0 l +f +Q +0.196 0.318 0.612 scn +q 1 0 0 1 189.876 497.0903 cm +0 0 m +-0.03 -0.092 -0.164 -0.17 -0.185 -0.265 c +-0.222 -0.433 -0.125 -0.678 -0.188 -0.838 c +-0.188 -0.839 -0.237 -0.941 -0.403 -1.05 c +-1.156 -1.54 -1.044 -2.156 -0.992 -2.333 c +-0.807 -2.959 -0.146 -3.264 0.451 -2.999 c +0.651 -2.909 0.79 -2.772 0.872 -2.69 c +1.143 -2.422 1.548 -2.621 1.836 -2.412 c +2.433 -1.979 2.576 -1.57 2.629 -1.416 c +2.85 -0.785 2.461 0.134 1.628 0.371 c +0.853 0.591 0.002 0.007 0 0 c +0 3.933 l +3.312 3.933 6.003 1.251 6.003 -2.061 c +6.003 -5.382 3.312 -8.064 0 -8.064 c +-3.312 -8.064 -6.003 -5.382 -6.003 -2.061 c +-6.003 1.251 -3.312 3.933 0 3.933 c +0 0 l +f +Q +0.192 0.31 0.596 scn +q 1 0 0 1 189.876 497.231 cm +0 0 m +-0.294 -0.832 -1.296 -1.347 -1.079 -2.407 c +-0.939 -3.088 -0.171 -3.557 0.648 -3.165 c +2.592 -2.234 2.592 -2.234 2.763 -1.674 c +3.159 -0.375 2.125 0.263 1.731 0.384 c +0.831 0.661 0.003 0.008 0 0 c +0 3.792 l +3.312 3.792 6.003 1.11 6.003 -2.202 c +6.003 -5.522 3.312 -8.205 0 -8.205 c +-3.312 -8.205 -6.003 -5.522 -6.003 -2.202 c +-6.003 1.11 -3.312 3.792 0 3.792 c +0 0 l +f +Q +0.188 0.302 0.58 scn +q 1 0 0 1 189.876 497.3701 cm +0 0 m +-0.353 -0.867 -1.383 -1.429 -1.146 -2.56 c +-1.024 -3.139 -0.35 -3.806 0.712 -3.399 c +2.444 -2.735 2.625 -2.666 2.946 -1.778 c +2.952 -1.763 3.406 -0.235 2.053 0.316 c +0.838 0.812 0.004 0.01 0 0 c +0 3.653 l +3.312 3.653 6.003 0.971 6.003 -2.341 c +6.003 -5.662 3.312 -8.344 0 -8.344 c +-3.312 -8.344 -6.003 -5.662 -6.003 -2.341 c +-6.003 0.971 -3.312 3.653 0 3.653 c +0 0 l +f +Q +0.18 0.294 0.569 scn +q 1 0 0 1 189.876 497.5073 cm +0 0 m +-0.193 -0.417 -0.585 -0.692 -0.795 -1.098 c +-1.093 -1.708 l +-1.262 -2.107 -1.291 -2.435 -1.188 -2.804 c +-1.126 -3.032 -0.727 -4.136 0.984 -3.565 c +4.73 -2.315 2.784 0.034 2.453 0.247 c +1.442 0.896 0.101 0.218 0 0 c +0 3.516 l +3.312 3.516 6.003 0.834 6.003 -2.478 c +6.003 -5.799 3.312 -8.481 0 -8.481 c +-3.312 -8.481 -6.003 -5.799 -6.003 -2.478 c +-6.003 0.834 -3.312 3.516 0 3.516 c +0 0 l +f +Q +0.176 0.286 0.553 scn +q 1 0 0 1 189.876 497.6602 cm +0 0 m +-0.013 -0.025 -0.053 -0.04 -0.076 -0.058 c +-0.365 -0.276 -0.692 -0.523 -1.173 -1.803 c +-1.244 -1.989 -1.457 -2.557 -1.185 -3.151 c +-0.782 -4.034 0.179 -4.205 1.672 -3.658 c +3.872 -2.853 3.987 -0.377 2.341 0.401 c +1.366 0.863 0.123 0.247 0 0 c +0 3.363 l +3.312 3.363 6.003 0.681 6.003 -2.631 c +6.003 -5.952 3.312 -8.634 0 -8.634 c +-3.312 -8.634 -6.003 -5.952 -6.003 -2.631 c +-6.003 0.681 -3.312 3.363 0 3.363 c +0 0 l +f +Q +0.173 0.278 0.541 scn +q 1 0 0 1 189.876 497.8516 cm +0 0 m +-0.034 -0.067 -0.142 -0.105 -0.203 -0.15 c +-0.741 -0.551 -1.014 -1.287 -1.254 -1.937 c +-1.386 -2.294 -1.492 -2.833 -1.246 -3.37 c +-0.614 -4.746 1.248 -4.148 1.804 -3.932 c +4.133 -3.027 4.261 -0.305 2.51 0.419 c +1.108 0.999 0.006 0.012 0 0 c +0 3.172 l +3.312 3.172 6.003 0.49 6.003 -2.822 c +6.003 -6.143 3.312 -8.825 0 -8.825 c +-3.312 -8.825 -6.003 -6.143 -6.003 -2.822 c +-6.003 0.49 -3.312 3.172 0 3.172 c +0 0 l +f +Q +0.169 0.275 0.525 scn +q 1 0 0 1 189.876 498.0396 cm +0 0 m +-0.037 -0.07 -0.152 -0.104 -0.217 -0.148 c +-0.223 -0.151 -0.766 -0.542 -1.153 -1.542 c +-1.498 -2.429 -1.549 -2.937 -1.35 -3.481 c +-1.145 -4.045 -0.491 -4.904 1.578 -4.323 c +4.082 -3.621 4.629 -0.761 2.993 0.316 c +1.701 1.166 0.079 0.148 0 0 c +0 2.984 l +3.312 2.984 6.003 0.302 6.003 -3.01 c +6.003 -6.331 3.312 -9.013 0 -9.013 c +-3.312 -9.013 -6.003 -6.331 -6.003 -3.01 c +-6.003 0.302 -3.312 2.984 0 2.984 c +0 0 l +f +Q +0.165 0.267 0.51 scn +q 1 0 0 1 189.876 498.2236 cm +0 0 m +-0.175 -0.317 -0.542 -0.437 -0.748 -0.722 c +-1.027 -1.109 -1.128 -1.336 -1.241 -1.614 c +-1.322 -1.817 -1.715 -2.863 -1.448 -3.592 c +-0.849 -5.223 1.105 -4.776 1.689 -4.601 c +4.425 -3.778 5.003 -0.758 3.22 0.385 c +1.946 1.2 0.234 0.423 0 0 c +0 2.8 l +3.312 2.8 6.003 0.118 6.003 -3.194 c +6.003 -6.515 3.312 -9.197 0 -9.197 c +-3.312 -9.197 -6.003 -6.515 -6.003 -3.194 c +-6.003 0.118 -3.312 2.8 0 2.8 c +0 0 l +f +Q +0.161 0.259 0.498 scn +q 1 0 0 1 189.876 498.4546 cm +0 0 m +-0.06 -0.132 -0.265 -0.21 -0.386 -0.291 c +-0.759 -0.542 -1.229 -1.473 -1.327 -1.735 c +-1.444 -2.049 -1.803 -3.137 -1.475 -3.94 c +-0.715 -5.801 1.956 -4.866 1.983 -4.856 c +5.297 -3.576 5.172 -0.368 3.116 0.573 c +1.411 1.354 0.007 0.017 0 0 c +0 2.569 l +3.312 2.569 6.003 -0.113 6.003 -3.425 c +6.003 -6.746 3.312 -9.428 0 -9.428 c +-3.312 -9.428 -6.003 -6.746 -6.003 -3.425 c +-6.003 -0.113 -3.312 2.569 0 2.569 c +0 0 l +f +Q +0.153 0.251 0.482 scn +q 1 0 0 1 189.876 498.7373 cm +0 0 m +-0.04 -0.083 -0.167 -0.135 -0.239 -0.193 c +-0.737 -0.595 -1.131 -1.172 -1.412 -1.908 c +-1.719 -2.716 -1.736 -3.696 -1.576 -4.141 c +-0.861 -6.127 1.881 -5.307 1.908 -5.298 c +5.872 -3.968 5.348 -0.494 3.424 0.518 c +1.628 1.463 0.058 0.121 0 0 c +0 2.286 l +3.312 2.286 6.003 -0.396 6.003 -3.708 c +6.003 -7.029 3.312 -9.711 0 -9.711 c +-3.312 -9.711 -6.003 -7.029 -6.003 -3.708 c +-6.003 -0.396 -3.312 2.286 0 2.286 c +0 0 l +f +Q +0.149 0.243 0.467 scn +q 1 0 0 1 189.876 499.0234 cm +0 0 m +-0.045 -0.106 -0.21 -0.167 -0.302 -0.236 c +-0.488 -0.374 -1.13 -0.939 -1.627 -2.442 c +-1.764 -2.855 -1.88 -3.934 -1.545 -4.673 c +-1.028 -5.816 0.793 -6.212 2.513 -5.554 c +6.321 -4.099 5.738 -0.283 3.153 0.723 c +1.353 1.423 0.007 0.017 0 0 c +0 2 l +3.312 2 6.003 -0.682 6.003 -3.994 c +6.003 -7.315 3.312 -9.997 0 -9.997 c +-3.312 -9.997 -6.003 -7.315 -6.003 -3.994 c +-6.003 -0.682 -3.312 2 0 2 c +0 0 l +f +Q +0.145 0.235 0.455 scn +q 1 0 0 1 189.876 499.4067 cm +0 0 m +-0.163 -0.362 -0.542 -0.515 -0.779 -0.805 c +-0.948 -1.011 -1.049 -1.26 -1.205 -1.475 c +-1.361 -1.69 -1.461 -1.951 -1.723 -2.734 c +-2.048 -3.705 -1.823 -4.543 -1.66 -4.957 c +-1.17 -6.199 0.623 -6.718 2.422 -6.139 c +7.03 -4.656 5.827 -0.75 3.286 0.539 c +1.422 1.485 0.008 0.018 0 0 c +0 1.617 l +3.312 1.617 6.003 -1.065 6.003 -4.377 c +6.003 -7.698 3.312 -10.38 0 -10.38 c +-3.312 -10.38 -6.003 -7.698 -6.003 -4.377 c +-6.003 -1.065 -3.312 1.617 0 1.617 c +0 0 l +f +Q +0.141 0.227 0.439 scn +q 1 0 0 1 189.876 499.8311 cm +0 0 m +-0.128 -0.296 -0.442 -0.404 -0.638 -0.631 c +-0.788 -0.804 -0.893 -1.009 -1.031 -1.191 c +-1.148 -1.346 -1.62 -2.354 -1.623 -2.361 c +-2.171 -3.896 -2.053 -4.61 -1.842 -5.154 c +-0.963 -7.425 1.653 -7.025 2.586 -6.68 c +3.893 -6.196 6.611 -5.189 5.553 -2.521 c +5.843 -3.224 6.003 -3.994 6.003 -4.802 c +6.003 -8.123 3.312 -10.805 0 -10.805 c +-3.312 -10.805 -6.003 -8.123 -6.003 -4.802 c +-6.003 -1.49 -3.312 1.192 0 1.192 c +0 0 l +f +Q +0.137 0.22 0.427 scn +q 1 0 0 1 189.876 500.2959 cm +0 0 m +-0.037 -0.078 -0.154 -0.129 -0.22 -0.184 c +-1.238 -1.037 -1.832 -2.884 -1.837 -2.903 c +-2.426 -4.762 -2.011 -5.635 -1.875 -5.921 c +-0.599 -8.601 3.356 -7.148 3.396 -7.133 c +4.442 -6.725 6.193 -6.042 5.899 -4.15 c +5.967 -4.512 6.003 -4.885 6.003 -5.267 c +6.003 -8.587 3.312 -11.27 0 -11.27 c +-3.312 -11.27 -6.003 -8.587 -6.003 -5.267 c +-6.003 -1.955 -3.312 0.728 0 0.728 c +0 0 l +f +Q +0.133 0.216 0.412 scn +q 1 0 0 1 189.876 500.7388 cm +0 0 m +-0.038 -0.067 -0.155 -0.091 -0.221 -0.129 c +-1.151 -0.674 -1.646 -2.172 -2.007 -3.267 c +-2.012 -3.284 -2.546 -5.066 -2.073 -6.279 c +-1.012 -9 2.932 -7.99 3.099 -7.945 c +4.318 -7.622 5.989 -7.18 6.001 -5.577 c +6.002 -5.621 6.003 -5.665 6.003 -5.709 c +6.003 -9.03 3.312 -11.712 0 -11.712 c +-3.312 -11.712 -6.003 -9.03 -6.003 -5.709 c +-6.003 -2.397 -3.312 0.285 0 0.285 c +0 0 l +f +Q +0.125 0.208 0.396 scn +q 1 0 0 1 189.876 501.0112 cm +0 0 m +-0.043 -0.052 -0.154 -0.029 -0.221 -0.042 c +-0.696 -0.132 -1.348 -0.689 -1.732 -1.731 c +-2.576 -4.014 -2.459 -5.548 -2.314 -6.26 c +-1.78 -8.88 1.72 -8.614 1.755 -8.611 c +4.215 -8.371 5.7 -8.227 5.951 -6.778 c +5.561 -9.721 3.043 -11.985 0 -11.985 c +-3.312 -11.985 -6.003 -9.303 -6.003 -5.982 c +-6.003 -2.67 -3.312 0.012 0 0.012 c +0 0 l +f +Q +0.122 0.2 0.384 scn +q 1 0 0 1 188.9707 500.9468 cm +0 0 m +-1.737 -0.589 -1.75 -4.504 -1.75 -4.544 c +-1.745 -7.052 -0.74 -7.832 0.016 -8.2 c +1.799 -9.068 6.088 -9.359 6.659 -7.635 c +5.92 -10.116 3.622 -11.92 0.905 -11.92 c +-2.407 -11.92 -5.098 -9.238 -5.098 -5.917 c +-5.098 -2.856 -2.799 -0.333 0.165 0.031 c +0.115 0.022 0.049 0.013 0 0 c +f +Q +0.118 0.192 0.369 scn +q 1 0 0 1 187.6411 500.5234 cm +0 0 m +-1.064 -0.939 -0.813 -4.868 -0.54 -5.601 c +0.43 -8.206 2.406 -8.584 3.21 -8.625 c +4.273 -8.681 5.3 -9.068 6.38 -8.967 c +6.693 -8.938 7.267 -8.802 7.587 -8.217 c +6.594 -10.165 4.569 -11.497 2.235 -11.497 c +-1.077 -11.497 -3.768 -8.815 -3.768 -5.494 c +-3.768 -2.81 -2 -0.54 0.432 0.225 c +0.372 0.201 0.292 0.168 0.231 0.144 c +0.162 0.102 0.062 0.054 0 0 c +f +Q +0.204 0.333 0.639 scn +q 1 0 0 1 191.4565 495.208 cm +0 0 m +-0.097 0.069 -0.097 0.069 -0.519 0.587 c +-0.662 0.762 -0.835 0.91 -0.974 1.089 c +-1.125 1.285 -1.232 1.593 y +-1.227 1.612 -0.03 2.438 0.591 1.363 c +1.026 0.61 0.244 -0.13 0.233 -0.131 c +0.153 -0.143 0.065 -0.046 0 0 c +f +Q +0.141 0.227 0.439 scn +q 1 0 0 1 192.4463 500.4146 cm +0 0 m +-1.295 0.463 -2.255 -0.325 -2.57 -0.583 c +-2.57 0.609 l +-1.402 0.609 -0.312 0.275 0.611 -0.302 c +0.521 -0.251 0.401 -0.185 0.312 -0.135 c +0.218 -0.094 0.096 -0.034 0 0 c +f +Q +0.208 0.337 0.655 scn +q 1 0 0 1 191.4961 495.46 cm +0 0 m +-0.335 0.354 l +-0.472 0.524 -0.626 0.679 -0.757 0.854 c +-0.976 1.148 -1.021 1.268 -1.02 1.273 c +-1.015 1.287 -0.029 1.7 0.33 0.953 c +0.59 0.409 0.174 -0.12 0.167 -0.121 c +0.106 -0.131 0.048 -0.04 0 0 c +f +Q +0.137 0.22 0.427 scn +q 1 0 0 1 191.6431 500.7461 cm +0 0 m +-0.651 0.121 -1.163 -0.01 -1.767 -0.45 c +-1.767 0.277 l +-1.038 0.277 -0.339 0.147 0.307 -0.09 c +0.224 -0.065 0.112 -0.032 0.029 -0.006 c +0.02 -0.004 0.009 -0.001 0 0 c +f +Q +0.216 0.345 0.667 scn +q 1 0 0 1 191.5 495.7261 cm +0 0 m +-0.004 0.004 -0.533 0.573 -0.71 0.862 c +-0.568 0.875 -0.482 0.883 -0.264 0.809 c +-0.18 0.781 -0.083 0.699 -0.025 0.631 c +0.033 0.563 0.091 0.45 0.104 0.362 c +0.135 0.141 0.099 0.019 0.074 -0.062 c +0.052 -0.043 0.021 -0.021 0 0 c +f +Q +0.133 0.216 0.412 scn +q 1 0 0 1 190.7813 500.9458 cm +0 0 m +-0.314 -0.005 -0.487 -0.009 -0.905 -0.207 c +-0.905 0.078 l +-0.519 0.078 -0.142 0.041 0.225 -0.028 c +0.157 -0.02 0.067 -0.003 0 0 c +f +Q +0.125 0.208 0.396 scn +q 1 0 0 1 189.876 501.0112 cm +0 0 m +0 0.012 l +0.072 0.012 0.144 0.011 0.215 0.008 c +0.15 0.006 0.046 -0.044 0 0 c +f +Q + endstream endobj 1348 0 obj <> endobj 1318 0 obj <> endobj 1317 0 obj [/ICCBased 1349 0 R] endobj 1349 0 obj <>stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  + 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 1342 0 obj <> endobj 1343 0 obj <>/XObject<>>>/Subtype/Form>>stream +q +184.836 446.278 m +184.836 462.278 l +200.298 462.278 212.835 449.741 212.835 434.279 c +212.835 418.809 200.298 406.271 184.836 406.271 c +169.374 406.271 156.837 418.809 156.837 434.279 c +156.837 449.741 169.374 462.278 184.836 462.278 c +184.836 446.278 l +178.229 446.289 172.826 440.887 172.837 434.279 c +172.828 427.661 178.229 422.261 184.836 422.271 c +191.442 422.261 196.844 427.661 196.835 434.279 c +196.846 440.887 191.443 446.289 184.836 446.278 c +W n +q +/GS0 gs +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q +Q + endstream endobj 1350 0 obj <> endobj 1351 0 obj <>/ExtGState<>>>/Subtype/Form>>stream +/CS0 cs 0.208 0.337 0.655 scn +/GS0 gs +q 1 0 0 1 184.8359 446.2783 cm +0 0 m +0 16 l +15.462 16 27.999 3.463 27.999 -11.999 c +27.999 -27.47 15.462 -40.007 0 -40.007 c +-15.462 -40.007 -27.999 -27.47 -27.999 -11.999 c +-27.999 3.463 -15.462 16 0 16 c +0 0 l +-6.607 0.011 -12.01 -5.392 -11.999 -11.999 c +-12.008 -18.617 -6.606 -24.018 0 -24.007 c +6.606 -24.018 12.008 -18.617 11.999 -11.999 c +12.01 -5.392 6.607 0.011 0 0 c +f +Q +q 1 0 0 1 184.8359 451.4419 cm +0 0 m +0 -0.468 l +0 -5.164 l +-6.607 -5.153 -12.01 -10.555 -11.999 -17.163 c +-12.008 -23.781 -6.606 -29.181 0 -29.17 c +6.606 -29.181 12.008 -23.781 11.999 -17.163 c +12.01 -10.555 6.607 -5.153 0 -5.164 c +0 -0.468 l +0.316 -0.694 0.738 -0.997 1.055 -1.223 c +3.817 -3.661 7.459 -4.869 10 -7.617 c +12.018 -9.8 13.458 -12.461 14.279 -15.528 c +15.076 -18.507 16.901 -19.346 16.917 -19.348 c +18.874 -19.542 24.735 -10.485 17.857 -2.241 c +10.879 6.124 0.769 1.958 0 0 c +0 10.836 l +15.462 10.836 27.999 -1.701 27.999 -17.163 c +27.999 -32.633 15.462 -45.17 0 -45.17 c +-15.462 -45.17 -27.999 -32.633 -27.999 -17.163 c +-27.999 -1.701 -15.462 10.836 0 10.836 c +0 0 l +f +Q +0.204 0.333 0.639 scn +q 1 0 0 1 184.8359 453.2891 cm +0 0 m +-0.296 -0.712 -1.487 -1.168 -1.735 -1.898 c +-1.987 -2.638 -2.003 -3.873 -1.53 -4.494 c +-1.227 -4.893 -0.45 -4.945 0 -5.167 c +0 -7.011 l +-6.607 -7 -12.01 -12.402 -11.999 -19.01 c +-12.008 -25.628 -6.606 -31.028 0 -31.018 c +6.606 -31.028 12.008 -25.628 11.999 -19.01 c +12.01 -12.402 6.607 -7 0 -7.011 c +0 -5.167 l +0.338 -5.201 0.788 -5.245 1.126 -5.278 c +2.249 -5.476 12.144 -7.557 13.761 -19.538 c +13.765 -19.565 14.171 -22.516 14.171 -22.516 c +14.636 -23.09 15.724 -23.507 16.459 -23.43 c +20.584 -22.993 26.416 -9.568 15.896 -1.312 c +7.943 4.929 0.035 0.084 0 0 c +0 8.989 l +15.462 8.989 27.999 -3.548 27.999 -19.01 c +27.999 -34.48 15.462 -47.018 0 -47.018 c +-15.462 -47.018 -27.999 -34.48 -27.999 -19.01 c +-27.999 -3.548 -15.462 8.989 0 8.989 c +0 0 l +f +Q +0.2 0.325 0.624 scn +q 1 0 0 1 184.8359 454.4082 cm +0 0 m +-0.627 -1.109 -1.866 -1.525 -2.708 -2.391 c +-4.764 -4.503 -4.447 -6.209 -4.44 -6.223 c +-4.355 -6.386 -4.355 -6.386 0 -7.408 c +0 -8.13 l +-6.607 -8.119 -12.01 -13.521 -11.999 -20.129 c +-12.008 -26.747 -6.606 -32.147 0 -32.137 c +6.606 -32.147 12.008 -26.747 11.999 -20.129 c +12.01 -13.521 6.607 -8.119 0 -8.13 c +0 -7.408 l +0.312 -7.428 0.727 -7.455 1.039 -7.475 c +5.587 -8.118 13.156 -12.018 12.674 -22.551 c +12.559 -25.065 12.662 -26.483 12.98 -26.764 c +14.309 -27.938 23.357 -23.699 22.629 -14.042 c +21.269 4.004 1.142 2.019 0 0 c +0 7.87 l +15.462 7.87 27.999 -4.667 27.999 -20.129 c +27.999 -35.6 15.462 -48.137 0 -48.137 c +-15.462 -48.137 -27.999 -35.6 -27.999 -20.129 c +-27.999 -4.667 -15.462 7.87 0 7.87 c +0 0 l +f +Q +0.196 0.318 0.612 scn +q 1 0 0 1 184.8359 455.3335 cm +0 0 m +-0.223 -0.377 -0.896 -0.494 -1.279 -0.706 c +-3.984 -2.198 -4.352 -2.882 -7.218 -8.204 c +-10.977 -15.407 l +-12.034 -17.649 -12.409 -19.973 -12.123 -22.512 c +-11.368 -29.209 -4.441 -35.048 3.701 -32.84 c +16.505 -28.457 l +19.639 -26.39 21.523 -23.894 22.614 -20.364 c +24.61 -13.907 21.812 -4.74 13.674 -0.575 c +6.26 3.219 0.029 0.049 0 0 c +0 6.945 l +15.462 6.945 27.999 -5.592 27.999 -21.054 c +27.999 -36.525 15.462 -49.062 0 -49.062 c +-15.462 -49.062 -27.999 -36.525 -27.999 -21.054 c +-27.999 -5.592 -15.462 6.945 0 6.945 c +0 0 l +f +Q +0.192 0.31 0.596 scn +q 1 0 0 1 184.8359 456.1333 cm +0 0 m +-0.174 -0.267 -0.682 -0.3 -0.974 -0.428 c +-3.27 -1.438 -6.363 -4.313 -7.593 -6.58 c +-13.39 -17.263 -12.999 -20.654 -12.686 -23.38 c +-12.044 -28.948 -6.307 -36.34 3.975 -34.525 c +32.478 -29.493 24.483 -7.887 15.417 -1.844 c +7.621 3.352 0.038 0.059 0 0 c +0 6.145 l +15.462 6.145 27.999 -6.392 27.999 -21.854 c +27.999 -37.325 15.462 -49.862 0 -49.862 c +-15.462 -49.862 -27.999 -37.325 -27.999 -21.854 c +-27.999 -6.392 -15.462 6.145 0 6.145 c +0 0 l +f +Q +0.188 0.302 0.58 scn +q 1 0 0 1 184.8359 456.834 cm +0 0 m +-0.26 -0.393 -1.01 -0.429 -1.443 -0.612 c +-4.281 -1.817 -7.531 -4.969 -9.346 -8.278 c +-13.498 -15.848 -13.757 -21.086 -13.243 -24.147 c +-12.335 -29.562 -7.257 -38.122 6.017 -35.862 c +29.657 -31.837 27.572 -10.232 15.691 -2.188 c +7.725 3.206 0.039 0.058 0 0 c +0 5.444 l +15.462 5.444 27.999 -7.093 27.999 -22.555 c +27.999 -38.025 15.462 -50.563 0 -50.563 c +-15.462 -50.563 -27.999 -38.025 -27.999 -22.555 c +-27.999 -7.093 -15.462 5.444 0 5.444 c +0 0 l +f +Q +0.18 0.294 0.569 scn +q 1 0 0 1 184.8359 457.5 cm +0 0 m +-0.27 -0.397 -1.042 -0.411 -1.488 -0.586 c +-3.111 -1.225 -7.25 -3.37 -10.633 -9.471 c +-11.685 -11.368 -15.021 -18.085 -13.796 -24.879 c +-12.453 -32.328 -5.461 -39.37 6.714 -37.227 c +28.951 -33.313 28.976 -11.259 15.609 -2.301 c +7.856 2.895 0.038 0.056 0 0 c +0 4.778 l +15.462 4.778 27.999 -7.759 27.999 -23.221 c +27.999 -38.691 15.462 -51.229 0 -51.229 c +-15.462 -51.229 -27.999 -38.691 -27.999 -23.221 c +-27.999 -7.759 -15.462 4.778 0 4.778 c +0 0 l +f +Q +0.176 0.286 0.553 scn +q 1 0 0 1 184.8359 458.1108 cm +0 0 m +-0.285 -0.403 -1.085 -0.384 -1.55 -0.549 c +-2.14 -0.758 -7.426 -2.783 -11.14 -9.4 c +-12.536 -11.888 -15.643 -18.441 -14.343 -25.555 c +-13.275 -31.4 -7.567 -40.72 7.05 -38.576 c +28.069 -35.492 30.907 -13.131 16.17 -2.838 c +7.979 2.883 0.04 0.057 0 0 c +0 4.167 l +15.462 4.167 27.999 -8.37 27.999 -23.832 c +27.999 -39.302 15.462 -51.839 0 -51.839 c +-15.462 -51.839 -27.999 -39.302 -27.999 -23.832 c +-27.999 -8.37 -15.462 4.167 0 4.167 c +0 0 l +f +Q +0.173 0.278 0.541 scn +q 1 0 0 1 184.8359 458.6836 cm +0 0 m +-0.294 -0.407 -1.113 -0.365 -1.59 -0.521 c +-3.037 -0.996 -8.057 -3.068 -11.887 -9.807 c +-12.95 -11.676 -16.305 -18.381 -14.886 -26.192 c +-13.691 -32.767 -6.813 -41.832 7.241 -39.858 c +28.692 -36.845 31.476 -13.851 16.374 -3.144 c +8.08 2.736 0.041 0.056 0 0 c +0 3.595 l +15.462 3.595 27.999 -8.942 27.999 -24.404 c +27.999 -39.875 15.462 -52.412 0 -52.412 c +-15.462 -52.412 -27.999 -39.875 -27.999 -24.404 c +-27.999 -8.942 -15.462 3.595 0 3.595 c +0 0 l +f +Q +0.169 0.275 0.525 scn +q 1 0 0 1 184.8359 459.2207 cm +0 0 m +-0.327 -0.44 -1.224 -0.37 -1.749 -0.528 c +-5.52 -1.667 -9.766 -5.26 -12.073 -9.267 c +-15.394 -15.036 -16.522 -20.933 -15.426 -26.792 c +-13.856 -35.181 -5.227 -43.019 7.675 -41.021 c +29.387 -37.659 31.678 -13.959 16.092 -3.122 c +8.188 2.374 0.041 0.052 0 0 c +0 3.058 l +15.462 3.058 27.999 -9.479 27.999 -24.941 c +27.999 -40.412 15.462 -52.949 0 -52.949 c +-15.462 -52.949 -27.999 -40.412 -27.999 -24.941 c +-27.999 -9.479 -15.462 3.058 0 3.058 c +0 0 l +f +Q +0.165 0.267 0.51 scn +q 1 0 0 1 184.8359 459.7354 cm +0 0 m +-0.315 -0.413 -1.169 -0.321 -1.671 -0.458 c +-5.628 -1.543 -10.186 -5.222 -12.509 -9.206 c +-13.794 -11.411 -17.706 -18.119 -15.958 -27.37 c +-14.312 -36.089 -5.369 -44.235 7.962 -42.157 c +29.829 -38.748 32.261 -15.07 16.713 -3.752 c +8.241 2.415 0.041 0.054 0 0 c +0 2.543 l +15.462 2.543 27.999 -9.994 27.999 -25.456 c +27.999 -40.927 15.462 -53.464 0 -53.464 c +-15.462 -53.464 -27.999 -40.927 -27.999 -25.456 c +-27.999 -9.994 -15.462 2.543 0 2.543 c +0 0 l +f +Q +0.161 0.259 0.498 scn +q 1 0 0 1 184.8359 460.208 cm +0 0 m +-0.326 -0.417 -1.197 -0.297 -1.71 -0.424 c +-5.005 -1.241 -10.022 -4.174 -13.317 -9.752 c +-16.642 -15.38 -17.707 -21.488 -16.484 -27.905 c +-14.771 -36.893 -5.522 -45.319 8.241 -43.229 c +29.819 -39.954 32.248 -15.425 16.845 -4.05 c +8.507 2.107 0.042 0.053 0 0 c +0 2.07 l +15.462 2.07 27.999 -10.467 27.999 -25.929 c +27.999 -41.399 15.462 -53.937 0 -53.937 c +-15.462 -53.937 -27.999 -41.399 -27.999 -25.929 c +-27.999 -10.467 -15.462 2.07 0 2.07 c +0 0 l +f +Q +0.153 0.251 0.482 scn +q 1 0 0 1 184.8359 460.6479 cm +0 0 m +-0.165 -0.201 -0.596 -0.119 -0.852 -0.169 c +-6.63 -1.321 -11.086 -5.48 -13.33 -8.99 c +-17.823 -16.018 -17.959 -22.68 -17.283 -27.032 c +-15.528 -38.313 -5.353 -45.642 6.913 -44.456 c +29.058 -42.316 33.217 -18.568 18.588 -5.674 c +9.722 2.142 0.051 0.062 0 0 c +0 1.63 l +15.462 1.63 27.999 -10.907 27.999 -26.369 c +27.999 -41.839 15.462 -54.376 0 -54.376 c +-15.462 -54.376 -27.999 -41.839 -27.999 -26.369 c +-27.999 -10.907 -15.462 1.63 0 1.63 c +0 0 l +f +Q +0.149 0.243 0.467 scn +q 1 0 0 1 184.8359 461.0591 cm +0 0 m +-0.345 -0.419 -1.243 -0.245 -1.775 -0.35 c +-5.333 -1.052 -10.598 -4.013 -13.752 -8.857 c +-18.474 -16.108 -18.606 -22.979 -17.885 -27.466 c +-16.272 -37.507 -7.1 -46.929 7.31 -45.507 c +29.58 -43.31 33.524 -19.12 18.666 -5.999 c +9.679 1.938 0.05 0.061 0 0 c +0 1.219 l +15.462 1.219 27.999 -11.318 27.999 -26.78 c +27.999 -42.25 15.462 -54.788 0 -54.788 c +-15.462 -54.788 -27.999 -42.25 -27.999 -26.78 c +-27.999 -11.318 -15.462 1.219 0 1.219 c +0 0 l +f +Q +0.145 0.235 0.455 scn +q 1 0 0 1 184.8359 461.4141 cm +0 0 m +-0.359 -0.424 -1.279 -0.213 -1.827 -0.305 c +-2.571 -0.429 -9.239 -1.713 -14.035 -8.521 c +-19.337 -16.049 -19.04 -23.602 -18.666 -26.5 c +-16.79 -41.041 -4.557 -47.127 6.015 -46.629 c +29.242 -45.535 34.043 -19.97 18.705 -6.311 c +9.693 1.714 0.05 0.059 0 0 c +0 0.864 l +15.462 0.864 27.999 -11.673 27.999 -27.135 c +27.999 -42.605 15.462 -55.143 0 -55.143 c +-15.462 -55.143 -27.999 -42.605 -27.999 -27.135 c +-27.999 -11.673 -15.462 0.864 0 0.864 c +0 0 l +f +Q +0.141 0.227 0.439 scn +q 1 0 0 1 184.8359 461.7397 cm +0 0 m +-0.366 -0.422 -1.29 -0.183 -1.842 -0.262 c +-5.616 -0.798 -11.203 -3.577 -14.553 -8.414 c +-20.526 -17.037 -19.484 -25.015 -19.142 -27.636 c +-17.325 -41.551 -4.721 -48.305 6.215 -47.597 c +22.827 -46.52 31.839 -32.415 25.896 -16.796 c +27.251 -20.083 27.999 -23.685 27.999 -27.46 c +27.999 -42.931 15.462 -55.468 0 -55.468 c +-15.462 -55.468 -27.999 -42.931 -27.999 -27.46 c +-27.999 -11.999 -15.462 0.539 0 0.539 c +0 0 l +f +Q +0.137 0.22 0.427 scn +q 1 0 0 1 184.8359 461.9951 cm +0 0 m +-0.38 -0.425 -1.322 -0.147 -1.889 -0.211 c +-3.74 -0.417 -10.183 -1.633 -15.334 -8.604 c +-20.12 -15.08 -20.496 -23.225 -19.964 -27.016 c +-18.071 -40.504 -7.311 -49.146 6.811 -48.521 c +13.567 -48.222 30.459 -42.962 27.513 -22.495 c +27.832 -24.187 27.999 -25.932 27.999 -27.716 c +27.999 -43.187 15.462 -55.724 0 -55.724 c +-15.462 -55.724 -27.999 -43.187 -27.999 -27.716 c +-27.999 -12.254 -15.462 0.283 0 0.283 c +0 0 l +f +Q +0.133 0.216 0.412 scn +q 1 0 0 1 184.8359 462.186 cm +0 0 m +-0.389 -0.421 -1.333 -0.109 -1.905 -0.156 c +-5.862 -0.48 -11.762 -2.986 -15.367 -7.721 c +-21.456 -15.72 -21.121 -23.999 -20.694 -27.186 c +-18.877 -40.772 -7.134 -50.361 6.621 -49.493 c +16.365 -48.877 27.809 -42.692 27.992 -27.284 c +27.997 -27.491 27.999 -27.699 27.999 -27.907 c +27.999 -43.377 15.462 -55.915 0 -55.915 c +-15.462 -55.915 -27.999 -43.377 -27.999 -27.907 c +-27.999 -12.445 -15.462 0.092 0 0.092 c +0 0 l +f +Q +0.125 0.208 0.396 scn +q 1 0 0 1 184.8359 462.2749 cm +0 0 m +-0.403 -0.423 -1.362 -0.067 -1.945 -0.096 c +-5.653 -0.278 -11.171 -1.795 -16.407 -7.987 c +-19.42 -11.549 -22.258 -18.906 -21.583 -25.522 c +-19.025 -50.599 4.157 -50.427 5.143 -50.408 c +17.394 -50.165 25.848 -43.174 27.755 -31.708 c +25.94 -45.423 14.204 -56.003 0 -56.003 c +-15.462 -56.003 -27.999 -43.466 -27.999 -27.996 c +-27.999 -12.534 -15.462 0.003 0 0.003 c +0 0 l +f +Q +0.122 0.2 0.384 scn +q 1 0 0 1 180.605 461.958 cm +0 0 m +-22.531 -4.551 -23.529 -35.032 -6.329 -46.266 c +6.848 -54.872 25.64 -52.177 31.068 -35.689 c +27.624 -47.255 16.911 -55.687 4.231 -55.687 c +-11.231 -55.687 -23.768 -43.149 -23.768 -27.679 c +-23.768 -13.386 -13.055 -1.592 0.778 0.109 c +0.544 0.077 0.232 0.04 0 0 c +f +Q +0.118 0.192 0.369 scn +q 1 0 0 1 172.812 459.498 cm +0 0 m +-16.566 -9.064 -17.348 -40.201 9.316 -48.722 c +16.64 -51.062 30.628 -50.199 36.986 -37.919 c +32.357 -47.005 22.916 -53.227 12.024 -53.227 c +-3.438 -53.227 -15.975 -40.689 -15.975 -25.219 c +-15.975 -12.683 -7.734 -2.069 3.625 1.499 c +3.1 1.309 2.399 1.057 1.873 0.867 c +1.31 0.61 0.543 0.297 0 0 c +f +Q +0.216 0.345 0.667 scn +q 1 0 0 1 200.7622 436.103 cm +0 0 m +-1.706 2.422 -2.871 5.192 -4.806 7.466 c +-5.581 8.375 -6.334 9.141 -7.046 9.74 c +-7.103 9.788 -12.699 14.577 -12.706 14.929 c +-12.708 15.035 -10.925 16.753 -10.74 16.825 c +-10.058 17.086 -7.544 17.231 -6.875 17.166 c +-5.111 16.992 -2.438 16.241 0.275 13.649 c +3.79 10.293 4.269 6.382 4.332 5.263 c +4.608 0.362 1.816 -1.552 1.125 -1.426 c +0.589 -1.328 0.314 -0.445 0 0 c +f +Q +0.22 0.353 0.682 scn +q 1 0 0 1 200.8965 438.5967 cm +0 0 m +-1.97 2.883 -3.056 4.472 -4.87 6.595 c +-5.072 6.832 -5.375 7.116 -5.591 7.34 c +-5.844 7.601 -6.16 7.969 -6.419 8.224 c +-6.913 8.711 -7.551 9.382 -8.074 9.839 c +-9.724 11.281 -9.908 11.547 -9.911 11.595 c +-9.914 11.655 -8.389 13.369 -8.295 13.411 c +-7.711 13.674 -6.801 13.346 -6.164 13.276 c +-2.962 12.927 -1.156 11.212 -0.476 10.566 c +2.531 7.709 2.783 5.143 2.904 3.909 c +2.938 3.565 2.929 0.875 2.709 0.41 c +2.675 0.337 0.707 -0.875 0.645 -0.861 c +0.33 -0.793 0.182 -0.267 0 0 c +f +Q +0.224 0.361 0.694 scn +q 1 0 0 1 199.9814 442.126 cm +0 0 m +-0.737 0.235 -1.076 1.45 -1.576 2.04 c +-3.148 3.895 -3.148 3.895 -3.897 4.678 c +-4.212 5.008 -4.84 5.354 -4.922 5.803 c +-4.014 7.981 l +-3.953 8.007 -1.427 7.15 0.33 5.083 c +1.631 3.552 2.397 0.755 2.281 0.574 c +1.906 -0.01 0.699 -0.197 0.037 0.011 c +0.026 0.014 0.011 -0.003 0 0 c +f +Q +0.141 0.227 0.439 scn +q 1 0 0 1 196.8853 459.5508 cm +0 0 m +-5.275 2.417 -9.403 2.407 -12.049 2.189 c +-12.049 2.728 l +-6.604 2.728 -1.522 1.173 2.777 -1.517 c +2.232 -1.205 1.506 -0.789 0.961 -0.477 c +0.673 -0.334 0.292 -0.134 0 0 c +f +Q +0.137 0.22 0.427 scn +q 1 0 0 1 193.0991 461.0352 cm +0 0 m +-3.078 0.794 -4.478 1.111 -8.263 0.96 c +-8.263 1.243 l +-4.866 1.243 -1.61 0.638 1.402 -0.47 c +0.981 -0.329 0.425 -0.126 0 0 c +f +Q +0.133 0.216 0.412 scn +q 1 0 0 1 189.0669 461.958 cm +0 0 m +-2.557 0.263 -2.657 0.273 -4.231 0.228 c +-4.231 0.32 l +-2.431 0.32 -0.671 0.15 1.035 -0.174 c +0.724 -0.122 0.312 -0.042 0 0 c +f +Q +0.125 0.208 0.396 scn +q 1 0 0 1 184.8359 462.2749 cm +0 0 m +0.335 0.003 0.669 -0.002 1.001 -0.014 c +0.701 -0.01 0.211 -0.214 0 0 c +f +Q + endstream endobj 1352 0 obj <> endobj 1340 0 obj <> endobj 1341 0 obj <>/XObject<>>>/Subtype/Form>>stream +q +315.165 487.275 m +315.165 492.275 l +318.477 492.275 321.168 489.593 321.168 486.272 c +321.168 482.96 318.477 480.278 315.165 480.278 c +311.853 480.278 309.171 482.96 309.171 486.272 c +309.171 489.593 311.853 492.275 315.165 492.275 c +315.165 487.275 l +314.621 487.278 314.17 486.83 314.171 486.272 c +314.168 485.727 314.619 485.276 315.165 485.278 c +315.715 485.275 316.172 485.733 316.168 486.272 c +316.17 486.824 315.713 487.279 315.165 487.275 c +W n +q +1 w 4 M 0 j 0 J []0 d +/GS0 gs +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q +Q + endstream endobj 1353 0 obj <> endobj 1354 0 obj <>/ExtGState<>>>/Subtype/Form>>stream +/CS0 cs 0.2 0.325 0.624 scn +/GS0 gs +q 1 0 0 1 315.165 487.2754 cm +0 0 m +0 5 l +3.312 5 6.003 2.318 6.003 -1.003 c +6.003 -4.315 3.312 -6.997 0 -6.997 c +-3.312 -6.997 -5.994 -4.315 -5.994 -1.003 c +-5.994 2.318 -3.312 5 0 5 c +0 0 l +-0.544 0.003 -0.995 -0.445 -0.994 -1.003 c +-0.997 -1.549 -0.546 -2 0 -1.997 c +0.55 -2 1.007 -1.542 1.003 -1.003 c +1.005 -0.451 0.548 0.003 0 0 c +f +Q +q 1 0 0 1 315.165 488.1997 cm +0 0 m +-0.013 -0.041 -0.073 -0.074 -0.082 -0.115 c +-0.11 -0.248 -0.02 -0.425 0 -0.559 c +0 -0.924 l +-0.544 -0.921 -0.995 -1.37 -0.994 -1.927 c +-0.997 -2.473 -0.546 -2.924 0 -2.921 c +0.55 -2.924 1.007 -2.467 1.003 -1.927 c +1.005 -1.375 0.548 -0.921 0 -0.924 c +0 -0.559 l +0.034 -0.556 0.079 -0.552 0.113 -0.549 c +0.142 -0.549 0.183 -0.536 0.209 -0.548 c +1.045 -1.475 l +1.44 -2.16 1.79 -2.114 1.805 -2.112 c +2.058 -2.072 3.187 -0.623 1.901 0.191 c +1.597 0.384 1.274 0.411 1.13 0.396 c +0 0 l +0 4.076 l +3.312 4.076 6.003 1.394 6.003 -1.927 c +6.003 -5.239 3.312 -7.921 0 -7.921 c +-3.312 -7.921 -5.994 -5.239 -5.994 -1.927 c +-5.994 1.394 -3.312 4.076 0 4.076 c +0 0 l +f +Q +0.196 0.318 0.612 scn +q 1 0 0 1 315.165 488.3418 cm +0 0 m +-0.03 -0.092 -0.163 -0.17 -0.184 -0.265 c +-0.221 -0.432 -0.125 -0.677 -0.186 -0.837 c +-0.186 -0.838 -0.235 -0.941 -0.399 -1.048 c +-1.15 -1.539 -1.036 -2.16 -0.983 -2.339 c +-0.8 -2.96 -0.143 -3.262 0.452 -2.998 c +0.652 -2.908 0.791 -2.771 0.873 -2.69 c +1.144 -2.423 1.548 -2.625 1.836 -2.417 c +2.431 -1.985 2.564 -1.604 2.628 -1.42 c +2.85 -0.787 2.46 0.134 1.627 0.371 c +0.853 0.592 0.002 0.008 0 0 c +0 3.934 l +3.312 3.934 6.003 1.251 6.003 -2.069 c +6.003 -5.381 3.312 -8.063 0 -8.063 c +-3.312 -8.063 -5.994 -5.381 -5.994 -2.069 c +-5.994 1.251 -3.312 3.934 0 3.934 c +0 0 l +f +Q +0.192 0.31 0.596 scn +q 1 0 0 1 315.165 488.4824 cm +0 0 m +-0.294 -0.832 -1.287 -1.354 -1.07 -2.414 c +-0.931 -3.09 -0.167 -3.555 0.649 -3.164 c +1.049 -2.972 1.516 -2.957 1.889 -2.695 c +2.243 -2.445 2.625 -2.13 2.762 -1.679 c +3.159 -0.375 2.125 0.264 1.73 0.385 c +0.831 0.662 0.003 0.008 0 0 c +0 3.793 l +3.312 3.793 6.003 1.111 6.003 -2.21 c +6.003 -5.522 3.312 -8.204 0 -8.204 c +-3.312 -8.204 -5.994 -5.522 -5.994 -2.21 c +-5.994 1.111 -3.312 3.793 0 3.793 c +0 0 l +f +Q +0.188 0.302 0.58 scn +q 1 0 0 1 315.165 488.6216 cm +0 0 m +-0.352 -0.867 -1.375 -1.438 -1.138 -2.566 c +-1.017 -3.142 -0.345 -3.804 0.713 -3.398 c +2.483 -2.719 2.628 -2.663 2.945 -1.783 c +2.951 -1.768 3.406 -0.235 2.053 0.317 c +0.863 0.802 0.004 0.01 0 0 c +0 3.654 l +3.312 3.654 6.003 0.972 6.003 -2.349 c +6.003 -5.661 3.312 -8.343 0 -8.343 c +-3.312 -8.343 -5.994 -5.661 -5.994 -2.349 c +-5.994 0.972 -3.312 3.654 0 3.654 c +0 0 l +f +Q +0.18 0.294 0.569 scn +q 1 0 0 1 315.165 488.7588 cm +0 0 m +-0.192 -0.416 -0.582 -0.691 -0.789 -1.097 c +-0.793 -1.105 -1.082 -1.703 -1.083 -1.706 c +-1.253 -2.111 -1.282 -2.441 -1.181 -2.81 c +-1.118 -3.036 -0.72 -4.135 0.985 -3.564 c +5.022 -2.213 2.486 0.225 2.452 0.247 c +1.442 0.897 0.101 0.219 0 0 c +0 3.517 l +3.312 3.517 6.003 0.834 6.003 -2.486 c +6.003 -5.798 3.312 -8.48 0 -8.48 c +-3.312 -8.48 -5.994 -5.798 -5.994 -2.486 c +-5.994 0.834 -3.312 3.517 0 3.517 c +0 0 l +f +Q +0.176 0.286 0.553 scn +q 1 0 0 1 315.165 488.9116 cm +0 0 m +-0.013 -0.025 -0.053 -0.04 -0.076 -0.057 c +-0.432 -0.327 -0.719 -0.611 -1.164 -1.801 c +-1.234 -1.99 -1.448 -2.564 -1.178 -3.156 c +-0.778 -4.031 0.18 -4.2 1.671 -3.658 c +3.876 -2.856 3.991 -0.38 2.341 0.402 c +1.366 0.864 0.123 0.248 0 0 c +0 3.364 l +3.312 3.364 6.003 0.682 6.003 -2.639 c +6.003 -5.951 3.312 -8.633 0 -8.633 c +-3.312 -8.633 -5.994 -5.951 -5.994 -2.639 c +-5.994 0.682 -3.312 3.364 0 3.364 c +0 0 l +f +Q +0.173 0.278 0.541 scn +q 1 0 0 1 315.165 489.1035 cm +0 0 m +-0.034 -0.068 -0.142 -0.105 -0.202 -0.15 c +-0.734 -0.546 -0.993 -1.253 -1.244 -1.936 c +-1.353 -2.232 -1.496 -2.812 -1.238 -3.374 c +-0.612 -4.739 1.248 -4.146 1.803 -3.932 c +4.138 -3.031 4.265 -0.308 2.51 0.419 c +1.108 1 0.006 0.012 0 0 c +0 3.172 l +3.312 3.172 6.003 0.49 6.003 -2.831 c +6.003 -6.143 3.312 -8.825 0 -8.825 c +-3.312 -8.825 -5.994 -6.143 -5.994 -2.831 c +-5.994 0.49 -3.312 3.172 0 3.172 c +0 0 l +f +Q +0.169 0.275 0.525 scn +q 1 0 0 1 315.165 489.291 cm +0 0 m +-0.037 -0.069 -0.152 -0.103 -0.217 -0.147 c +-0.48 -0.327 -0.918 -0.951 -1.084 -1.383 c +-1.402 -2.209 -1.592 -2.802 -1.342 -3.486 c +-1.138 -4.046 -0.487 -4.899 1.578 -4.322 c +4.081 -3.623 4.628 -0.763 2.992 0.316 c +1.701 1.167 0.079 0.149 0 0 c +0 2.984 l +3.312 2.984 6.003 0.302 6.003 -3.019 c +6.003 -6.331 3.312 -9.013 0 -9.013 c +-3.312 -9.013 -5.994 -6.331 -5.994 -3.019 c +-5.994 0.302 -3.312 2.984 0 2.984 c +0 0 l +f +Q +0.165 0.267 0.51 scn +q 1 0 0 1 315.165 489.4751 cm +0 0 m +-0.175 -0.316 -0.541 -0.436 -0.745 -0.721 c +-1.04 -1.133 -1.134 -1.367 -1.233 -1.614 c +-1.283 -1.739 -1.712 -2.854 -1.439 -3.598 c +-0.844 -5.219 1.105 -4.774 1.689 -4.6 c +4.424 -3.78 5.002 -0.76 3.22 0.385 c +1.946 1.202 0.234 0.424 0 0 c +0 2.8 l +3.312 2.8 6.003 0.118 6.003 -3.203 c +6.003 -6.515 3.312 -9.197 0 -9.197 c +-3.312 -9.197 -5.994 -6.515 -5.994 -3.203 c +-5.994 0.118 -3.312 2.8 0 2.8 c +0 0 l +f +Q +0.161 0.259 0.498 scn +q 1 0 0 1 315.165 489.7065 cm +0 0 m +-0.06 -0.132 -0.265 -0.21 -0.385 -0.291 c +-0.751 -0.537 -1.207 -1.436 -1.319 -1.735 c +-1.402 -1.96 -1.802 -3.124 -1.467 -3.945 c +-0.712 -5.795 1.956 -4.866 1.982 -4.855 c +5.299 -3.58 5.174 -0.371 3.116 0.573 c +1.411 1.355 0.007 0.017 0 0 c +0 2.569 l +3.312 2.569 6.003 -0.113 6.003 -3.434 c +6.003 -6.746 3.312 -9.428 0 -9.428 c +-3.312 -9.428 -5.994 -6.746 -5.994 -3.434 c +-5.994 -0.113 -3.312 2.569 0 2.569 c +0 0 l +f +Q +0.153 0.251 0.482 scn +q 1 0 0 1 315.165 489.9888 cm +0 0 m +-0.04 -0.083 -0.167 -0.135 -0.239 -0.193 c +-0.739 -0.597 -1.12 -1.159 -1.404 -1.909 c +-1.678 -2.633 -1.751 -3.637 -1.568 -4.146 c +-0.856 -6.124 1.88 -5.306 1.908 -5.297 c +5.872 -3.969 5.347 -0.495 3.422 0.519 c +1.628 1.464 0.058 0.122 0 0 c +0 2.287 l +3.312 2.287 6.003 -0.396 6.003 -3.716 c +6.003 -7.028 3.312 -9.71 0 -9.71 c +-3.312 -9.71 -5.994 -7.028 -5.994 -3.716 c +-5.994 -0.396 -3.312 2.287 0 2.287 c +0 0 l +f +Q +0.149 0.243 0.467 scn +q 1 0 0 1 315.165 490.2749 cm +0 0 m +-0.045 -0.106 -0.209 -0.167 -0.302 -0.235 c +-0.485 -0.372 -1.122 -0.935 -1.618 -2.443 c +-1.723 -2.761 -1.897 -3.881 -1.538 -4.677 c +-1.024 -5.812 0.792 -6.206 2.512 -5.554 c +6.336 -4.105 5.75 -0.288 3.153 0.723 c +1.353 1.423 0.007 0.017 0 0 c +0 2 l +3.312 2 6.003 -0.682 6.003 -4.002 c +6.003 -7.314 3.312 -9.997 0 -9.997 c +-3.312 -9.997 -5.994 -7.314 -5.994 -4.002 c +-5.994 -0.682 -3.312 2 0 2 c +0 0 l +f +Q +0.145 0.235 0.455 scn +q 1 0 0 1 315.165 490.6582 cm +0 0 m +-0.163 -0.361 -0.541 -0.515 -0.777 -0.805 c +-0.945 -1.011 -1.046 -1.259 -1.201 -1.474 c +-1.269 -1.568 -1.409 -1.763 -1.714 -2.734 c +-2.048 -3.798 -1.784 -4.665 -1.597 -5.087 c +-1.005 -6.421 1.188 -6.695 2.68 -6.041 c +8.251 -3.594 4.333 0.165 2.965 0.677 c +1.252 1.319 0.007 0.016 0 0 c +0 1.617 l +3.312 1.617 6.003 -1.065 6.003 -4.386 c +6.003 -7.698 3.312 -10.38 0 -10.38 c +-3.312 -10.38 -5.994 -7.698 -5.994 -4.386 c +-5.994 -1.065 -3.312 1.617 0 1.617 c +0 0 l +f +Q +0.141 0.227 0.439 scn +q 1 0 0 1 315.165 491.083 cm +0 0 m +-0.128 -0.296 -0.441 -0.404 -0.637 -0.631 c +-0.787 -0.804 -0.891 -1.009 -1.028 -1.191 c +-1.149 -1.351 -1.614 -2.354 -1.616 -2.362 c +-2.165 -3.906 -2.034 -4.643 -1.834 -5.161 c +-0.959 -7.42 1.653 -7.023 2.585 -6.679 c +3.892 -6.198 6.61 -5.196 5.552 -2.522 c +5.843 -3.227 6.003 -4 6.003 -4.811 c +6.003 -8.123 3.312 -10.805 0 -10.805 c +-3.312 -10.805 -5.994 -8.123 -5.994 -4.811 c +-5.994 -1.49 -3.312 1.192 0 1.192 c +0 0 l +f +Q +0.137 0.22 0.427 scn +q 1 0 0 1 315.165 491.5479 cm +0 0 m +-0.037 -0.078 -0.154 -0.129 -0.22 -0.185 c +-1.232 -1.033 -1.806 -2.828 -1.83 -2.904 c +-2.22 -4.142 -2.232 -5.159 -1.867 -5.927 c +-0.58 -8.633 3.354 -7.149 3.394 -7.134 c +4.44 -6.729 6.193 -6.052 5.898 -4.154 c +5.967 -4.518 6.003 -4.892 6.003 -5.275 c +6.003 -8.587 3.312 -11.27 0 -11.27 c +-3.312 -11.27 -5.994 -8.587 -5.994 -5.275 c +-5.994 -1.955 -3.312 0.728 0 0.728 c +0 0 l +f +Q +0.133 0.216 0.412 scn +q 1 0 0 1 315.165 491.9907 cm +0 0 m +-0.038 -0.067 -0.155 -0.091 -0.221 -0.13 c +-1.146 -0.672 -1.618 -2.109 -1.997 -3.263 c +-2.003 -3.281 -2.538 -5.073 -2.065 -6.285 c +-1.01 -8.991 2.93 -7.989 3.097 -7.945 c +4.317 -7.624 5.989 -7.184 6.001 -5.584 c +6.002 -5.628 6.003 -5.673 6.003 -5.718 c +6.003 -9.03 3.312 -11.712 0 -11.712 c +-3.312 -11.712 -5.994 -9.03 -5.994 -5.718 c +-5.994 -2.397 -3.312 0.285 0 0.285 c +0 0 l +f +Q +0.125 0.208 0.396 scn +q 1 0 0 1 315.165 492.2632 cm +0 0 m +-0.043 -0.052 -0.154 -0.029 -0.221 -0.042 c +-0.695 -0.132 -1.346 -0.69 -1.729 -1.732 c +-2.601 -4.102 -2.422 -5.693 -2.305 -6.268 c +-1.773 -8.88 1.72 -8.614 1.755 -8.61 c +4.215 -8.37 5.7 -8.226 5.951 -6.783 c +5.562 -9.72 3.043 -11.985 0 -11.985 c +-3.312 -11.985 -5.994 -9.303 -5.994 -5.991 c +-5.994 -2.67 -3.312 0.012 0 0.012 c +0 0 l +f +Q +0.122 0.2 0.384 scn +q 1 0 0 1 314.2603 492.1987 cm +0 0 m +-1.727 -0.587 -1.739 -4.385 -1.738 -4.546 c +-1.734 -6.483 -1.193 -7.61 0.017 -8.2 c +1.798 -9.069 6.085 -9.361 6.66 -7.637 c +5.921 -10.115 3.622 -11.92 0.905 -11.92 c +-2.407 -11.92 -5.089 -9.238 -5.089 -5.926 c +-5.089 -2.857 -2.798 -0.333 0.165 0.032 c +0.115 0.022 0.048 0.013 0 0 c +f +Q +0.118 0.192 0.369 scn +q 1 0 0 1 312.9341 491.7764 cm +0 0 m +-1.086 -0.961 -0.817 -4.853 -0.535 -5.61 c +0.431 -8.208 2.403 -8.585 3.207 -8.626 c +4.27 -8.681 5.298 -9.068 6.378 -8.967 c +6.691 -8.938 7.264 -8.802 7.584 -8.218 c +6.592 -10.165 4.566 -11.498 2.231 -11.498 c +-1.081 -11.498 -3.763 -8.816 -3.763 -5.504 c +-3.763 -2.812 -2 -0.54 0.432 0.225 c +0.372 0.2 0.292 0.168 0.231 0.144 c +0.161 0.102 0.062 0.054 0 0 c +f +Q +0.204 0.333 0.639 scn +q 1 0 0 1 316.7451 486.4531 cm +0 0 m +-0.091 0.065 -0.091 0.065 -0.52 0.593 c +-0.662 0.769 -0.836 0.916 -0.974 1.096 c +-1.233 1.432 -1.232 1.599 -1.232 1.6 c +-1.226 1.62 -0.028 2.446 0.591 1.368 c +1.026 0.611 0.245 -0.132 0.233 -0.134 c +0.153 -0.145 0.065 -0.047 0 0 c +f +Q +0.141 0.227 0.439 scn +q 1 0 0 1 317.7354 491.6665 cm +0 0 m +-1.294 0.462 -2.254 -0.325 -2.57 -0.583 c +-2.57 0.609 l +-1.403 0.609 -0.313 0.276 0.609 -0.301 c +0.52 -0.251 0.4 -0.185 0.31 -0.134 c +0.217 -0.094 0.095 -0.034 0 0 c +f +Q +0.208 0.337 0.655 scn +q 1 0 0 1 316.7852 486.708 cm +0 0 m +-0.336 0.357 l +-0.473 0.528 -0.628 0.683 -0.758 0.858 c +-0.977 1.152 -1.021 1.271 -1.02 1.277 c +-1.015 1.292 -0.028 1.706 0.328 0.955 c +0.588 0.409 0.173 -0.121 0.167 -0.122 c +0.106 -0.133 0.047 -0.04 0 0 c +f +Q +0.137 0.22 0.427 scn +q 1 0 0 1 316.9321 491.998 cm +0 0 m +-0.649 0.12 -1.161 -0.01 -1.767 -0.45 c +-1.767 0.277 l +-1.039 0.277 -0.34 0.147 0.306 -0.09 c +0.223 -0.065 0.111 -0.031 0.028 -0.006 c +0.02 -0.004 0.008 -0.001 0 0 c +f +Q +0.216 0.345 0.667 scn +q 1 0 0 1 316.7891 486.9756 cm +0 0 m +-0.004 0.004 -0.536 0.578 -0.712 0.865 c +-0.569 0.878 -0.483 0.886 -0.265 0.812 c +-0.18 0.784 -0.084 0.701 -0.026 0.633 c +0.032 0.564 0.089 0.451 0.102 0.362 c +0.133 0.142 0.096 0.015 0.073 -0.061 c +0.051 -0.042 0.021 -0.02 0 0 c +f +Q +0.133 0.216 0.412 scn +q 1 0 0 1 316.0703 492.1978 cm +0 0 m +-0.314 -0.005 -0.486 -0.009 -0.905 -0.207 c +-0.905 0.078 l +-0.519 0.078 -0.142 0.041 0.224 -0.028 c +0.157 -0.02 0.067 -0.003 0 0 c +f +Q +0.125 0.208 0.396 scn +q 1 0 0 1 315.165 492.2632 cm +0 0 m +0 0.012 l +0.072 0.012 0.144 0.011 0.215 0.008 c +0.15 0.006 0.046 -0.044 0 0 c +f +Q + endstream endobj 1355 0 obj <> endobj 1338 0 obj <> endobj 1339 0 obj <>/XObject<>>>/Subtype/Form>>stream +q +323.67 445.774 m +323.67 461.774 l +339.132 461.774 351.669 449.237 351.669 433.775 c +351.669 418.313 339.132 405.776 323.67 405.776 c +308.199 405.776 295.671 418.313 295.671 433.775 c +295.671 449.237 308.199 461.774 323.67 461.774 c +323.67 445.774 l +317.055 445.784 311.661 440.386 311.671 433.775 c +311.661 427.165 317.055 421.767 323.67 421.776 c +330.277 421.766 335.68 427.168 335.669 433.775 c +335.68 440.383 330.277 445.785 323.67 445.774 c +W n +q +/GS0 gs +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q +Q + endstream endobj 1356 0 obj <> endobj 1357 0 obj <>/ExtGState<>>>/Subtype/Form>>stream +/CS0 cs 0.208 0.337 0.655 scn +/GS0 gs +q 1 0 0 1 323.6699 445.7744 cm +0 0 m +0 16 l +15.462 16 27.999 3.463 27.999 -11.999 c +27.999 -27.461 15.462 -39.998 0 -39.998 c +-15.471 -39.998 -27.999 -27.461 -27.999 -11.999 c +-27.999 3.463 -15.471 16 0 16 c +0 0 l +-6.615 0.009 -12.009 -5.389 -11.999 -11.999 c +-12.009 -18.609 -6.615 -24.007 0 -23.998 c +6.607 -24.009 12.01 -18.606 11.999 -11.999 c +12.01 -5.392 6.607 0.011 0 0 c +f +Q +q 1 0 0 1 323.6699 450.936 cm +0 0 m +0 -0.46 l +0 -5.162 l +-6.615 -5.152 -12.009 -10.55 -11.999 -17.161 c +-12.009 -23.771 -6.615 -29.169 0 -29.16 c +6.607 -29.17 12.01 -23.768 11.999 -17.161 c +12.01 -10.553 6.607 -5.151 0 -5.162 c +0 -0.46 l +0.316 -0.687 0.738 -0.99 1.054 -1.216 c +3.814 -3.66 7.459 -4.866 10 -7.615 c +12.018 -9.799 13.458 -12.46 14.279 -15.526 c +15.091 -18.561 16.901 -19.341 16.918 -19.343 c +18.873 -19.537 24.733 -10.481 17.857 -2.239 c +10.881 6.124 0.77 1.958 0 0 c +0 10.838 l +15.462 10.838 27.999 -1.699 27.999 -17.161 c +27.999 -32.623 15.462 -45.16 0 -45.16 c +-15.471 -45.16 -27.999 -32.623 -27.999 -17.161 c +-27.999 -1.699 -15.471 10.838 0 10.838 c +0 0 l +f +Q +0.204 0.333 0.639 scn +q 1 0 0 1 323.6699 452.7832 cm +0 0 m +-0.297 -0.712 -1.488 -1.167 -1.738 -1.898 c +-1.989 -2.637 -2.005 -3.871 -1.531 -4.492 c +-1.227 -4.891 -0.45 -4.943 0 -5.165 c +0 -7.009 l +-6.615 -7 -12.009 -12.397 -11.999 -19.008 c +-12.009 -25.618 -6.615 -31.016 0 -31.007 c +6.607 -31.018 12.01 -25.615 11.999 -19.008 c +12.01 -12.4 6.607 -6.998 0 -7.009 c +0 -5.165 l +0.338 -5.198 0.788 -5.242 1.126 -5.275 c +2.249 -5.474 12.142 -7.557 13.761 -19.535 c +14.172 -22.508 l +14.637 -23.083 15.725 -23.499 16.46 -23.421 c +20.584 -22.986 26.414 -9.565 15.896 -1.31 c +7.945 4.929 0.035 0.084 0 0 c +0 8.991 l +15.462 8.991 27.999 -3.546 27.999 -19.008 c +27.999 -34.47 15.462 -47.007 0 -47.007 c +-15.471 -47.007 -27.999 -34.47 -27.999 -19.008 c +-27.999 -3.546 -15.471 8.991 0 8.991 c +0 0 l +f +Q +0.2 0.325 0.624 scn +q 1 0 0 1 323.6699 453.9038 cm +0 0 m +-0.627 -1.11 -1.868 -1.524 -2.71 -2.39 c +-4.768 -4.502 -4.451 -6.209 -4.444 -6.223 c +-4.359 -6.387 -4.359 -6.387 0 -7.407 c +0 -8.129 l +-6.615 -8.12 -12.009 -13.518 -11.999 -20.128 c +-12.009 -26.739 -6.615 -32.137 0 -32.127 c +6.607 -32.138 12.01 -26.736 11.999 -20.128 c +12.01 -13.521 6.607 -8.119 0 -8.129 c +0 -7.407 l +0.312 -7.427 0.727 -7.454 1.039 -7.474 c +5.586 -8.118 13.154 -12.018 12.674 -22.547 c +12.56 -25.06 12.663 -26.477 12.982 -26.758 c +14.311 -27.928 23.356 -23.682 22.629 -14.041 c +21.27 3.998 1.142 2.018 0 0 c +0 7.871 l +15.462 7.871 27.999 -4.667 27.999 -20.128 c +27.999 -35.59 15.462 -48.127 0 -48.127 c +-15.471 -48.127 -27.999 -35.59 -27.999 -20.128 c +-27.999 -4.667 -15.471 7.871 0 7.871 c +0 0 l +f +Q +0.196 0.318 0.612 scn +q 1 0 0 1 323.6699 454.8291 cm +0 0 m +-0.223 -0.378 -0.896 -0.494 -1.28 -0.706 c +-3.988 -2.198 -4.356 -2.882 -7.222 -8.202 c +-10.979 -15.406 l +-12.035 -17.648 -12.409 -19.972 -12.123 -22.51 c +-11.368 -29.204 -4.441 -35.039 3.701 -32.831 c +16.504 -28.45 l +19.64 -26.383 21.524 -23.889 22.614 -20.364 c +24.61 -13.907 21.812 -4.74 13.674 -0.575 c +6.261 3.219 0.029 0.049 0 0 c +0 6.945 l +15.462 6.945 27.999 -5.592 27.999 -21.054 c +27.999 -36.516 15.462 -49.053 0 -49.053 c +-15.471 -49.053 -27.999 -36.516 -27.999 -21.054 c +-27.999 -5.592 -15.471 6.945 0 6.945 c +0 0 l +f +Q +0.192 0.31 0.596 scn +q 1 0 0 1 323.6699 455.6289 cm +0 0 m +-11.795 -5.181 -18.994 -27.783 -4.636 -33.729 c +5.806 -38.053 30.469 -28.935 22.345 -10.09 c +19.107 -2.58 10.176 3.509 0 0 c +0 6.146 l +15.462 6.146 27.999 -6.392 27.999 -21.854 c +27.999 -37.315 15.462 -49.853 0 -49.853 c +-15.471 -49.853 -27.999 -37.315 -27.999 -21.854 c +-27.999 -6.392 -15.471 6.146 0 6.146 c +0 0 l +f +Q +0.188 0.302 0.58 scn +q 1 0 0 1 323.6699 456.3296 cm +0 0 m +-0.26 -0.393 -1.011 -0.429 -1.444 -0.612 c +-4.284 -1.815 -7.534 -4.967 -9.349 -8.277 c +-13.499 -15.843 -13.758 -21.083 -13.244 -24.145 c +-12.335 -29.557 -7.256 -38.113 6.018 -35.852 c +29.65 -31.827 27.567 -10.229 15.691 -2.187 c +7.726 3.206 0.039 0.058 0 0 c +0 5.445 l +15.462 5.445 27.999 -7.092 27.999 -22.554 c +27.999 -38.016 15.462 -50.553 0 -50.553 c +-15.471 -50.553 -27.999 -38.016 -27.999 -22.554 c +-27.999 -7.092 -15.471 5.445 0 5.445 c +0 0 l +f +Q +0.18 0.294 0.569 scn +q 1 0 0 1 323.6699 456.9956 cm +0 0 m +-0.271 -0.397 -1.043 -0.41 -1.49 -0.586 c +-3.112 -1.224 -7.251 -3.368 -10.636 -9.471 c +-11.688 -11.366 -15.022 -18.08 -13.796 -24.877 c +-12.453 -32.323 -5.461 -39.361 6.714 -37.217 c +28.943 -33.303 28.97 -11.254 15.609 -2.3 c +7.857 2.895 0.038 0.056 0 0 c +0 4.779 l +15.462 4.779 27.999 -7.758 27.999 -23.22 c +27.999 -38.682 15.462 -51.219 0 -51.219 c +-15.471 -51.219 -27.999 -38.682 -27.999 -23.22 c +-27.999 -7.758 -15.471 4.779 0 4.779 c +0 0 l +f +Q +0.176 0.286 0.553 scn +q 1 0 0 1 323.6699 457.6064 cm +0 0 m +-0.285 -0.403 -1.086 -0.384 -1.551 -0.549 c +-2.515 -0.89 -7.505 -2.918 -11.143 -9.4 c +-12.539 -11.886 -15.644 -18.437 -14.343 -25.553 c +-13.275 -31.396 -7.567 -40.711 7.05 -38.566 c +28.064 -35.482 30.902 -13.127 16.17 -2.838 c +7.979 2.883 0.04 0.057 0 0 c +0 4.168 l +15.462 4.168 27.999 -8.369 27.999 -23.831 c +27.999 -39.293 15.462 -51.83 0 -51.83 c +-15.471 -51.83 -27.999 -39.293 -27.999 -23.831 c +-27.999 -8.369 -15.471 4.168 0 4.168 c +0 0 l +f +Q +0.173 0.278 0.541 scn +q 1 0 0 1 323.6699 458.1792 cm +0 0 m +-0.295 -0.407 -1.114 -0.365 -1.591 -0.521 c +-3.039 -0.995 -8.059 -3.066 -11.891 -9.807 c +-12.952 -11.675 -16.307 -18.377 -14.887 -26.189 c +-13.692 -32.762 -6.813 -41.823 7.243 -39.848 c +28.687 -36.834 31.471 -13.847 16.374 -3.144 c +8.08 2.737 0.041 0.056 0 0 c +0 3.595 l +15.462 3.595 27.999 -8.942 27.999 -24.404 c +27.999 -39.866 15.462 -52.403 0 -52.403 c +-15.471 -52.403 -27.999 -39.866 -27.999 -24.404 c +-27.999 -8.942 -15.471 3.595 0 3.595 c +0 0 l +f +Q +0.169 0.275 0.525 scn +q 1 0 0 1 323.6699 458.7163 cm +0 0 m +-0.327 -0.44 -1.225 -0.369 -1.749 -0.527 c +-5.521 -1.665 -9.768 -5.259 -12.076 -9.267 c +-15.396 -15.033 -16.523 -20.929 -15.426 -26.791 c +-13.856 -35.175 -5.227 -43.009 7.675 -41.011 c +29.382 -37.65 31.673 -13.956 16.092 -3.122 c +8.188 2.374 0.041 0.052 0 0 c +0 3.058 l +15.462 3.058 27.999 -9.479 27.999 -24.941 c +27.999 -40.403 15.462 -52.94 0 -52.94 c +-15.471 -52.94 -27.999 -40.403 -27.999 -24.941 c +-27.999 -9.479 -15.471 3.058 0 3.058 c +0 0 l +f +Q +0.165 0.267 0.51 scn +q 1 0 0 1 323.6699 459.2314 cm +0 0 m +-0.315 -0.414 -1.17 -0.321 -1.672 -0.458 c +-5.63 -1.542 -10.189 -5.222 -12.512 -9.206 c +-13.797 -11.409 -17.707 -18.115 -15.958 -27.369 c +-14.312 -36.085 -5.369 -44.227 7.962 -42.147 c +29.823 -38.738 32.256 -15.066 16.713 -3.752 c +8.241 2.415 0.041 0.054 0 0 c +0 2.543 l +15.462 2.543 27.999 -9.994 27.999 -25.456 c +27.999 -40.918 15.462 -53.455 0 -53.455 c +-15.471 -53.455 -27.999 -40.918 -27.999 -25.456 c +-27.999 -9.994 -15.471 2.543 0 2.543 c +0 0 l +f +Q +0.161 0.259 0.498 scn +q 1 0 0 1 323.6699 459.7041 cm +0 0 m +-0.326 -0.417 -1.198 -0.297 -1.711 -0.424 c +-5.006 -1.24 -10.024 -4.173 -13.32 -9.752 c +-16.644 -15.378 -17.708 -21.484 -16.484 -27.903 c +-14.771 -36.889 -5.522 -45.311 8.242 -43.22 c +29.813 -39.944 32.242 -15.421 16.845 -4.05 c +8.507 2.107 0.042 0.053 0 0 c +0 2.07 l +15.462 2.07 27.999 -10.467 27.999 -25.929 c +27.999 -41.391 15.462 -53.928 0 -53.928 c +-15.471 -53.928 -27.999 -41.391 -27.999 -25.929 c +-27.999 -10.467 -15.471 2.07 0 2.07 c +0 0 l +f +Q +0.153 0.251 0.482 scn +q 1 0 0 1 323.6699 460.144 cm +0 0 m +-0.165 -0.201 -0.596 -0.119 -0.852 -0.169 c +-6.632 -1.32 -11.089 -5.48 -13.333 -8.99 c +-17.824 -16.015 -17.96 -22.678 -17.283 -27.031 c +-15.529 -38.309 -5.353 -45.633 6.914 -44.447 c +29.053 -42.307 33.213 -18.564 18.588 -5.674 c +9.722 2.142 0.051 0.062 0 0 c +0 1.63 l +15.462 1.63 27.999 -10.907 27.999 -26.369 c +27.999 -41.831 15.462 -54.368 0 -54.368 c +-15.471 -54.368 -27.999 -41.831 -27.999 -26.369 c +-27.999 -10.907 -15.471 1.63 0 1.63 c +0 0 l +f +Q +0.149 0.243 0.467 scn +q 1 0 0 1 323.6699 460.5547 cm +0 0 m +-0.345 -0.419 -1.243 -0.245 -1.776 -0.35 c +-5.454 -1.074 -10.584 -3.985 -13.756 -8.856 c +-18.476 -16.104 -18.606 -22.976 -17.885 -27.465 c +-16.272 -37.503 -7.101 -46.92 7.31 -45.498 c +29.575 -43.3 33.52 -19.115 18.666 -5.998 c +9.679 1.938 0.05 0.061 0 0 c +0 1.22 l +15.462 1.22 27.999 -11.317 27.999 -26.779 c +27.999 -42.241 15.462 -54.778 0 -54.778 c +-15.471 -54.778 -27.999 -42.241 -27.999 -26.779 c +-27.999 -11.317 -15.471 1.22 0 1.22 c +0 0 l +f +Q +0.145 0.235 0.455 scn +q 1 0 0 1 323.6699 460.9102 cm +0 0 m +-0.359 -0.424 -1.28 -0.213 -1.828 -0.305 c +-2.573 -0.429 -9.242 -1.712 -14.038 -8.521 c +-19.338 -16.045 -19.04 -23.601 -18.666 -26.5 c +-16.79 -41.035 -4.557 -47.119 6.015 -46.621 c +29.237 -45.525 34.039 -19.966 18.705 -6.311 c +9.693 1.714 0.05 0.059 0 0 c +0 0.864 l +15.462 0.864 27.999 -11.673 27.999 -27.135 c +27.999 -42.597 15.462 -55.134 0 -55.134 c +-15.471 -55.134 -27.999 -42.597 -27.999 -27.135 c +-27.999 -11.673 -15.471 0.864 0 0.864 c +0 0 l +f +Q +0.141 0.227 0.439 scn +q 1 0 0 1 323.6699 461.2358 cm +0 0 m +-0.366 -0.422 -1.291 -0.183 -1.844 -0.262 c +-5.618 -0.797 -11.206 -3.577 -14.557 -8.414 c +-20.527 -17.033 -19.484 -25.013 -19.142 -27.635 c +-17.325 -41.544 -4.721 -48.297 6.215 -47.587 c +22.825 -46.511 31.838 -32.41 25.896 -16.796 c +27.251 -20.083 27.999 -23.685 27.999 -27.46 c +27.999 -42.922 15.462 -55.459 0 -55.459 c +-15.471 -55.459 -27.999 -42.922 -27.999 -27.46 c +-27.999 -11.999 -15.471 0.539 0 0.539 c +0 0 l +f +Q +0.137 0.22 0.427 scn +q 1 0 0 1 323.6699 461.4912 cm +0 0 m +-0.38 -0.425 -1.323 -0.147 -1.89 -0.211 c +-3.742 -0.417 -10.186 -1.632 -15.337 -8.604 c +-20.121 -15.077 -20.496 -23.224 -19.964 -27.016 c +-18.071 -40.5 -7.311 -49.138 6.811 -48.512 c +13.567 -48.212 30.458 -42.954 27.513 -22.495 c +27.832 -24.187 27.999 -25.932 27.999 -27.716 c +27.999 -43.178 15.462 -55.715 0 -55.715 c +-15.471 -55.715 -27.999 -43.178 -27.999 -27.716 c +-27.999 -12.254 -15.471 0.283 0 0.283 c +0 0 l +f +Q +0.133 0.216 0.412 scn +q 1 0 0 1 323.6699 461.6821 cm +0 0 m +-0.389 -0.422 -1.334 -0.109 -1.906 -0.156 c +-5.864 -0.48 -11.765 -2.986 -15.37 -7.721 c +-21.457 -15.717 -21.121 -23.997 -20.694 -27.186 c +-18.848 -40.99 -7.359 -50.367 6.621 -49.484 c +16.365 -48.868 27.809 -42.685 27.992 -27.284 c +27.997 -27.491 27.999 -27.699 27.999 -27.907 c +27.999 -43.369 15.462 -55.906 0 -55.906 c +-15.471 -55.906 -27.999 -43.369 -27.999 -27.907 c +-27.999 -12.445 -15.471 0.092 0 0.092 c +0 0 l +f +Q +0.125 0.208 0.396 scn +q 1 0 0 1 323.6699 461.771 cm +0 0 m +-0.403 -0.423 -1.362 -0.067 -1.946 -0.096 c +-5.655 -0.278 -11.174 -1.795 -16.41 -7.986 c +-19.422 -11.547 -22.258 -18.903 -21.583 -25.522 c +-19.025 -50.59 4.157 -50.418 5.143 -50.399 c +17.394 -50.156 25.847 -43.167 27.756 -31.704 c +25.941 -45.413 14.205 -55.995 0 -55.995 c +-15.471 -55.995 -27.999 -43.458 -27.999 -27.996 c +-27.999 -12.534 -15.471 0.003 0 0.003 c +0 0 l +f +Q +0.122 0.2 0.384 scn +q 1 0 0 1 319.437 461.4541 cm +0 0 m +-22.531 -4.549 -23.531 -35.025 -6.331 -46.258 c +6.847 -54.864 25.642 -52.17 31.071 -35.682 c +27.627 -47.245 16.914 -55.678 4.233 -55.678 c +-11.238 -55.678 -23.766 -43.141 -23.766 -27.679 c +-23.766 -13.386 -13.062 -1.593 0.777 0.109 c +0.544 0.077 0.232 0.04 0 0 c +f +Q +0.118 0.192 0.369 scn +q 1 0 0 1 311.6421 458.9941 cm +0 0 m +-16.565 -9.064 -17.346 -40.196 9.317 -48.713 c +16.643 -51.053 30.634 -50.189 36.991 -37.91 c +32.363 -46.995 22.921 -53.218 12.028 -53.218 c +-3.443 -53.218 -15.971 -40.681 -15.971 -25.219 c +-15.971 -12.684 -7.737 -2.07 3.624 1.498 c +3.099 1.309 2.397 1.056 1.872 0.866 c +1.309 0.609 0.542 0.297 0 0 c +f +Q +0.216 0.345 0.667 scn +q 1 0 0 1 339.5962 435.5991 cm +0 0 m +-1.706 2.422 -2.871 5.192 -4.806 7.466 c +-5.581 8.375 -6.334 9.141 -7.046 9.74 c +-7.103 9.788 -12.699 14.577 -12.705 14.929 c +-12.707 15.035 -10.925 16.753 -10.74 16.825 c +-10.058 17.086 -7.544 17.231 -6.875 17.166 c +-5.111 16.992 -2.438 16.241 0.275 13.649 c +3.79 10.293 4.269 6.382 4.332 5.263 c +4.608 0.362 1.816 -1.553 1.125 -1.426 c +0.589 -1.328 0.314 -0.445 0 0 c +f +Q +0.22 0.353 0.682 scn +q 1 0 0 1 339.7305 438.0928 cm +0 0 m +-1.97 2.883 -3.055 4.471 -4.87 6.595 c +-5.072 6.832 -5.375 7.116 -5.591 7.34 c +-5.844 7.601 -6.16 7.969 -6.419 8.224 c +-6.913 8.711 -7.551 9.382 -8.074 9.839 c +-9.724 11.281 -9.908 11.547 -9.911 11.595 c +-9.914 11.657 -8.495 13.252 -8.295 13.411 c +-8.132 13.541 -7.808 13.456 -7.601 13.433 c +-5.32 13.184 -2.962 12.927 -0.476 10.566 c +2.531 7.709 2.783 5.143 2.904 3.909 c +2.938 3.565 2.929 0.875 2.709 0.41 c +2.675 0.337 0.707 -0.875 0.645 -0.861 c +0.33 -0.793 0.182 -0.267 0 0 c +f +Q +0.224 0.361 0.694 scn +q 1 0 0 1 338.8154 441.6221 cm +0 0 m +-0.737 0.235 -1.076 1.45 -1.576 2.04 c +-3.148 3.894 -3.148 3.894 -3.897 4.678 c +-4.212 5.008 -4.84 5.354 -4.922 5.803 c +-4.014 7.981 l +-3.953 8.007 -1.427 7.15 0.33 5.083 c +1.631 3.552 2.397 0.755 2.281 0.574 c +1.906 -0.01 0.699 -0.197 0.037 0.011 c +0.026 0.014 0.011 -0.003 0 0 c +f +Q +0.141 0.227 0.439 scn +q 1 0 0 1 335.7192 459.0469 cm +0 0 m +-5.275 2.417 -9.403 2.407 -12.049 2.189 c +-12.049 2.728 l +-6.604 2.728 -1.522 1.173 2.777 -1.517 c +2.232 -1.205 1.506 -0.789 0.961 -0.477 c +0.673 -0.334 0.292 -0.134 0 0 c +f +Q +0.137 0.22 0.427 scn +q 1 0 0 1 331.9331 460.5313 cm +0 0 m +-3.078 0.794 -4.478 1.111 -8.263 0.96 c +-8.263 1.243 l +-4.866 1.243 -1.61 0.638 1.402 -0.47 c +0.981 -0.329 0.425 -0.126 0 0 c +f +Q +0.133 0.216 0.412 scn +q 1 0 0 1 327.9009 461.4541 cm +0 0 m +-1.314 0.178 -2.48 0.278 -4.231 0.228 c +-4.231 0.32 l +-2.431 0.32 -0.671 0.15 1.035 -0.174 c +0.724 -0.122 0.312 -0.042 0 0 c +f +Q +0.125 0.208 0.396 scn +q 1 0 0 1 323.6699 461.771 cm +0 0 m +0.335 0.003 0.669 -0.002 1.001 -0.014 c +0.701 -0.01 0.211 -0.214 0 0 c +f +Q + endstream endobj 1358 0 obj <> endobj 1336 0 obj <> endobj 1337 0 obj <>/XObject<>>>/Subtype/Form>>stream +q +327.999 212.271 m +327.999 217.271 l +331.311 217.271 334.002 214.59 334.002 211.277 c +334.002 207.966 331.311 205.274 327.999 205.274 c +324.687 205.274 321.996 207.966 321.996 211.277 c +321.996 214.59 324.687 217.271 327.999 217.271 c +327.999 212.271 l +327.449 212.274 326.992 211.817 326.996 211.277 c +326.991 210.734 327.456 210.27 327.999 210.274 c +328.542 210.27 329.007 210.734 329.002 211.277 c +329.006 211.817 328.549 212.274 327.999 212.271 c +W n +q +1 w 4 M 0 j 0 J []0 d +/GS0 gs +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q +Q + endstream endobj 1359 0 obj <> endobj 1360 0 obj <>/ExtGState<>>>/Subtype/Form>>stream +/CS0 cs 0.216 0.631 0.792 scn +/GS0 gs +q 1 0 0 1 327.999 212.2715 cm +0 0 m +0 5 l +3.312 5 6.003 2.318 6.003 -0.994 c +6.003 -4.306 3.312 -6.997 0 -6.997 c +-3.312 -6.997 -6.003 -4.306 -6.003 -0.994 c +-6.003 2.318 -3.312 5 0 5 c +0 0 l +-0.55 0.003 -1.007 -0.454 -1.003 -0.994 c +-1.008 -1.537 -0.543 -2.002 0 -1.997 c +0.543 -2.002 1.008 -1.537 1.003 -0.994 c +1.007 -0.454 0.55 0.003 0 0 c +f +Q +q 1 0 0 1 327.999 213.1963 cm +0 0 m +-0.013 -0.041 -0.073 -0.074 -0.083 -0.115 c +-0.111 -0.248 -0.02 -0.426 0 -0.56 c +0 -0.925 l +-0.55 -0.922 -1.007 -1.379 -1.003 -1.919 c +-1.008 -2.462 -0.543 -2.927 0 -2.922 c +0.543 -2.927 1.008 -2.462 1.003 -1.919 c +1.007 -1.379 0.55 -0.922 0 -0.925 c +0 -0.56 l +0.034 -0.557 0.079 -0.553 0.113 -0.55 c +0.142 -0.55 0.184 -0.536 0.21 -0.549 c +1.046 -1.473 l +1.441 -2.153 1.79 -2.106 1.805 -2.104 c +2.057 -2.064 3.185 -0.619 1.901 0.191 c +1.598 0.383 1.275 0.409 1.132 0.396 c +0 0 l +0 4.075 l +3.312 4.075 6.003 1.394 6.003 -1.919 c +6.003 -5.23 3.312 -7.922 0 -7.922 c +-3.312 -7.922 -6.003 -5.23 -6.003 -1.919 c +-6.003 1.394 -3.312 4.075 0 4.075 c +0 0 l +f +Q +0.208 0.616 0.776 scn +q 1 0 0 1 327.999 213.3379 cm +0 0 m +-0.03 -0.092 -0.164 -0.17 -0.185 -0.265 c +-0.222 -0.433 -0.125 -0.678 -0.188 -0.838 c +-0.188 -0.839 -0.237 -0.941 -0.404 -1.049 c +-1.156 -1.538 -1.044 -2.153 -0.992 -2.33 c +-0.81 -2.948 -0.137 -3.26 0.449 -2.997 c +0.649 -2.907 0.789 -2.769 0.872 -2.687 c +1.143 -2.418 1.548 -2.618 1.836 -2.409 c +2.434 -1.976 2.571 -1.584 2.629 -1.416 c +2.851 -0.784 2.461 0.135 1.628 0.371 c +0.853 0.591 0.002 0.008 0 0 c +0 3.934 l +3.312 3.934 6.003 1.252 6.003 -2.061 c +6.003 -5.372 3.312 -8.063 0 -8.063 c +-3.312 -8.063 -6.003 -5.372 -6.003 -2.061 c +-6.003 1.252 -3.312 3.934 0 3.934 c +0 0 l +f +Q +0.204 0.604 0.757 scn +q 1 0 0 1 327.999 213.4785 cm +0 0 m +-0.294 -0.83 -1.296 -1.345 -1.079 -2.404 c +-0.955 -3.01 -0.239 -3.591 0.647 -3.163 c +1.047 -2.97 1.515 -2.951 1.888 -2.688 c +2.104 -2.536 2.607 -2.182 2.763 -1.673 c +3.16 -0.374 2.125 0.264 1.731 0.385 c +0.831 0.661 0.003 0.009 0 0 c +0 3.793 l +3.312 3.793 6.003 1.111 6.003 -2.201 c +6.003 -5.513 3.312 -8.204 0 -8.204 c +-3.312 -8.204 -6.003 -5.513 -6.003 -2.201 c +-6.003 1.111 -3.312 3.793 0 3.793 c +0 0 l +f +Q +0.2 0.588 0.741 scn +q 1 0 0 1 327.999 213.6182 cm +0 0 m +-0.352 -0.866 -1.383 -1.428 -1.146 -2.558 c +-1.025 -3.14 -0.35 -3.809 0.711 -3.398 c +2.484 -2.712 2.629 -2.655 2.946 -1.777 c +2.952 -1.763 3.406 -0.234 2.053 0.316 c +0.838 0.812 0.004 0.01 0 0 c +0 3.653 l +3.312 3.653 6.003 0.972 6.003 -2.341 c +6.003 -5.652 3.312 -8.344 0 -8.344 c +-3.312 -8.344 -6.003 -5.652 -6.003 -2.341 c +-6.003 0.972 -3.312 3.653 0 3.653 c +0 0 l +f +Q +0.196 0.573 0.722 scn +q 1 0 0 1 327.999 213.7549 cm +0 0 m +-0.193 -0.417 -0.585 -0.691 -0.795 -1.098 c +-1.093 -1.707 l +-1.262 -2.105 -1.291 -2.433 -1.189 -2.801 c +-1.126 -3.029 -0.725 -4.141 0.983 -3.563 c +5.011 -2.2 2.486 0.226 2.453 0.247 c +1.442 0.896 0.101 0.219 0 0 c +0 3.517 l +3.312 3.517 6.003 0.835 6.003 -2.478 c +6.003 -5.789 3.312 -8.48 0 -8.48 c +-3.312 -8.48 -6.003 -5.789 -6.003 -2.478 c +-6.003 0.835 -3.312 3.517 0 3.517 c +0 0 l +f +Q +0.188 0.561 0.702 scn +q 1 0 0 1 327.999 213.9082 cm +0 0 m +-0.013 -0.025 -0.053 -0.04 -0.076 -0.058 c +-0.364 -0.275 -0.691 -0.521 -1.173 -1.803 c +-1.243 -1.988 -1.457 -2.555 -1.186 -3.148 c +-0.781 -4.033 0.18 -4.204 1.671 -3.654 c +3.863 -2.846 3.98 -0.373 2.341 0.401 c +1.366 0.862 0.123 0.247 0 0 c +0 3.363 l +3.312 3.363 6.003 0.682 6.003 -2.631 c +6.003 -5.942 3.312 -8.634 0 -8.634 c +-3.312 -8.634 -6.003 -5.942 -6.003 -2.631 c +-6.003 0.682 -3.312 3.363 0 3.363 c +0 0 l +f +Q +0.184 0.545 0.686 scn +q 1 0 0 1 327.999 214.0996 cm +0 0 m +-0.034 -0.067 -0.142 -0.105 -0.203 -0.15 c +-0.702 -0.521 -0.962 -1.182 -1.171 -1.711 c +-1.281 -1.991 -1.54 -2.648 -1.288 -3.269 c +-0.891 -4.246 0.088 -4.488 1.621 -3.988 c +4.051 -3.195 4.189 -0.578 2.798 0.287 c +1.588 1.039 0.134 0.266 0 0 c +0 3.172 l +3.312 3.172 6.003 0.49 6.003 -2.822 c +6.003 -6.134 3.312 -8.825 0 -8.825 c +-3.312 -8.825 -6.003 -6.134 -6.003 -2.822 c +-6.003 0.49 -3.312 3.172 0 3.172 c +0 0 l +f +Q +0.18 0.529 0.667 scn +q 1 0 0 1 327.999 214.2871 cm +0 0 m +-0.037 -0.069 -0.152 -0.104 -0.217 -0.147 c +-0.454 -0.309 -0.887 -0.883 -1.091 -1.383 c +-1.28 -1.846 -1.632 -2.707 -1.384 -3.387 c +-0.994 -4.454 0.002 -4.769 1.578 -4.319 c +4.069 -3.61 4.619 -0.754 2.993 0.316 c +1.701 1.166 0.079 0.148 0 0 c +0 2.984 l +3.312 2.984 6.003 0.303 6.003 -3.01 c +6.003 -6.321 3.312 -9.013 0 -9.013 c +-3.312 -9.013 -6.003 -6.321 -6.003 -3.01 c +-6.003 0.303 -3.312 2.984 0 2.984 c +0 0 l +f +Q +0.176 0.518 0.651 scn +q 1 0 0 1 327.999 214.4717 cm +0 0 m +-0.176 -0.317 -0.542 -0.437 -0.748 -0.722 c +-1.049 -1.139 -1.146 -1.381 -1.241 -1.614 c +-1.291 -1.738 -1.721 -2.847 -1.448 -3.589 c +-0.846 -5.228 1.105 -4.775 1.689 -4.598 c +4.413 -3.769 4.993 -0.751 3.22 0.385 c +1.946 1.2 0.234 0.423 0 0 c +0 2.8 l +3.312 2.8 6.003 0.118 6.003 -3.194 c +6.003 -6.506 3.312 -9.197 0 -9.197 c +-3.312 -9.197 -6.003 -6.506 -6.003 -3.194 c +-6.003 0.118 -3.312 2.8 0 2.8 c +0 0 l +f +Q +0.169 0.502 0.631 scn +q 1 0 0 1 327.999 214.7031 cm +0 0 m +-0.06 -0.133 -0.265 -0.211 -0.386 -0.291 c +-0.759 -0.541 -1.229 -1.474 -1.327 -1.735 c +-1.444 -2.049 -1.803 -3.136 -1.475 -3.938 c +-0.713 -5.804 1.956 -4.863 1.982 -4.853 c +5.283 -3.568 5.162 -0.364 3.116 0.573 c +1.411 1.354 0.007 0.017 0 0 c +0 2.568 l +3.312 2.568 6.003 -0.113 6.003 -3.426 c +6.003 -6.737 3.312 -9.429 0 -9.429 c +-3.312 -9.429 -6.003 -6.737 -6.003 -3.426 c +-6.003 -0.113 -3.312 2.568 0 2.568 c +0 0 l +f +Q +0.165 0.486 0.612 scn +q 1 0 0 1 327.999 214.9854 cm +0 0 m +-0.04 -0.083 -0.167 -0.135 -0.239 -0.193 c +-0.736 -0.594 -1.131 -1.171 -1.412 -1.908 c +-1.719 -2.715 -1.736 -3.694 -1.577 -4.139 c +-0.858 -6.132 1.881 -5.304 1.908 -5.295 c +5.598 -4.044 5.76 -0.555 3.075 0.691 c +1.838 1.266 0.163 0.34 0 0 c +0 2.286 l +3.312 2.286 6.003 -0.396 6.003 -3.708 c +6.003 -7.02 3.312 -9.711 0 -9.711 c +-3.312 -9.711 -6.003 -7.02 -6.003 -3.708 c +-6.003 -0.396 -3.312 2.286 0 2.286 c +0 0 l +f +Q +0.161 0.475 0.596 scn +q 1 0 0 1 327.999 215.2715 cm +0 0 m +-0.045 -0.106 -0.21 -0.167 -0.302 -0.236 c +-0.487 -0.373 -1.13 -0.938 -1.627 -2.442 c +-1.764 -2.854 -1.88 -3.932 -1.545 -4.67 c +-1.027 -5.814 0.793 -6.21 2.513 -5.55 c +6.314 -4.092 5.733 -0.28 3.153 0.723 c +1.353 1.422 0.007 0.017 0 0 c +0 2 l +3.312 2 6.003 -0.682 6.003 -3.994 c +6.003 -7.306 3.312 -9.997 0 -9.997 c +-3.312 -9.997 -6.003 -7.306 -6.003 -3.994 c +-6.003 -0.682 -3.312 2 0 2 c +0 0 l +f +Q +0.157 0.459 0.576 scn +q 1 0 0 1 327.999 215.6543 cm +0 0 m +-0.163 -0.361 -0.542 -0.515 -0.779 -0.805 c +-0.948 -1.011 -1.05 -1.26 -1.205 -1.475 c +-1.369 -1.701 -1.472 -1.983 -1.723 -2.733 c +-2.048 -3.703 -1.823 -4.541 -1.66 -4.953 c +-1.229 -6.046 0.416 -6.786 2.422 -6.135 c +7.014 -4.645 5.816 -0.744 3.286 0.54 c +1.422 1.485 0.008 0.019 0 0 c +0 1.617 l +3.312 1.617 6.003 -1.064 6.003 -4.377 c +6.003 -7.688 3.312 -10.38 0 -10.38 c +-3.312 -10.38 -6.003 -7.688 -6.003 -4.377 c +-6.003 -1.064 -3.312 1.617 0 1.617 c +0 0 l +f +Q +0.149 0.443 0.561 scn +q 1 0 0 1 327.999 216.0791 cm +0 0 m +-0.128 -0.296 -0.442 -0.404 -0.638 -0.631 c +-0.788 -0.804 -0.893 -1.01 -1.031 -1.191 c +-1.148 -1.346 -1.62 -2.353 -1.623 -2.36 c +-2.172 -3.895 -2.053 -4.608 -1.843 -5.151 c +-0.961 -7.428 1.653 -7.023 2.586 -6.676 c +3.891 -6.189 6.606 -5.178 5.553 -2.521 c +5.843 -3.224 6.003 -3.994 6.003 -4.802 c +6.003 -8.113 3.312 -10.805 0 -10.805 c +-3.312 -10.805 -6.003 -8.113 -6.003 -4.802 c +-6.003 -1.489 -3.312 1.192 0 1.192 c +0 0 l +f +Q +0.145 0.431 0.541 scn +q 1 0 0 1 327.999 216.5439 cm +0 0 m +-0.037 -0.078 -0.154 -0.129 -0.22 -0.185 c +-1.238 -1.037 -1.832 -2.884 -1.837 -2.902 c +-2.426 -4.76 -2.011 -5.632 -1.875 -5.918 c +-0.597 -8.6 3.355 -7.144 3.396 -7.129 c +4.441 -6.72 6.192 -6.035 5.899 -4.15 c +5.967 -4.512 6.003 -4.885 6.003 -5.267 c +6.003 -8.578 3.312 -11.27 0 -11.27 c +-3.312 -11.27 -6.003 -8.578 -6.003 -5.267 c +-6.003 -1.954 -3.312 0.728 0 0.728 c +0 0 l +f +Q +0.141 0.416 0.522 scn +q 1 0 0 1 327.999 216.9863 cm +0 0 m +-0.038 -0.066 -0.155 -0.09 -0.221 -0.129 c +-1.15 -0.674 -1.646 -2.172 -2.007 -3.267 c +-2.013 -3.283 -2.546 -5.064 -2.073 -6.276 c +-1.009 -9.004 3.058 -7.952 3.099 -7.941 c +4.318 -7.615 5.989 -7.169 6.001 -5.576 c +6.002 -5.62 6.003 -5.664 6.003 -5.709 c +6.003 -9.021 3.312 -11.712 0 -11.712 c +-3.312 -11.712 -6.003 -9.021 -6.003 -5.709 c +-6.003 -2.396 -3.312 0.285 0 0.285 c +0 0 l +f +Q +0.137 0.4 0.506 scn +q 1 0 0 1 327.999 217.2598 cm +0 0 m +-0.043 -0.053 -0.154 -0.029 -0.221 -0.042 c +-0.696 -0.133 -1.348 -0.689 -1.732 -1.73 c +-2.577 -4.014 -2.459 -5.548 -2.314 -6.259 c +-1.864 -8.468 0.843 -8.703 1.755 -8.611 c +4.299 -8.355 5.7 -8.214 5.951 -6.775 c +5.562 -9.713 3.043 -11.985 0 -11.985 c +-3.312 -11.985 -6.003 -9.294 -6.003 -5.982 c +-6.003 -2.67 -3.312 0.012 0 0.012 c +0 0 l +f +Q +0.129 0.388 0.486 scn +q 1 0 0 1 327.0938 217.1953 cm +0 0 m +-1.738 -0.59 -1.75 -4.505 -1.75 -4.545 c +-1.745 -7.049 -0.739 -7.83 0.017 -8.199 c +1.798 -9.07 6.085 -9.361 6.66 -7.631 c +5.921 -10.109 3.622 -11.921 0.905 -11.921 c +-2.407 -11.921 -5.098 -9.229 -5.098 -5.918 c +-5.098 -2.856 -2.799 -0.334 0.165 0.031 c +0.115 0.021 0.049 0.013 0 0 c +f +Q +0.125 0.373 0.471 scn +q 1 0 0 1 325.7642 216.7715 cm +0 0 m +-1.064 -0.938 -0.813 -4.867 -0.541 -5.6 c +0.429 -8.205 2.405 -8.584 3.209 -8.627 c +4.272 -8.682 5.299 -9.067 6.379 -8.965 c +6.692 -8.936 7.266 -8.798 7.587 -8.212 c +6.594 -10.16 4.569 -11.497 2.235 -11.497 c +-1.077 -11.497 -3.768 -8.806 -3.768 -5.494 c +-3.768 -2.81 -2.001 -0.54 0.432 0.225 c +0.372 0.2 0.292 0.168 0.231 0.144 c +0.161 0.102 0.061 0.054 0 0 c +f +Q +0.22 0.647 0.812 scn +q 1 0 0 1 329.5791 211.4561 cm +0 0 m +-0.095 0.068 -0.095 0.068 -0.519 0.587 c +-0.661 0.762 -0.834 0.909 -0.973 1.089 c +-1.125 1.286 -1.231 1.594 y +-1.226 1.612 -0.029 2.438 0.592 1.362 c +1.027 0.609 0.245 -0.131 0.233 -0.133 c +0.153 -0.144 0.065 -0.047 0 0 c +f +Q +0.149 0.443 0.561 scn +q 1 0 0 1 330.5688 216.6631 cm +0 0 m +-1.295 0.462 -2.254 -0.325 -2.57 -0.584 c +-2.57 0.608 l +-1.402 0.608 -0.311 0.274 0.612 -0.302 c +0.522 -0.252 0.402 -0.186 0.312 -0.136 c +0.219 -0.095 0.096 -0.034 0 0 c +f +Q +0.224 0.659 0.831 scn +q 1 0 0 1 329.6191 211.708 cm +0 0 m +-0.335 0.354 l +-0.472 0.524 -0.626 0.68 -0.757 0.854 c +-0.976 1.148 -1.021 1.268 -1.019 1.272 c +-1.014 1.287 -0.028 1.7 0.33 0.952 c +0.591 0.409 0.174 -0.12 0.167 -0.121 c +0.106 -0.131 0.048 -0.039 0 0 c +f +Q +0.145 0.431 0.541 scn +q 1 0 0 1 329.7661 216.9941 cm +0 0 m +-0.649 0.12 -1.161 -0.01 -1.767 -0.45 c +-1.767 0.277 l +-1.038 0.277 -0.339 0.147 0.307 -0.091 c +0.224 -0.065 0.112 -0.031 0.029 -0.007 c +0.02 -0.005 0.009 -0.002 0 0 c +f +Q +0.227 0.675 0.847 scn +q 1 0 0 1 329.623 211.9746 cm +0 0 m +-0.004 0.004 -0.533 0.572 -0.71 0.861 c +-0.568 0.874 -0.482 0.883 -0.264 0.809 c +-0.18 0.78 -0.083 0.699 -0.025 0.631 c +0.033 0.563 0.091 0.45 0.104 0.361 c +0.135 0.141 0.099 0.019 0.074 -0.063 c +0.052 -0.044 0.021 -0.021 0 0 c +f +Q +0.141 0.416 0.522 scn +q 1 0 0 1 328.9043 217.1943 cm +0 0 m +-0.314 -0.006 -0.487 -0.009 -0.905 -0.208 c +-0.905 0.077 l +-0.519 0.077 -0.142 0.041 0.225 -0.029 c +0.157 -0.021 0.068 -0.004 0 0 c +f +Q +0.137 0.4 0.506 scn +q 1 0 0 1 327.999 217.2598 cm +0 0 m +0 0.012 l +0.072 0.012 0.144 0.011 0.215 0.008 c +0.15 0.006 0.046 -0.045 0 0 c +f +Q + endstream endobj 1361 0 obj <> endobj 1334 0 obj <> endobj 1335 0 obj <>/XObject<>>>/Subtype/Form>>stream +q +334.002 303.277 m +334.002 319.277 l +349.464 319.277 362.001 306.74 362.001 291.278 c +362.001 275.808 349.464 263.279 334.002 263.279 c +318.54 263.279 306.003 275.808 306.003 291.278 c +306.003 306.74 318.54 319.277 334.002 319.277 c +334.002 303.277 l +327.395 303.288 321.992 297.886 322.003 291.278 c +321.994 284.663 327.392 279.27 334.002 279.279 c +340.612 279.27 346.01 284.663 346.001 291.278 c +346.012 297.886 340.609 303.288 334.002 303.277 c +W n +q +/GS0 gs +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q +Q + endstream endobj 1362 0 obj <> endobj 1363 0 obj <>/ExtGState<>>>/Subtype/Form>>stream +/CS0 cs 0.259 0.565 0.682 scn +/GS0 gs +q 1 0 0 1 334.002 303.2773 cm +0 0 m +0 16 l +15.462 16 27.999 3.463 27.999 -11.999 c +27.999 -27.47 15.462 -39.998 0 -39.998 c +-15.462 -39.998 -27.999 -27.47 -27.999 -11.999 c +-27.999 3.463 -15.462 16 0 16 c +0 0 l +-6.607 0.011 -12.01 -5.392 -11.999 -11.999 c +-12.008 -18.614 -6.61 -24.008 0 -23.998 c +6.61 -24.008 12.008 -18.614 11.999 -11.999 c +12.01 -5.392 6.607 0.011 0 0 c +f +Q +q 1 0 0 1 334.002 308.4409 cm +0 0 m +0 -0.468 l +0 -5.164 l +-6.607 -5.153 -12.01 -10.555 -11.999 -17.163 c +-12.008 -23.778 -6.61 -29.171 0 -29.162 c +6.61 -29.171 12.008 -23.778 11.999 -17.163 c +12.01 -10.555 6.607 -5.153 0 -5.164 c +0 -0.468 l +0.316 -0.694 0.738 -0.996 1.055 -1.223 c +3.817 -3.661 7.459 -4.869 10 -7.617 c +12.018 -9.8 13.458 -12.461 14.279 -15.528 c +15.076 -18.506 16.901 -19.345 16.917 -19.347 c +18.874 -19.542 24.734 -10.485 17.857 -2.241 c +10.879 6.124 0.769 1.958 0 0 c +0 10.836 l +15.462 10.836 27.999 -1.701 27.999 -17.163 c +27.999 -32.633 15.462 -45.162 0 -45.162 c +-15.462 -45.162 -27.999 -32.633 -27.999 -17.163 c +-27.999 -1.701 -15.462 10.836 0 10.836 c +0 0 l +f +Q +0.255 0.553 0.667 scn +q 1 0 0 1 334.002 310.2881 cm +0 0 m +-0.296 -0.712 -1.487 -1.168 -1.735 -1.898 c +-1.987 -2.638 -2.003 -3.873 -1.53 -4.494 c +-1.227 -4.893 -0.45 -4.945 0 -5.167 c +0 -7.011 l +-6.607 -7 -12.01 -12.402 -11.999 -19.01 c +-12.008 -25.625 -6.61 -31.019 0 -31.009 c +6.61 -31.019 12.008 -25.625 11.999 -19.01 c +12.01 -12.402 6.607 -7 0 -7.011 c +0 -5.167 l +0.338 -5.201 0.788 -5.245 1.126 -5.278 c +2.249 -5.476 12.144 -7.557 13.761 -19.537 c +14.171 -22.514 l +14.636 -23.089 15.724 -23.505 16.459 -23.428 c +20.584 -22.992 26.416 -9.568 15.896 -1.312 c +7.943 4.929 0.035 0.084 0 0 c +0 8.989 l +15.462 8.989 27.999 -3.548 27.999 -19.01 c +27.999 -34.48 15.462 -47.009 0 -47.009 c +-15.462 -47.009 -27.999 -34.48 -27.999 -19.01 c +-27.999 -3.548 -15.462 8.989 0 8.989 c +0 0 l +f +Q +0.247 0.541 0.651 scn +q 1 0 0 1 334.002 311.4072 cm +0 0 m +-0.627 -1.109 -1.866 -1.525 -2.708 -2.391 c +-4.764 -4.503 -4.447 -6.209 -4.44 -6.223 c +-4.355 -6.386 -4.355 -6.386 0 -7.408 c +0 -8.13 l +-6.607 -8.119 -12.01 -13.521 -11.999 -20.129 c +-12.008 -26.744 -6.61 -32.138 0 -32.128 c +6.61 -32.138 12.008 -26.744 11.999 -20.129 c +12.01 -13.521 6.607 -8.119 0 -8.13 c +0 -7.408 l +0.312 -7.428 0.727 -7.455 1.039 -7.475 c +5.587 -8.118 13.155 -12.018 12.674 -22.55 c +12.559 -25.063 12.663 -26.479 12.981 -26.762 c +14.31 -27.933 23.356 -23.69 22.629 -14.042 c +21.27 4.006 1.142 2.02 0 0 c +0 7.87 l +15.462 7.87 27.999 -4.667 27.999 -20.129 c +27.999 -35.6 15.462 -48.128 0 -48.128 c +-15.462 -48.128 -27.999 -35.6 -27.999 -20.129 c +-27.999 -4.667 -15.462 7.87 0 7.87 c +0 0 l +f +Q +0.243 0.529 0.639 scn +q 1 0 0 1 334.002 312.3325 cm +0 0 m +-0.223 -0.377 -0.896 -0.494 -1.279 -0.706 c +-3.984 -2.198 -4.352 -2.882 -7.218 -8.204 c +-10.978 -15.407 l +-12.034 -17.649 -12.409 -19.973 -12.123 -22.511 c +-11.368 -29.203 -4.44 -35.038 3.702 -32.832 c +16.504 -28.455 l +19.639 -26.388 21.523 -23.893 22.614 -20.364 c +24.61 -13.908 21.812 -4.74 13.674 -0.575 c +6.26 3.219 0.029 0.049 0 0 c +0 6.945 l +15.462 6.945 27.999 -5.592 27.999 -21.054 c +27.999 -36.525 15.462 -49.053 0 -49.053 c +-15.462 -49.053 -27.999 -36.525 -27.999 -21.054 c +-27.999 -5.592 -15.462 6.945 0 6.945 c +0 0 l +f +Q +0.235 0.518 0.624 scn +q 1 0 0 1 334.002 313.1323 cm +0 0 m +-0.174 -0.267 -0.682 -0.3 -0.974 -0.428 c +-3.27 -1.438 -6.363 -4.313 -7.593 -6.58 c +-13.39 -17.263 -13 -20.654 -12.686 -23.379 c +-12.044 -28.943 -6.306 -36.331 3.976 -34.516 c +34.376 -29.152 23.202 -7.033 15.417 -1.844 c +7.621 3.352 0.038 0.059 0 0 c +0 6.145 l +15.462 6.145 27.999 -6.392 27.999 -21.854 c +27.999 -37.325 15.462 -49.853 0 -49.853 c +-15.462 -49.853 -27.999 -37.325 -27.999 -21.854 c +-27.999 -6.392 -15.462 6.145 0 6.145 c +0 0 l +f +Q +0.231 0.506 0.608 scn +q 1 0 0 1 334.002 313.833 cm +0 0 m +-0.26 -0.393 -1.01 -0.429 -1.443 -0.612 c +-4.281 -1.817 -7.531 -4.969 -9.346 -8.278 c +-13.499 -15.849 -13.757 -21.087 -13.243 -24.146 c +-12.334 -29.559 -7.254 -38.113 6.021 -35.853 c +29.652 -31.827 27.567 -10.229 15.691 -2.188 c +7.725 3.206 0.039 0.058 0 0 c +0 5.444 l +15.462 5.444 27.999 -7.093 27.999 -22.555 c +27.999 -38.025 15.462 -50.554 0 -50.554 c +-15.462 -50.554 -27.999 -38.025 -27.999 -22.555 c +-27.999 -7.093 -15.462 5.444 0 5.444 c +0 0 l +f +Q +0.227 0.494 0.592 scn +q 1 0 0 1 334.002 314.499 cm +0 0 m +-0.27 -0.397 -1.042 -0.411 -1.488 -0.586 c +-3.111 -1.225 -7.25 -3.37 -10.633 -9.471 c +-11.685 -11.368 -15.021 -18.085 -13.796 -24.878 c +-12.453 -32.322 -5.461 -39.359 6.715 -37.218 c +28.949 -33.308 28.975 -11.258 15.609 -2.301 c +7.856 2.895 0.038 0.056 0 0 c +0 4.778 l +15.462 4.778 27.999 -7.759 27.999 -23.221 c +27.999 -38.691 15.462 -51.22 0 -51.22 c +-15.462 -51.22 -27.999 -38.691 -27.999 -23.221 c +-27.999 -7.759 -15.462 4.778 0 4.778 c +0 0 l +f +Q +0.22 0.478 0.576 scn +q 1 0 0 1 334.002 315.1099 cm +0 0 m +-0.285 -0.403 -1.085 -0.384 -1.55 -0.549 c +-2.14 -0.758 -7.426 -2.783 -11.14 -9.4 c +-12.536 -11.888 -15.643 -18.441 -14.343 -25.554 c +-13.275 -31.396 -7.567 -40.71 7.05 -38.567 c +28.067 -35.485 30.905 -13.13 16.17 -2.838 c +7.979 2.883 0.04 0.057 0 0 c +0 4.167 l +15.462 4.167 27.999 -8.37 27.999 -23.832 c +27.999 -39.302 15.462 -51.831 0 -51.831 c +-15.462 -51.831 -27.999 -39.302 -27.999 -23.832 c +-27.999 -8.37 -15.462 4.167 0 4.167 c +0 0 l +f +Q +0.216 0.467 0.565 scn +q 1 0 0 1 334.002 315.6826 cm +0 0 m +-0.294 -0.407 -1.113 -0.365 -1.59 -0.521 c +-3.037 -0.996 -8.057 -3.068 -11.887 -9.807 c +-12.95 -11.677 -16.306 -18.383 -14.886 -26.191 c +-13.691 -32.763 -6.811 -41.823 7.247 -39.848 c +28.69 -36.835 31.472 -13.848 16.374 -3.144 c +8.08 2.736 0.041 0.056 0 0 c +0 3.595 l +15.462 3.595 27.999 -8.942 27.999 -24.404 c +27.999 -39.875 15.462 -52.403 0 -52.403 c +-15.462 -52.403 -27.999 -39.875 -27.999 -24.404 c +-27.999 -8.942 -15.462 3.595 0 3.595 c +0 0 l +f +Q +0.208 0.455 0.549 scn +q 1 0 0 1 334.002 316.2197 cm +0 0 m +-0.327 -0.44 -1.224 -0.37 -1.749 -0.528 c +-5.52 -1.667 -9.766 -5.26 -12.073 -9.267 c +-15.394 -15.036 -16.522 -20.933 -15.426 -26.792 c +-13.857 -35.175 -5.228 -43.007 7.675 -41.012 c +29.388 -37.654 31.678 -13.959 16.092 -3.122 c +8.188 2.374 0.041 0.052 0 0 c +0 3.058 l +15.462 3.058 27.999 -9.479 27.999 -24.941 c +27.999 -40.412 15.462 -52.94 0 -52.94 c +-15.462 -52.94 -27.999 -40.412 -27.999 -24.941 c +-27.999 -9.479 -15.462 3.058 0 3.058 c +0 0 l +f +Q +0.204 0.443 0.533 scn +q 1 0 0 1 334.002 316.7344 cm +0 0 m +-0.315 -0.413 -1.169 -0.321 -1.671 -0.458 c +-5.628 -1.543 -10.186 -5.222 -12.509 -9.206 c +-13.794 -11.411 -17.706 -18.119 -15.958 -27.369 c +-14.312 -36.083 -5.369 -44.225 7.962 -42.147 c +29.829 -38.742 32.261 -15.07 16.713 -3.752 c +8.241 2.415 0.041 0.054 0 0 c +0 2.543 l +15.462 2.543 27.999 -9.994 27.999 -25.456 c +27.999 -40.927 15.462 -53.455 0 -53.455 c +-15.462 -53.455 -27.999 -40.927 -27.999 -25.456 c +-27.999 -9.994 -15.462 2.543 0 2.543 c +0 0 l +f +Q +0.196 0.431 0.518 scn +q 1 0 0 1 334.002 317.207 cm +0 0 m +-0.326 -0.417 -1.197 -0.297 -1.71 -0.424 c +-5.005 -1.241 -10.022 -4.174 -13.317 -9.752 c +-16.642 -15.38 -17.708 -21.487 -16.484 -27.904 c +-14.771 -36.888 -5.523 -45.309 8.242 -43.221 c +29.817 -39.947 32.246 -15.423 16.845 -4.05 c +8.507 2.107 0.042 0.053 0 0 c +0 2.07 l +15.462 2.07 27.999 -10.467 27.999 -25.929 c +27.999 -41.399 15.462 -53.928 0 -53.928 c +-15.462 -53.928 -27.999 -41.399 -27.999 -25.929 c +-27.999 -10.467 -15.462 2.07 0 2.07 c +0 0 l +f +Q +0.192 0.42 0.506 scn +q 1 0 0 1 334.002 317.647 cm +0 0 m +-0.165 -0.201 -0.596 -0.119 -0.852 -0.169 c +-6.63 -1.321 -11.086 -5.48 -13.33 -8.99 c +-17.824 -16.019 -17.96 -22.681 -17.283 -27.032 c +-15.528 -38.307 -5.35 -45.631 6.918 -44.447 c +29.057 -42.308 33.214 -18.565 18.588 -5.674 c +9.722 2.142 0.051 0.062 0 0 c +0 1.63 l +15.462 1.63 27.999 -10.907 27.999 -26.369 c +27.999 -41.839 15.462 -54.368 0 -54.368 c +-15.462 -54.368 -27.999 -41.839 -27.999 -26.369 c +-27.999 -10.907 -15.462 1.63 0 1.63 c +0 0 l +f +Q +0.188 0.408 0.49 scn +q 1 0 0 1 334.002 318.0581 cm +0 0 m +-0.345 -0.419 -1.243 -0.245 -1.775 -0.35 c +-5.333 -1.052 -10.598 -4.013 -13.752 -8.857 c +-18.474 -16.108 -18.606 -22.979 -17.885 -27.466 c +-16.272 -37.501 -7.101 -46.918 7.31 -45.498 c +29.578 -43.303 33.522 -19.118 18.666 -5.999 c +9.679 1.938 0.05 0.061 0 0 c +0 1.219 l +15.462 1.219 27.999 -11.318 27.999 -26.78 c +27.999 -42.25 15.462 -54.779 0 -54.779 c +-15.462 -54.779 -27.999 -42.25 -27.999 -26.78 c +-27.999 -11.318 -15.462 1.219 0 1.219 c +0 0 l +f +Q +0.18 0.392 0.475 scn +q 1 0 0 1 334.002 318.4131 cm +0 0 m +-0.359 -0.424 -1.279 -0.213 -1.827 -0.305 c +-2.571 -0.429 -9.239 -1.713 -14.035 -8.521 c +-19.337 -16.049 -19.04 -23.602 -18.666 -26.5 c +-16.791 -41.034 -4.557 -47.118 6.016 -46.62 c +29.239 -45.526 34.04 -19.967 18.705 -6.311 c +9.693 1.714 0.05 0.059 0 0 c +0 0.864 l +15.462 0.864 27.999 -11.673 27.999 -27.135 c +27.999 -42.605 15.462 -55.134 0 -55.134 c +-15.462 -55.134 -27.999 -42.605 -27.999 -27.135 c +-27.999 -11.673 -15.462 0.864 0 0.864 c +0 0 l +f +Q +0.176 0.38 0.459 scn +q 1 0 0 1 334.002 318.7388 cm +0 0 m +-0.366 -0.422 -1.29 -0.183 -1.842 -0.262 c +-5.616 -0.798 -11.203 -3.577 -14.553 -8.414 c +-20.526 -17.037 -19.484 -25.014 -19.142 -27.636 c +-17.325 -41.544 -4.721 -48.295 6.216 -47.587 c +22.826 -46.511 31.838 -32.411 25.896 -16.796 c +27.251 -20.083 27.999 -23.685 27.999 -27.46 c +27.999 -42.931 15.462 -55.459 0 -55.459 c +-15.462 -55.459 -27.999 -42.931 -27.999 -27.46 c +-27.999 -11.999 -15.462 0.539 0 0.539 c +0 0 l +f +Q +0.169 0.369 0.443 scn +q 1 0 0 1 334.002 318.9941 cm +0 0 m +-0.38 -0.425 -1.322 -0.147 -1.889 -0.211 c +-3.74 -0.417 -10.183 -1.633 -15.334 -8.604 c +-20.121 -15.081 -20.497 -23.226 -19.964 -27.017 c +-18.07 -40.5 -7.309 -49.138 6.814 -48.512 c +13.57 -48.212 30.458 -42.954 27.513 -22.495 c +27.832 -24.187 27.999 -25.932 27.999 -27.716 c +27.999 -43.187 15.462 -55.715 0 -55.715 c +-15.462 -55.715 -27.999 -43.187 -27.999 -27.716 c +-27.999 -12.254 -15.462 0.283 0 0.283 c +0 0 l +f +Q +0.165 0.357 0.431 scn +q 1 0 0 1 334.002 319.1851 cm +0 0 m +-0.389 -0.421 -1.333 -0.109 -1.905 -0.156 c +-5.862 -0.48 -11.762 -2.986 -15.367 -7.721 c +-21.456 -15.721 -21.121 -23.999 -20.694 -27.186 c +-18.848 -40.988 -7.36 -50.366 6.622 -49.484 c +16.365 -48.869 27.809 -42.686 27.992 -27.284 c +27.997 -27.491 27.999 -27.699 27.999 -27.907 c +27.999 -43.377 15.462 -55.906 0 -55.906 c +-15.462 -55.906 -27.999 -43.377 -27.999 -27.907 c +-27.999 -12.445 -15.462 0.092 0 0.092 c +0 0 l +f +Q +0.157 0.345 0.416 scn +q 1 0 0 1 334.002 319.2739 cm +0 0 m +-0.403 -0.423 -1.362 -0.067 -1.945 -0.096 c +-5.653 -0.278 -11.171 -1.795 -16.407 -7.987 c +-19.42 -11.549 -22.258 -18.906 -21.583 -25.522 c +-19.025 -50.59 4.157 -50.418 5.143 -50.399 c +17.395 -50.155 25.849 -43.167 27.755 -31.707 c +25.94 -45.421 14.205 -55.995 0 -55.995 c +-15.462 -55.995 -27.999 -43.466 -27.999 -27.996 c +-27.999 -12.534 -15.462 0.003 0 0.003 c +0 0 l +f +Q +0.153 0.333 0.4 scn +q 1 0 0 1 329.771 318.957 cm +0 0 m +-22.534 -4.552 -23.533 -35.028 -6.33 -46.26 c +6.848 -54.863 25.642 -52.17 31.069 -35.688 c +27.625 -47.252 16.911 -55.678 4.231 -55.678 c +-11.231 -55.678 -23.768 -43.149 -23.768 -27.679 c +-23.768 -13.386 -13.055 -1.592 0.778 0.109 c +0.544 0.077 0.232 0.04 0 0 c +f +Q +0.145 0.322 0.384 scn +q 1 0 0 1 321.978 316.4971 cm +0 0 m +-16.565 -9.063 -17.347 -40.195 9.314 -48.713 c +16.64 -51.053 30.632 -50.191 36.987 -37.914 c +32.359 -46.999 22.917 -53.218 12.024 -53.218 c +-3.438 -53.218 -15.975 -40.689 -15.975 -25.219 c +-15.975 -12.683 -7.734 -2.069 3.625 1.499 c +3.1 1.309 2.399 1.057 1.873 0.867 c +1.31 0.61 0.543 0.297 0 0 c +f +Q +0.267 0.58 0.698 scn +q 1 0 0 1 349.9282 293.1025 cm +0 0 m +-1.706 2.422 -2.871 5.191 -4.806 7.466 c +-5.58 8.375 -6.333 9.14 -7.046 9.739 c +-7.103 9.787 -12.7 14.578 -12.706 14.928 c +-12.708 15.034 -10.925 16.753 -10.74 16.824 c +-10.058 17.085 -7.544 17.231 -6.875 17.165 c +-5.111 16.991 -2.438 16.24 0.275 13.649 c +3.79 10.292 4.269 6.381 4.332 5.263 c +4.608 0.361 1.816 -1.553 1.125 -1.426 c +0.589 -1.328 0.314 -0.446 0 0 c +f +Q +0.271 0.592 0.71 scn +q 1 0 0 1 350.0625 295.5957 cm +0 0 m +-1.97 2.883 -3.056 4.472 -4.87 6.595 c +-5.072 6.832 -5.375 7.116 -5.591 7.34 c +-5.844 7.601 -6.16 7.969 -6.419 8.224 c +-6.913 8.711 -7.551 9.382 -8.074 9.839 c +-9.724 11.281 -9.908 11.547 -9.911 11.595 c +-9.914 11.655 -8.389 13.369 -8.295 13.411 c +-7.711 13.674 -6.801 13.346 -6.164 13.276 c +-2.962 12.927 -1.156 11.212 -0.476 10.566 c +2.531 7.709 2.783 5.143 2.904 3.909 c +2.938 3.565 2.929 0.875 2.709 0.41 c +2.675 0.337 0.707 -0.874 0.645 -0.861 c +0.33 -0.793 0.182 -0.267 0 0 c +f +Q +0.278 0.604 0.725 scn +q 1 0 0 1 349.1475 299.125 cm +0 0 m +-0.737 0.235 -1.076 1.45 -1.576 2.04 c +-3.148 3.894 -3.148 3.894 -3.897 4.678 c +-4.212 5.008 -4.84 5.354 -4.922 5.803 c +-4.014 7.981 l +-3.953 8.007 -1.427 7.15 0.33 5.083 c +1.631 3.552 2.397 0.755 2.281 0.574 c +1.906 -0.01 0.699 -0.197 0.037 0.011 c +0.026 0.014 0.011 -0.003 0 0 c +f +Q +0.176 0.38 0.459 scn +q 1 0 0 1 346.0513 316.5498 cm +0 0 m +-5.275 2.417 -9.403 2.407 -12.049 2.189 c +-12.049 2.728 l +-6.604 2.728 -1.522 1.173 2.777 -1.517 c +2.232 -1.205 1.506 -0.789 0.961 -0.477 c +0.673 -0.334 0.292 -0.134 0 0 c +f +Q +0.169 0.369 0.443 scn +q 1 0 0 1 342.2651 318.0342 cm +0 0 m +-3.078 0.794 -4.478 1.111 -8.263 0.96 c +-8.263 1.243 l +-4.866 1.243 -1.61 0.638 1.402 -0.47 c +0.981 -0.329 0.425 -0.126 0 0 c +f +Q +0.165 0.357 0.431 scn +q 1 0 0 1 338.2329 318.957 cm +0 0 m +-2.557 0.263 -2.657 0.273 -4.231 0.228 c +-4.231 0.32 l +-2.431 0.32 -0.671 0.15 1.035 -0.174 c +0.724 -0.122 0.312 -0.042 0 0 c +f +Q +0.157 0.345 0.416 scn +q 1 0 0 1 334.002 319.2739 cm +0 0 m +0.335 0.003 0.669 -0.002 1.001 -0.014 c +0.701 -0.01 0.211 -0.214 0 0 c +f +Q + endstream endobj 1364 0 obj <> endobj 1332 0 obj <> endobj 1333 0 obj <>/XObject<>>>/Subtype/Form>>stream +q +186.627 218.274 m +186.627 223.274 l +189.939 223.274 192.621 220.593 192.621 217.271 c +192.621 213.959 189.939 211.277 186.627 211.277 c +183.315 211.277 180.624 213.959 180.624 217.271 c +180.624 220.593 183.315 223.274 186.627 223.274 c +186.627 218.274 l +186.078 218.277 185.622 217.823 185.624 217.271 c +185.62 216.731 186.077 216.274 186.627 216.277 c +187.173 216.275 187.624 216.726 187.621 217.271 c +187.622 217.829 187.171 218.277 186.627 218.274 c +W n +q +1 w 4 M 0 j 0 J []0 d +/GS0 gs +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q +Q + endstream endobj 1365 0 obj <> endobj 1366 0 obj <>/ExtGState<>>>/Subtype/Form>>stream +/CS0 cs 0.176 0.529 0.353 scn +/GS0 gs +q 1 0 0 1 186.627 218.2744 cm +0 0 m +0 5 l +3.312 5 5.994 2.318 5.994 -1.003 c +5.994 -4.315 3.312 -6.997 0 -6.997 c +-3.312 -6.997 -6.003 -4.315 -6.003 -1.003 c +-6.003 2.318 -3.312 5 0 5 c +0 0 l +-0.549 0.003 -1.005 -0.451 -1.003 -1.003 c +-1.007 -1.543 -0.55 -2 0 -1.997 c +0.546 -1.999 0.997 -1.549 0.994 -1.003 c +0.995 -0.445 0.544 0.003 0 0 c +f +Q +q 1 0 0 1 186.627 219.1992 cm +0 0 m +-0.013 -0.041 -0.073 -0.074 -0.083 -0.115 c +-0.111 -0.248 -0.02 -0.426 0 -0.561 c +0 -0.925 l +-0.549 -0.922 -1.005 -1.376 -1.003 -1.928 c +-1.007 -2.468 -0.55 -2.925 0 -2.922 c +0.546 -2.924 0.997 -2.474 0.994 -1.928 c +0.995 -1.37 0.544 -0.922 0 -0.925 c +0 -0.561 l +0.034 -0.558 0.078 -0.553 0.112 -0.55 c +0.141 -0.55 0.182 -0.536 0.208 -0.549 c +1.037 -1.473 l +1.432 -2.162 1.781 -2.116 1.796 -2.113 c +2.048 -2.073 3.175 -0.62 1.896 0.192 c +1.594 0.385 1.27 0.411 1.126 0.396 c +0 0 l +0 4.075 l +3.312 4.075 5.994 1.394 5.994 -1.928 c +5.994 -5.24 3.312 -7.922 0 -7.922 c +-3.312 -7.922 -6.003 -5.24 -6.003 -1.928 c +-6.003 1.394 -3.312 4.075 0 4.075 c +0 0 l +f +Q +0.173 0.518 0.345 scn +q 1 0 0 1 186.627 219.3418 cm +0 0 m +-0.03 -0.093 -0.164 -0.171 -0.185 -0.266 c +-0.222 -0.434 -0.125 -0.678 -0.187 -0.838 c +-0.188 -0.839 -0.237 -0.941 -0.403 -1.05 c +-1.157 -1.54 -1.045 -2.159 -0.993 -2.338 c +-0.812 -2.951 -0.139 -3.261 0.448 -2.999 c +0.646 -2.911 0.784 -2.775 0.866 -2.694 c +1.137 -2.427 1.542 -2.629 1.829 -2.42 c +2.42 -1.988 2.555 -1.604 2.619 -1.418 c +2.84 -0.784 2.454 0.136 1.624 0.372 c +0.851 0.592 0.002 0.007 0 0 c +0 3.933 l +3.312 3.933 5.994 1.251 5.994 -2.07 c +5.994 -5.383 3.312 -8.064 0 -8.064 c +-3.312 -8.064 -6.003 -5.383 -6.003 -2.07 c +-6.003 1.251 -3.312 3.933 0 3.933 c +0 0 l +f +Q +0.169 0.506 0.337 scn +q 1 0 0 1 186.627 219.4824 cm +0 0 m +-0.295 -0.834 -1.295 -1.352 -1.079 -2.413 c +-0.941 -3.092 -0.175 -3.558 0.645 -3.166 c +2.581 -2.241 2.581 -2.241 2.752 -1.679 c +3.15 -0.374 2.119 0.265 1.727 0.386 c +0.83 0.662 0.003 0.008 0 0 c +0 3.792 l +3.312 3.792 5.994 1.11 5.994 -2.211 c +5.994 -5.523 3.312 -8.205 0 -8.205 c +-3.312 -8.205 -6.003 -5.523 -6.003 -2.211 c +-6.003 1.11 -3.312 3.792 0 3.792 c +0 0 l +f +Q +0.165 0.49 0.329 scn +q 1 0 0 1 186.627 219.6211 cm +0 0 m +-0.353 -0.868 -1.382 -1.434 -1.146 -2.564 c +-1.026 -3.142 -0.354 -3.806 0.709 -3.4 c +2.435 -2.741 2.615 -2.673 2.848 -2.025 c +3.232 -0.958 2.919 -0.038 2.048 0.318 c +0.863 0.804 0.004 0.01 0 0 c +0 3.653 l +3.312 3.653 5.994 0.972 5.994 -2.35 c +5.994 -5.662 3.312 -8.344 0 -8.344 c +-3.312 -8.344 -6.003 -5.662 -6.003 -2.35 c +-6.003 0.972 -3.312 3.653 0 3.653 c +0 0 l +f +Q +0.161 0.478 0.322 scn +q 1 0 0 1 186.627 219.7588 cm +0 0 m +-0.193 -0.418 -0.584 -0.692 -0.794 -1.099 c +-1.091 -1.709 l +-1.261 -2.111 -1.291 -2.44 -1.189 -2.809 c +-1.127 -3.035 -0.731 -4.134 0.979 -3.567 c +4.729 -2.327 2.779 0.033 2.448 0.247 c +1.441 0.897 0.102 0.218 0 0 c +0 3.516 l +3.312 3.516 5.994 0.834 5.994 -2.487 c +5.994 -5.8 3.312 -8.481 0 -8.481 c +-3.312 -8.481 -6.003 -5.8 -6.003 -2.487 c +-6.003 0.834 -3.312 3.516 0 3.516 c +0 0 l +f +Q +0.157 0.467 0.314 scn +q 1 0 0 1 186.627 219.9111 cm +0 0 m +-0.013 -0.025 -0.053 -0.04 -0.076 -0.058 c +-0.436 -0.329 -0.724 -0.613 -1.172 -1.804 c +-1.294 -2.128 -1.428 -2.622 -1.186 -3.154 c +-0.786 -4.034 0.174 -4.205 1.666 -3.662 c +3.819 -2.879 3.945 -0.361 2.337 0.402 c +1.364 0.864 0.123 0.248 0 0 c +0 3.363 l +3.312 3.363 5.994 0.682 5.994 -2.64 c +5.994 -5.952 3.312 -8.634 0 -8.634 c +-3.312 -8.634 -6.003 -5.952 -6.003 -2.64 c +-6.003 0.682 -3.312 3.363 0 3.363 c +0 0 l +f +Q +0.153 0.455 0.306 scn +q 1 0 0 1 186.627 220.1025 cm +0 0 m +-0.034 -0.067 -0.142 -0.105 -0.203 -0.15 c +-0.738 -0.548 -1 -1.255 -1.252 -1.938 c +-1.385 -2.296 -1.491 -2.836 -1.247 -3.372 c +-0.62 -4.745 1.243 -4.15 1.798 -3.936 c +4.073 -3.057 4.215 -0.289 2.506 0.421 c +1.109 1.002 0.006 0.013 0 0 c +0 3.172 l +3.312 3.172 5.994 0.49 5.994 -2.831 c +5.994 -6.144 3.312 -8.825 0 -8.825 c +-3.312 -8.825 -6.003 -6.144 -6.003 -2.831 c +-6.003 0.49 -3.312 3.172 0 3.172 c +0 0 l +f +Q +0.149 0.443 0.294 scn +q 1 0 0 1 186.627 220.291 cm +0 0 m +-0.037 -0.07 -0.152 -0.104 -0.217 -0.148 c +-0.425 -0.29 -0.869 -0.842 -1.09 -1.384 c +-1.279 -1.849 -1.632 -2.713 -1.384 -3.395 c +-1 -4.452 -0.005 -4.766 1.573 -4.327 c +4.077 -3.63 4.625 -0.767 2.988 0.316 c +1.701 1.168 0.079 0.148 0 0 c +0 2.983 l +3.312 2.983 5.994 0.302 5.994 -3.02 c +5.994 -6.332 3.312 -9.014 0 -9.014 c +-3.312 -9.014 -6.003 -6.332 -6.003 -3.02 c +-6.003 0.302 -3.312 2.983 0 2.983 c +0 0 l +f +Q +0.145 0.431 0.286 scn +q 1 0 0 1 186.627 220.4746 cm +0 0 m +-0.175 -0.316 -0.542 -0.436 -0.748 -0.721 c +-1.047 -1.138 -1.145 -1.38 -1.239 -1.615 c +-1.289 -1.739 -1.721 -2.852 -1.448 -3.597 c +-0.854 -5.222 1.1 -4.778 1.685 -4.604 c +4.42 -3.787 4.999 -0.764 3.215 0.386 c +1.946 1.203 0.235 0.424 0 0 c +0 2.8 l +3.312 2.8 5.994 0.118 5.994 -3.203 c +5.994 -6.516 3.312 -9.197 0 -9.197 c +-3.312 -9.197 -6.003 -6.516 -6.003 -3.203 c +-6.003 0.118 -3.312 2.8 0 2.8 c +0 0 l +f +Q +0.141 0.42 0.278 scn +q 1 0 0 1 186.627 220.7061 cm +0 0 m +-0.06 -0.132 -0.265 -0.211 -0.386 -0.291 c +-0.737 -0.526 -1.203 -1.41 -1.325 -1.736 c +-1.409 -1.96 -1.811 -3.121 -1.476 -3.944 c +-0.72 -5.801 1.951 -4.87 1.978 -4.859 c +5.294 -3.584 5.17 -0.372 3.113 0.574 c +1.411 1.356 0.007 0.017 0 0 c +0 2.568 l +3.312 2.568 5.994 -0.113 5.994 -3.435 c +5.994 -6.747 3.312 -9.429 0 -9.429 c +-3.312 -9.429 -6.003 -6.747 -6.003 -3.435 c +-6.003 -0.113 -3.312 2.568 0 2.568 c +0 0 l +f +Q +0.137 0.408 0.271 scn +q 1 0 0 1 186.627 220.9883 cm +0 0 m +-0.04 -0.083 -0.167 -0.135 -0.239 -0.193 c +-0.735 -0.593 -1.129 -1.17 -1.41 -1.909 c +-1.685 -2.632 -1.76 -3.635 -1.577 -4.146 c +-0.866 -6.126 1.876 -5.311 1.903 -5.301 c +5.874 -3.976 5.345 -0.496 3.416 0.521 c +1.627 1.465 0.058 0.121 0 0 c +0 2.286 l +3.312 2.286 5.994 -0.396 5.994 -3.717 c +5.994 -7.029 3.312 -9.711 0 -9.711 c +-3.312 -9.711 -6.003 -7.029 -6.003 -3.717 c +-6.003 -0.396 -3.312 2.286 0 2.286 c +0 0 l +f +Q +0.133 0.396 0.263 scn +q 1 0 0 1 186.627 221.2744 cm +0 0 m +-0.045 -0.106 -0.21 -0.167 -0.303 -0.236 c +-0.487 -0.373 -1.127 -0.938 -1.625 -2.443 c +-1.73 -2.761 -1.906 -3.878 -1.546 -4.676 c +-1.031 -5.818 0.788 -6.214 2.508 -5.559 c +6.319 -4.105 5.737 -0.286 3.15 0.724 c +1.354 1.425 0.007 0.017 0 0 c +0 2 l +3.312 2 5.994 -0.682 5.994 -4.003 c +5.994 -7.315 3.312 -9.997 0 -9.997 c +-3.312 -9.997 -6.003 -7.315 -6.003 -4.003 c +-6.003 -0.682 -3.312 2 0 2 c +0 0 l +f +Q +0.129 0.384 0.255 scn +q 1 0 0 1 186.627 221.6582 cm +0 0 m +-0.163 -0.362 -0.542 -0.515 -0.779 -0.805 c +-0.947 -1.012 -1.049 -1.261 -1.205 -1.476 c +-1.367 -1.7 -1.47 -1.983 -1.721 -2.735 c +-2.06 -3.745 -1.792 -4.628 -1.661 -4.961 c +-1.172 -6.201 0.619 -6.721 2.417 -6.144 c +7.025 -4.662 5.824 -0.754 3.284 0.539 c +1.422 1.486 0.008 0.018 0 0 c +0 1.616 l +3.312 1.616 5.994 -1.065 5.994 -4.387 c +5.994 -7.699 3.312 -10.381 0 -10.381 c +-3.312 -10.381 -6.003 -7.699 -6.003 -4.387 c +-6.003 -1.065 -3.312 1.616 0 1.616 c +0 0 l +f +Q +0.125 0.373 0.247 scn +q 1 0 0 1 186.627 222.082 cm +0 0 m +-0.128 -0.296 -0.442 -0.404 -0.638 -0.631 c +-0.788 -0.804 -0.893 -1.01 -1.031 -1.191 c +-1.147 -1.346 -1.619 -2.354 -1.622 -2.361 c +-2.173 -3.904 -2.042 -4.642 -1.843 -5.159 c +-0.967 -7.426 1.647 -7.027 2.581 -6.683 c +3.886 -6.201 6.602 -5.198 5.542 -2.518 c +5.833 -3.224 5.994 -3.998 5.994 -4.811 c +5.994 -8.123 3.312 -10.805 0 -10.805 c +-3.312 -10.805 -6.003 -8.123 -6.003 -4.811 c +-6.003 -1.489 -3.312 1.192 0 1.192 c +0 0 l +f +Q +0.122 0.361 0.239 scn +q 1 0 0 1 186.627 222.5469 cm +0 0 m +-0.037 -0.078 -0.154 -0.129 -0.22 -0.185 c +-1.236 -1.035 -1.83 -2.885 -1.836 -2.903 c +-2.227 -4.14 -2.24 -5.156 -1.875 -5.925 c +-0.602 -8.604 3.351 -7.152 3.39 -7.137 c +4.435 -6.729 6.183 -6.049 5.89 -4.151 c +5.958 -4.516 5.994 -4.891 5.994 -5.275 c +5.994 -8.588 3.312 -11.27 0 -11.27 c +-3.312 -11.27 -6.003 -8.588 -6.003 -5.275 c +-6.003 -1.954 -3.312 0.728 0 0.728 c +0 0 l +f +Q +0.118 0.349 0.231 scn +q 1 0 0 1 186.627 222.9893 cm +0 0 m +-0.038 -0.066 -0.155 -0.09 -0.221 -0.129 c +-1.149 -0.673 -1.644 -2.171 -2.005 -3.266 c +-2.01 -3.282 -2.546 -5.07 -2.073 -6.283 c +-1.016 -9.001 3.053 -7.959 3.094 -7.948 c +4.312 -7.626 5.98 -7.185 5.993 -5.583 c +5.994 -5.628 5.994 -5.673 5.994 -5.718 c +5.994 -9.03 3.312 -11.712 0 -11.712 c +-3.312 -11.712 -6.003 -9.03 -6.003 -5.718 c +-6.003 -2.396 -3.312 0.285 0 0.285 c +0 0 l +f +Q +0.114 0.337 0.224 scn +q 1 0 0 1 186.627 223.2627 cm +0 0 m +-0.043 -0.052 -0.154 -0.029 -0.221 -0.042 c +-0.696 -0.133 -1.347 -0.689 -1.732 -1.731 c +-2.576 -4.018 -2.459 -5.555 -2.314 -6.268 c +-1.868 -8.458 0.839 -8.7 1.752 -8.612 c +4.209 -8.376 5.692 -8.233 5.942 -6.786 c +5.553 -9.723 3.042 -11.985 0 -11.985 c +-3.312 -11.985 -6.003 -9.304 -6.003 -5.991 c +-6.003 -2.67 -3.312 0.012 0 0.012 c +0 0 l +f +Q +0.11 0.325 0.216 scn +q 1 0 0 1 185.7217 223.1973 cm +0 0 m +-1.735 -0.588 -1.748 -4.507 -1.748 -4.547 c +-1.744 -6.481 -1.201 -7.607 0.015 -8.199 c +1.797 -9.066 6.081 -9.359 6.651 -7.642 c +5.914 -10.117 3.621 -11.92 0.905 -11.92 c +-2.407 -11.92 -5.098 -9.238 -5.098 -5.926 c +-5.098 -2.855 -2.799 -0.333 0.165 0.032 c +0.115 0.022 0.049 0.014 0 0 c +f +Q +0.106 0.314 0.208 scn +q 1 0 0 1 184.3926 222.7744 cm +0 0 m +-1.065 -0.939 -0.813 -4.875 -0.541 -5.608 c +0.425 -8.204 2.403 -8.583 3.208 -8.626 c +4.27 -8.682 5.294 -9.071 6.373 -8.972 c +6.625 -8.948 7.249 -8.828 7.579 -8.222 c +6.588 -10.166 4.567 -11.497 2.234 -11.497 c +-1.078 -11.497 -3.769 -8.815 -3.769 -5.503 c +-3.769 -2.812 -2.001 -0.54 0.432 0.225 c +0.372 0.2 0.292 0.168 0.231 0.144 c +0.161 0.103 0.062 0.054 0 0 c +f +Q +0.18 0.541 0.361 scn +q 1 0 0 1 188.1982 217.4531 cm +0 0 m +-0.089 0.064 -0.089 0.064 -0.518 0.595 c +-0.66 0.77 -0.832 0.916 -0.969 1.096 c +-1.153 1.336 -1.228 1.588 -1.225 1.6 c +-1.219 1.619 -0.023 2.449 0.592 1.369 c +1.023 0.611 0.244 -0.132 0.233 -0.134 c +0.153 -0.145 0.065 -0.047 0 0 c +f +Q +0.125 0.373 0.247 scn +q 1 0 0 1 189.1953 222.666 cm +0 0 m +-1.292 0.462 -2.253 -0.325 -2.568 -0.584 c +-2.568 0.608 l +-1.402 0.608 -0.314 0.276 0.606 -0.3 c +0.517 -0.25 0.397 -0.184 0.307 -0.133 c +0.215 -0.093 0.095 -0.034 0 0 c +f +Q +0.184 0.553 0.369 scn +q 1 0 0 1 188.2393 217.709 cm +0 0 m +-0.336 0.357 l +-0.471 0.528 -0.626 0.683 -0.755 0.857 c +-0.971 1.148 -1.017 1.271 -1.015 1.275 c +-1.01 1.29 -0.025 1.71 0.328 0.955 c +0.583 0.408 0.172 -0.12 0.166 -0.121 c +0.105 -0.132 0.047 -0.039 0 0 c +f +Q +0.122 0.361 0.239 scn +q 1 0 0 1 188.3931 222.9971 cm +0 0 m +-0.649 0.121 -1.161 -0.01 -1.766 -0.45 c +-1.766 0.277 l +-1.038 0.277 -0.341 0.147 0.305 -0.09 c +0.221 -0.064 0.11 -0.031 0.027 -0.006 c +0.019 -0.004 0.008 -0.001 0 0 c +f +Q +0.188 0.565 0.376 scn +q 1 0 0 1 188.2437 217.9775 cm +0 0 m +-0.004 0.005 -0.532 0.572 -0.709 0.863 c +-0.562 0.878 -0.481 0.886 -0.263 0.812 c +-0.178 0.783 -0.083 0.7 -0.026 0.632 c +0.032 0.563 0.087 0.449 0.1 0.36 c +0.13 0.142 0.09 0.006 0.071 -0.06 c +0.049 -0.041 0.02 -0.02 0 0 c +f +Q +0.118 0.349 0.231 scn +q 1 0 0 1 187.5317 223.1973 cm +0 0 m +-0.313 -0.006 -0.486 -0.009 -0.905 -0.208 c +-0.905 0.077 l +-0.519 0.077 -0.142 0.041 0.224 -0.029 c +0.157 -0.021 0.068 -0.004 0 0 c +f +Q +0.114 0.337 0.224 scn +q 1 0 0 1 186.627 223.2627 cm +0 0 m +0 0.012 l +0.072 0.012 0.144 0.011 0.215 0.008 c +0.15 0.006 0.046 -0.045 0 0 c +f +Q + endstream endobj 1367 0 obj <> endobj 1330 0 obj <> endobj 1331 0 obj <>/XObject<>>>/Subtype/Form>>stream +q +183 308.272 m +183 324.272 l +198.462 324.272 210.999 311.735 210.999 296.273 c +210.999 280.812 198.462 268.274 183 268.274 c +167.538 268.274 155.001 280.812 155.001 296.273 c +155.001 311.735 167.538 324.272 183 324.272 c +183 308.272 l +176.393 308.283 170.99 302.881 171.001 296.273 c +170.99 289.666 176.393 284.264 183 284.274 c +189.607 284.264 195.01 289.666 194.999 296.273 c +195.01 302.881 189.607 308.283 183 308.272 c +W n +q +/GS0 gs +0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do +Q +Q + endstream endobj 1368 0 obj <> endobj 1369 0 obj <>/ExtGState<>>>/Subtype/Form>>stream +/CS0 cs 0.184 0.553 0.369 scn +/GS0 gs +q 1 0 0 1 183 308.2725 cm +0 0 m +0 16 l +15.462 16 27.999 3.463 27.999 -11.999 c +27.999 -27.461 15.462 -39.998 0 -39.998 c +-15.462 -39.998 -27.999 -27.461 -27.999 -11.999 c +-27.999 3.463 -15.462 16 0 16 c +0 0 l +-6.607 0.011 -12.01 -5.392 -11.999 -11.999 c +-12.01 -18.606 -6.607 -24.009 0 -23.998 c +6.607 -24.009 12.01 -18.606 11.999 -11.999 c +12.01 -5.392 6.607 0.011 0 0 c +f +Q +q 1 0 0 1 183 313.436 cm +0 0 m +0 -0.468 l +0 -5.164 l +-6.607 -5.153 -12.01 -10.555 -11.999 -17.163 c +-12.01 -23.77 -6.607 -29.172 0 -29.162 c +6.607 -29.172 12.01 -23.77 11.999 -17.163 c +12.01 -10.555 6.607 -5.153 0 -5.164 c +0 -0.468 l +0.316 -0.694 0.738 -0.997 1.055 -1.223 c +3.817 -3.661 7.459 -4.869 10 -7.617 c +12.018 -9.8 13.458 -12.461 14.279 -15.528 c +15.091 -18.562 16.901 -19.343 16.918 -19.345 c +18.873 -19.539 24.733 -10.483 17.857 -2.241 c +10.879 6.124 0.769 1.958 0 0 c +0 10.836 l +15.462 10.836 27.999 -1.701 27.999 -17.163 c +27.999 -32.625 15.462 -45.162 0 -45.162 c +-15.462 -45.162 -27.999 -32.625 -27.999 -17.163 c +-27.999 -1.701 -15.462 10.836 0 10.836 c +0 0 l +f +Q +0.18 0.541 0.361 scn +q 1 0 0 1 183 315.2832 cm +0 0 m +-0.296 -0.712 -1.487 -1.168 -1.735 -1.898 c +-1.987 -2.638 -2.003 -3.873 -1.53 -4.494 c +-1.227 -4.893 -0.45 -4.945 0 -5.167 c +0 -7.011 l +-6.607 -7 -12.01 -12.402 -11.999 -19.01 c +-12.01 -25.617 -6.607 -31.02 0 -31.009 c +6.607 -31.02 12.01 -25.617 11.999 -19.01 c +12.01 -12.402 6.607 -7 0 -7.011 c +0 -5.167 l +0.338 -5.201 0.788 -5.245 1.126 -5.278 c +2.249 -5.476 12.142 -7.556 13.761 -19.537 c +14.172 -22.51 l +14.637 -23.085 15.725 -23.501 16.46 -23.424 c +20.584 -22.987 26.414 -9.567 15.896 -1.312 c +7.943 4.929 0.035 0.084 0 0 c +0 8.989 l +15.462 8.989 27.999 -3.548 27.999 -19.01 c +27.999 -34.472 15.462 -47.009 0 -47.009 c +-15.462 -47.009 -27.999 -34.472 -27.999 -19.01 c +-27.999 -3.548 -15.462 8.989 0 8.989 c +0 0 l +f +Q +0.176 0.529 0.353 scn +q 1 0 0 1 183 316.4023 cm +0 0 m +-0.627 -1.109 -1.866 -1.525 -2.708 -2.391 c +-4.764 -4.503 -4.447 -6.209 -4.44 -6.223 c +-4.355 -6.386 -4.355 -6.386 0 -7.408 c +0 -8.13 l +-6.607 -8.119 -12.01 -13.521 -11.999 -20.129 c +-12.01 -26.736 -6.607 -32.139 0 -32.128 c +6.607 -32.139 12.01 -26.736 11.999 -20.129 c +12.01 -13.521 6.607 -8.119 0 -8.13 c +0 -7.408 l +0.312 -7.428 0.727 -7.455 1.039 -7.475 c +5.586 -8.118 13.155 -12.017 12.674 -22.548 c +12.56 -25.061 12.663 -26.477 12.982 -26.758 c +14.311 -27.929 23.356 -23.684 22.629 -14.042 c +21.269 4.004 1.142 2.019 0 0 c +0 7.87 l +15.462 7.87 27.999 -4.667 27.999 -20.129 c +27.999 -35.591 15.462 -48.128 0 -48.128 c +-15.462 -48.128 -27.999 -35.591 -27.999 -20.129 c +-27.999 -4.667 -15.462 7.87 0 7.87 c +0 0 l +f +Q +0.173 0.518 0.345 scn +q 1 0 0 1 183 317.3276 cm +0 0 m +-0.223 -0.377 -0.896 -0.494 -1.279 -0.706 c +-3.983 -2.198 -4.352 -2.882 -7.218 -8.204 c +-10.977 -15.407 l +-12.034 -17.649 -12.409 -19.973 -12.123 -22.51 c +-11.368 -29.204 -4.441 -35.04 3.701 -32.832 c +16.504 -28.451 l +19.64 -26.383 21.524 -23.889 22.614 -20.364 c +24.61 -13.908 21.812 -4.74 13.674 -0.575 c +6.26 3.219 0.029 0.049 0 0 c +0 6.945 l +15.462 6.945 27.999 -5.592 27.999 -21.054 c +27.999 -36.516 15.462 -49.053 0 -49.053 c +-15.462 -49.053 -27.999 -36.516 -27.999 -21.054 c +-27.999 -5.592 -15.462 6.945 0 6.945 c +0 0 l +f +Q +0.169 0.506 0.337 scn +q 1 0 0 1 183 318.1274 cm +0 0 m +-0.174 -0.267 -0.682 -0.3 -0.974 -0.428 c +-3.27 -1.438 -6.363 -4.313 -7.593 -6.58 c +-13.39 -17.262 -13 -20.653 -12.686 -23.377 c +-12.045 -28.943 -6.307 -36.332 3.975 -34.516 c +34.372 -29.149 23.201 -7.033 15.417 -1.844 c +7.621 3.352 0.038 0.059 0 0 c +0 6.145 l +15.462 6.145 27.999 -6.392 27.999 -21.854 c +27.999 -37.316 15.462 -49.853 0 -49.853 c +-15.462 -49.853 -27.999 -37.316 -27.999 -21.854 c +-27.999 -6.392 -15.462 6.145 0 6.145 c +0 0 l +f +Q +0.165 0.49 0.329 scn +q 1 0 0 1 183 318.8281 cm +0 0 m +-0.26 -0.393 -1.01 -0.429 -1.443 -0.612 c +-4.281 -1.816 -7.531 -4.969 -9.346 -8.278 c +-13.498 -15.848 -13.757 -21.085 -13.244 -24.146 c +-12.335 -29.558 -7.256 -38.113 6.018 -35.853 c +29.65 -31.827 27.567 -10.229 15.691 -2.188 c +7.725 3.206 0.039 0.058 0 0 c +0 5.444 l +15.462 5.444 27.999 -7.093 27.999 -22.555 c +27.999 -38.017 15.462 -50.554 0 -50.554 c +-15.462 -50.554 -27.999 -38.017 -27.999 -22.555 c +-27.999 -7.093 -15.462 5.444 0 5.444 c +0 0 l +f +Q +0.161 0.478 0.322 scn +q 1 0 0 1 183 319.4941 cm +0 0 m +-0.27 -0.397 -1.042 -0.411 -1.488 -0.586 c +-3.111 -1.225 -7.249 -3.37 -10.633 -9.471 c +-11.685 -11.368 -15.021 -18.084 -13.796 -24.877 c +-12.453 -32.323 -5.461 -39.362 6.714 -37.218 c +28.943 -33.304 28.97 -11.255 15.609 -2.301 c +7.856 2.895 0.038 0.056 0 0 c +0 4.778 l +15.462 4.778 27.999 -7.759 27.999 -23.221 c +27.999 -38.683 15.462 -51.22 0 -51.22 c +-15.462 -51.22 -27.999 -38.683 -27.999 -23.221 c +-27.999 -7.759 -15.462 4.778 0 4.778 c +0 0 l +f +Q +0.157 0.467 0.314 scn +q 1 0 0 1 183 320.105 cm +0 0 m +-0.285 -0.403 -1.085 -0.384 -1.55 -0.549 c +-2.14 -0.758 -7.426 -2.783 -11.14 -9.4 c +-12.536 -11.888 -15.643 -18.441 -14.343 -25.552 c +-13.349 -30.994 -7.597 -40.716 7.05 -38.567 c +28.064 -35.482 30.902 -13.127 16.17 -2.838 c +7.979 2.883 0.04 0.057 0 0 c +0 4.167 l +15.462 4.167 27.999 -8.37 27.999 -23.832 c +27.999 -39.293 15.462 -51.831 0 -51.831 c +-15.462 -51.831 -27.999 -39.293 -27.999 -23.832 c +-27.999 -8.37 -15.462 4.167 0 4.167 c +0 0 l +f +Q +0.153 0.455 0.306 scn +q 1 0 0 1 183 320.6777 cm +0 0 m +-0.294 -0.407 -1.113 -0.365 -1.59 -0.521 c +-3.037 -0.996 -8.057 -3.068 -11.887 -9.807 c +-12.95 -11.676 -16.306 -18.381 -14.886 -26.189 c +-13.692 -32.763 -6.813 -41.824 7.243 -39.849 c +28.687 -36.835 31.471 -13.847 16.374 -3.144 c +8.08 2.736 0.041 0.056 0 0 c +0 3.595 l +15.462 3.595 27.999 -8.942 27.999 -24.404 c +27.999 -39.866 15.462 -52.403 0 -52.403 c +-15.462 -52.403 -27.999 -39.866 -27.999 -24.404 c +-27.999 -8.942 -15.462 3.595 0 3.595 c +0 0 l +f +Q +0.149 0.443 0.294 scn +q 1 0 0 1 183 321.2148 cm +0 0 m +-0.327 -0.44 -1.224 -0.37 -1.749 -0.528 c +-5.52 -1.667 -9.765 -5.26 -12.073 -9.267 c +-15.394 -15.036 -16.522 -20.932 -15.426 -26.791 c +-13.856 -35.176 -5.227 -43.01 7.675 -41.012 c +29.382 -37.65 31.673 -13.956 16.092 -3.122 c +8.188 2.374 0.041 0.052 0 0 c +0 3.058 l +15.462 3.058 27.999 -9.479 27.999 -24.941 c +27.999 -40.403 15.462 -52.94 0 -52.94 c +-15.462 -52.94 -27.999 -40.403 -27.999 -24.941 c +-27.999 -9.479 -15.462 3.058 0 3.058 c +0 0 l +f +Q +0.145 0.431 0.286 scn +q 1 0 0 1 183 321.7295 cm +0 0 m +-0.315 -0.413 -1.169 -0.321 -1.671 -0.458 c +-5.628 -1.543 -10.186 -5.222 -12.509 -9.206 c +-13.794 -11.411 -17.706 -18.119 -15.958 -27.368 c +-14.312 -36.085 -5.369 -44.227 7.962 -42.147 c +29.823 -38.738 32.256 -15.066 16.713 -3.752 c +8.241 2.415 0.041 0.054 0 0 c +0 2.543 l +15.462 2.543 27.999 -9.994 27.999 -25.456 c +27.999 -40.918 15.462 -53.455 0 -53.455 c +-15.462 -53.455 -27.999 -40.918 -27.999 -25.456 c +-27.999 -9.994 -15.462 2.543 0 2.543 c +0 0 l +f +Q +0.141 0.42 0.278 scn +q 1 0 0 1 183 322.2021 cm +0 0 m +-0.326 -0.417 -1.197 -0.297 -1.71 -0.424 c +-5.005 -1.241 -10.021 -4.174 -13.317 -9.752 c +-16.642 -15.38 -17.708 -21.487 -16.484 -27.902 c +-14.771 -36.889 -5.522 -45.311 8.242 -43.22 c +29.813 -39.944 32.242 -15.421 16.845 -4.05 c +8.507 2.107 0.042 0.053 0 0 c +0 2.07 l +15.462 2.07 27.999 -10.467 27.999 -25.929 c +27.999 -41.391 15.462 -53.928 0 -53.928 c +-15.462 -53.928 -27.999 -41.391 -27.999 -25.929 c +-27.999 -10.467 -15.462 2.07 0 2.07 c +0 0 l +f +Q +0.137 0.408 0.271 scn +q 1 0 0 1 183 322.6421 cm +0 0 m +-0.165 -0.201 -0.596 -0.119 -0.851 -0.169 c +-6.63 -1.321 -11.086 -5.48 -13.33 -8.99 c +-17.823 -16.018 -17.96 -22.68 -17.283 -27.031 c +-15.529 -38.308 -5.353 -45.633 6.914 -44.447 c +29.053 -42.307 33.213 -18.564 18.588 -5.674 c +9.722 2.142 0.051 0.062 0 0 c +0 1.63 l +15.462 1.63 27.999 -10.907 27.999 -26.369 c +27.999 -41.831 15.462 -54.368 0 -54.368 c +-15.462 -54.368 -27.999 -41.831 -27.999 -26.369 c +-27.999 -10.907 -15.462 1.63 0 1.63 c +0 0 l +f +Q +0.133 0.396 0.263 scn +q 1 0 0 1 183 323.0532 cm +0 0 m +-0.345 -0.419 -1.243 -0.245 -1.775 -0.35 c +-5.333 -1.052 -10.598 -4.013 -13.752 -8.857 c +-18.474 -16.108 -18.606 -22.979 -17.885 -27.465 c +-16.272 -37.503 -7.101 -46.92 7.31 -45.499 c +29.575 -43.3 33.52 -19.116 18.666 -5.999 c +9.679 1.938 0.05 0.061 0 0 c +0 1.219 l +15.462 1.219 27.999 -11.318 27.999 -26.78 c +27.999 -42.242 15.462 -54.779 0 -54.779 c +-15.462 -54.779 -27.999 -42.242 -27.999 -26.78 c +-27.999 -11.318 -15.462 1.219 0 1.219 c +0 0 l +f +Q +0.129 0.384 0.255 scn +q 1 0 0 1 183 323.4082 cm +0 0 m +-0.359 -0.424 -1.279 -0.213 -1.827 -0.305 c +-2.571 -0.429 -9.239 -1.713 -14.035 -8.521 c +-19.337 -16.049 -19.04 -23.602 -18.666 -26.5 c +-16.791 -41.035 -4.557 -47.119 6.015 -46.62 c +29.237 -45.525 34.039 -19.966 18.705 -6.311 c +9.693 1.714 0.05 0.059 0 0 c +0 0.864 l +15.462 0.864 27.999 -11.673 27.999 -27.135 c +27.999 -42.597 15.462 -55.134 0 -55.134 c +-15.462 -55.134 -27.999 -42.597 -27.999 -27.135 c +-27.999 -11.673 -15.462 0.864 0 0.864 c +0 0 l +f +Q +0.125 0.373 0.247 scn +q 1 0 0 1 183 323.7339 cm +0 0 m +-0.366 -0.422 -1.29 -0.183 -1.842 -0.262 c +-5.616 -0.798 -11.203 -3.577 -14.553 -8.414 c +-20.526 -17.037 -19.484 -25.015 -19.142 -27.636 c +-17.325 -41.545 -4.721 -48.296 6.215 -47.587 c +22.825 -46.511 31.838 -32.41 25.896 -16.796 c +27.251 -20.083 27.999 -23.685 27.999 -27.46 c +27.999 -42.922 15.462 -55.459 0 -55.459 c +-15.462 -55.459 -27.999 -42.922 -27.999 -27.46 c +-27.999 -11.999 -15.462 0.539 0 0.539 c +0 0 l +f +Q +0.122 0.361 0.239 scn +q 1 0 0 1 183 323.9893 cm +0 0 m +-0.38 -0.425 -1.322 -0.147 -1.889 -0.211 c +-3.74 -0.417 -10.183 -1.633 -15.334 -8.604 c +-20.12 -15.081 -20.496 -23.225 -19.964 -27.016 c +-18.071 -40.5 -7.311 -49.139 6.811 -48.512 c +13.567 -48.212 30.458 -42.954 27.513 -22.495 c +27.832 -24.187 27.999 -25.932 27.999 -27.716 c +27.999 -43.178 15.462 -55.715 0 -55.715 c +-15.462 -55.715 -27.999 -43.178 -27.999 -27.716 c +-27.999 -12.254 -15.462 0.283 0 0.283 c +0 0 l +f +Q +0.118 0.349 0.231 scn +q 1 0 0 1 183 324.1802 cm +0 0 m +-0.389 -0.421 -1.333 -0.109 -1.905 -0.156 c +-5.862 -0.48 -11.762 -2.986 -15.367 -7.721 c +-21.456 -15.72 -21.121 -23.999 -20.694 -27.186 c +-18.877 -40.767 -7.134 -50.353 6.621 -49.484 c +16.365 -48.869 27.809 -42.685 27.992 -27.284 c +27.997 -27.491 27.999 -27.699 27.999 -27.907 c +27.999 -43.369 15.462 -55.906 0 -55.906 c +-15.462 -55.906 -27.999 -43.369 -27.999 -27.907 c +-27.999 -12.445 -15.462 0.092 0 0.092 c +0 0 l +f +Q +0.114 0.337 0.224 scn +q 1 0 0 1 183 324.269 cm +0 0 m +-0.403 -0.423 -1.362 -0.067 -1.945 -0.096 c +-5.653 -0.278 -11.171 -1.795 -16.407 -7.987 c +-19.42 -11.549 -22.258 -18.906 -21.583 -25.522 c +-19.025 -50.59 4.157 -50.418 5.143 -50.399 c +17.394 -50.156 25.847 -43.167 27.756 -31.704 c +25.941 -45.414 14.205 -55.995 0 -55.995 c +-15.462 -55.995 -27.999 -43.458 -27.999 -27.996 c +-27.999 -12.534 -15.462 0.003 0 0.003 c +0 0 l +f +Q +0.11 0.325 0.216 scn +q 1 0 0 1 178.769 323.9521 cm +0 0 m +-22.529 -4.551 -23.528 -35.026 -6.329 -46.258 c +6.848 -54.862 25.641 -52.169 31.069 -35.683 c +27.625 -47.245 16.912 -55.678 4.231 -55.678 c +-11.231 -55.678 -23.768 -43.141 -23.768 -27.679 c +-23.768 -13.386 -13.055 -1.592 0.778 0.109 c +0.544 0.077 0.232 0.04 0 0 c +f +Q +0.106 0.314 0.208 scn +q 1 0 0 1 170.9761 321.4922 cm +0 0 m +-16.563 -9.063 -17.344 -40.194 9.316 -48.713 c +16.64 -51.054 30.629 -50.189 36.987 -37.91 c +32.359 -46.995 22.917 -53.218 12.024 -53.218 c +-3.438 -53.218 -15.975 -40.681 -15.975 -25.219 c +-15.975 -12.683 -7.734 -2.069 3.625 1.499 c +3.1 1.309 2.399 1.057 1.873 0.867 c +1.31 0.61 0.543 0.297 0 0 c +f +Q +0.188 0.565 0.376 scn +q 1 0 0 1 198.9263 298.0972 cm +0 0 m +-1.706 2.422 -2.871 5.192 -4.806 7.466 c +-5.58 8.375 -6.333 9.14 -7.046 9.74 c +-7.103 9.788 -12.7 14.579 -12.706 14.929 c +-12.708 15.035 -10.925 16.753 -10.74 16.825 c +-10.058 17.086 -7.544 17.231 -6.875 17.166 c +-5.111 16.992 -2.438 16.241 0.275 13.649 c +3.79 10.293 4.269 6.382 4.332 5.263 c +4.608 0.362 1.816 -1.553 1.125 -1.426 c +0.589 -1.328 0.314 -0.445 0 0 c +f +Q +0.192 0.576 0.384 scn +q 1 0 0 1 199.0605 300.5908 cm +0 0 m +-1.97 2.883 -3.055 4.471 -4.87 6.595 c +-5.072 6.832 -5.375 7.116 -5.591 7.34 c +-5.844 7.601 -6.16 7.969 -6.419 8.224 c +-6.913 8.711 -7.551 9.382 -8.074 9.839 c +-9.724 11.281 -9.908 11.547 -9.911 11.595 c +-9.914 11.655 -8.389 13.369 -8.295 13.411 c +-7.711 13.674 -6.801 13.346 -6.164 13.276 c +-2.962 12.927 -1.156 11.212 -0.476 10.566 c +2.531 7.709 2.783 5.143 2.904 3.909 c +2.938 3.565 2.929 0.875 2.709 0.41 c +2.675 0.337 0.707 -0.875 0.645 -0.861 c +0.33 -0.793 0.182 -0.267 0 0 c +f +Q +0.196 0.588 0.392 scn +q 1 0 0 1 198.1455 304.1201 cm +0 0 m +-0.737 0.235 -1.076 1.45 -1.576 2.04 c +-3.148 3.894 -3.148 3.894 -3.897 4.678 c +-4.212 5.008 -4.84 5.354 -4.922 5.803 c +-4.014 7.981 l +-3.953 8.007 -1.427 7.15 0.33 5.083 c +1.631 3.552 2.397 0.755 2.281 0.574 c +1.906 -0.01 0.699 -0.197 0.037 0.011 c +0.026 0.014 0.011 -0.003 0 0 c +f +Q +0.125 0.373 0.247 scn +q 1 0 0 1 195.0493 321.5449 cm +0 0 m +-5.275 2.417 -9.403 2.407 -12.049 2.189 c +-12.049 2.728 l +-6.604 2.728 -1.522 1.173 2.777 -1.517 c +2.232 -1.205 1.506 -0.789 0.961 -0.477 c +0.673 -0.334 0.292 -0.134 0 0 c +f +Q +0.122 0.361 0.239 scn +q 1 0 0 1 191.2632 323.0293 cm +0 0 m +-3.078 0.794 -4.478 1.111 -8.263 0.96 c +-8.263 1.243 l +-4.866 1.243 -1.61 0.638 1.402 -0.47 c +0.981 -0.329 0.425 -0.126 0 0 c +f +Q +0.118 0.349 0.231 scn +q 1 0 0 1 187.231 323.9521 cm +0 0 m +-2.557 0.263 -2.657 0.273 -4.231 0.228 c +-4.231 0.32 l +-2.431 0.32 -0.671 0.15 1.035 -0.174 c +0.724 -0.122 0.312 -0.042 0 0 c +f +Q +0.114 0.337 0.224 scn +q 1 0 0 1 183 324.269 cm +0 0 m +0.335 0.003 0.669 -0.002 1.001 -0.014 c +0.701 -0.01 0.211 -0.214 0 0 c +f +Q + endstream endobj 1370 0 obj <> endobj 1308 0 obj <> endobj 1309 0 obj <> endobj 1310 0 obj <> endobj 1311 0 obj <> endobj 1312 0 obj <> endobj 1313 0 obj <> endobj 1381 0 obj [/View/Design] endobj 1382 0 obj <>>> endobj 1379 0 obj [/View/Design] endobj 1380 0 obj <>>> endobj 1377 0 obj [/View/Design] endobj 1378 0 obj <>>> endobj 1375 0 obj [/View/Design] endobj 1376 0 obj <>>> endobj 1373 0 obj [/View/Design] endobj 1374 0 obj <>>> endobj 1371 0 obj [/View/Design] endobj 1372 0 obj <>>> endobj 1307 0 obj <> endobj 1383 0 obj <> endobj 1384 0 obj <>stream +H|SmPW%F*Me4#"b(8 +6c3~u &jђv !:T,~h2U+hԢ2ѱTn|i7Oϙ{{}oñ YiyKs9Ne4,ۤU^5DW`>L̨u ( 1F,@ܞx{ AP,-F+Mp 6V +a߱G[] qK,#9~i>BH- 8\ +=Uxs2<B $"H!dj>m5+ +T)U'7gd ӄ9aH>e ԋ;>9wh+SsB_oQ0v[i endstream endobj 1316 0 obj <> endobj 1385 0 obj <> endobj 1386 0 obj <>stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 13.0 %%AI8_CreatorVersion: 15.0.0 %%For: (donna) () %%Title: (type_tags.ai) %%CreationDate: 4/4/11 7:44 PM %%Canvassize: 16383 %%BoundingBox: -227 -63 143 234 %%HiResBoundingBox: -226.5 -62.001 142.5898 233.748 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 9.0 %AI12_BuildNumber: 399 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_TemplateBox: 40.5 29.5 40.5 29.5 %AI3_TileBox: -239.5552 -349.6377 319.4453 433.3623 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 6 %AI9_OpenToView: -239.25 83.5 4 1355 732 18 0 0 43 154 0 0 1 1 1 0 1 %AI5_OpenViewLayers: 777777 %%PageOrigin:-399 227 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 1387 0 obj <>stream +%%BoundingBox: -227 -63 143 234 %%HiResBoundingBox: -226.5 -62.001 142.5898 233.748 %AI7_Thumbnail: 128 104 8 %%BeginData: 7336 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD0AFFA8282F53FD7CFF06A8FF5359FD7AFFA92EA8FF537EFD7BFF %53282E28A8FD27FF2E2828A8FD51FF847EAFFD27FF5953AFA928FD7BFF59 %2EFFA82FA8FD7AFF847E7E2E59FD7CFFA87D7DFDFCFFFDFCFFFD31FFA9FF %FFFFA9FFFFFFA9FD76FFA9FFA9AFA9FFA9AFA9FFA9AFA9FD1AFFA87E537E %A8FD2BFFA8A9A8AFA8FD23FFA9A9A8A9A8A9A8A9A8A9A8A9A8AFFD17FFA9 %7E282F282F282F2F7EA8FD26FFA8532F282F282F53A8FD22FFA9AFA9AFA9 %AFA9AFA9AFA9AFA9FD16FF7E2E0128062F292F072F062F7EFD23FFA85906 %06062F282F0629062F84FD1FFFA8A9A8A9A8A9A8A9A8A9A8A984FD16FF84 %28062F282F292F29302F30292FA8FD21FFA8530629282F2F2F29302F2F29 %2F84FD1FFFA9AFA9FFA9AFA9FFA9AFA9AFA9FD09FFA8A87DFF7DFFA8FD04 %FFA8280529282907532F53292F292F072FA8FD1FFFA92E00280629062F29 %2F292F292F072FA8FD1DFFA8A9A8A9A8A9A8A9A8A9A8A9A8FD04FFA87DFF %7DFFA852275227277D27A8FFFFFF530628062F5AA9FD04FF7E302F300753 %FD1FFF7E05282FA984A82F7EA8A9845A2F302953FD1EFFA8AFA9AFA9AFA9 %AFA9AFA9A9A9FFFFFF52FF5227527D7D52527D527DF8A8FFFFA800280628 %7DFD07FF7E2F292F06A8FD1DFFA905280653FFFFFFA9FD05FF7E292F0684 %FD1CFFA8A9A8A9A8A9A8A9A8A9A8A9A8AFFFFFA8527D7D27A8FD05527DFF %7DA8FFFF5328282959FD04FFA9FD04FF7E302F2F59FD1DFF7D28282853FD %0AFF5A292F53FD1DFFA9FFA9AFA9FFA9AFA9FFA9AFA9FD09FFA8FFA8FD06 %FFA82E002806A9FFFFFF7E067EFD04FF292F292FA8FD1CFF5300280653FD %04FF595AA9FFFFFF7E2F292FA8FD1BFFA9A9A8A9A8A9A8A9A8A9A8A9A8AF %FD13FF2828062FFD04FF2F2F29FD04FF542F2F28FD1DFF2E28062953FFFF %FFA82F067EFFFFFFA92F2F28FD1DFFA9AFA9AFA9AFA9AFA9AFA9AFA9FD12 %FFA828052828FFFFFFA82F072FA8FFFFFF2F2F2829A8FD1BFF8428052806 %59FFFFFF8406292FFFFFFF842F2929A8FD1BFFA8A9A8A9A8A9A8A9A8A9A8 %A984FD14FF2828062FFD04FF2F292FFD04FF54292F28FD1DFF5328062953 %FFFFFFA82F075AFFFFFFAF292F28FD1DFFA9FFA9FFA9FFA9FFA9FFA9FD15 %FF53002806A8FFFFFFA82984FFFFFFA8062F0653A8FD1CFF7D00280659FD %04FF532FA8FFFFFF7E29062FA8FD1BFFFD04532E5353532E535353287EFD %13FF7D2828282FFD09FF532F28297DFD1DFF7E28062853FD0AFF53062953 %FD1CFF5300280006002800060028000053FD13FFA92828050653FD07FF53 %29282828FD1FFF28280053FD09FF7E062806A8FD1CFF2E05002800060028 %000600280053FD14FFA8052806282E7E84AFA87E292F282F06A8FD1FFFA8 %062853FFFFFFA8A9FFFFA87E282F067DFD1DFF5300280628052806280528 %060653FD15FF7D0028052806280628062806280059FD21FF7D0053FFFFFF %7E062F28280628012EA8FD1DFF2E05002800060028000600280053FD04FF %A8FFFFFFA8FFFFA8A8FFA8FD07FF7E06280528282806282828057EFD23FF %5952FFFFFF7E28062828280053A8FD1EFF53002805280628052806280506 %53FFFFFF7D52FF7D52A852A852A8527DFF7D7DFD04FFA9A8282800060006 %002828A8FD24FFA8A8A9FFFF8400060006287DA8FD1FFF28060006002800 %06002800060059FFFFFFA852A8277DFF7D527DA8527D7D27A8FD07FFA87E %597D537EA8FD2BFFA8282E7D7DFD22FF5300280528062805280628050653 %FFFFFFA87DA852527D52FF527DA852527D27FD3AFFA8FD25FF2E06000600 %280006002800060059FD04FF7DFFFFA8527D7D7DA87D7DFF7DA8FD60FF53 %00280628052806280528060653FD72FF2E05002800060028000600280053 %FD72FF5300280628052806280528060653FD72FF28000006000500060005 %00060053FD72FF7E2E532E5352532E5352532E537DFDFCFFFDFCFFFDFCFF %FDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFD9AFFCACAA8CACACA %A8CACACAA8CAA8FD74FFFD0DCAFD18FFA8A859595883A8FD53FFCACAA8CA %CACAA8CACACAA8CACACAFD17FF7D2E0B2E0B2E0B3434A8FD52FFFD0DCAFD %15FFA82D0B052E0B340B340B340B59A8FD29FFA8845959535959A8FD1EFF %A8CAA8CAA8CAA8CAA8CAA8CAA1FD05FFA8FFA8FD0DFFAE2D2D2D342E3434 %34123434340B59FD28FF7D2F0C2F2F352F352F5AA8FD1DFFCACACACBCACA %CACBFD05CAFFFFFFFD047DFD0DFF2D0B0B2E0B0C0BFD07340B59FD25FFA9 %2E2E0C2F0C352F352F352F357DFD1BFFA8CACACAA8CACACAA8CACACAA8FD %04FFFD04527D7D7D275252A85252A8FFFF590B0B2E0B345FAFFD04FFFD04 %340BA8FD24FF2E2E2E35358484FF5A36355A35357EFD1BFFFD0DCAFFFFFF %52A8522752FF525227A8A82752FFFFA82D052D0B2E84FD06FF340B34120C %2EFD23FF522E2E2F0CA9FFFFFF5A2F3635362F3584FD19FFCACAA8CAA8CA %A8CAA8CAA8CAA8CAFFFFFFA8A8FFA8A87DFF7DA852A87D7DFFFF84052E0B %2E83FD05FFAFAFFD04340C34AEFD21FF842E2E2F2F5AA9FFFFFF5A5A355A %365A2F5AFD1AFFCACBCACACACBCACACACBCACACAFD12FF5805052D2DFD04 %FF830B342E340C3434340BA8FD21FF59052E2E35A8FD06FF5A2F5A35352E %A8FD18FFCACAA8CACACAA8CACACAA8CACACAFD12FF7D052D0B59FFFFFFAF %0C340BFD073459FD21FF2E2E2E3535FD07FF5A35355A353559FD19FFFD0D %CAFD12FF5205050B34FFFFFF84340B340B340B340B340B59FD20FFA82E06 %2E0C3584FD04FFAF845A2F352F360D59FD18FFCAFFCACACAFFCACACAFFCA %CACAFD13FF7D052D0B59FD04FF34340BFD05342E2E83FD20FFA9282E2E35 %2F35A8FFFFFF5935355A355A353559FD18FFA176A176A176A176A176A176 %9AA1FD12FF7D2D050B0BFD05FF595F59340C340B2E0BAFFD20FF842E062E %2E352FA9FFFFFF5A2F352F352F352E59FD18FF4BFD042044202020442020 %2076FD13FF2D2D0B0B59FD07FF2E342E340B59FD22FF062E2E2F2F36A8FF %FFFF59352F5A35362F2F59FD18FF76204B444B204B444B204B444476FD13 %FF7D042D050B59FD06FF340B2E0B0B7DFD21FFA82E052E0C2F2EAFFFFFFF %5A0D352F352F2F0684FD18FF4B44204B2044204B2044204B2076FD13FFAF %58052D052D2E8484A884832E342D0B58FD23FF7DFD042E35A8FFFFFFAFAF %35352F352E59AFFD18FF76204B444B444B444B444B444476FD07FFA8FD0C %FF842E042D052D050B050B052D050B2EFD24FFAF282E062E0684FD05FF59 %0C352E2E59FD19FF4B44204B2044204B2044204B2076FFFFFF7D7DFF52A8 %7D52FF7D52A852FF527DFFFFFFA858050B052D0B2D052E050B52FD26FFA8 %05FD042EAFFD04FF592F2E2E53FD1AFF76204B204B444B204B444B204476 %FFFFFF52A87D52A8FF52A8277DA87DA85252FD04FFA87D2D0B0405040505 %2E7DFD28FF7D052E062E06597D84592F060C2EA9FD1AFF4B442044204B20 %44204B20442076FFFFFFA8275252527D52A85227FF52A85227FD07FF847D %597D59AFFD2BFFA82E2E062E062E062E062E59FD1CFF76204B444B444B44 %4B444B444476FFFFFF7DA8FF7DA8FF7DFFFFA8FFA8FFFFA8FD3AFF592E05 %2E062E065984FD1DFF4B442044204B2044204B20442076FD4FFFA8A8A8FD %20FF76204B444B204B444B204B444476FD72FF4B44204B2044204B204420 %4B2076FD72FF76204B444B204B444B204B444476FD72FF5244204B444B20 %4B444B204B2076FDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFD2FFFA82E0BA8FD %7BFFA82D58830BA8FD2EFFAFFD4CFF2DFF830B59FD2CFFAF353584FD4BFF %2E2E5905A8FD2CFF067E840D84FD4AFFA87D59A8FD2DFF2FA8AF0C84FD7B %FF0C59840C84FD7BFFAF3559A8FD7EFFAFFD42FFFF %%EndData endstream endobj 1388 0 obj <>stream +%AI12_CompressedDataxu?dF-QqژUYQڊ@u#…;~< lJ#H6̈ e/~r鷏?^ B^͛O>E?Տ/J}U}/O~zQ>y/kӻw?я_.o{Օo>֧|˟~Q,Ouӧw^zq.~Ne.i׿zpR_6R_:Xc^l^׹}z㻏|Ç7O?.~u}>yOo^CZҟWuOoާW«-_޿~XwۇëO߼OoXtxR?o>ԏU?[o_m]Ǐk~__oTG_iǶ_?MePwx:Յ2^dmS9^2]uN8:m>?o=׾z }./X/cy1nlӛyZ*?z(~x:.|cu{w~I[>ɮY.i(Ete݊$وlmo/k/_Oj^l_jݷ~{?F67?O`x/޽{uVzCաk{.?}st\㧧<^~xQWӗ7/_~姏_ob{Ƀnu|/klK6k.mǴc6^:untd}>>k|~~j/=]~׾z|||Y减ȷRo?ye]ûW}S{=4^]|}Ƿ>C݋wO_=~uyuwo>~ݧ"˷޿nGۇ/?/x?|VYGo +W8~Rۧzckٞ~|<|θ]>y~Ƿ事u4ljm׿-$vZݧOIHϭ- |M}W2@qۇQ_wO>!rJC.F]|;5??gً~a/E+~7{T=I_#>|/r__R;>]ӻzzS?\|~},]ӗPO 1}{IN?Y3ٿ|+U66F0/kcleWMm}UHG}Ah xΗƩE +޼zW7^}zY1nn~?.뇋S9J9.ʱ]>|SWg~y-c}$#| S>Ưb?-/_?=O}.y/uwxg;; ߩvR_PsC=kD3;sR𶍧䗂oC~doT޿Q>o$ w<6?^_ElpLfO~].ߥZ_O?ݣɖ\>}~U#4؟24R pp= }J)c\zk/G*>n8ek726U}\x? SMyZ" jnnyf:D|vrZeZb׼zYnuX::뺭zWzޮwz [mm֚u۱]mקf~=ƽ~}ޗ}k~W~wq/{(xL\Q؎ҚWq}m}qUwUEGW\ҕu}'Ս?nq{y\(;Z_ZoJJڣUp={{[skޕݵw]rtr9E7;a)7gUw]ou x;3^{{ɻ޻=u?{St}=.Pz5Ӿ/Sw񾔞}iQ9דvs yr(ӫ֯g=}[ۓvtˁm{1L?A.}}Jݺ[;ܻx;?q%=xLi<ڈ1sbX~aƢD|a#OutIVNuzfKFWcj騃Aաr21j^w[Vڹ{=o+et\oӯo/oo+:|J~r?]WVumu /w*)p{{w{{{s{]~Hnvn +^3L7c=w׷73]OϷO9:^POw Lrԯ/ԯ6/X:`_~ C=."+S{=ֺz\vWz]cd纳ǺˇJ㻺oj'\ծkyN/޺}v]{^\j_NG2uV\׾>joߗʜ e +SeU%{+k3s9c0ױt[Gu=:J_חpQ{uڇta=q(yoQ{ћ?刴ެ}9_՗kr"Ee( K8՗iSV<\5i˘dLdLsdLr#?"';Nwr›G$&="C#kϜ;\(gC9Jt&ڕ?C_Lnk!M:7O/>잺|&W!|Շ IIgQOW#b]S?2nq{\㱝?NCwBhQ͒$^`?>WA#QH$q98BcXcuWhnNΙr48glXg(:Nou.ڝth#Nڃ>UTώFݩ "g9ffL.9F8ךzޑ3{C\($I(ROEr2ӑtI9v$g'9?JQ{9[%=m]kvyKN_$ء8liJRou8>]顬u9oǨ| +aý,wXr򧽋6-ҭZ[<45C%8r\kqe@Kv,ݱǒQKzh@b鏄%'ς,Lr)E)Zwrӽx\Ic^,OV" o:{cR= O׵U[!H9V:!v +XN$S$RGPK$Ow^{V;}k+})}g䵾~GYj߿w\+սcyT X&e2E]KZb5ͯwWn9Q;_=n4~~cst?=J&Ơ?ucϏPΟy~O?}~DBʩĹSK\l4;KqaNmƘ^=ŅY;fu$ +U4;ɹH.&'fZ$3fT3?kG,n-l2pg]E|mk1g+S<?)ek*jRVyzZ>ʼVt-n}H߫(5y}1M)o޽{xk}vwɟ={}(q}|[[bgS7W_EDL%SDУ+*UIqݜP9aK|q-G4Ae6'=JW?B혴iSz6jg|^St[@m Q.tgk^<6KS +feF?$ՎT9XfϞƳCmЍOüI:7`yb`.vXe]]kO!Uz G?:~[&v4"qBi"Iɞf|~A=d#Ͻ9g&湉mv;9I%)D?z)M56pffqN~ڼh6'E) tLb*u$,AԷbMʋYd!K }š=mS:/m/8k(}0:u[.ӴR)Y4ygiCnUi0.nl)bM6QMw4ʢE~Qk3ֶw[/3O*jiOVc=Vkfd55귐 > z~V@ ү3.Eu=0KN+O}]S }f}\tMEp]C ]ߦ~I^S9RöatȌ2i}Kq9A!0ױoE[UXz~kv%uUcϾ.C ).1F$ڞC˺u\, 4HWC͉;ɲ> rzt.IWH'4I{Zz-rXA:yɸ4i{H[j۰ғNsIdԓN<4N+t=:tuYn#]mHAv[ +-C#]mѓ.[qk[VLh_t]Nߏtu٤wtKOl? ݲtJO:Ytږvv/Q'WcNУN9 A4G,+SCfkڣNM u^Ɔ:zP';r?KC}QWҡSp u)5@ңNVj ufAekޣN uzL uʢC8괽7I{?&&ttE˺]:it˦uu=PWۣE.)@:i I{ݏt +rڶtQr.({iQrq," 7ۦ#{kރqJW-SQOTY: WUW5;eGMq^wj{楃\]xm7@q\;eS!WܾfA.ǽQz;ɲ裔v|L9YVä,?UoRNӴueōJ 4WxPNr 7R:2 =r6v)de('{GeW@=$,lӁ'acy I{Z瀜 e:rb[v9:ifbhZ3VFh 7WYW}EJ\}e]*휸y*rZ]*ϟ'%JN\u}⪋R*휸j,qe9qvN\哝's;-%,q>q.qջGk]yxe]:}Zqqw̉Tĵ%2slIW]W=nR,WaMN\Wi.qg,ʉs*uU9qĵ.WiU89y6'W]WiU8&%q.qg,ˉs:WYWq]N\}ʲmy[U9quUU&%GWٓ9q͉kUFRJ\ǹO\u%:8S*휸ʀ>O\ǩO\ HW]WLK\C}⪰JS*%eyʲ+R*ĵ.WiĵWYWyO\'zUg.Ks>qE9qvJ\uu:풷- p vI\C.E:7I\#PIt$q@ݦi +m..q$o5l)6[K&lTH6'B:itMA:9G;tF ݦy5om5o;IHIK:lA].xtu&%P'ð;$q@ݡP7<\.s.s32k̵ 32tk)]*UU)s-y*rZ]*Uəkچ<\K3W}M\}겔J;g<\eGUS:;'I~5:*y.h9tZ.? ݮk6ZȦ5mtUs +䨙횵tf-5ktf3PI7h:" qжmA2aAR׽它{v䮃a sWߺK_oNL&/m2y_/~㋿/'&M?e}Gab[c3Y blqslEދ6벧5ל$C}Cp=%-ׯG˴)_-n%}`V^^,TR`_nlu,_Md_ҮU/)xL_ieU4{}Ob ELwNҔaӂmsۊ*mwʰ5Nj-Զe4% +֞d~b߭^\L|r`[v&2B#>NÂY -`[on2`[bLKM,ؖ,-el˂ml#g#vhXp[N^iZ],hc m*m9ȤGi6gU ݮX-+.lvilBK" ˧maYm Ѷeh[Nj-6oZmsB$ѶsѶ,S:ۨcm[p[q" 91pٻh[jmzEh[-h.=vmדBmYڰp[6Qȣ2(۫;m<Ѷ:kDm˲(V#vDܦ}X*Ѷ`hp[I(HMmiױGE_MFYQQ<=FqbG:%0*6u+rާQfQ9쏹TT6ʲak,}cRѾ7 +KT0-LeciebLk0W0{9}kS=`*I4c{p}waQå@w^A¦@`CkToR=z pؑT@F\:}R,p@c6NdMFUTjkkQ}u =,Q]%EշYj北ƥ)kPTu0η1O1t0*n^zRh(ZDJL=Dwm *m?Q ܁1wa`@8+ǩ#,ӫJ8#LƸĘ6-_^o*T[;&fgś{㛶ohXoxMz](M} +6e I~t"&_pJMwp (Dķ]=&kDՑh{PѶ|eN&j@e#&7cFnpn$ ږI>nuQ=lA7xS{&d4tӶJ7QG;udZJMi:oҖL֙z6oߙoޖXSm۲&园sd5GM]aƼ^7McMFȱD.sz/t#o:QM,kNDi9:_XpHNۆ .3Qi{ )ƽ#Tp©;LSr[2dN8i +T,kG8Ѻ7M ͩqbBv ɲbBNn)xn퀜HΞ +9k} +^wʩȽTP)P.0'驘}65Ή;Y@VVkN:ut- ҩʻDv)ցN|otbA'2%Ή[pNd}XsN)D58'apN*Dm1@7$^qͤF:- Љ= KN4TtlT6tje[)'@:}5 +:m{Eӷ ؑNJ:i#ŰaNG޴u9NUm:Љ}cNr,:=&, 2ˑtڶ*EؑN[ -HT~F:9nsV'SAӂ ,+krB:>['[V=n}*lUk ttUkn9r[Nګ+A:0>TS.HvHC:1aOWՠeJ:n%@gZF{[:0#a#N.: t2bsUtC#>Nft.-]{5fzkWm*x3Nk+-aVDHWCKXgLSi.KO:Oǖ6 ]}ʪm)N^cɢ6sKYUn9Ww6U;yd KX9wSشlYƌ4ҧ2'+(,GY'W2tU t^nUCY/rI'n!sŲtǜ^{^ǜ\PۗؗԂtÜ0'W0'E s9iǜl׮V.r2?n]{ ^}rzWӭQnSN=rź2(WG`F9).rrymp9x% RNTkPn#Rʉ' ǜޓUNx^;s[`n>ɜ!yN8W:[8snN9望HA&*,ι49NuppNT眸*sҞ*3| 6sҶӷn/ͱƒ)R*}.A9ُ$vgQ H10o <+r6O9 +Y,_nv0'`ٷ9i[0W\ @9_98o+ u^š97ä9iknSx"5Y%گ^F:QeX2WSŧKv[]tj[6@'˔:5Χv)W>Z.@'߸6:@'r| +ky Љ+2D,Uҍ3zn2;҉7Љ|-q{K~9GA'7DGloCtb{s\)@'2'ݨmc_eK9լs"n%>)0'W dZZpI{XUڲ Kqt޺U-q1t}*;r>ZiRYDNF6uTt}*s_ As2[ )8`[ުm#tpN9muŜ,}>'?+x\YacNښw5#TԉYE礁:9&זn2svn` +fҮA; :xF +{Z޺ɴ[:eem9cťsS'Gf +ɼyl";-o:=>;6 NKC8/BxVanI=u5=Oƺ] 3Nj|V05f֩>Vm%:ٽaY'55tfq:yk˂ u]ުr>Ozu;r[*9>'?8m=H%(脯[iJd[:^'FS]ϛϚ r)VQ Y]pT@\WE@'(<tu!SzM]pl?s.|A Ȟr%$Nu%& rL q2aVޅ B eװA2A^ `/t̽6$tȇtG_A}MI 88$y yl!@!dօrY˺B*B*SYAdA(١:%;=Z&ҕ5T*v/bBHT\*v.DŎmPs#+ى<ٹkv.D΅ٹ\Tօ\<B"s#$<7B20B~!@B2B* n>H`6B `H!aB`X!gNe(BY)ycĵ=.<'Ȗ-攫S"ϖu Dڇ NiJ*,5GfEeZLx[C;a9?*lsmeZʶL]V"?߷ƧRD&^M{ &gZ%lS7}JdRվaȤm +g*6Ym'FǨgGEҥgJ29_"b? cL!iKHRUpDCV"vsruÚimhVJ D^ZQڝevŀ ։θ۝gON-։y DvcDuZ'ڝu(]79'{s>%j4s,;"mcs;d's"hw;΁21Z':ilwJBr$ +u:yH|-\;I9Y>T;eKlo։Lt18g]Z'.{sY۽:ѹ?։LPՊu7ԟVsD(o`~eiocsl nQN.tu$0I`ԥQwNG98 05$XIf+'RWNt,u$XIԕL]9 sԝ;'$aqM1N2M1N׼8''bdbR7N /jdb@RWN''bdR7N''`4mKQ0qF1N2F1N( u$S@QQ(I`ԍfE8 iFQ3NnD8 I@ԕ)'nC8 qr?d-n8N I& 3!$oMI‰ onMI xC7od@t඘oٶoM@IB⺉mq-nd-Ku6m趸m鶸mݖAݖ5n`Ihvk6t[6n&7M2ݰM t6tn& $ mpx|C6o& $mmްM2M |[\7|[\7q-nm̷mmM2M [6Ʉ[6p&nq$nYnq->p&p&N8dl lM`Ib 5r&r&9\ k(jPMI P$c̡9\ :\HkpM\5qa:L :Ln:7M20M 4ɜ4s&p$С80M24t&$Ka:L :L@١I 4t&t&ada@:THjIj4t&t&M@iAi0MI C5t&t&a$IhM2M  C4I3tx&$IgLL  C3ɤC3th&$ҡ@:eE2 ҹe+-[ ҹes$HI9Ls9494 2ɜ2sX&$a:, :,@f\3I2sX&p28 3$0I9Ls.\2ɘs$0I`s.9wLsd̹b3$(IG9WLr\1(IP\ 1/B21 ̙c) `J9 L9 (a0L20L 0ɜ0s&p$sΡ80L20L 0ɜs&p$sΥml[9L 0ɔ0r&P$sιbsŤÜ+&`ނ97L:̹as$0I97Lsn00I`Das$s &q9 9  C0ɠC0t&$: :~ /IsΡ: :@^K2Kz /ɠ/t%$I]K2.t%$a: :@]K2Kz$8].ɘ s%`$c̥mln k":@]A]KvIv C/t%t%N:KvIv sada98]9v C/s% s%`ac$c1\L.ɐC.r%@8[pK2\.qᖀ8ܒ8ZPK2PK`j C-ɌC-q%0$38ܒ8g% $#a8̒8Y0K2,q% $#ġ80K20K`f ,ɐ +r%@$CȥmlnX!X0KfIf ,r%r%@ȡdȕV"a@9̒L9(Y0K20Kf ,ɘ,s%p$qa9̒sada8KbI&b C,t% ux%dԹX+ux% uh%ԡdԡ:PVQVJ@^IF^ +ux% uh%:J@VIFV * ԹUҡέ@ИsC[%:JuCPs$XZ sc[%:Junts#$XVIέun66?ٌ@Y%AҒ [%A:Jtntsҡ@:L:JtX%$a: :@UJ2JZ C+Isa9s΅UAV.PRIf]H%.hRI]8%.NI&^H%μpJ^8%z(%P/JI^(%/ȇRJ SSq;%SI"]%NJt!$҅P IFI"J C)t(%t(%IQIQ0J FI&F sadС@: ;%醈B +:wJ2\) d#)%\) йRs$΍%:WJ:йRs$HJIG:At\)HRPJ NI&N )t%,G|SJ J 3$sΡ8B)I 9Ns.ĹpJs8B)I AJIf$ЅR AR8Ns.\8%=0JJ%99> 'ɘC(s%`$ca99WJs\)(JIPΕ(FIG97JrnJM&B/( ̙QQΕ&)ɔ)r8%`$a̡998RPJ0JF C)ɜC)s(%p$sΡ9̹PJs8pJpJr8)i )JS.ĹPJs(%`$c[0S1SC)s(%s(%`̡d̡90R9SpJ\yQ8Bs.]% t!'qЅO@B.]% t!8(qЅQ@J C)t(%t(%AQAQ0JFIF (t%t(%dҹSpJNIJ C)t(%t(%С$a:@RAJ C)sd̡90R1Jc.\8%s8)qЅS@J.](% t8B)q҅RHJANI]8%:\(%s8B)q΅R8R 1JI\8%pJst a.\%9JB(1ȅO'I B3.8G\%0JPJ`J C)ɌC)q(%88Q0J20J`F (ɌC)q88SpJPJ`J C)Ɍsġ88QPJ2PJ`J C)ɐCr(%@$C.\(%pJ)qȅS A.\(%PJB)qȅR $APȅS $Q.\(%PJB)q̅R $a.\(%ιPJ)q΅S \%s!8(1΅PHB.|']$ u!8B(qԅPPP QFIBJ C)u(%u(%QQQQ0J@FIFF (u%u(%ΝPSQSpJudԹRʆ:WJ:ԹRs$X7 CFI΍`+%\) ֹRsc :WJutC)u(%Ν:PN +-_9ڗ٧RPJ2PJt8B)IC)qЅS $.](%PJB)qЅR $.](%PJpJs8)8׌&8QbkBIb]J v'q5$ %λ&8Pׄg^3Jz(IC)zPJ2B)|80J2(}a0J20J"s$<7J8ϕ4s )d֜e)ɹ)%ʺR+%]*kJIdDΕ\s$JvnDΕdJI,+%]uعR;WJJ ;*v8%dSBNI١PC)fRkv(%(%Dy(%9C)!)!)I ה_SJR ה8C)q6$!9%8SN6J.QVJdYPJ/S qJ/9%R?5 {.ӛDId08#ipHk]sN\X9AѮyS2UpJF:攌 NTǵI%^UL*8TRǶ)8攔A2N`T8%'+qJNDn d쾊˴)li8%LHA*d~֤9斥I%Tw +D5ksJj[0 Nڏ&;{TRlncR\.kJg!6ӄuT*!H=HL*/(_GL >RImkhϱ9%2xXEFO["R2ODRT"R^)M;%zfY29pJd ~uJcxklzo5i JnSR^^ۗJۄdRƣc60iJtS";@|xe_G}߷D^ жRUҡԵ@k%RJ:W(u$PbIRK.K],,u$j^IԽx%dSXXPKx%x%d)pc5jx%NJQ+qW8 $4i%KNC,18M+I4 iX0 $4i%KLC,q"8KKJK@iڂ%%RPWQXJK@%%NRHWQWJJt(5$HbIŒ&H], Xҁ@^IԼG+ WrQ̒L9(ZpK2pK%0$3\KpK@n s$#.G\%pK-qą[C.I \b-I|-q[2ČsK-q[x $-[%NpKB.q…\ $.#\%8ܒDKp!8KB.q…\R}G;}B.q…\ $1ƥm(K2Kq%0$3\K2Kq%0$38ܒ8 \K2Kr C.ɔC.qʹ[pK2pKn -9vIz C/r%r%P!d!:@`@_K~I&]%cĴ%c%t8/q҅`P.c]% v8/qڅ_h_ a~I]%Kї%u!8B0qօ`X.g]% v!8B0q؅`h` _Z- ؅` aI K۰p$a_K2L C0ɴC0q@;L;h_K2K &$!; ;~ /ɴ/v%v&v(&d@;$hdidLI 1v8&vᘌ11&ch.]H&v!8B21څchd$؅c d@;wLI wW3!8pLI C2vH&vH&ɤ v2kC2vH&$%]IG;L;&AyKK&A;Lv*tsֹcpL2pL` 1ɬ1uH&$!;$ ;$ s$:gsˤck&BnsϤC{&:Mu.ts$PIE:Luz:<P 3ɤ3tx&$!8L2L ҇u@1( $.^*H?9mf8'ޚױ[W+b('~UNd4#Zg76"*Ș[9Ei~8Q7ZA:b?596n8crn2'R-Q湘4U>T9U='}bԶ?嬛U1NՎ61 DJ3aHmZo ImXw-6D^# DfR $8LR1I ԍ@'B8 qu$3ԅ` 'PN:qHM8 pqԅ 'QN:pu$@IRN.H8@Iԍ@q2d@RuM(I( 5&&`e(l)lE]6qdQ\ k (D]5dд&& bdbPLI&( E5&&PL@&B4 iuӤ#&P7Mntu$Z:TO7Mn?49'I t4n&n&L؆i hC4m&m&6DIF hC4m&m& hɆh\4lndi0MK&5ccpL I& d1l8&l8& dɆdِLmd@6ȆcȆPL@If lK۰`ن`0L`If& ada6؆bنbl0m&m& ada@7 aa\1n(&n& a $ a@7 L7 a0LL C0ɀ0q!8L8`L2L \ ``L`I 0r&c'8pKnIn -rd8[[K`rIr C.qdʹ[pKnIZC-rwﶻI=̠2; m٠@Z!C` wEoEF}C[2 vW:C Ԓ +9 W"C9P@a9̒ +9(Y0K*0Kj C-C-0KfIf Y0K*0Kf ,,r%PPa@9̒OaTa@9(YR)Y0KfIb C,r%r%b C,C,r%PR!@9ĒJ9(X0K*0Kؖ0K(Q.D)I)yQnfB)9䔼('$)%rᔼ '$!'$!'9I% 9I%@NN rrJrrJrrJ*夃$夔$夔('$)EM(yQNBIRNFIRJRNFIRNFIR΍d$㤔881aTa8 QR!Q0JFIF C)rRJ +0J`F (q2J^Q $'8%8%8%qJqJqJ^Q$$$'$BINBɋpJpJpJ^PPk]Cxrv$F LV@8\KRKpI@.Ie. C&q$q$0D%%q$00 ơ8T8TW$~!N" $p$p$aTa8$8$/I%qv-`& q2Iq2Iq2I^IIIBLDTDT8$8$ɸ}Lʸ.u$@FLu$@$r]&I\HD %Tu$\HD +" I\HR!_.u$r]" \@$2Ir[$@$oDrH\CR)]Z +.3INCR!.!T!9$ABN !qrH +?@ + C!C!qeQF8 A0H*0H r] + RH*QA +.0H`\ARe.u$q= ץgbyr{΃; OaTa8 I p2H +H |C |A"!77@H*H |C |C o$ a7 G7# w w7ܑ7;pG*䎀7CCpeQBő +890G*0Gp#uuDp#p#saTa89R9PG`Haq#q#0sRsa@9̑908G*ds#`qbq!9đ908G*Gs#`saNs8#99#/Im$$$綜X44䌼8'g$9'g$9'grNGrNHrNȋsRFsk* 50 c$)V$)'c$)'c$)'cE9#PeʡTʍeIϑr#@cBca9 +9 2PF +d81ɸ4F*ri4F*ti@4F +Ru)F*Rx)T!@F@^ +#y)FH^ +#`/HHddN;" +ռ'W+pE*Wt_dUȫH^%dd,\\Sw:"uNGI:":"9BCBy I1:"9F'S5F'S$dLLJ֝TWN;"ٺ)R)|iT)0E`_"~i@?T藪H_"0M'+5Evݱ*X;E땝BI[f'b4׵&b:XODOOOzGD07EomOtGDkarQ!Xp"p pOz9AD*(A/'OĆ"" K"\a0,Glg"> +E|(EH6q"v6A٬ۆ4Eo$U{,bW滰E/~㶈ņc"lwXUMFt["oUq]Ğ6H*QboDw|{gS|{ͬу/bܲsdU|6|/E|0 Flˆ Xg%sFE[lؘ˱j/b糔'tvQafc;"ok8%XZ#+ +yTJIJE^ -H%$H%H*[$I*[$I*[ER"EE^4.4.4.ttp*[S"S"S"/I"(#gTSwF)H)0E(#(#T,E,ERF@)HE)(8#(T$4RA4Hs)H) Eh#X#kX#pkk$H@55hX#QY#QY#/II5򢨴b!81g2gD e¡Tp8#gg!@8I#pH#i!T!8NH|3Tn8# g qa7̑ +790G +G|C|;פ qI|Co#NH|o#oh uT¡@܇G*䏀:P?RQH@IE }u($u($ԡa: XARYA0H`Ie C!u($u($b PARQA0H@IE u$u($֡|!u#u#bCu#!::X@H*H`X?RY?G`He?G*H`INɋu[ua$dTI"Im κH^DDDB$D$D,d$d$dX'$Y'$Y':i$:$X'$Y'$Yײr]NI=$@::J:PTJ +pJ@N ))u8%I*uH%uH%BHSRISpJ NI%@SpJ*JR C*NIJ C)((JJ9(Q0J*d9 RR!RxJIJ C)0J*0JF (k2J\Q嚌J&ʵ Ż.Br5y%P+)kJ\V嚴JZ kJ\VR!פ&5 rQэ嚼&)5%`I,kK\CkRK*0ƚOWJYș^\YR1d&5%sMf kw|%sMj8d&,tMf k2K*Hd@&I-tMj kg+0K +K bHWRYW"֡: +;`WJ*;`XRaXKbIb C,J*J^ ++vx%.v%v%$a'NrIn[XvI.yNrINrIn[SI;%I;%I;%/.I.I.yNjHNzINzɋvKvڅ`]&ɺ²u-|uK^_K`~IeXթC0u&u&B~ //u%ᗀ:: &!|.K`]%]%viw)K*.xiK*.zK*K^%/JK@_%bvIe_%/vIvIdd[Ovɫ'$zmؓcj1.m8&٣cR{DVIvh:dVII1y I1ɡ;)&9t'5t'$ԻaNkNHI2ɑ;I&;I&9r>ffcwLrNIecwLrNkNIvhedKOɫ'$[zL'ͤDKeR 2iTeL``Z&L`j& 2;zi&[fbdދgG>3b5Ekw&['!l62R43 U,s|PL GZ&ϑmJ+9y,Hb:Dd쌑LjyH& }ϭao]$Q$+P҄eb/e2 ;~sz>5:sY&nYZ& sY&V2o2~9fsI&[͔CeCdbۨJa=PEoTR4@gRAgHM)I%) $h$hH*$qITɋLLL^4e4e8f©4p*$q*ˤTIT 8E28E2H&ɤdLL*LL) 0202L`)Ie) ,eJL*JL@) (2(L , +R,@ 2 2X&ˤ4-4-ˤp4-hJ&hJ&))R$ +RI&pbT2X&`ˤbDE2Ld E2H&Mˤ0.51.51.=¸L8&"\&p& C4Ia8,'ˤa8, +8,eङToL,B7I& !T!7$dRdܐLI |2oX&og|2pL*߰L eRe߰LI|2pX&pX&n#eR eL I!I!\Z&ALDL +R2R2R2)KDKDKˤ .-1.-1.-¸LqH&B\J&q)q)q)|0.-¸LĸLĸL +3R4R4)KDC4s&9,0eL*L 22sX&pͤD2tX&uH&!TI2uH&ɤ!:I&tX&aTa@:,HeRQeL@Ie,PeL*0D@ 22uk:,:,PeL +222)K$XXIa]J&b]J&b]J&u)uX&B]Z&uiuiuiԥeKDKd{f!u)u)|.-ºLĺLĺL +3R4R4)KDC4u&:,XeL*L` 22uX&ͤD2uX&uH&N C2C2uH&:I&/I2Iօddb,dźL^eeeB,D,D,d$d$dX'C$Y'$Y':Y&ɺ܇X':Y&:Y&ɺ]d 2uaTatH&"]J&t)t)t)ҥd"ҥe"ԥeRPPPIA]Z&L:$ H'L*L ]33t&ѤI4II4Yeee,]X&9Y&/2I2II3yqN eeR9'$9'$AɋsLsL*L C22tX&ˤa@:,J:,HeL*L  2tX&ˤҭ}dT2sX&pˤp.-q.-q.-BLtH&ɤ!:$ +:$@eL*L 22LI% C2t-{/ҥeRHHPIA]z&B]&B]&u)u&$QeL@IE,HeL*L@ C3C3Ձ:,:$PdL*L` C2dL@IE 2uX&uX&aTa:,PeRQ'a@:Y&t"aTaI% 2uX&uiuiuiԥeKDKɤ.%DKɤ.%DKˤ.-.-.-B:,]J&]J&44,.%.%ХeR@@@'Ϥ`.=a.EaѤP.EQ!$d9, eR!eHɃrX&rX&PʡTʡrX&PˤP!@9$J9$('!T!@9$(dR)eLI, eL*L 22rX&PˤbCa9,9,022sX&`ˤ`.-a.-a.-Ls)s)̥d"̥d"ΥdR8ɖNNX&]Z&tititiХeKDKɤ.%.%.%ҥeRHHHIa]z&b]&b]&v)v&$a'a;, +;,`eL*L C3C3LI C2vH&vH&N C2C2vH& ;I&/2ImpYe,,ƔE,,,d$d$dh'C$i'$i'E;Y&I܇h vLva$ZXuX&aTaR2R2)C2R2R2)KDKDKˤ.-.-.-Lu)u)!t)t)|nY&uK3f"-Ϥny&MĻ%-DKhKe22{iL*2}i>4ʾLL_Z&H&֓dm=I&$l%ؓdjI2.mH&٣^=ڰLC+$;L^ڰL?+$ddН,eeCwѽɑ;Y&;"9r'$GdFd]C#wL^CwLrNI2cwX&a0veRLԡE2dR[zH&Lh!d"-D[ILDLDe.$$%K2dW#[&tO/[dE).n#s˪XMLj'_I׻_DId3'Fud_G}bU>R,R?`6"dN>. w=Ja܁}b/'mb'FK.=O./l_=|$|$|婼+OJSIJSyWJWJWʋ2U6l=+LA` +` +` +TSSS0(0Xb\7e,KWI㫼UUIVy]% FX)WIKXIcb+(RE(YE(oVF)ͺ&/QF)(A7 +ce@_)+(+gT@_}YRVRV^ e%+e%+e^)+^9+pV^蕳蕳蕳ziIT;xRy"ޅPV*;`RaZ9vF)(b]F6Ja]F6XGq"ZII[yNJrs%9ʖJrmrm%9C\ys%Q])C]I$$P")bER +HPER,RPN,)vY#E[e;y!T^u+{{ء; +;`W*WD;hRiWJ +W*W +C_J +C_w+w+ +^^x+{⹰rvI)2)B^ILJA^ILuRL`yQ%ĒbyaO˖KRR%’ԓKB%RŒCcIᱼȒz)^K)أ^RDRNDr)zY.E[eB=DQT!=DR0Y&K& d{,{,žDRY"K" d{,{,`a|bba=L=La!T!=DR] ^VL)ˊ)^VLbJ^VLb%Sb˒Cfya%'%F˖.žd6d`/lE=,ogY^-zZd,IiySONˢSS*(((RGGa){TN{ a){rZ^KS'%'%N zrZzZRKR CjzH-zH-N iiz8-PR!@=I-zH-@!|=I-/IjIԒ̓b'%'<9-<9-<9-/IkI,ʬ>ʬ>ʬTQ"QfEJUV_BS=/p/^GS'%'%'=/`!TIz0PRFz/z/PT@=S'!=OS #R蕟 R__/~i?3`4\uV +ΊJa0! Ί(VWa0 `*0/",nʃ~l 9ZR`^-@)0zR=ް`VWʃ`VW )>X ,RG((L(RTK0l[VV3,c|o I +(<(D|a^|a+&[2a^?0 ?00`00EJa@01,LyC´`* ӂiô`˧Mu?n;oo_ǿ>-,G|Mb%l???x?ۏCx~Cҗۯٟ~~84%Xޗ Oȉ3ا\/qG?L?/Yu;-1׈]w>.Q}Z Q`l2{ҷr]֕MzeYVyRk.}E?4}_syG~?'y<8-'ܳNxew <)'I(מ'9jWq>rnsߑ'ٯH\$I*@lݹ<ɧXKO)[.'i_8I'i='7|nEI@-*^Ϸsl=zZng9l/j ,v,;m?yy>msmؕhɟ2]6qHx=-biv`"/}ܑ-O\:s ԞsOUY^}߭Ƕ +v1w0ٞ9iRA[vCoMO.E/aIskYy\3olf9āqͺ%lukxX։Y79Ys56{lQ-Ekf3&ݫrl,߹f67c>rͺ 3Y>E{r.e +k.=fy*N܃;4%^q9K[}h,vc4GtCFec~DZYyv\ +Sj{hQ\>uN6 髱١\~~ޤ2+g:/Fڟ>\hg='70 +!qbS53)QprqsѾ}ꍋ\ vWE{Gh-/X|]]h)_4r,wGFgJo3;Ȟet;f_{uDF$XĨSfM_6I YݦoY6`\䲬b^/c9>G2u1VGƹ]1O6pU]o}$c.uKjy>.?+%OgfesF]#/bYafu%rݼ=cVtݬ=s/7g ?lޞfY{fze~qت X41[4ϋfv->\6+ O𡥮ek +Kƒ>te_ZHby >ͺll!=yɗM^׭u6eEYiڿ~i?zz|t~)=_?Ͽ~cy_짣?M/U:vKԷQ_psٞ ^;p~x>i_,cgx}yN7W^7Gc=X8Lߟf9%R|{t6d`_ +!3?7G^GavztDІbv=_p/o#0+ÍϱmNDZ eAܵnCu_ڡ?Mh?2|C^ܯf"uc|u +Ypӵth^W{ՕԶ=얣]H^WyX+l>+4|;^~}^)1밙?4/UGpYBȆ;tVc8sjh{O" E?߹(l*v- H{ ﻻqU콷X4yv9,h+=`D#fMiaḠ ZZw5"lçOs'iMnom6lA9fj^<ǥc[E0JD]qځxpMFГYvWޚ;t..Cv`[mzm};G#|#rnt[6Bl Bsk}؁M\ZClnܗݸ}:s's6Gl<߼MKFˋzú|NS,h3d/{vc`#> O' h>Y|mxIL녝zM[nt?y7kݷ-rClKv0,x.?jd{OcI?F!$nz5m]ֿ힔Y_m-> ۟So.zzV ;#g)rɧF|${?Y^,-{a1Q;/BmB~{ =[DlͰ`?~oj~]NKW3bOev"u_ƕOq[PracYx1Cݸ=xfnfeQ#0?ױ:fDqCJ-;ĝ[[^jiX#swzI,퓝^[k| *л׳כmAom麆AQh3;/g|Ձomy}_N5xkS]Npւ8þjDyzɶqr}-?vbgԯl?8gϖRpVxOERb_EDs# Mܗk7ӵ["hOa`{^-skbk+v~Pңm^ۥMoHnkܓ /3eh{׷ڏlz&Y_s:cJ5Wr:uYΑ s]un5s +؏̂!]|l lK!m=u'J+鰕79U~U+׉Yo@P3%>, QQ8g+}vmi2z#<['O}7ާ.D숯-r-pc3ig{3]嗚ǙMgl9bk@wrHpgSJ趴Aegtl+Us(>Dnʼeq ^ |L: Z|-nq<5Z K3#}!yMݮCwUr\>=V/[Ղ>_tM,3}lf:]fWfi=-X(~wzhghpP}q\\?!/8hXܹ w6[!˚-$x̜>mcj|k1]PϵN=s1;!>i.qUawX]wx(1Nw[fL n)N4  +yiΨߪK YW~2d?]ݲ=;jfs6W?z_>gӼG-Y5zqXqy3(__f.툊)?]Ӎ۹m`쌥e,'~%>sR{Sx.5]lq4[㲽?<Ղ63nøf_rY`Zm1$ FaR=4^O[3(O(tV>s>l8,h37b(޷ݵШ篟zm+dΰXّ߰O˃jU|ٛ@so~MOx#\KIhqͻVy!(.fV?Kzwy^DźOG .g4}HA~ӌz y"S~L=te$.C./{ZWHlv >ְN?ݺdyžeϣ/pc\̟4z[<-ө%|S/SaڌUC^Rgط9o~l P\>on6Y6'-V=ٛx? R9aۚ$xZ~u^5+,1;xb 8Ϸٌ뷍ta~ޢ6l>i{  /qͪT߽0Gyb3o61kWQW,ȷ۬=hkNXm۞*׏lkmse\+`7[ t"Yl,[֋}i<gyv0c]cC|# ;߽^Sӑ"M#έhbXRwscwXՋ/X +bw?ĩz/懵lj.gW~Wi~>8lRϫ%W<+G :o\/.Vv3~i-N߬gfI~xڞcSæ}v#..d>o=uFߞyVkVേ¶f)oqtYpDo}'PZ[,yv4Anh~|y6vbCqMJ3҂=%_<+f݅{eGy`zMב5?'hq賦V|ju)Ofce6Jvm{}?& ّ'hJgMv73ӵhMeDwiX)vOD84W_/^ir|w|xwjp~MP!/_KӍmkWZuu;gOݰSϣץf_o\1>SԷεV?vP #e?\yx}jO5zsgݷEf>g=j<`+eK嵬*"|fCѵd{n63x][hhyˁ{w]кAw`/h/a_87}_yo'{Y2$󉨍+szFf% <3JN*_ְg`Y{\ڣԛ&m8̈ay%1fkĊфYx'#~]&vdOKm=!㎽T`+Zoѷh[#E^kx{2qvkCK4=lg^gx[O yc"}?Po>6>bw=J绯o{}ֽ]ēScZ/O˗x߱/ztm=et~cO|1{~ݏo|(n7m|Oo}vc巾{ܢvL[&x[?>OC]x.?^9iiC3v(;鑯=\&*= Vr>ϧL_6W`lӟYZg$:R֓5||y\Q)BE=o2mU<-: {".z8fBcԇ=hOR%vmoEq6{շgV#O{v5lLy˓^u9yo{ҟA$+}K0|-}bmM}rƃLP]3$;u>ԥSM\ֆe}o՝n1;|n.o14CG+2G =Aols~Ѥky-H*~9Kz{eNs6N߻b}17WY{": EcgI`;vE"t6޿-ߌvy 1 fI ; OxLSۖZw48WNqYS^ϡ@=w~}٣ܑ +A5mqh-vq +3_S5A_lc8}" ?u<}ʖ-jqca7NYc zV˶yq/{> dApJ.W1egѶ+S:,9YuEGO]-/ځ$xyPύ%5_[Qc^;znmh65ںqGB佶pK9:DfLBj7& lWq^'\#c EGMhrx8K<A-ű?ɢ+$Cdh4VQfb^3x[n6?'lqrWtA?QwX\(B/41x1u%6M)W'}WثFpHZ¼]F=FgxKRMtWVVl!崙mM=|+~ĀK|/o8;r㎏U0Ŭ܂͑2 ? +_z:ߊ+#k[k>޶wR2Z3s +qb` n.GprGoCҊ/u1~~)U<"v &lͶ3Q*'-Qi8ZHXmkDx剰y~xOrDޟ"f?ǝA^2'uO]#zEG> ㈱`˻5]A3oc/m%:Tn%}I?+,!/떓?V[,+V nf9cȚj3L4lGHq4B{eo4&۲6}Zq`={[gÍ#ލC +r]cc[=mbWNu˺ %`6xإڔlt$sOFC)օYW{JtWj9ܭym~Zk9K8}cc<VuO Wz Qu[#]#c+,|y17H3'J|h +D sy ;G"@ >75{w xkV}>]/H~s32~3h O/;oS79}{ISxof Raw}G>ړ1aҍXchz5R Y#hߵ4{5bO7&Vr +%|'S'#_} CV{M3|Ne - +Gpf+x{8׫~zTzCtV{=bi#1j5CUTJWOEn0$X{T "Ͱ4}B%Ƕ1_ ƃ(7lnې+hӾn ݮ;UAv@_j/L4 >)y +mi;#V} s [Dgp :7+lTZ! n7b`>>1+wƫmW<l!4)xMNk@*-뺂LhuCfah엂T}l{zq<+ +o3L+ZæN>IzⶓaDs) [ItFV wF&.v{0d-1Fh\f dp_1е@LL CCdFQѵ^t57o `7붖 %c5v{F-=ܨ=Ƨq #أSe"ނM3D`:u^!^Zj R 3d.il{i&ڏ`ij +SnҝY5|>lêЭ`spe[WW 6ǮW5clz&ĝ|ה5toʶE 1OCncDN]N~}5v7B1}fR@tuLcd҆ PG,BbOon}zx).{6-Ju7c4e_jOp> ̾) XRoxC/϶ָȜ1`{K%eFN}#PLh.SxFW/̓|*˶l}?>;k)Wӗ21-Pۮ\gcxXqLyiOd2qoJhgtnXtgyWԋ +`pqq^GvcW5%8myiyL^g}ps_ C9{,أ +l]fʶk, Aot5j u +KX_Gg%/[?6;esΝZwM_;Hk|ׂ^&r M1Z9`f&{d^xYA_^PO,ܮ;#&Zryrm _t_Wg3]^f"3b9,]0Hz$5M;oٵ/+ @} qmJC\+xklz_fubl2b =A_#>KCñ T >,ɁQ!_; 92cgԐCbY07uwJ}]*zdf~j!A"zq%/A_շ؊Go)A4O.nqwla_K)wlkW6-XZ1_@ Ȋ _Gύ+awI0 kv0shS[8aǜgZ`[<5̶>4Չ ζ7;taXt֖:gdh9}sa38w7/&|=>qP^QWh\^#‚Q6ÃS=9muڄ/d[du\Դ-[-sY,Eϥrgl{$iG}uLjm;Ӷw#I+>PLtq Θ-nt)_QrdOVG {؁v"SC.qi]^fжʳK ?A%2i*G_yNI{c>©xX)om z6k{Z":i>j4-|\!+wwtݛS\$wu# UX#jElh6chs=zMt /AFjpT¬ǽ)#?g7Ɔ|-a7e">Sp㘺4sMziݜ \C>Rq&]k&?{s ߔ +S㕷ic1-VݸA 6ބhO{պ)&5!Y[QSx;A/_A_SVWƉ]G` Qu\F&-5gcJ30a]mI#(m&&rҺL~K昱Ɓ_E)+6Vxb.ctB#͓BynKoi7P(:uQ +*~L<Mc/lg=0N8 6F7EϠD[7[`t]ާ2*W![1%vTEЋƃ} j9L۩ #^'\۰J||.]=}c`Nwۑ#"7')vpdhƲ?#rFO˂Gqw&/8^n8c902v`sEpe$jK~I/{x}V7abc(̔s쎠C/ޝ)3;)_X1ޛ]juJV|±MK|莖ה'XЖnoHwz_W}Q|=bdFA; Ob3rA9K[>5RolN(l8q5ersNU:1;8\~)`oX^:/I-csj{9^94XP,I󊎿-tuY'ɗ`˳Њq`]Jl]msbK/ӰZB2д{ KE{1oN܆kv m2}$TcBv\##ȏj0IW;s8k;X) ;ZQ)t4VjeVV1;[P;{s~Q=kBRl[좹9;"2kf"y~1|'P[lȼYQi &;;sHv0x:TDX;8ki`ueט(QpvUFJ 8Tu9I-*[#rrG `y5NVy3Wwըe)ɔXUsMܝ_.R[+3U +!}c-4Ca逊/]TQ΃Z x1f.Og&6J]fڂ v%N-u+`NClQaʴB&W9HIGUy5ɳlB/N!xWs'Δd@G_KgR{b&ҏe&ֱ:|$/ ^l;t\_]8Քb $DjO˘.dcTzLGYu(N$UJX c-5bpYsߧMz:NVCe}_[|XGJMv; ynR}'O\#[pck% ́⏑Wq闍T)_XkZ`J 4O%'fW1%n^{mcn +bWFÄaMc4 (o?XW!15C1.'{XI$6uZ +5dD*.ł3?Š 'S[ѝ*6^sDV ض'ըϽ~3^Ŵ}ZL Z}e~7+zbkNdzLZ8s]!BZSLBw.3fKFW ]ýuuͱ3S>/<4lzqk2V Js5]c8I]]EK,ݠqJx6Թz +x5w[~U#X~39'˙PVOޛ\Ŵv 'sU\{cVhu'$ޑJ*[(xzQX5)BPzNB1# "v0or +N?;؎|Åssgү +ƸRw7A빦MW=VC[_>d^_`+|68ymK;f%Pr=q~yUg0~t,pkE^'c]ykӞYy*g3MKrGG4v`UygX +ŒO.S[xfdt_j-U1v$ۑ\[ЈjQjk|"q3p'n0aVɏ;۹E -~bTh+ Vy/;i{:x}vex߶cQ ܹTGIxs!,5ipǬ[Xw3D\- =[۱ŀ;uJUbJZ]^Bj!RUw^*U ɲ(1`U; kvзD\)*;컍Ac;;9r%k}iWڢiW`%[Vi^P#w0[-+y֗ڹWuNoAmKxՌea-8aKȒf]bM]՟|m.bmke)-[Zf4{Yu/c,+S:oYmmJ@n+%Y^ʷG5lm+3 >Qfr͂'1[NV"okFΚE2)G>uz1='cpjnJf:&,kH߯[>2wu!7"8cSpf`W}{_)#/#S+ˆG.l}L[.^LL1Ͱ烔3>>Kٷ^n؝ S&,Ƙ1ǿf2c{ܞU Rw+]uf޲? P53Y%!lt UN2ΐ*3̙i[yI/9*=v2UsJa 4|Nb*0hO!4LE^L,ZZ1~h1W _ \;\#w>;?VsRWzD _eߑRƼzR +e%Fy2M%# gWEřf Wrƥ7?;.gfI_;YqU^y_r"P`R_lf8ؐ c9󻱑5|%gΩi*$Xk;}rV+'RcYBUa+ȾV!#ZJkli4z)ܳ +N4\}T*K^ ׶,9jPxgIaIѤ-D8}Tʪ 8YHi~>#rwe)t4W9έE{9jU]Q^-5a3̂>I3vPf&~$Ýmm%@&2uik9W8 ; j*|gv+HUVbɭ1m(C}Xe\UJxΕrU(WKӶ. mav#]+FX#[YZZmmyE{8Tpig;;frX.`J۞A,u0jClm_k`"5V#>GUhK2lZS(G̶-Q *F%Դ7- HBt5`|ovӨVU',TxG{dĮE˳蠱Op@6b.+fpWtVd,ih =ǠD*Z%x֪+<=e')Yif"TӪ 9x3͋A g9g;Ay&ӧ8dcZ+Teۦ4kUJFF)H"SԽ5LXc[[/UhEh#FWl{F +uֵS${ezTو ߴmD$/ ε|rz+P] hox>+߅ֈmp!lZ "Vwݲv [\˭]U˨uX,=l)#B[սUye@VuWps5RxU2cQ]VhRYvͶ Ju|UzU4ffK0z~EYŊOrN{6勬" Uٲ.!ojpNOlFN$9lubγ\+tQ48>s#R8{$DiqMQL!'lE7/+ܰWlj0AqRMlAq^A ӵt_A_vWۼkhTL*n$TҖ(Yg"ߨY+۵-=n%i>w)VGpF->p?z =ޭiQkwkW~2{h,[_$UFdٲǂlfxvSg9φRZJ'sMХlѹ5N~L2{rk['2`#{r;MOo#xWwR_Fײcs̻deۋE )A +\Brʶ}0:+Tv˄ouZ}*ZT4nV.gR.'Nʮ]\4EܡH- tȞݒfRNhL IX> CܣSh%rȇלHD6b=bDDڦީw \0ɈX$|6k`"ℨACv)bHz_lKLڢ u'dDKNZ*h}=o'`nS"PLkʕ3"+t2,CUH<Z2 )ڈ؂"OeZՙuL~IiERbhޣ.X;HͪS6$H|Ye({ +WqK2fXN%bР $)+nB|f2t o -D(;mKJ,$ +(h!jU= +\)JEL:,J"5 3X 颍@ERbF/Bj :UM6^("Wkom+TM68ЬFQnE[WF+e")GIS;M@TgHwT&f`#DYс؝mfJ\ǥݩDhBЌI<%699ܓ2+Ϻ9j6%1m5JMp!)sn_Pv\%:#dq2q0 ;n̙}DW1m[ՖBĠxH0\'b[ي1N;9Wfw3[RPƋjI3#P4 -AtŎ@nQtY$mRPZIBe +l~ + p(ʜŨȣ눚!y4Z=jk'b9뀴Wk[-7WriߘQ롘+5rAiH":<Ż&mD+S9%0)k݊lGP% +Ǡ-:*NSIEK04N1(oiK#bY8V);%r/yT֩׊BYMNj_"*uؔXcb#ostd0$4Fop8jgm5<mN؅J 2"-ː\O:m^v7abRY)}e{qZ rz4#]zNBB'LNKբc_m2i}?]SÐA[>S+!t)YxYTNrZnRVuYm5< nGgmeŮL\&t2'Dl\v>ד%49ZQ0thPRD) ĸ| +-ޒׅ.RQ_S~FP1z%1N㢝l`3{eJH}25iJa0#' &A`D&mFi3"nCB4xfD.FmPr@wtG# +FϴC\ c`YX;l_ӽ'm ]ssB +てr$ +A4#X 6$ٞĚV;!N5 k!*UβYAxر- 9a𘂷t kP!);.EoeC0yۼfKbŒ<*]gNK(TW`\`)Ah(o+;fIdad@7Ğ5#2 :dd +eq)Hm&m%tՄ8t0%#Ye)23Έ&9#~I\SH.=\ee fWܑקdf +K1tNd+X\'D xڶ5hzߜ8w2]yZjze mjЯN:q:ٍ|LC9SP&@ҷtM[2ꨓ{Fd':d䴤8 CpFqzY>gD*lNʌiF  d1ZZJ(U'&mIbP{D? 'hh0u@C%h6.M;#v 7LŮS2}:rW4᪞.k׽8OUMKiK^V$Wʐbs;$Sp=-EZ@3+V?FU9߳ a @bv2ƌ$kRi!HV"ʤ#kjNUr#c6IJ#f-.MmҊUӀ q\3!@Ǯ`5 p,/D-zdFE δ$T%_jIU/)Te@\;bW(hjFmT D0U21DN(< ejӷRT^ӊC!eQK{}=eCrMZQM ^05,IiL<# 7 uF=L*nr{y}wy驐?'ɣ/j͋篾fO~]㛓_}=;B>' ?'û^|v{{G/7W?Oڟ{y⚟v9>7Wgw7һ<>woo/.wM Fع/$~|իoϾ Hmwnw߼~}~f8|hֶ_r]{|]ƠQn^|}QoϚ~G}&umK9{Guս {ۺ&ս-2Xٛׯ/Ϯ?zsow/~{3z^ }%_h;3ۯ=P:qSŸϋ:2/vn76A'7ع{_n.*9?`{6gp6՚©gyn\}= WzOonno0,on>;V|) ~vs&mMpg'_\_:8@$+m[o-Nv=bKA=_cbՉĝܗmlkp]Ww9|h~ݘf6C̳˻o_^mC;xqqoU->5?X0&{|C' }8 &]\}ً6so?@YL ڹyCxsۛo~⾢.˹={qq鶒1Tm}:Ƽkm,76}dkGfQfݘ3=XT&0rhŦ&`k1[$ö%t5G:cՁV֦ܩ:Vk鷗_]_٫-MyDxok.v۳닫/..ﯻuS3۝ nmj8D>stream +d CVӡs+F^qfSSO7/;닳mE,>ops7&3X Mă_ʽ+}ӜO+Q_[Zmۺ+V۶>ա +ѶԻ@۽!0uS390fc s ICs$ 4Unُ:|cޑa%a0=f*da6&a69S6fg{pl;ʻum='?ͧ:l+3G}(6?rz'_a.Eyh᳛Ϸ8|yOLB6\_qk갢~c9m@ZRl[%>bQ5uVwr[X$#G9ZԆ8r#G{ G>r_m;rM]uC-QB;򳣄vg ?}_#IV_l˳9cy?͇QIͻlփ4ϧ'[C?a~c5 ;VP+T~E565c{e`A)~Tsff/.ܘk23?FǶǫA>]ȏ;ǣ Bހ>tt!oc]'Z߼xNuj-ǭpquuݧ^\\Nŧ]\]}z{ӛ۳o5~nGwW*¶&zT~Dks]9._ĺ-#~Wm Pf5Ory%y!ȦeZvU`mջO~Ï}ȥP65ے-DZ&rX ˻]Kn-iZon1X;C;7vOmm"Ss[:ܤ@pȽ]xwNC-NAԜzŽǚSo:\k'7}7&-: (__l26BQa;.NN o,̷/wP>pz7{Ufy//={qݱ/uU f?fGlY8@5D{ώQ5;fG Ż{ >ԚbZܖS7StӶvᎌt_us3[|q<1{s՛[:;GN}c om!8{Of[2t厎~o厾:{}ۋ~wjG`K+2{-׷gwgWXU!ok6-o^;NxcEtԮow6543|EY)m1n󍅀<ԐTm1cݕbզ&to{ζP#٧D|Vl 띜g7,sۙÃ/ +(=q>rib^3Ius}qInkIwGiv?omwZ}30Lf +|Gmԧa6*Ѱy_$L lcZ8.rv.Y5¹ܢQ;ۗ[hQߝrߝǻsk[xws:ܮ +}:Wq}# W0+=3yDSԃ+mEuPh%h0R}55=/1|}pow2ʦ& p #6qݛel~0zcqLk*x7ǽbnK;*鶸e1mҁ`h&]zm +8U6|7hm+@Yݞ](7I~쫍݄l<|-l0 +]..{ZNɶu>϶{~z5~Th[mGm!â7̌+q5/զV2CJw9nn^|s{1Vx~golL{x'w_@)?\ͅ +o.W7W옾8ů?ɛo?~➖Ǧ?ueȅ\3pk['1T}>!{׾ ["FTUCy9^ʿ5<-5%QH]2:5lȿԖ,%"m!2qh!ڶ_B +mJڶ}Ŷrm:דg'_n }0O3-@9En=mkڗi잺ULخiN8\SެeeR ĔXi;^04־WtYڱHKhum{~YNYDO63[qtYZFOsBGоc2}ǪilZY&J[~iH +%!8ʎڿdH+;Y!l,;n#C>`Ƿcq(k!S9(o +I*6PzdFBT[BlcӸ@~GmIy:hܡ ;\cG + <Ȭ{ٓ7ɗ;+>mGGp?̵֖D%8K}FTVڹGG]IF4xN/NSJm.*wXeJCm?\nMm=DOQj.R۲.pGrrat1j]4yоsێeJ^>X[:۠qr-qv WǦb "uӻW9J̓x6B"I3*M +Nc;ıhC؎Tr+KiJlmWa@ĈkfbkS*82ԶZnGX`Q&{Y?ɯ~}"TzH|t>8͡Gsq9|T>(?ŪF0jņ1 i"OR~S1v9/A5atK;Fm^ƣOz4jCcl3(۱Qx9AeJcN\ͣK^ecj[e"b!$mZ;[M5r=ysnKɲ$?7Fn'Bư x!t V/Bfɚ%U.Q$UQ14tԄJnڶ)~eߍ\ukLe֝OUZyHB>]Tyn;RƗDkԲJtiP̉""oȦd: .{Pc!_t@rktWݺ!Q;h[_W0V(|Tw Tn.Xʨr4bhB b¥+I 0X}Yzm.&%&1KDy4xЛu`M3!y"hDzֶY;Z'ZcڝQJưBE;ł:]t"Vc](Vu4D65i!$]>!1,"~(:Hw?E +4eYEAl8v&4@S鎘S 9"[fgn MV 7BڑP 2طt$Q>cSL&]4jAV\l +YeCH:X?1H@Rcƨqja +c'-7mNQhgTh eE^^8ښ0@< ^߶sbt b_QPuF\b82iDdWMl_QMjΉ,֚mSh'=}~麶{fa\kY +tMyh"դa\)DIw>hel-+8G`S +,Ȓ7Xf!䃵S:Zq%x5*9"ih+&ٟc̃0!\,?QgFV݁o] rG5h* + Y' I7QcB0"@‰i[.6"8elrOڲhG1 +Gedԫ+h&̠UWk̯ +QoN]b$'oI*Fi0. HU,F'n; )CT EےaUzUs-[ilE݈cy펬cz2AFa\C).L,Iж C[AMwzff57Q&)bY\Q1( +.1\1vBqeVm(ĜJIY)N 7nS<|e@fsf9AC3b)v.;]@G:^Rz%l +pI 7S. _W0)"b#>Nk]l5/q=1C>v*1WG|2 J+ݖj3"0[;MF g׫]l\GՖMHV}j'FӪ-0}ѳL"q?ڽ1DŽ;0>{4&8&H@4"yX${K, ڡݬ&GHCPXJ.C4̏|9 j-l{-˶須AX^1;fuCR#ǵߪpbZ&]RX(WDOd -ĦBl;B% "nu JT LJc's"{*|^E2h@%rd.؞"<`˦6Fcgƍl[Y6h3Pq<+vU(ݤ֖3Ns Qʼnriz_̢HDyw:-mf*0FLr=˫Pe}4/1ӂ7=:,42!6}KMG . 7n6@d?W㕑Id1W%A6B#b"!Mëe*w`}joۿ*j$R.[rGVDZx#7CB%;;5MsVCGo`}3)v +Doam]_kh-Kt"57%;{qAēFFKU%PNZzO}P[Kl[ +:2HE6K.&O Kd)%m_洍4FG$ܖ1xxRF^Io:b8BF*y6sK#}\H yRjϭK- ?1YЩ/j ACU&LBI,Mlaj.L[R"#K& MMtCP[n¤vmU'o-%새]d! ybhhL`NKws%2ⲱ@3brsd74Y\깒T&$`鹞U~r"U!9uve.]CK 19fsRȪ|DÉ*+`eq[( +&ߟY7_]|v{뿜}{ߞnynpyU7I5&1gOr{ɗi?5;̓pKL~I6w!zU!$ZT< +,Ϙu"7#M~co,Ɖsc2iUDfoNs=mb&&%usFdG Y\f;Щ)M `X1ep'wאYyq91*wB #xR@gEDn-h[3h1Ze,$ }n*hT&h@,)JU} AİV\,xvΝpU[3~w;UD`/*Gj|~hJhY .e8gu#2%G8y\2MxwKT=(8uSCF7y{̘%us=Y D#W+] %% , O[%:8Eg##I pԝ@ +sr4~n ~3`x7MZzͧDvbxn#rEDlcD u`Jʌ ;c0BJb'+F- tBklEեFS;w ~İċj}|g) +vĊ 6v{セ,rH{*&q쿀7rF(˚Bt16#3[Bk̈.8 b"X>t<}ɱnxғi2$(ø,YNsUqFDkGlQXqXi?u46R1Uad9I:#64uՌHv |Ac7M숚 Nlv$)2aD 13+R8 HŒf vF +.f]mq]*CUv0"ktnjn9*bB{Cʈ88a]ҳZO7瀸X׶Ov891keٮRQEgzg!&Al~ӶQp8Uޡ0eC6C$4UICCuΑvUeU׶ipG- +' 5y>lj|" 䳌ɹTEoWs'Ck-ƵHK虯nsSF C`Qd$Q$\Q%tLlۏ Ca5$'@= V%9$]~!pXͧA5 `:,)D6?2IAW fr'a'5U,k`* c6SF!,zdEBue9鈜{'"a!шC^J#"KN8'c&)XdSEwǠƯA*GPѼ#ˉ0="݅3k +'Elsb:9tbbN!xcn16v[mZYŪ^:s6ŮvKa+v__UrҤ,|My\T.N,4Ē2^ٖ%+ǾZ\Cj!Wl +!u* -ІĨwV#& 8fxDJS:#"48\Zn&[pyRo5uY=*8xJpL_7. ٔDlӶC*4 jKn 2нfH&׌!85QԵ yI RCcas)jj/H-T+0s0b(#,g-§^9`1 d2* {tch^Q!Dd1u͍_z0hQ +݋X"nnInyW"IF88ij8zIZ &&JVؤ +mV.&ֳd4&3Ŵ!9#0FdycI%`Z`G#N$wfׄ#Wyx zlC|fOx:%*bOQOb =[M{ +}VcLjGLԟգ4lԲ֌OЅm/d(P̌l"n;XvQ$;9C7d?~I(cENLPn&F WQm+֤S?Q=š2%某ە 褩M4 +?>]HlTc\tΤ),Z! &ANqRA(e~m5/s:PL_J~̡{45xǛ2TIgCSPM{jF ++)6EU9`mqC$2Y/"hnnabZd6f7P#D.j=za}zido#*1$+| s){p{7?Uay'̆5V/n6%J6ZȒ/Q\;`٪Jp̧SOȗzUcߋb W %^%*#|1dCwٳxF]gť}z^|I]\GDj"qL* EW@޲zW,c%uVT#ZמaHHF"˯mPI1י),<״0 Ii} ʓ'S lAe)fZր"FM%K}+O2!g+l\¤ދ`XaXY0-w"bp#LyoLlQC\Z-Yjj( +Zj)nd;۶Za1ha2PmLB99IkhA3dƊ WkZ7*ۡD눣6bٞ -qGp˜m4#J m+B2\D0F',طf&h8t +CO t6*I!QrA%8DOƖ6Un29i & +6,B zɉENE |u- +v rƽ[v~PRZUpJ< 5(*|YU/$pu!KF!vH(6 7l VG|qFFn&% (!`s =ƄF]0-h6՘XQEd!#Yy F5YijՊo%;ZjFRC++)GZ3OZ^ӈv,< +uGLo))lL^ELhq$8![6dӋɮ!EF&j"1~|L&[v"kQ~ա0a/i7A@<ž˴<|TA;{Xj.f}"9;YEFv0C&D +b[U&[]= hgDyҁ bc4Ě8]v3YDj=`?8˱,] {]6ĉf=ٍ.\=R@(8YN1̲%zr( "`rHP-UTB#JSP3yꁏ-f[;qX4{'z;g_mՔZ6žDn48LlW4BDm8H:™Z T+Kd`eYIε\FuK[D$.eBX]j6y_S$8@.!'y 8&ar̺ IO ~o񈜑TgaS&)dK.-CߢzKpIo\LlcL76@k~f:mcȳ]CFR RV\ %~.ۨ4a?!칧=v4nXh/\V=&ɵO &I.q}᭽Iy֛l\)\Av +jNy Nbp~ttS?X}=Z|xpS)nC<Y)w|C =Nxtq'Fq' +C{b1x'_~v!>䝘GO}t>{%M<|_x>i'+AA‚ ;Р{y ,!B$0@`&& ! Ńз1CG)A X`HewHAP׃Bف#C9V Iq%%E5IIe"{IxR vJa^Q*=)Ń`J{JPVp]\ X.v K1@KMg^[.vK.EKR/ŹZ `*a +kTd +z(S38S@jHSnw@M1!N@b7y:r8s)0a5)Nܩ=Xx +iu=䩈{@Or=Ń%>~)8T8! 02¹rPi*Ap **]EEXTK`TF5{ZpThڎ\r^&TR.,Sz*5p[ހj +poF~8ˉh'_Hc1c `\\4"#zkhðUw]G1zaa1!M>{01ﱆ C>=b#هT&A6غ[bQg#Z"ۃ>]c/1|=Xbhb@4m^XlƠn7cۥKc{,q]`ۃhV#cӬھj(k6K@kpCZwijm'n=uzlm=.V[`޺6y5ĵb rm0]X[ t7jkKkV]yY^ۃ8; 6NںX@_~58Fƃ`5` l{ +Vaౄ6yb5 6z8یKPl<؁ŶK`l{8=X m%@vCwl-A`5L@F_Beۃ%X6lq`IK`mfloG; d;0` 4nC>Y[Kq{F_ۃ%q%9X>no=[n%=X!Y Cn9XB}=9؁#ɱv;Òwvzh~8ւ@'GMZB)z^Tn}/,m4˭%d=XaX /m,!@0&1ycȼk (s{5K8>Հ6%AzXskK``mn|=uě%yd ] ]:Pɲك%ܹ=Xxn,A swb}nB琀vm? ,8ݺX BM[}5z.` nY.v`z`t`=8}%%Ct7_ ڥ9i֝cΤIJ^O+M?B4)u?*(:Qʯ (:tb=2ѧR9 moAkA$k Am,{9"9hmFEGil_Hu8ubpVŐf`^r_EHJD-鲮l2#pOW`$8 5!gouOJ # t kD vpG@&(nvW)O=Ibq(YQ<*r<`THD18X +[aN+$ٓ/SHpy*Cu4I)t(>7xrRjkٶ$or&S**>8=.~AV҉Aw\\D}L`AHFtV V%JMyc) _|Yˡd+ @<ꤔ*RīX#7|6(_ + h4W +uK/AJX$7#[۴W5V%W4-:mv|߯:BɜT }dkhKZmrRs5,^8%{ 蒨#-kΉp,89ߤ1FD׆і ׮eWrz҃E}|rP-tPՆIce1 +ߜ*$'7%'(g"Vh2tXjYy%DxJmYUp@h߶Vśܠ*1cy ⫲/4\sV%!׎<,д|EIsX"^Kɴ@ ae1DAe,ҽ$.sljUpFKzDP$Ov&_V!R1d Eh˰ +HQ5 _!v(zi0S4 +Qc1#Ù!-Vi)(Kć0¯<9WAa* sBZ_jbW;lt,?d[^xHͺ_hˍ&| M_y@:QdS 4UqfsRsBͰFjt|8!K*vkQq]uUÖ2P;%'褬"ȭ."l`3c9>STre1;Z/`4b\  +8G P|2{'P%t pQ 9фL4AD Q!_aKQk<0QOlOsLΘ8>mo:D 7S$V"^??f\mZM3 $Ue$T.)A3{ g{/DW5:$ձ'ީvUH֑UE2RN:XQ1F*9++h>/'މ?T|rCNbF-zMǯ=v<%UhJ'yO<+|iUQ4a 8p s$M'!4 n|\WPb25:&iܡ0Fh.tck즶N *:4^BG,qIIcX8nЏ8-| +u>i4" [ ÒC?j#iqe0k6>*bC^ؒpoѬPtR@ìBԍYx)LE~R"}Qcbhm[?lQN_1Hc[O1DLPN/yʐz*RB|^gm}E%jtP.tMekYy +K8E!%L-\"`4Zҡ*DI,Ӳ@(nR7 +z: +S&L{DݑAIg\^C㰐zqw=aTTְ| 7̷I\|ZB6;fQm R4-6I}n +bc:3P +A%M-kX勏x_{;N<4h_/|}w˝Wj! + ۻĝ󛛫y볯.͋YX\r8LT%x"=#IOẖ8֢i]wWAisƤ^(`# (rѝCA +0npZ .tJ18Zl;jĹfH] +4~LI4VZMf"/$HKR=:p DVω^K&hxUc"ɕ$XI Xʤۨ`F/aD@%A<b +L# k^ ~d 0Y_*ýψ#Ō&&  +' p^ +! 0nmв&6S$قdP=Aqm>$zXrlJUVȲD ;B +I-Aj1;'A+Q(Au%SeY'y]s9)RX&M"2u4I'M*dr%e<$FH7RduB}Q(`:NL-"-\=VlWhV74ۦU:Gd'E JG#+)}^ Q̦ QFo'K!(1%;IIJXfM$578: +(E'17x_%^!D +/5UPqnA Kf۸ȭ~tƠúLı|Q[m ;ܲl*(C6 hCDN%##V3BH^246ۘ"oe JE풢 ofcGI7\Nۉqݞ(ȢR&i{TPH;H=Dȱ)Sq̟|3ri9L|Uք4:p`62 ;!qj<" Vl܅n> h /s<7Ezˇ66~E)GɈ? HHM!OOQJq>q`t%BW$SC2ݨql=XQJ$9œ,it0@ %7` #0ҭ$`rp)&~Df3H!Y˥SX<&B`!>!H[Uuz_C,/7# P$,qݼ,lE d- +8O^P0-;#&P|jdT$~,EN!,$^6%nķ/A&dp//ʾ +Qom{!@Aѵ;oPE|[#3xKVKVPumO@5+tLMd#ưD-<+HReX]zzEcE eI ]3lq" TQH>mDXH J !j)UE4rg"J%kؾ[Y2Ij{H~YU^ך,Q!+DR#Nhcy̹j1Xt$ϐV;HGCUՏ1CUM@!ۋbBNUS霊(]LyCb,"PEbDfh@hD8mIynOmGK]dRE8 2 +D )Q%#Фo%3˗lRu/]4eAof\]3ʚH:K|':5dM-tCRv^I]QdUo/:1hxMGxES˂u9`ۓ@FPԮF`̺0!U Hfю\ʩgkgLK(XO(eLD)KQNuW/|ԏʶb,QE.g 68U'VͥdBV{8 +[C1:E.T,W>z TylLjRcQ5H]\,M@dN(e얻O1j]*@0R 6w!LAidV)( `j/;e$g1 +$ k+f"R8]A9a8{O%H6tT +<($dq7C$ABeӥ?9TaB ++,ԓ,UiXqY4O^ϰN< UXID-SVųHM*5Q^Yՠ*.Ljƛqbԯ-̙ԠqY4IxF\E0t+psR-糱mW> +0#5F}峐nNZ26JgO U,?JU! I6@b7 IDEN9^pHaH.!.'̩qX]°`4щtk^ +ZA>kB$NtCB Wgh)W {׋o}Yđ( N25ZdÒHےl/Q[bQ71%dk|scc 'EUs ȼA̡ј F'72iE"[Y>1j4H\|꒘'{N7SHD%}Ó؏hhSD.gI?M3$t4}#h ;OX%>/6Sī0 bN1ǢÑYqJo cL ZC"]F0 #A}֨5'CDN #.@y]F{*)ɴ$;|撌\=8~Ĕ5<8G.R$m-bEGcCPjCX'Ay]Ft@Y-1"Sp\ݨ2(+ + +I(@mr,q>\FxIR77Rx98NBGBk!wQU3&a7]8 2 suY|. ҺWjC PBіXTQVYL'wa}kE|[ڹ+A%a}L,ݤD #3H _3CAY43%`e/vSh<_|UNٴmyD+2;nScDw"<0ObCbcuEo?sd^!]dE,^0J6dz>%<Q&R[XLa0Q*|l>*GS*N`JDb_(սd NU0>$hQ=*ĥNQG˪HG)ghBK١ <`eC"/S @@G`"8f@DAZykPb LI +rmf6T4K>~f2\ȃJma>FUN܀<|o0rĆp&ePyeie. USAă\r|P,ʨ4 DAhJBv̮hKtepڸͳBv5 =^=HʸN>u6EScB+:ϺĻM"J],"v>Ocnu[:'[dI +Z"Vr{\,|$mv*9GZkh9պF63mL! +N?Mէ63 rTmU2mĥaʽQtD)#jtjP)JDeD^)Ѯ2̾U5Ȫ@W|X19] EG]p`4%[؉n0<}# /DR(,yT6.p{m'ҹ愔K{&I e{eJz~.crpZ*7 B/YR { @ p EhH!Y4j.@"Vn%*9jfW#7ANKƟF$ );AO @<+Kp.D)5 Y"2jA`2nTƪ#NEpLŮ%w-`T:?q=L6,zkmM6z[cMcF[@om}c|m͞6z} 5wykS c|#M5pڼykmMcؼYF[4ɅhwЧ,  U}<1zM񌳶4ŏe]JxzTJ!qb[V;$1h[cJuEl{ϡy +Qj݃#@@&OLQȻ|Ed!v]DW7fx..,#tBSGɒ x-yg1!f٥xwl?[9 PvS8At`FjV7zԓ#IГe e#r%̫esT> +݀FUpY+>. +SP(00JXhJVX2y^UqfA5q(/h< fK4?W¬iYh?Uؤ p;+ruUglҝG&OdkY1 C&&PoY fS"M.2Q;ibަƇͼtԨWXH2G9AUE;`Θz=Dmp̶Uܜeж4E}:٨R稱cyFK~ w@_ӹj,*mF/UN"#mUB#iYB@屚稸dU[styEj^i;ٯvhyԋ=ml +3-WFY6챚fYuzQY?4V EePOu[k7֪L8;!n'Dh%P5ݼD, +(v\ +jt9>9(ZInŕDS^, N_++{)KhǜD9F" `F6&f%k6@DKvK|heC2:x^\'zRȌDE-DKpGϢ/j>JDhɸ,hn$l_E;1%I2>\(.doNW/ɚe3ATǪapɅ(=ݮs/$0- +?qaXmuH 7`{Ǿ}=h6Ymf[NbBֻm:{5-Y]ht&>mu\# 0b12^Kr}&9?QBt d]G,#ErmcKL#o0'~0Qd݃YRƞ@(vG EDo.F3w4@}4K=JFK6xf lUf'"mMFK ZHj %é؁a}Tfl9 r^fnU7;e0CZZYHhpuS1 -@%lrS {q|"cCI)FHE2Ez(fuʈaIx@P]DYdS>ԬaD# ŊO"z/̱200b* vQ'Ey ?AP⩛Q0?r6'.Fxcp,tcSQBcGa[|Peuґh Y.p\%b[XL;ƒ[r.iM=zd5͎ +%OqZ.d^M`5!cha԰1(kAD#b +ZP5ȹz9mk|qs#HM!I5HFnɛYڑjo4 lU-G%6F*O a Du+* +>Da4dA<:A4Eб"ø7OfլXmֹV)qQSևײ88GrVAn,rbB~riBD fBzU&dQDiYLf:la +ϫq%uЫM8$c +a%8Z,r$)D V5s#EQ{Tӓ"704OUx=qj'|ѭj^PR(O-EHۿOG3<|T (j`) +P?**\%'R9S2]#SX `3_تЎtX>O,W by6/J؅h<"6^d:yc5ݭi(5>k-\1}ܢ.)0kȯ*v#KU[~}o5 P EV)߇ `x'[FQCt)J>&ĤV?kz-\| +.ƈ'iO +>\>,@1}( DB/T*bCL!ȇvZT߆ +FpGfj(&|@߅TM)fŲuǂS ]#dd,"'Ɨ&Nrp2'_MKZdj'uZ25$c8Ub6uDw7HƧ$a`U%\/ra^SĺJܗ^Pjiv496vHZeQǖ3h!%L$9QŖ"W=|i- +uR"I=$q2dd$ƻnWHz >LL BoJ} ҔՔ K@nUԡЇ;54-qB́G*'+WU7\݂nAἺߠ\BhL3E[d[|5}+n.e\j Щʹ ,J=z)ΥGdqV99sW)e>ҫd N"]&A{@5qFomHO**o[^bx0 !RE˘Ywheu#s& D,)_H? Yk.F +>!&gRRͮhv{!TëG{N)me]\TӅjGhܶS"S2]},$Kxk/,FQ譀"\1ݨb{7$;!*)CػQAGm$Mͥ\diO9Z[ftNJGm>G6:' +6 +hē\ @s[]hnk<T4Rکf ʲQqx3eJb|X]f4K i~9Xh6$B>dsBn_UtAޤU*C:OSFpu%J~c1QQz=FEolYQ`\;ZS;43P'*JOށŘ3w&%z0D)U٣^|.*ԢmkTx#n{荁K>_Hɕ},VzoT=zB~($Ue#^# .ԸnORp]Ӹ}!3< $2KR xX2{¾P)Et +6r)(-&.l`*%r ~!OpK 95<@CjOiR7 Q TlJLQҚhL{|[qʡJ +CX!Ϯ8ӫn>OK^Ư?{RvihI?YIyM4=O D ?Ka]-p 8O6^,뫓>-*i}~/掜}߸ZXO/l]m*IN 2beT4QX9;o'jl`#r:*ƅ@Ch>S:DjBWOa3 +& +\tS84 t)@Y*4J-G#K͌#eȧ(=[ڧŵA4 RBɤNYI~;w|Vǭ +34WJ&/[ZUU&#d09 +qtz Q$ *@MN~HnzWUw ^[!^˞m*ń#j85}Ul,F'ֽ"$Ag;2K3J ͖J/EֶX=9* We~!F6ħ6BdTrndlI0ivԓg_I!{TKX+m6ɼ$.ɰ c͠&J CCX|GdW&:`2I&%3 OAv 1ɔ^|2Eϙ&X +#Rҵ -'$I>ƞ$xMu핣y{ +Dc$Ny:W9xkm#%ЙÊm!c-R!<; N"g X]ĵ(d7#ME ;QU 1w-nh/\|t9* E?g\]R\`e\ͬ:6u*g+Xφ!P0yo Uk9]e܅YJYL{rE囈& R&X@];@~.6F "g]1:P:&<:6"E/<31Bsf ?8uмyf=9^|<#L\,p*(`/>|s$vk`Qӓ-=ʿh-n$q4;Xҁ"HV`>dNGhovpn0{1XEOӰD,O!0n;$SK%TmT +Bl6mz剋 ;͏]FL58PKfv%oc{ :e].b>''S6%I8Bʃa-Y#vژE4{˪,1Ѯav+IW8U`[M(LH?خ)NJK_^ ӆNDc +XF<`:7)m * +PwJ'2X*A*k`q?cVd8.ńi-8'ZP2+ͫvSS "L.f:+-'cPjj!_mQP[ 0)b8}!bRe sf'VdZEBs\dA] HfCJ0xqɝv5U:*EP5`FP}B.4 RQm + M{z9cr`zh.$8aMɞzW/jbk΍[ِ19z|JsTVcs)Zޱ&'t8d}~:U2Be6duEPDep R.$j" rã7j9uz *QT85]uG7AGr+!>3g4@8xisj$e[~8E>^"Pp@| *q>9bkI9T& 1#U[i}dQ g6`e3VLU ʱ~'" h TB&ς +Q3S* Y of爆5hp՗;0Ȯq~eA7v"R;ЦIou_^k$AwaYrXdmݣ`s2fQ2+qAAޔE};r +D/-yl1àtW#@wل듫L3%O +F^O#JP`4͜cz#dOp3$] +AXr˦,쳬9Q'qv5al}\IAuBeRқtAzx T:xWuJ Nr0*t;" +#Q:c4; |pw,*9kl}*gKϝ7T2 . +wS7;އ/Xהt;Ft U.t]= EFw۝bO8:Vĵ{WWҸyA~|k]'樏Kp)EJL)'d\JAbs(]KAMS _^R>nϿBČ -lH'ngae2& + XL > +@]4X){j5y->Z,R'J%+^uэDVHBp۴80t'2H^L:b/JW[-qM( +a#&]HЍ +v@B +#Gg26S(r +va +\.g73'c} 3jupK!+#6 gMB PANԈ"'/ Vik]:;c V4]B|_}'OpnWA[Xqc<7{:Y+`CsF4j}БyRY"$p }PzNU((᚝#tu@-d`M +D5tBր/tc +nJ%~xH @UT;eT`"u %f`F8@#;&R0nz +nT@돽|ap;swp +T:%Vvm~R g@|kbS&~p[Ëjj<{#VI!?f]ƭ1521LشO9^$P R\›ik2 +zŁC_fz A\*p#DLGUxqрT/h?}r4 #@:|=cc~$>3]7A{[ss1Ya?98TbǸk$L 5E#+f8#'ۛziɃcޙjA;NG$9Z'%vרF+1Jl4哲݃n^8 >z5w:yW,>g5:1/-.b9ˈ"HÊEI34Pyϛ&MO1/C i$E[<\e҃4a# .˶rL[A`oy^'@v1P6exq~?uX/Vgnj[%MnW K?6HdBa㷺teG4 B+f?{~]GHWšH娤́BnѿOYZ-1 ՁI&OX؄ZjzUw S6}O:aL"\)dʲҺ\Dܶ^?o(z`-N65:Yb8?\1]a%H4F2!:fݛwJ*צAGV 10jNHleuM):;Dfс8˸*#y t4=s|FY +O7G(@8ec:.C:v7Gs|?8\~4Y*qjN4鼪 fP !SYn xniZ/Rp\kf{=vh:Z|aa#GKq{ux#h>?FQ_7lhيF1vsyߏK:<vDc '3y11I1 aDj)7/p3B?/fa?{ @Hhe&¯ہ8tNJ2?qs*iEPrH߉BjR#*FFy)2Z o YkS +~jՅA:dfе|C + ::2BC/N-Jh8Ÿ.KPU"3nsІŭ>SL'ϝB}j x2߶:oy1"bݰƕ91b9_͝:tI YWhBΏKm͏J@UְGS691>AGc36[;rS^ü]ɥwLSt$ BWBygs6  / 7Dxn9Vɠy?y̜z/€i4kPGH.~iGC PBe4ԁܥJ r񫽗ӑ|P#1M*"RHAJ(b+@QHS5OCܜ сBP[IQySu`S?$9!IQCa/8+C<^D%o,G Gf_v ?jǚ>yv[p7ҿN-c/@Em±u%R8F1P7,*eH9QEѫrAw-cɆedP)F: 'S +}j0TW ؘ⨍"SA +UWKSpKuӍ' v r:#)0{bb@Uf8P;:^,?{^WaJ 0# sPa:O(Fq1#ݤH jO+ZjdujKDr r^NR9VO?{& + @a~'2bc &wiO†΋/mn4}5jN= x]"D'} +W{ڍ^qwب*Ve*@^28y̦.ZU%P^(KiJָ6UA6NSwȳ&lD4mW|%9wJ2.>Q\19:es/@gI%$7$Yje\bYZMƪ-qP/6|KK:,L4_ʔO&,4 m!Q\D9/H+.*$!XkA +[5LL=&tΫnL+S݀G|NOՓ9NC>'՝O.CT~c*O 4۪`9  ᴆ$.p~C$^mYw=lG7Nf)BxQ$}_ +s ]𱄶/Q(vrb"դI%(%E Hd=O0BBqF~c]} (KshӒl?թlNаT뼙UujoXޤaU"IT.WrRE"=B]>\(4KBM=OvgG*<ct-x I1UFAQPs';ܳ dڿ]Z&{e +MmQՇD@ =pK $cpdxުqÐbI ^CހraKھ7/d/4e9/K M $ JѶeF`HiVLiVk& uv=sևГU:}Gd@HX @Ӭ 6)蓃 +,*O:.c-˪k(+_̛ͯ(q` 6O^]Ne g^uQvO raQJb}+~p +̃\ ^AV; CM~KQGҍ̈́g'R⻋jTfEueW=,GeSIIJNCk?q|&,[uղN(,QoTP2m!QAz(hC0Q+pyH^RJ&ix$". kha*NHssl'7$zRcQZJwUUx,a :']sFE50-$ ˂j6l<إ7liX= +U!m+G9!f̼j$Aq9RwLMwF>&"hQgn 5YנHlR@iN'e\reav1#:X.U;XoTkb :%H$ྦྷ o![{_W +K} ?2#^LNM":9A5+bʺ'd!֪rOA1C#)*7,d>:&k]1)&HGBD; +;tC/Yo[C}Nf-~g{^GDXjQœˠ.'kH$ -i_`KG,x:p0e(MH eeIwkCe8J*<*]IB%4ufd +Q6 Œ_,Y$ˬcp$G( MxkOgK`m70 0N#WWݫ + AW̘}%cüaǥ))+Q$$`޹OEv(R0qL d+RэGRzyJqQP^EԻ#e`LKNJ$"NK?s +@ +LhBBw"w +K8;=<& LU,t/xʎ+j MPewGYmP,IzZYG62S^+s<1]bRSw;m LCtAnMc% Ēr_/JB&uATrvUG;)Ba_ +y_瘠O>7za0EdIR1BsNXaܜҾ{rn\_ +ۣ>*p ]?D*^;E*d@&̓QCKâCjcUFp g\YXu&ȺdBގG80 ̀ov.Dqv4HQ:"9h +Ua\n&OuY>"wLCr_Ol>W^rրlL֑-4?.DҼH@ >SX 9yZFR%4[ H9Ro&P0-\MrT24i ݠaQ0^Y2X/BC!G \:IV42"$Am\pa/f`ڧ |O"䚳.uHK8AXGDbbJAmR04φ/`)^7L;u|]sw-H%-Q7"<#ss\"| %m5>JL$e,4@='I&_H";@EСR% K0,t96(С섇0N'K,r\Tlb%VN[Mk蒦I$뱝pE+RSDfs*TI~QX,sc))4\src'ͳŧ +TqI$P@I+XNfi䩆s P0+n҂>:FjH-ut3HWj )`ЯqO&$AT.N03Bk5]ŴH:ۣVN/3/8zv>gȚm.QUg( 16[b0V4pwA.tJ@^T7m 9 A]x<ݻP>ȓm7žn. .G2(-VVLO\n-ɇ{\'H>#) +Wq3?K`*JRS!GRҊ-{f1p Dy!i|FS +#>t#GVRLP2>f[[.k%"_ΐ#8w'kXQJGjf8U+Jeb$bLˎ%_@)r.{Ծ;bń{ pMA9P6 pG=!d2ς+%8bCt*,:jǚ-m!ފi f'ؤb=M>s{sqMŬ`Gq4 Aʎa ޹z>L$;&or/刁H+dgza&#&T`9ƒ1)Y:ԐvJUِRt>o֠ EMȎo F" Hd/:$FsCX9fIM̛7Yf14>2{CBAYӴ+d$#pOVm{׳uB,X]BܥYiS % Jg@ W:EE2m߻x*R,aˮX-O~+3fnUUa;1ȉ*W9<SR*2cA "P@fipyT^2[&5s}wT#[g6BR!٤ڔpslo,oC04w'{|O\aPx%O"*q8@kȃgnol7`!d$;igpj[DF@d{ '̭S͜VD2Ë.&G[,q!CIi;;pa>_O >Alphz%ԣ߬D<%JPH,gHY V >EY< +39 N7W +vFpRxnj #y֥XF"";^ҫ)<ƧûI3r,)IУLCd" ;A dЛ9*^jqq]ijyyۨ"~(%0ֈ0I!ǘ3W3IA"XkZE->GP`YK@0+m5-\3d*n+?VJ\Js+4!yC E#"#D1[B3-Qމo?'(\꿵qc%j2[P.&}^j]ij86܌PŶH͏C<ޫd]УFz]ZC lz'xx0t[ BcAKl 4sD+ଡ଼qVnXeUF% 5(u! xb¹ : gRrJŘaQ HD8Ksx<1 +kgեHz.aWWcƃ f_HW̮:O*BPF@2_&[z=3'@vEgQH?$&[xw{"glQOM㔍Ivq)o)ڙ+a,Ni[pA7c'%$m< zeh"lܣx:b/B<4%N8W f]B!n) #K&iUڃ5ŭ;nYyQ6e-]&WS|v݁SfT﹛wE*r]x^#1X_d|.Y6 xj0>lY! TC&)B;m9XсH?QZ hgPI^Mt`0׫r;2nj?l5(&LRAȜvY !pPҦ6= fi _/̪ВB 4eOf P ȰddK+ .r6o aDrrJ(I1g{VPj@ӱx_ْtf< 9TA@؞DDE>`ERo/c9Бl03*V j!:Ϻ.31M˚wT: 5Se`Qn Wڎc9GφjE81Ka3Ot6@!s[S!S(QѳL6p8vsHqDzYp AxH g(VsYLÙ<*S n-!ZY/K[rHx>pPסؖ"V,ː)XH9}3 19qCs8>u#>D3ҥY]ϟ]Q9H(kڏہ@L mb\Z6–ApC=[=)|'x Rh 0s F6`$M1< PHZ<@Xn: ϔ$xFU@E'w D3 ҥmYkh\z6*%v0ƥẘ(z~gbjm5Si͎`0d^72pyOXbE;=7@3rdڥhƦŴ(hm=fO809@iYkS mzrD5' 1a^];x_??'G''~s~pruq'?ʏ8ϫ>.ϯ__=ξ| 곳ۯ>''(xO>9ާO}r..ngn/n7WgWg/N>ƻ胓:t6~5-s}lw: ,Rjֱ.u7~4kejN{w=x< 7;ߙyr?mq}r-ɯ/ᬊBmDn2.0_巌4ΡoIG!|tLwƯ |v +ow 5\X3-R-Iƫ{OȪl/?xG|uWͰy+D.>67盋GO/_bmm=:G?}۳//}r\O~_|znzD\~~qE <'*G)?N体AN'G>0zOG['2//-& +_f>Q2rY;2.ٷo_&x`ηGd;Nի}sqgkO<ӓw?O/^~u{sv{}˗aCs܅_߾΍og'䓋o.^D~gп6/ }/o+ERZB>{v ~ؗz'/_Nc7\㫯#n^|?g_>vio~o.n^9Lx󯾾}uܟ_}mxqOOr >/^F?6 ;yϰo< o}OУ~OɮJ +sy\ (OLRt%Q7DA9 䦜ZG_WyUvcrmHZ]W),A$Y}G_WA}]GWUytU]C{*ˣ<*ʣ誼cZWyU}G_WY}G_WyU}}Ǵʣ<*ʣ]]GWUytU]Ǵ;ӟΏݏTȕ&tbm')eAm\~<OwO W\'4m['[O{<޹CXx-cğpWbJ Ϸm_ת͡%/|.z?5nf6['56V8xn=mȹzjǬ<@y0쫋O7Kb\`;첯a1Oodzء_<|bءFT]:߇8X+ؾ=x̿7BKGo ͍;=U'FϾѶONLMs*A^#y|۷yo3omm7^{oyc :f׵ԄsKEL%9V~f*h94IϢ:dK-hho.^ #N]4&3nZet}o..Dmv5-˃YťyՓ?EOZ"7\-mqR`ӱ?uIp>y:`i\S=87t쫋37לʛr-R8]S|389j֓̚l/~o~=?dkcUj]z{s S_ۄ^W:o_zgn*Za1;̎k񹭕yՌS; +X7c[rq Vmeަgϗo~MŶW瓃)Y[xzO3n-[zksn< wXh~7N6d.meiǁ9kS~׃~Vkovܽl(.,Krs{"lXE\u;٩Z䔶8Mmrqe泗)M8iabr?z\ wW:%{jE,Qlר壍u$Ixmڶߓ9aa't?Mjq26X;`&h~2A:|OsZ{^D aq=6nvL!ǒ3qh恣nWmm04u/i&W[;XUQO +ˀ{Xx7hr}0E'Q9vy|烧EԲ|e~x`hkmi%ofAkVo4T9ǡU*n1>fe4=?L&H=|MnNv/|/}XJjK=j,v^SrJZ>e.Ҵ.Gu a$΄#>y3,NL;l]+Ð37U-Γiഭ:_q=OX Ƶ0M ~FyOkKci7+G=б܆&+౭Ͳ :eR:)EVVm<2vގ_tIܶ[ˬj5 ۫gIr zZ'_f4.ϻc g/޼!9fCnݾξxGzۿ vߟ{ut[^ߧC~Jmׯ_"W8зsy[ӑ<,y\ćP [l.G[$mkof>.ΎyQPnNɎO<$e]ʧz4ŶWw,b=ā3Ju{<{*8~Pc{`9O_B$'omkϷ|mz\´|~L51~zv{wVـbؓۓ={~{>Bu~qqӳ^}uq/ z“o^}ftngn|j=99r%Bc[?ޜ]zyvsqun?;y5~2폽<{yqrkGBFOnTAG~v۝R}׷/_ߞ|~jsū~_\;xQϷO^`oﯮ +]g__yhunmUz :$cmws0il{wF}8\Χ. fg3O>~}{=& 6s ūl72_?o_okg:͛=޶_g7Y*N뫋wob?w﹬: +? ssNΜ߳mp6f; +-ZV,CRGdM_r߼X$=c]OP@y:C1{zOi4 U=C2=p7_rgoEa5y<^׿lD6y$ʵKF<rE=m3l3K׳aWNm!ﰚ&x[o  cD,t>?@uMoXoH?+iR`gdm r体bݹ_+ôNDv^٬K"9ZOWaΩ`5-a8LZ_׬.o[5ݼ{jVo+0P|ړ8`|_4wпV-Ƙ-k0R4YL$o= Ǒۜpw"d 'Bi,-6U 5ρ[3?=g)OQ}WI +Sm,˔v;dD \)ء=ĐUM%šDS”AdӀA=۟hx9!HKxE"nDDOM5Y?*zOe}_˯<.wa0.s b Lw { kh9aVNC0nhꦪOs>dj6l⢓@I1n'g݋kHlx?МDS:PlxO_4f7(tGm! E+Ӄ\zopd uѩ.%mR%>'!t8 YV,/|v;D6m)a6r6SU~Bl4YCIE P㴱d.l2ϋRKn(,w%|Kn~^Z_Gm{@C3{-9Z?z--zؑb ۝ |/Br ,Wό(M.)n6_@2'n|J޾$eoVüsWEڰO3ӁqD]_}?EëAtdvzw,ltmV o Oa+{p/t{6=, *[ҢWo,n\R2,F>nB/%dz8%'x!/i͘/"hi f&@_:cKoF,}t3#^5ajʤ/du@yvVDFo8j~<΄QfG; A[0𾄗BO^ 1? ouĀ+3E@uyY==|nn sl}wx:qbsUA[ĆH;cb9._@sӂJW\k˨aY#ԭOˮMǼd}zvSg|Ѫ! uz!6݉E|9;ܻMޟpfۊ}-w,mdkm6_y7>\r`E2j=zMrlaٱX>N)9<Zr.=6B䪾Q'KW,:}$ o6Q= ߄bh AL1/AIJ+=G슫.ĩ +dA1@Dvċ;R t +f n$p#D"{t*HBuV"xAR豇G5ޢHnBXEJ*W)Ok;UG9:Hg\,Vݍ 29 ȤQ"Q,f:FeI!;_$r6O`Kɑ&Wcy*P5V]-r-_nw2Te䞂Z#=yH=#I_Ur|uV륊,W彼~mm Ӌna';yO:ScɓXK! +#RhדXuV{ۣpzg7(#BtX!ST\knRP~FE[U+ޣ\1.ϊSز?2TW*TʋRm/Ar?J'R)Ie){ԨNep *&_R37JʱOU.ٕr3ܔk҄"[PV!oj-գ*,*\Wh>ԢU):nNgBz\Lw*d6vԛYYeR*[WJ֮*jd*jdUf AUƖC;=4nFmS4jR;}_ԱN3u +kQ=ꅫWrSƴ4.˧ xoi@*jjJ덧Ylcʵ|5%; iÃIܗ-bHl:'Oz9ef)tޤZD(miC-JGڟt;sF{2BV̪1e5% Yy\_sϹ m1ܪkH#ZZ}mHA^ +QW[h:.ÊrMx–` +`KELHpD.YYF9|oƖr.p̫ +M1I|B>7>w'y~1Gh~TMW+}ȥCٌlM-, /0ۻp7^752G|NI2 >oآtC[Vݱ1RaSk |:A =?hըؓ}hg7觉C UX0W87]Q1Ok}b[}^+G 3mѰxn\UuFp]F?O;}072f>\lnݴ[fu<k5Fa&f=رVR A2411G+GU7 y LΠ.)gN'rb!(`x7 m1K5 '"UegRrfAķɴrtxFuWJ'1t|6X?:BA\2:X n G8\YqɵONzeA,Śl&'$c[WIv]s@j 2b^ĒtPDƲ5Ͻ嶛Ok(xz?}9,[i=*ܧځ\B냙Ntr9]:Q3P\Z4j1[24$zrC\71ݜTwَIs@<c+S@Jgf=0i~>ܪb"+b@`I9'aJ4yHj b vK]v)[gphlRòٔ$Z)R'4XLpt{k#ҘݥTb Q +Q&lZ nMs)X'ՠْ ~A'^$9[> o?o1T4`N#V ;l26?`T1ب@!@|lGC7D؛%`,N +&9`)HO $]CJ|(!V$ç04)ưs$KA*Ac,DVDpAr&|M AbTWspYsc9)!L|zDJ%y1$l{f.ϒc$V)rc|DT a3M|lavoSRj^u֬h%CJDyCxLJ'HJjFD 9}H$X!1!$D+.U[$>j@)2 쑣0FvG֍ M!Sb&2ך.ⷔ}JUQ0'VKb |*Xpͬ^dc.50]Ao}~{@zACN  L,jtb"&vcA)E +` G<Ŝ9(w3fz|4 yd۽xf%y.2qw2@NM;K+TkPm֕u +- +a.F#^bjn9dȱr#&[B`%1M 5+GC1ztb}?ےЦ_Ԅe80Jm1-<i3|rNԔ~~J,=+_Fm4oݎwisg5gRfY1|guC!;+SgnWK p5`Lk`rGaRpcI:M([ +5{ í²`6.:o =w^ڽqԡVf$/Wxltq+rѶX6?a@NOa@E/@|.ߤ6| T +^F<؛q.bjWϐLv<^bR6SHˬ&5% b.d(_u'N$ #:< +G{uTQ@% omi- +:=Q=ۚ tu>=yC?o[᎟D׿M(*6n6RH{d0˸_r }yRj(iٲ?4ߤ+$ދ/s#e|YE*maq">=^٩6Va:AjD)e[1R50_sK:4/o5EOҤS &9k󽹩D.,tiic֋a=^kꥐ!^"Wn޴2_;[I?ny\,tyi2n"LƁ} D?bq8%șh&o(0&1̵`sT^5 (̊URy(^^<_mE 2\\40<"+c|? M$,?`![5 n9^ D?= aɪ*) . +v/LjKQh0$=aA__=?dǷu}6m2xksn}͠ R.%8.pK|zD☠5FUq1>'PťP5;knR\s>iIWvW1-%Zwc䒏d5q +&$t@n/WpO~TdԈdU z31d/YcsևŬ?xP~|"5-MJQ z< +SAhVWd(m"<-L"| Cb5z'ז%:m(dyWǵqE%5e +Nc!z/!O*4ᇎ8:kx0ZuQbWq\B%dJmK 1-fGݳ6lFe" ܷ\%1pb^|$|Mnmw{e~IKLHBNrH]lG@4=#-Y{ͧPEm:WGےr|qe#H] + + m,PYI$f5^ɔ&H^['TH/N9mNB9VB:$ ?Ҥ%km 0)mCpțmpNsT^Um\3@R73| u}/؁e5}E~΅ +/Ҫ_mDW>P;FKu"ϦnGEPHhB c&-14gGx$Gz 6IUݢbHpPy43\ic_F~9H0m VvݒX2H=@w܆!tbr6uHb4g|Q@#X Zt3 +RHa=gHoՒHcmk- K=,Y*XI.iؚ5r(ƮųRB<Ǔ=Dj =Ý34MW6q+?G5e?CSjp >mӕ%5Bo'D/x́Jgtx~PyԦLM餸O9s)$%'JB}rޭwta(Vd{礔&:1#O{/x:p+\KǔM+O(ࡁ۠KeSi)NjNmJtOd.4c ˭"6'ԙ$}?穾VqS*SQR;.C-3u7NɟO;.KٮJacO 1pĀUO)#(|J.r:X2R9,{,6Xg~lD\-| +:8$Oo#%nrJ%<.sH RD~{9VD +UT錉Q>22T*HB1䖅T&W&Z6A/HXXc "8B_ $4DJ4RYhMQc{GO|&BvR n=s t)NDsE%-b`̽(%-Hԩ04!vxZ3BGͬF9P&~ 57!z&\lE>@?B@w .x$qO@̫9>T33+>cK9Q&LŔ@% +7ݝ:NcJ*67aKƉȐMש7KÛn`S-8'HH-}EtPu2T /_԰xefpo_A^BP}wb$Ӫb)ƖhoȎÌ':fA!WAbB1 lUy ˿*c=G܏}2ѴiURmɥNP/a#xi +]]uLo ,N)b\vh$e x#$q@SV%{}ǂ{-dw KǪL6_h`$ky_=.H8K4Wn!ye(5RB:Q +%ybO7`e> !Yo1,@2TP{17_@9$$a^Ñf B!0G (5g52njRuֆW'=IcՔb.a-^< }nN|]-gֳp>PZcAyxpjCq]HHcm҅C>1HPât%} CEIJݷVX5'}YgE(&ܽ$"4IZ"q@φY$r%8KAy)n2>,ɯlLx5&Ӷ##@=fWoDHgLMb$0=|Kr)(L.]Z=gA-wY"}yb0o.AGyS=gq2~C'AG/ "%2̡Ϡcf ~C'ADz>ȡϠce ~C'A'-Vx-:vTn9tO A,>̡Ϡ#9t"f%5gm v%H/NZ}Z<.Mc5:sE:^#%l3o +ĀÒ6>"*sN8"$"r%%98$ɚ(}[GAcA >W +$&OB$8c2Mhۆ%JvO72!z嚾rClV4`#X*Qo9Īr{'v#ooyY}{@,=:{8x0 x{h;VIAK0 a)q^]n7y`Sӄ`M3J!ԩ_</,Ɏ`Ο<>UN3OC`_=;B){ endstream endobj 1390 0 obj <>stream +)~HiIK_QZm#Ss'K-}vKϗ52m`F;%{x|/eJ'{F ^]qT_ZMeS^d!i&=XE-Ob@WȞ+;wy:ʯH{W^$=Iጨ+6=.h qONǕf7#2.Al?D^̯R$~:uRXww8_2% "2ߋϤ$"3Gd7~y<"8Wy"2qi90E,ל,,aaYX>7.XzfItt7[U^ۇfOyu1RGE2_AT1V/ö=Wz&Qsޅ&}'bƙ:|M>)pY'vB{p0j +s#`X憎ǽẅv>[ڱpwp\_Lh[f}YDP3B33ec $>F'^;D8RH \O'Dh0N8 |ޙQFij{:>",C:Ut`1e>J]"8{"/}6`{G J"$f^X6-cW ֨5<ǰ`N/GFU"1 ],Ա|(!TbFX>2x;72Ra72R!i@s\bs}4CFZ#5exrRطS'z +;/_O}ܒM1q T8DD2$'?H㏏Ib!S0OK|Z Ur#<^ERzAPNIE dLf7mK\`d%n D9ʣNn*{tG=V3(q*x)fUFx-TJDW5x-neñN\LIlkGFX-$mlGΜ-ܽ~rXX‘[ߓcaT>ʍױ:Ic_LS:Az߬$WvN %JroEẘ#/!;!8>꾽*6"u|k H&:#>'}$…J-@'M60fZ˦x?̇t|1Azʦ←_dR#MǷOЕ_˦˥cɦ˥xl:Xf~5ϸaN6_.md=wi~Mgogi鸠^U6ml:$'l_Ql:eV;l:/dl;#_ʦ{_MG V6ݫLd 4 [W7 Wz.Rɭ!1b8ղ}.].Ϸ [tիߢM%IHҰgNq$UH.ޘU @*,%FN"eD&bl(l\8]=(l.{T+tq;=WMߔ.$̝P&D:I$'Ӆ>d(ʌhJREHQ6xܑo/ +I<:fpϕ=\O<׎(\0V* +u/OFgD:)'e3 qH/XDq RG0difO/M3PB=]P^| +zy~Li(Lډn̈́J[!uK#+ɮ7V )7Su.;LRbP nbmuX[V@+ "̘K5>R*vZ 3OPzBgW2S7oI<ݾU<( oK^ +U k$So-$OUPΪ%$2ë,ÆDI++jbm*܉e>~ FUJD*}O2pK +wb^a+If?}X;f*9{mȤ:dm%r3Ə`~a7{8OwD@8_[b/rd 当Η }!!u&1IJ:8z -&%=Sc^Ә|IncU4RV$&up5WJb:Ak'h ÐV׸IV1迼[r)jo_qm ^M 3UEV8 |lIór\ + %]pSDNOLK:lZ#&pic e]n]Grj-R + ̭9JssJH] +QFt 7AT&ˊR'J"6&uu U'* ٳ/cWZF:_TDpMj*Vq8CI<6 A*fNJv2B"|JK;:,D@Ee$Lh=UfA˺]d7-$~Yfߢ ?8|W^]q"|}hguU@X_8WvכLZĎuqCvD=>t`9o~R[›%=ճ,x&[9V޷9`t2KŎ_Z.1SՌUf*F)!yϕH*૒/y%_'HfN]c*3o{UEGͮ*Qe.Aw.?z:oQ, {J)2 Pj{H$N(59N@ gJ$ֿd=^@Hgw>|_e +t)_IyT^퓢|=E'E^UdNQ>2gD@( +^>(p}oT|̨KS^ Wn7XOPc wC {oWPYvU?֝]oXu^~xU'XO5##~t/ru]?qz|:q((''GuPxϻOuD^[Oܒ7|o<$.K9I| _of"}]?6owHCϣ$1{cC{J#coMT]c}I{B]?~oU.GZ>}2<GuC̪~B[OxGA'NLuxQO^8u~dS'~Ӄ~Y]?qÐ^?'KiɭdIɊ]O"m7YI'Ɇs&7pDk']?q XRyCGF+O|pZ7*rt%U8+~𞓶;ѻ7OƦ(T4hXŹA]`BZ nAi16ņBPd{tϫ NciձS̒Z-Bz|EPǟR勧iweirL=yeʚΈ3tbM=<]Um^pBٌj؏Vn|@0k#{Wij]tn:]ǡ7Qk kb"myjvuĂDz1 f,Ir>L_tKL˚>h66MW~O{1/,6U2_|$'yYQ]4 UŮDJd4jyIBٌlM!3I'"7Q{"'jQg_:M#g⌤9:k|tMb|" +hJU5/3?UlJf>dۇFM 835V Sۃ?QEwl9'\ښ`ҮtC,F^IIlvOV ;qW'}_B(@u"nMYT:m5W{GZuxg>2|4px`vAA/ND7 T Jkʈ+ u$ ꍯf 8&=(ƇF)J9ш8V,ebfkkB6Ҥ6K꧐& +={v_blQxƣ`# 'LׅmW|d!-4DW=G*(rgZt߄:kuuݬM;mQӌ c$g >5oaCK~F yixr8ֱi@~G.9 >Ŷ]daK0_r.165 %F|Wݧt'>.UML c)l1pA'D;=F[sh(BN,=_,|`4-6>˗񼩫Ga`Y./cz,= "Uwz]+oucJ?ukz3bvDN>B-@Ko \3wLZ`75N ղP`u[Am{ Glє 5N!aQ>QymM4b3n((l^}2zDaڧ:f|azkc{L"Hf钪 ]Sb9yӈHÇqX6J,.o{1(@cQC|~.Dg*4Owr@d^09Sw.0CZaqj|Ћ<23BgW#k G0 .A] d@@\a\PsܭUI \I/̺ %wo\5dsE\5l\z%MTtg{ b tLvcaloN{AƔ 2ԊVZRVC!i:TOnym#[t}6{] &mu"GKd]% +W~WAէ L_Пp@?Jݳ}=Nd]Wo\Ejp + _NTIhm*qO~7@rj$ReBùqH;{mwwxeD#-R^1Rt0i`G!A n|a2 +$M N,OxW}NP~2 "L+@J"0>3/Ї#c3G ֭dژQmlw[>2?D)s +*Ѩ Nл;c\Dqxb~D9̯HQn-{kNg~̯`F^׺1kr`bxc96̯\5\2W%P(+z2;2U̎L]Nmkc?1Qp߰)_sY%I߽ }5FUIeI0`ĊR=H`+'y|#(d$B\9';FC1@ޔyu؆3oҮ.j FޑX N6%1"մ֒Px:2jjux AOL"a1'B Fr^d69 \v$7YTv*[l +ão>2ؐp?AD|ȢG *:-PiGi13=s-Ƿ8$yϰH.}SEHs>mCBM'|pP&Uv!37gB -=~t @mسNN h(td(J& TEc|~OV&X=#y'7`RM$W +w 0Lb7M`kRğm- +-H~{,8c +gflk*ƭn8:KB64؆SJUf._4w8Y@`q:~Xa+{"vtf3hyup`6 uG_˖m&3S]Ϯ>f^؝") C`W + &c ՗y7|RaCzkܩZF0g|Nz14P2eQ0ȵ2 Op]5rRzBp3;w<~'?Zy\{~yZ͓*N} v}|xéo~;^+Gpu.|zpm wK5n\7jOowy O*c;'^ډkϟMA@r?gNhx +/^*|ߟݿt!o} _K?\L+{?p6~f;7|xr^_tÝ­8pҲW>`,@lKߺBۯݹ%N!'2OOy04tWXݯ? nf;g߿{`;/ pm^p\(W>v Lwi~~cg}r+ԥKUv蒙' BO;! +=k دt! +؛wCOs!ߛ{M̂M oμ[߽w7wݽy[>/;[wn^ۜ9+W{7omՑ?+%W13bc.|_}jf0TNyI, nx-^% +.f!7ɗ_p/տ_˕>q;_\§={9&_ ԿW׃ӺovЭd NׄO}Aڙ^=[}WUWO/>o;_~^nI|ް0"{'S>S~没K___;ɸ|lelfއc_YIkJ[|e?׻S,krfm_û~Q?VW!_P =G?]{A~}יV+c +HaƘ&]Y=s{W&'{S{ԋ?C~>Tf™oᵯt7+:9Nv'4]]GOO|anϗzև ~8 ? etsšH+ +^_Mc~q׾eWϿ/W7=Ë׿?ޅ.w'ᇡHߍ_O/}䪃o40?hg}vQ>ktCW}{u)g.\/ɗ&0p'N_T_ +yo|G_ї.*i,JŃGT>-7?W0aXq 9FɃgsΝ~Z8ؘ7=D}W/+K'['}RWNw>ǕgqM៯a5^]wt? _x_>>pgĽC7Qd + ٻ)ܩ;і\>wx8S`z*gKmC|헏}ezk/Pg;7^}ލE?usyZ-rv;첸\gyeܭ3[l|aƻ6L }`u+|u_y'm׼O[Yƻ-.uVe ;տ%˯'zlp*ם~-GSqٶ+q| la;bbz!笙rH$|`}ƌ{w1'sKm!@·~\;i!ѽ'x->y!uy&*Z>!u-x _IvSlOFaEpfn͇펈 #_rV_uO}ωO~.?Xp?+*O&X.PTa0#)PTa(x0wUx_]=$d=q~/.\g@>>db],d]$pēBO_K BY'/%م2cO_x(ev +?~@Y:_^dE7~/Y%>Y_/v[GʣhVK᥷^毒~}pզk0 2oURF-p #Ss!MNŸO=~_דwOm^{?qeߗ7W}W׿ǪyS>Zxܣcĝ~Ƴh|ބr_~u}\]h%Ni?|K둫|X9jޜNqߞXC|Í>\*Jͮ|\ĉWB,~{76"|KE_. c9=T)pϜ  s܍ ^wܾ 1q'Y~$:(sii>CҀ(N^$r_ < U|yر()D_{cϧܼi/W=7OCx<^ǔZ]aT/yy u>mx/?]W*l`b`0!yݜm!'[sH6g[BPn|wݛW~341O=141O?1{GzlNl`,}"#$H6{(6?d~ꝏ$0G +zS5}D E؜:QG?ٛeNPrS(dH : >VQ CU^pkA;./Vcur-QS=eS i{/3 ,G蘄}(b95B B^;5Jrk(nf";Rg~eO{[MGjI-V#Û;hLxQs(G|  \RqMՒ=bkL[Ӱ"/EƜJS6Fq/ #_3?c- NR#D0b@V}(ZluǸCU'+)Te$;jEvȓfu۸0UhbF]K+=4sY${ǒU +4ǎ' ѱ~1 CtlIR@T9oǐyx*zOᚨJߔ*Mt@ ė@po7!dIqdBu X!KȊ@J6;]k_<-<<bFl^vg)VҨKfQec $O[Rӹ˭-GaaBr|ɘ(6"0r0Ɉ$@<GKJ#*=Vyuq.󋝗[7wXsO嫦2O]#D@ohk ]k1yV"~:piѩ m[,(2Xl/KÙ\-Ў>W/j0ٺD"1Tf֟Hdk`:*7…cbc΋U0AXݦ@yMN"Q4W +h@jUU jkD)bHH^y01,_ٌT" $suNeZ!rB1F 꺋fyv3'uʍ“jCû3qY5x. P9^әYl9"pCqHP2ȂX%cYP1TZPMmZq_BŽs6bdh>hx"I~Z 5AL-WG*Ngt5c,h SK4V):}qc\N7fs8 . 9iS08k9(-JV3~ ˋez O](rc MW'AD@8"qm3ME$&əB"p$Gpրr*l5NΆcr@+PL R aJjnw?E'w,D̉޴ٚed+cՋ$ xZX"?SN HpZ- NU@'8>4ӧ+.3!*IN*\ׇ_az1g`-Х'B|yrN"abwXŴv_rUTCZ8);$\(tLr۔]&@oتSނsܰy\~B[/j0}J灟.SQ`@)*EUt$١[ɯbOoЫ3LYEP]gG =kNB_BغٚedWcՋ$'2ڃ @]&=]@5*vX@\ +slb|+L.Ūao5$J4Wvi&GlzQEԵa`jE+$߄P3̕K] *w^[iآfNXS(G`$TxxQ&}R|2FkDU@ x:;SzjTi?b@g*Js^)VӋ*@i2WnzyZkmpY1fI7f4Kփl:9 *q<hf;ed#b$LC.f8-)]VM˩|3!e{ ihrLpZbrPF1 J:؝CO 3Z~)}H4x0ࠨSJVhˁ@hXI\,yw ;4,0% Isi#6ߘ?)Ïi*cJ?XNJV6UI濩)09/tC0Y;t{"fBG!9GT4e !\OGXp|yN(N|&,.kF{NY%r@ob}@FMZ3AJ`D\Eu6M +RFB@N'$(0H NQ=Srp04Keb P%G$jIиjmcիF݃ n,wFP%MŹYD(`Q^ +=H5RrR?pQ#fDxB"F֐# H1/(PVj 6F3 1>lkIV1Gq4`4=^ zmw"<_ԹU1GZ<ZS\21Ψ>s2jAP$HJzepq($eT䴬ivgrKbt!o1f.sɰֻ&k'c$M`} UʇcpV +ALR&,NGW>{cJ)oNb!c$cl$JaɔI:-]!G EO_$ z 2aI& M" +ebA'R U' BCKHИ]8;p޺)) ~3t4c^'Jl'y5T@V NKJ6ծ(`u|A9R&m gF QL"!DYr fg9$Gbź1&kW +$Q]o~1"Lp=~ +sQf|(t(G@q $H>(h~<~-ܑ&!F7sfT0^aO,XVGYw?(TLA`m]05XNw`(yI#3X;#3'Nc =YAF&LuY=һMF5\D2IܡOȧr* zEFހd8aj#{NHĤyyԜaԊ4(s?C |s5\}vY?1;JԷ'UZr VV'ӣ#Ǣ_!ZD$G@VOp^9]8d;HBkW͑b'4/)+4&b\*-yT+bBTz|37fHk iI5u騑=[VJbE^<0٫$K{ƶChPE!c9Wrm +2Ŵ6 +'P#t 5"GH2 Fb2#J [<U#]yމ +mN̓ғ"R3Fne6ǵMfID'.T60wI +?x>^YVRꘀ0.~1FkQw(;~Nέ֓ 0jvd0P?Xux֨?u0RY??B-YrUM$XC]jbվѥ̕Y]o}x7ܾ;~}V%ςNV iߞݑ7Uyv:kӝ該;"8dh ]ݤ-CjTj~CV{(\:[?ɳ7}qk/l.~孃P Ld5ׯ}݃[/xx ߹^{S9s޽;oܺ}٬g޿uCxw~[??#io|`+wo?}w|>{_~g7t\ٜ7s} 9twxpܺy/~=Xa˵wT6Uog杽x?'ݓ@I`2lOV7r)Ðw涌Ͳfڠ:G̋yf815J;GB\93; nj2F\ U_ޱf +i9(d!g1*2$9a7׍=.Yk^EOqIW'  #8}bE&2Ɋ<1bg\]eO.?bu}5݄ꪎ/-߇*}7A%9M)}:QYF~_-`N'*;_1(hx(5bx/'~G;bPj$^R%B ?xz[j:2x/TΛNԼ~Wqed9<ռ|;9ЉhY?bi:ra2aHA]e_ (]ZBSvYͭ} 8gCfh%11w=eҶjx]333άQ5HhCa+lOjqD!&Y^+2GuaHs|g2_N 9` +`6_ۋݍSN#vbeHŨqI|&0R!r3YCg&*QT<Iwj,eJN/(qSaQ#1Ɋ8jnYCo9zNB>.dkd: Ol +W<} MM!@ʎRn1㣌9Q(1> +02=Z7'@Q̊%h9l|B~鏚VEimABRC082PCUs +drYEڇy8T{MO9Mh%¤eU f >?*/[2akzb%JxUa9~UT'YdP&'aY &= ݝVLiSRz=u빪BUR,dRL&U V.a(9do ˆ94|EJĈbMg(DHT%b tRsZV_d]B}q>c)K|廬|lCYiˢ316S)APί jMK}\eTF`7.j}t,b= K2SJ~jr +5tzcSY+sl΁s+.ܗ1SW e,]mG*vᝁ-_-CB73d2Ӝ@&51rQ W Ʉy7٭N [8hU +(G|aaS,jiI֍ȇ'xgyG9 9znEVqV$mF!fш4pQwB]ꙢkVToM.'# Yb ds]SmXW՛РU6HR;iNeAAU6t.}R #8[kf=s`3|\-7]qsb:❶~JzMuJ{=mK,JOh\ZESWg̃l\?Kb]Vuמ 8^1[314CH3+##Z*Y` FԿb &PN08 2RNN~j|7=Y6*;j-lTDK[r0ꀭ0 U47JMfaz +UBR2PmCP MIX/܄Y^~egU(ZKSMa%޼*[SPXmt/%K9GV$K/Jם1^g?l}(ϩl{0y0~Mipe#}#mIѷ7;o+#OUcr܊ )ї$8}Wp^kr(q(t?sw3!VE7YO?>} ;0y^V=&w9V>lV9c$I_X4?j4/"yLW\!LmQP4m4:5`Y#Z|n+%jrV5[T[qbdiAG ΄`͇E~^Gڵ^s ήOah.ha4 /#N?0Rqb 2/ Ҍ)l}|B`-摅HM*Q gAjq6S{3 dCfun]WMhmCnedyT#qk14E{J)nŒ6 WZ, 80T̔,1^>1d™Xׁ1ЃYtyi9\ S(Ez!eeL{ `RtY.ZewgqwމWwo^ӭOn}u.Gh܈""r1x޿q[dGI߹zʅkq\+ؒg{]G#ߖoPl&=kexG+q~ ruۃgggG΄)OI6Hz ɓj%+J$-a U":CG먅]/Zk xK;d 4f}8ZLJ5AKN3hjCH@Om6~(Et֓AiG1Wre:=Sg7 nR<]lh(*8T|d5ev.X)NuqM[&h'bҦ0,OØev:HT,jj:/27"Y73R }Ri lr>Ffw'dk +R14$gҔIk QSt:b^č^ uSLS@=?d|׮RW]OѢ+!BJ({if;c]4pR؂OvoxAS0Ed!Y:XHwaR$S$Ï3-Cả\* 3"e[4#2UB fJ@.KXt)v"CA;c.T]zEYj4ieԠeʈ+}|d Nj[ĐrP ޞ;/ KJmbԌ~k2I%c \򄯖'1!UyUr1Tbs1Q ߨnU. RD_i}F1[:fdF)bn,+Krk/)Kv4#&"[!Tx"r')ƇO)i>W6fmdu%3 +U-MpiCLXs4ӲǢF}ВXvh;gGC`#;/ %E  ȿŸ!Lڵ=iRDOc w!`؊kxV6.&, + bd<`c. Lѻ+K:*|,҃2³e 6.wm 5(={QV @#賴t6:K~մjNn}r2 whFY$He:"Q3ؚڱmNCޣ9/!1 C…x@{vjY1/ݭ.zK[:f)Sri<]衻Ta'٨3VdVU- tܵ(d2}8-D8c mdQhH8f7MоR3 w囊ژKqJ.660ϠU6$faǪ 2aFcfRr+6SM-_|mX~1%IA_c @FJViZg4-% ]U.yMbN*qE!TKTlƖϚ$yF e*-|xovMi1k GLOw8bS` +/#&(cR&D0fDHc}}Y{M^`?,r1[:gmY촼q0dVH52$5*:y-wePCf tJh_ RjWϧ*k#DYq e4\WDdv Bx͘V'zCXKӁ t*sW]x:GK[T5k+&YZ]q+SؑYUY!7U3Tu7Sd2tߐYB3hkFZ +.3[jtD4S +tl9HS>=wAYt6$y, ]-j6Y2p!Am g|]ϘC>UvbFш^3,ͧ*A֏Immm-X>FlZ)h4ĬSg|h)C\ck@ڰ,BNSYgH +owfʬXhV?"DZKM)r٥hr6*=A@5յ'n@w +Nu@@KǜcL y̑dS&3jmWx(("s C Kws MJg*ZLpt>eM*H 50%VFY˄xU-PLvF3ʟ)ȃ+Ƃ!2@a6%iΚYy kӃ#l72hVPy5+gԀgڎ:#`ig7oKͯIqK-jxlg/!rgm4ssVwhngXB4 G5Y},_ hdl0߉@^+b4b$@BIl=*0)X] =`45G:VrZe0b}&:. }f|gl +ް%poKݥ-U7,`ץY&cƫ7,lp_K!%ЉՃA3VZ+ +\K*Tj1ّ~QRCbZ$J5zvV=ޏ`Jl c6i"Dׄr`a^Fq@jʾ@Ǫ&}@IZJRg(O~ \\i6"xrJvBYPGH|0*\,\l4naErT֋8@.h]kh=+ +1ֲ7o`*S S͂d `1TF)V"(l5Y*T}-Ѻ~j#ʭiɤҵk3HUa@T# - ,Hq+($,.y0\ +kPz4]j'~*Vr%2CPZ**C &6tԘOD^P?f\([mŘ((H÷`Ql6hWŕJt}kЬ[* *\I!?b>t毶&fvAp,#QFC +Rzu4z> 3QfK;ғ7XA[ᢵ(x54d24Ü(?qhq@I,o0)w W;ONVH=#w)ZYc$y0d7š*&Hֆ-E-~X`2`O:Z>u},w LSLPt4ea$1+6VҜ?db@S@&A!j=24 GT# "%hj48v酮;d !vVv;6b^9S@]`| ˺L8 `;e? +@ 0طͮp(&vÆO(n, %`CRjZl5 rᤥk׸U0h+tC}2aPTهWESu1jh1FXqhy kD:fPf rɒV;K9ٖV% Xeh!8P lIU4MN[Rig8C`&Md+  Rt+Fw&C.eK3 0Ҁj9G2rzuR,pA.uq*}2G ʄRu(*Bz\L3]?Cߢ0Z"I1XO%?E眷rpbVyXベKlIoS1FȳȮB$2 >\JMdF+ۆhGׂl8VkJ',,+<Ql +&hV['rȿ2Q41hRYI˛kncRiZ1~e_#`!/;sCqSz~m Rd%ӎ3D=;+PL4tcI l=eC9[#G󒢉FMrM 8j+[׮*3 +tF@X =bFrvIR}3/gZĔ%r>oa>>?/6K"Ղ:j;l竪4(u-WܷGFkFu8糪h5QK6heuuO,!wiHkhɼl`O0.A<82 s@}nA߮n\"N7$'`+l 9|1Z#KCkleٽ)bQ"g麒 bt7"]Yc NV摓EO+Xp|)Mrg۬f{ aXXjc:Iqk Z[&c +C&qq>;=`Q>К3i'{Z"/C=g5?nMJ~f]>\JWW1eh<˸|7:h;|h9|!t >C(>z#;5Ţ P_')[Dx͓7Ga|&Ml5awM@Wv G09T'!ϥ˂e!ƺڡpe1e1e1e1'b罏9{a&Dz(1}$5]>3T֗1 F|>iݾ.hvIۙIZI~VINlEɒHSHǘuپ:D5K Eoh_Y-iہՐߝa ?=;xziw,fƲEZM]}̃\9Slyۨ.l-qP٧RC{L[mݕ-%~!Y +A~kKՈǺ Yu>@sp#^-ؿ59mq]7jPXcFjlU~? ^yjùtA"w!"D6 VdA^sZ( \Z-u.ȟƉ2̨UWSaug뢵NM%0dUxU=/#:09Ged6E֙@ !Q իII4i.H& +~VT(vZ1hvff + L򅜖y45!)n`^ L2*gY{|Q{Rl5aGTOe92PWtxYՊQDu1I`T21RP:--n;Ӵ@1rmff%?:qYi%?ה:VRke9tBu3Ԭ7,0mZshe6tO]bP4.Uf.7SFCc.pZ5)8MЬfXQA;sX:B Βa^#ϧŖin;n̨+1 + + PetIȻeް #- 5c5NZ>2Z%eXkxd6M i+hpn\_h6i$ YRsH`4BYŷ + [2om:>u,)-Y}AmQJemQBB I&)rͪk^`|ݙ^C1D[̌XQbhtm@$;Q(<Y.WҤ.Xz`Nk3B܌CL'Vȣq|MuU1< iZBS2S#8a,:m'v>eT4'PP$Z_GWfMg\- ÀnFȴfB>xg.C}amVYk';"hdgjӲ0>s˜AHCQhBkQi]E VA+C& 蝲Q)k~x#Z؆뇵TGwoIdFuƨ5S4 +6VBȢi[^??F=֜Q(y|c3RՄ5#BYa;]DT4md?(*p`qij'R0 ͡6#Hh!$֑:D(CA쵔Ccój%?YZHȚ^:\1>u 0m(Gy3q,"lo#V?[l2J2E {_a7lrzD mm$(nU #I94 R"B heQ{:*wN}60)t[#guF"nļ}b^ZfkcQdW [,ի)cewJȖϛKzDbQDېūBRrĿ\HΨ;ΜqY mLjj(lzʷS} ~5xL9,T4 5@=Z Y(a{DipU̟2ʫmM%P-thB@iF+F ^} ZV8@6u%b>#}eNfEَ U-V huQ6^+HBocAkaG]fG +1IӠ#N=c#F !k:2x_!rGi=n JbMv\`z@JƝ!T;Sg H2! K^ޮ-M]1a8ǔ: ]oJdX~K+떵C-DQ +!]چ`*샷TN-]QضJRIxYL-`..ȹ<فŠOfd*9v4K0Us?i2n1pH6UZIz"Z9siv2mD@^*ڈMoŏ1egd-2u\ NZUI V˺d5}V$-x_0ꕤ2ŸYi~T蒳~a3C}s\@[)k̵ӻu!``[Jg̣3jlU5c1f)$ZB#oϾxwG1%EKe'i)2Q#9d<]Jnm/p5kڞTdAYpZ48V08Uj4˥s4%``@oWYYʺRDZB!>GN-_ Q;Z֏!;ny<͝h<jxѴ3=8pvP{:kuh+|]b䰝lePV_SMh(sRY5稁 grnrm G|9h$΂7_cӬOCì7cN 0!b'^e n$mV5=XbHI fFbneVi W-}}_sv\Le lbX$3--3鱦`݊3-Zr\UE48Ϊ{5<-,zsp\Ioc|qkЬ96>L-Mbut9Kcj3l#i)f»}.8;phքf +Q3T 4~tǪbjH]`Eth̃Ldc#i1,<'clAKZg' 4|^CQgMLט?0ꈏQ2w&5$Aߦ,?y`oMi"Ct+T[أؿM%uecmԝk<Xc#hl^ o1 ''GmQi5[88o$y)3`UhNS,8C}yH#jXqʒ*&bFU#cǒ&b$0ZEcwfdz_|}1b=lnlmeu#,7\adAy2kE%lӗ} +2?Wj#Ppz/W/,Q~#`9QxQPXhS+ϡ[6;U;8<5tu٣PLRήnI1imEȺsUXHY}eg2J5k?Fe0=l n ="J]KVO@`c:\l 'ͣT4nѬ=zlBGqXvs{'^/޽yO>rrBWd ^b{7꣤\vr\-g{AB Y^ҥ5K}VIexwD72?>sDESD1D@1~MϦȨU~p^"h4nC)kV HRNEJ۵2otI5/&4oG6{=јn1*f^GY ,~1ԪjckO'vBYX-=G=L w| ȧ*,f״l:o3G7́0.yw棽#E;s4gcan?-cQ5Σ՘Ί9wwr<<<<=变 FEP #e#$+& h7S +Ϥ|ʢD{;rb4mU&WiϣeN45,11~`=zyCT -Y/}I,j!/LS +~~ezo] jx[8Z@:zuL"D3ǿuh c3%7 &t +PlT^T< #֑Wf3.]xg9:=x|M[:`yKRuJMHF9h Z(N`&h=>c +\چ%JJҏLV ULj +ëAQ^fnܡ0*P1h( E=/t7j϶ڈ,*_63mXX*s}wYtn}^=H?~QIe#Dye*ʉWM꺆M +GHb8,f!AZ7 ћWY t9`t8 p: 7I{:voo˚|8託ߝid&ǜW퀭 ʴCJ4;X "Y>ɍ#|8(,ЍV\fa/Ssh(/˓Ԁ8 EYOW8Stc+Zn?#Nׅ?~Ћ1}Z/ke'g0nt,,.*BĨa KJ+#N9M py1C:ihxbv8:&@xAG bѭ <6ax."X 4r(Fay2;;v2x[#}hPQ;>3Xρu>j (#ŷW,0L^6hclC'2mK(m9~diĂ`ѼBQ~tk;!n޷);b_S3/PKуie3%ji2  ;ZYY5}v3XYPE-d4#VW)sQgY5Y8*7Cqth4QSYFA>o#snֵƬ5vQƞ@^9Q!^Uu8APqQPIHŞE!A$|]j-) *A E!-,cUf+dLP##Xe, 2v2z}B*s;;hcNH A6|t[()1GaT09u@0y5UjS=L*` ;\9@p~ӆW|?uJ`~iǣz#m@1a"lAz[Ar256dA"MѰH.a5j֑j,Yazq9!,񭫚v wuʧh|q/ς/E2qOmSZ8P}oR RГܜ$ uBl 9033zʁ` PZk(.h}ϪQ ݃;QT/]M6? +%((ԍB `8:Q0,vGiP] 蝄?]Db' K7dѢO /1;jX$r6x\6@حM'%8 =k&&u'G%"^Oj*k7pYQU(A!*]ŒZVFT'j l~ww)o2v1PBwQqMa7SvO"hZPxzSlCzwY?5޿gw wQFG$L2-'r~X"u;\%>`-qF ԶI +491X8I,f@{YZVz3o`"c5(yW{CDp&g +pKwt"C+>A3]Daŭ(m`"@0I)`d'G\|?mhS^aCq%k}K(mKý27AQP :&@=2a!a٦f +5PU2!ƪjɚT|+nXxd(@)t]8p@9Wr9m#{@1#.Zw\szLO/Y(nj=GPSo_ΩCtW9AaϦ!Xpe*( e9Q劑-6d6*!wM&ºv1t aU|σ:kH+,ˊ5/MK[.P|jV +0{j$ =,<"#>eGn!OgO/`0H Z6ђM뜦)lE⬨#L8묊f +kos!&G~ +U6<ǒLö>Y @u9ea*I}XlfD@ ݜ}[PULoA$t*XiO~( dڃ)4p`5L=y)PaL*5sm/ѮA@,u c̳$>"J@ejA97䀿Or-GQeF1?|?=fu3*G'*i8Rc0TQW8 XaŰʱTG67Ⱥ`FaY=į̀))TBlTVpQs=\eN/"svEbNb{ n 6ϣٺPKMC n14^/5EfZ\e[1fkWWķ| VFk+lo"Bֵ]ruQ)u + +`) !|gM +~erӴ),gڝCShBkZlU~SVHqe` EJ5̯ + 9W)7y]E{32]Þ+{n-.krR64O`<  a^ z#AUfpL/E1sIJ)T)KhyV-B'%fRM4F0c2DՓvf)e,6/&zYEgM @'K*ZAl+nCY ˿YݑRo_a]E0KS \!?W9a<*CY8ƳS{fusXk<4ڻdo%x{ّP3xJv',e^иA0;؈\pAKv6CU pR( ZEv̎,MX ҙZ 2fs ߆NTOy0Im, ̞ 0+EȽ.40L Xi)JZSObKɞ*g.O/.-ҰD3^fgX0Zb$BOGN(z,1I^ȨduRĀf u_8 \X:iwI4:BD40DiS+Q4ZDa@=W儲ULPӚ^ + TVw&§dVÄT5,.ǎ} ɾ,wa5[ɑׅSJV*6]=L2zMY* ’M;,CɘjRQܸTe +)j7$/11k>p5JMQUњ1J\6Xz%Vْ{qQ$K,"tP ͒+EQZSEw9Թֶ4 z]"U`ދ5x~L ?gYtR_ 7~XݻȜ54ku,cs7UTqMQ9ףz\a)JRjŷ 8I8Q=Ȃ e3 _d߼Ѥz) 7y=xGi鵚 I=)4 dд%#oDCQ#<$(]׶l:XIx8dXW%$")SSwО;n}[ *7Iȗ,Z_b>iΔ~en}J)psyO*9p8FY-T7gJjĀ3 _j)> U^=,IbX? +Dd%kMUzBw/Qt ʯ97mEA^z@g^_/~«{;}d/1X^,+h~3|~y/f*y7} yP؅%!?$тk"8Y5B_˞XxR38܄ۄ {+p/Wj!fD,J:%+.&Ђ#,WA]zs $ 6#Ɲrť 5b4k6g}$xNתOl@pAr:zmZMs$TA'lEfv$g+%1kPEKg%)K%- kXaDTp(=LU8w/xk(peú޲pu hIe3/wdn0DAB\4|EEQu6Ƣ:o6 u`]'/)I\ :dU. +qMi+: EWDUZz8~֘ +sy}^lmqC2{ (bhx +c%HgVڰe W9=XVu$0w^Pyz=JUL ?dtxc K}kFߦ}aH@jlwW*:bkda8ʷj8 Z}h0whf7˟/C6r7V DA6R3]ܶNRO/񺃚_ @E"7;=e+Gs#8N1PE;|[3^pR|#|m1Bdvz@@Z:yJIr*l`n6 sVm03Uu| ֩MR1wG+]OL/#!u*XV$B)z +(ڦde +7h\s&dCu%H#M4>~޽!eHH$lhE--%Dx" cl.'Ś~iL8%qDph*ɖ(޵s5m +t E\Th^m8Hn'mTˡcN ;e#l(Ӛz/yw/xO,xo|5urLWu=cƧ4./f"d(,-GrsZ`tڮ^Շu8m$wdV'UƑ(ޗ+y˧ջb<^OHh=~KHt_&ke 0ϷSΈoma,N 1͜8ݶYd{Q-NlE_Ҹudy 0FBGm\⺫bClfk3|H4HVRqS|v=q|c=;[0. sޱؽPSdҒ-Yd!ns6e+V] Rr^Q[Bd#0ϰ.B<?De 8k|\8*`Q-v![r7">?޹QtZ! "֘^`ATeg r8VAqm +,)8$ sT,q@)Xb2 f9RJӬ#MYF yAI2R\JvYM_ۀޭe^O^fc5 ]6 SP"1ƫbK[ RdZ:TŃ|Ȇꇇ,܁jT=):OGņS5vUaD}[(s7Hqn'p1ֱWl!&;=u>6  +XتB,pkP5]4]hR})ec+>Տ cT*4L U+0qe βi>PHn Q\I\+ N3?%LM0aLYܚn$a䛶C6}SsC<*ppe:Av^'n-q%TUΠ_&UqWuaFmu}??r%< JzM>LuS8SmXNg~ Eg+갣WU5/bܜ3_6:8g0f\D[LjH$bU83}gDY + ?k7!odlف1Yܟd:VC=^Gfc !jY|J +dR\|껿]ec^ +h̨hX/Se!t=;N]FXFJ;9cE\+z"DK^E[a7G}hgaSUS!_9#S k:(!$mXmSmP^+u|<@`d!l+Iц Q&Si9rs0Au-Dփ܊P1v4:gu+}?PFrrqV}A萁l,'^DN݌fisZ?8&ûmO!^//^ې11vәA-Sa<Âk-g d"dɪi%:#wWq焅 |K)vYc,mrMJC7GtLbʸ*eM}/6._.ԃ{76G#\c-Xsz;NN"@MA'W }ڵ6+ e(amՂJT}%]`}Q_rUZxbjh39HkRp8(Jo֪qxDCpCgf{aȢߩ ƓG5 +{I1P+V;duZVWk_se*Y$8ruz?^7jEn3{Z?\_ׂዄ,|8Gs'Z3êjYw. 5^JϮ fa\}N;ޟ +]$DXceXu?8*pL^9]1`]2NTEGj2;֍d޲MTH24Rn ."Sc&ZDx*8Tjq]7Y8]t_8ݵn[iq& l#(!-,*hɼ?W6o4n=N}P|UI3Od*@9.9au[vdIdC%:z> ]ZwdL![HtkmZO; b: +.?{E??~۷o?J,-x?',(b~o]Wx/Ov\??qc(.v9DT5X`({ vO5D{yPM0oNЁq ?Zof~ +IRh*Qɶqqz(+x0KP닻dn"KT崅oAaؒ)2<Lv\7on?k~X7o^W_yF/_yA܅c +&yY<;x7'Ϣ)__^_7߽$-mD&fdYFqhKlsJa5D^u(_.|`]}˱9<=XŰNд1te@9,$ThP2? h`g}@ SL!v\`CE/x5"L6VmrÙ]--Lս^rZ}F;Ջ^u4j@zosΩ3)Af0@4`/X'}V;/,Rhb2m;hy4'GdDmU 5Do{`ﺪxpg!sj]ku7C=X6.OfJ(#}6E}nmKvGly4F%3']E\e*K#-[-X!>& -w({2E`zA#>DzcMg)eýLPg;-W~Z/ۃ_/bBiE=ƳaIXȉL5m̖Z26g|Z9s4a="XcJW'%~8PxM^S@?Jr+tY:̍qP\ԠxSci&d[ƹ bYYrp{yt*AYsl17Ε%.LRX(hIQlFȁ8UJ~_$,4h}筸(q>s΃(b02q +i" ћIwtH@T8ΦF7S γsoӺ +^,ަg{9lᙽ$+Zu4{/g"jae(NÌ35C˃N(2)ȣl?zꝪe,:HSKiE_ 2T%ˢtJi͘qh +N4Q?kPݜ*6p邢a#|6Ž[~;cQOo僖DB~8(#P;Yo^fjkLBȌ:,5^`B] D57mdmtҜlȸ:]DBʎIWZ;AqBsln֋>ʝսق=HkЎ)ʮ8H6xKb遪M9* P1s%A&PVTZ!J% ! +XWN)qZP&j$"6D;S1à_wlNjgs9l^":$/#igiWPM:QSR~OL$-k1>;t`W-eZ +v,)@$R8{TW3obA,3`QrG}d "PG8=FW@ ˃{7 pD0*?"튥cBZqbE$Xm)>[K6F\K7==Πe2ӊ>zFc/cI4AT`aAw!~ԯ-A Ԝ|5l=g󊍙p^Ņ2jaqvifd?]RK]q +Tjgt &[>WTf'ŒDHiˈP}oEl0bPqJ +Pvad1l9( ~Tbm%ۊ3C*>qW"%X%;[UȯށPjWdl#r⨏C9q>.ai݅Ruqn'W|:=٫h:CYad7q,ѭ`aS5jɼ@;}~ cJaSbMQ2xxAYR-,_iB(IwgaEjrn|vxj򸢐΅), 5W_MnZcILu'S &C屺9ݔ 1qї%gl@9]ث; @&vSzCe8="YU(M,0Q*!9%T}ɜQ˰b^fD)1y80XϢߥ) nUdPHƆ7BIC}7SӁstjVg +Qg^OEi f^\jI\n֩@+װ5oXۤ7갨W0.*v6 Zm+&4_NKEGNj\fwP''ռIo7o|fpIT~0Vv,8JȽH!&*ϮbU=ΩzUqcr6k34}[l4mw +zZwuDe.‡boEVDV}627|vmODg:; +И6QeYE_ /@ Fʬ̳>cV-$RStkH|&f|AmPh߾a0dFZlxdXv 7ȮwhW0D?_a=囂mLͬ7|2s] >9>E"c g3@۬Qm!z|WPiNyK䠻s"`I}2+@ =ȢfvRG._IL\͠x*xRqH'KqʶdeS`$N=w2i ay%$CX^YMrT-I[ECrys(ho Y)޿_ݏْ_[ۏZ?2͛W7핝MWp +|/WphA3@B2'MMƒhr|L#Q#(}W-8|E*_$+.q}ݦݦߦܦyu]S]%T'Z8}gjv0~,\:cCu5:p(.5?emrܼ#QXAc##PzPW{?3)4X 0 Q4i0z,5n*S8?Hq> +uzW䥖848MP݌.ܚ{fH!,M'Zf5_3yLnQxtԶ7I']t߯aϷ~4_F_8 +$r wp`*W5yzU@fǨN@.}gx@lwXTt}}W[7v0i3}+)]NK{?}^ݢuKum +eKRu "zۺ1:0R5ۥm ꎙI}h9Y,5c(I%^ Je!f2Kmo,FudںG%M;f|ؾ_ӃnO=L[6jR@'LHQZ,4&&w0H.gV6=۰&fBhOp5ɜZ;Ts;;`Smײ+.'_@Xd=w5g뮉߄񱳟eN&@=ҪL:˕U}Ҹ_ӃnO=W j0QM[vIM1muD{CԍjeYTx(q5sYuϴzZk$\%ə;\wuhC{MD c&P$׹nNy*RL rl*Zzuu6vC~Lcz;p =Z&]xʑJ|B7͓a4 ˩a kvyCwIo<oYqS+TF(Υ6q]wt(/ه-)Ƥۙe`\+".,6V :E`/K&p\@WS=/0Ju*DzuOۿ$gHmf V8NIҪe[{i;\$0UU-G|6Q~6jwf"++cq,^)͂)S7xv]e;ԓdtK=?8a[+6fI``LWܑlOPb*sě+ #c\iǬ&{ێ͚I4 _] Óޙ^? sxK*hO3=<.ӚAjn >&͛W\G2*BQq?QI iD=mV^Dz{Y[P)J]LLض +$<)KMEyƥM^^2}PbɓW2ɾ" ?%.;.Q⺩=H q9>QTq}7%^`Flդ"O-Qf + M<8?U˜WIp.!iR&Dy6Ez0sDO4̅U:k6@ٳ&1D+fp8?̪l{)YާSK9(,Z/fuk%KZ ,-40Ț$.䶕/bW]y~Ľ ޣfC|IenYv&ssOG~CD*G(N&bP~0μA5YD +,O<č-M8ǵmqo0YD?cEp>*A  + ym+a~r'GS(3Th㬪.⵾h=>$Y:sļIQtME횺!f] .d ̤4⃇C%Tz@e 3l:[k +J9)'lI u5C[+{[V;MY ښK X8BDХ.ej)DͬaUjʺ&o*U SӪR բ3$}ͱ"W\a,GCFql<ͷ1(K(}xxT)<3V]QV1Bqm1i(}$(J%is6WRuYb1| ̞mm->a}>360k#s0[6pSs]!Xxjr,Ţ(~n^ jca݁5%7#`7Nr[(Vjʼn^fVئt'npq/-?(aOmW[(ITLJJ):%^Ӳ%[7sٟ[K0cs̸Aqb dѝy i5Gϼ,Z̢r!#MY LCcv+yOsXXWm>֞٢"O[u}%B>RB20CtҸbrh6.{ӱ e!'?vq r Q}XzE'Nzߨ݆>dQ~_JԻLEMGcTL,6҂Zlˊ,}DrlI?}2X؞mև֯=n?1|՘q2I-Lu>˷YUMFk4/ͅ=DY?eN:|21 ܡEъ=i)|o/v +)[u4n̵4/&niHߴq}MSRӢ]iho}nև=_l}go~ǯ~훟_ꟿo~_Oo~o_<__?? 9>  endstream endobj 15 0 obj <> endobj 27 0 obj <> endobj 37 0 obj <> endobj 65 0 obj <> endobj 78 0 obj <> endobj 90 0 obj <> endobj 116 0 obj <> endobj 129 0 obj <> endobj 141 0 obj <> endobj 167 0 obj <> endobj 180 0 obj <> endobj 192 0 obj <> endobj 218 0 obj <> endobj 237 0 obj <> endobj 255 0 obj <> endobj 287 0 obj <> endobj 306 0 obj <> endobj 324 0 obj <> endobj 356 0 obj <> endobj 375 0 obj <> endobj 393 0 obj <> endobj 425 0 obj <> endobj 444 0 obj <> endobj 462 0 obj <> endobj 480 0 obj <> endobj 515 0 obj <> endobj 534 0 obj <> endobj 552 0 obj <> endobj 570 0 obj <> endobj 605 0 obj <> endobj 624 0 obj <> endobj 642 0 obj <> endobj 660 0 obj <> endobj 695 0 obj <> endobj 699 0 obj <> endobj 718 0 obj <> endobj 735 0 obj <> endobj 753 0 obj <> endobj 785 0 obj <> endobj 789 0 obj <> endobj 808 0 obj <> endobj 825 0 obj <> endobj 843 0 obj <> endobj 878 0 obj <> endobj 882 0 obj <> endobj 901 0 obj <> endobj 918 0 obj <> endobj 936 0 obj <> endobj 971 0 obj <> endobj 975 0 obj <> endobj 994 0 obj <> endobj 1011 0 obj <> endobj 1029 0 obj <> endobj 1056 0 obj <> endobj 1057 0 obj <> endobj 1058 0 obj <> endobj 1059 0 obj <> endobj 1060 0 obj <> endobj 1138 0 obj <> endobj 1139 0 obj <> endobj 1140 0 obj <> endobj 1141 0 obj <> endobj 1142 0 obj <> endobj 1143 0 obj <> endobj 1223 0 obj <> endobj 1224 0 obj <> endobj 1225 0 obj <> endobj 1226 0 obj <> endobj 1227 0 obj <> endobj 1228 0 obj <> endobj 1296 0 obj [/View/Design] endobj 1297 0 obj <>>> endobj 1294 0 obj [/View/Design] endobj 1295 0 obj <>>> endobj 1292 0 obj [/View/Design] endobj 1293 0 obj <>>> endobj 1290 0 obj [/View/Design] endobj 1291 0 obj <>>> endobj 1288 0 obj [/View/Design] endobj 1289 0 obj <>>> endobj 1286 0 obj [/View/Design] endobj 1287 0 obj <>>> endobj 1211 0 obj [/View/Design] endobj 1212 0 obj <>>> endobj 1209 0 obj [/View/Design] endobj 1210 0 obj <>>> endobj 1207 0 obj [/View/Design] endobj 1208 0 obj <>>> endobj 1205 0 obj [/View/Design] endobj 1206 0 obj <>>> endobj 1203 0 obj [/View/Design] endobj 1204 0 obj <>>> endobj 1201 0 obj [/View/Design] endobj 1202 0 obj <>>> endobj 1126 0 obj [/View/Design] endobj 1127 0 obj <>>> endobj 1124 0 obj [/View/Design] endobj 1125 0 obj <>>> endobj 1122 0 obj [/View/Design] endobj 1123 0 obj <>>> endobj 1120 0 obj [/View/Design] endobj 1121 0 obj <>>> endobj 1118 0 obj [/View/Design] endobj 1119 0 obj <>>> endobj 1030 0 obj [/View/Design] endobj 1031 0 obj <>>> endobj 1012 0 obj [/View/Design] endobj 1013 0 obj <>>> endobj 995 0 obj [/View/Design] endobj 996 0 obj <>>> endobj 976 0 obj [/View/Design] endobj 977 0 obj <>>> endobj 972 0 obj [/View/Design] endobj 973 0 obj <>>> endobj 937 0 obj [/View/Design] endobj 938 0 obj <>>> endobj 919 0 obj [/View/Design] endobj 920 0 obj <>>> endobj 902 0 obj [/View/Design] endobj 903 0 obj <>>> endobj 883 0 obj [/View/Design] endobj 884 0 obj <>>> endobj 879 0 obj [/View/Design] endobj 880 0 obj <>>> endobj 844 0 obj [/View/Design] endobj 845 0 obj <>>> endobj 826 0 obj [/View/Design] endobj 827 0 obj <>>> endobj 809 0 obj [/View/Design] endobj 810 0 obj <>>> endobj 790 0 obj [/View/Design] endobj 791 0 obj <>>> endobj 786 0 obj [/View/Design] endobj 787 0 obj <>>> endobj 754 0 obj [/View/Design] endobj 755 0 obj <>>> endobj 736 0 obj [/View/Design] endobj 737 0 obj <>>> endobj 719 0 obj [/View/Design] endobj 720 0 obj <>>> endobj 700 0 obj [/View/Design] endobj 701 0 obj <>>> endobj 696 0 obj [/View/Design] endobj 697 0 obj <>>> endobj 661 0 obj [/View/Design] endobj 662 0 obj <>>> endobj 643 0 obj [/View/Design] endobj 644 0 obj <>>> endobj 625 0 obj [/View/Design] endobj 626 0 obj <>>> endobj 606 0 obj [/View/Design] endobj 607 0 obj <>>> endobj 571 0 obj [/View/Design] endobj 572 0 obj <>>> endobj 553 0 obj [/View/Design] endobj 554 0 obj <>>> endobj 535 0 obj [/View/Design] endobj 536 0 obj <>>> endobj 516 0 obj [/View/Design] endobj 517 0 obj <>>> endobj 481 0 obj [/View/Design] endobj 482 0 obj <>>> endobj 463 0 obj [/View/Design] endobj 464 0 obj <>>> endobj 445 0 obj [/View/Design] endobj 446 0 obj <>>> endobj 426 0 obj [/View/Design] endobj 427 0 obj <>>> endobj 394 0 obj [/View/Design] endobj 395 0 obj <>>> endobj 376 0 obj [/View/Design] endobj 377 0 obj <>>> endobj 357 0 obj [/View/Design] endobj 358 0 obj <>>> endobj 325 0 obj [/View/Design] endobj 326 0 obj <>>> endobj 307 0 obj [/View/Design] endobj 308 0 obj <>>> endobj 288 0 obj [/View/Design] endobj 289 0 obj <>>> endobj 256 0 obj [/View/Design] endobj 257 0 obj <>>> endobj 238 0 obj [/View/Design] endobj 239 0 obj <>>> endobj 219 0 obj [/View/Design] endobj 220 0 obj <>>> endobj 193 0 obj [/View/Design] endobj 194 0 obj <>>> endobj 181 0 obj [/View/Design] endobj 182 0 obj <>>> endobj 168 0 obj [/View/Design] endobj 169 0 obj <>>> endobj 142 0 obj [/View/Design] endobj 143 0 obj <>>> endobj 130 0 obj [/View/Design] endobj 131 0 obj <>>> endobj 117 0 obj [/View/Design] endobj 118 0 obj <>>> endobj 91 0 obj [/View/Design] endobj 92 0 obj <>>> endobj 79 0 obj [/View/Design] endobj 80 0 obj <>>> endobj 66 0 obj [/View/Design] endobj 67 0 obj <>>> endobj 38 0 obj [/View/Design] endobj 39 0 obj <>>> endobj 28 0 obj [/View/Design] endobj 29 0 obj <>>> endobj 16 0 obj [/View/Design] endobj 17 0 obj <>>> endobj 1314 0 obj [1313 0 R 1312 0 R 1311 0 R 1310 0 R 1309 0 R 1308 0 R] endobj 1391 0 obj <> endobj xref 0 1392 0000000003 65535 f +0000000016 00000 n +0000046044 00000 n +0000000004 00000 f +0000000006 00000 f +0000046095 00000 n +0000000007 00000 f +0000000008 00000 f +0000000009 00000 f +0000000010 00000 f +0000000011 00000 f +0000000012 00000 f +0000000013 00000 f +0000000014 00000 f +0000000018 00000 f +0000359516 00000 n +0000372837 00000 n +0000372868 00000 n +0000000019 00000 f +0000000020 00000 f +0000000021 00000 f +0000000022 00000 f +0000000023 00000 f +0000000024 00000 f +0000000025 00000 f +0000000026 00000 f +0000000030 00000 f +0000359585 00000 n +0000372721 00000 n +0000372752 00000 n +0000000031 00000 f +0000000032 00000 f +0000000033 00000 f +0000000034 00000 f +0000000035 00000 f +0000000036 00000 f +0000000040 00000 f +0000359656 00000 n +0000372605 00000 n +0000372636 00000 n +0000000041 00000 f +0000000042 00000 f +0000000043 00000 f +0000000044 00000 f +0000000045 00000 f +0000000046 00000 f +0000000047 00000 f +0000000048 00000 f +0000000049 00000 f +0000000050 00000 f +0000000051 00000 f +0000000052 00000 f +0000000053 00000 f +0000000054 00000 f +0000000055 00000 f +0000000056 00000 f +0000000057 00000 f +0000000058 00000 f +0000000059 00000 f +0000000060 00000 f +0000000061 00000 f +0000000062 00000 f +0000000063 00000 f +0000000064 00000 f +0000000068 00000 f +0000359726 00000 n +0000372489 00000 n +0000372520 00000 n +0000000069 00000 f +0000000070 00000 f +0000000071 00000 f +0000000072 00000 f +0000000073 00000 f +0000000074 00000 f +0000000075 00000 f +0000000076 00000 f +0000000077 00000 f +0000000081 00000 f +0000359795 00000 n +0000372373 00000 n +0000372404 00000 n +0000000082 00000 f +0000000083 00000 f +0000000084 00000 f +0000000085 00000 f +0000000086 00000 f +0000000087 00000 f +0000000088 00000 f +0000000089 00000 f +0000000093 00000 f +0000359866 00000 n +0000372257 00000 n +0000372288 00000 n +0000000094 00000 f +0000000095 00000 f +0000000096 00000 f +0000000097 00000 f +0000000098 00000 f +0000000099 00000 f +0000000100 00000 f +0000000101 00000 f +0000000102 00000 f +0000000103 00000 f +0000000104 00000 f +0000000105 00000 f +0000000106 00000 f +0000000107 00000 f +0000000108 00000 f +0000000109 00000 f +0000000110 00000 f +0000000111 00000 f +0000000112 00000 f +0000000113 00000 f +0000000114 00000 f +0000000115 00000 f +0000000119 00000 f +0000359936 00000 n +0000372139 00000 n +0000372171 00000 n +0000000120 00000 f +0000000121 00000 f +0000000122 00000 f +0000000123 00000 f +0000000124 00000 f +0000000125 00000 f +0000000126 00000 f +0000000127 00000 f +0000000128 00000 f +0000000132 00000 f +0000360008 00000 n +0000372021 00000 n +0000372053 00000 n +0000000133 00000 f +0000000134 00000 f +0000000135 00000 f +0000000136 00000 f +0000000137 00000 f +0000000138 00000 f +0000000139 00000 f +0000000140 00000 f +0000000144 00000 f +0000360082 00000 n +0000371903 00000 n +0000371935 00000 n +0000000145 00000 f +0000000146 00000 f +0000000147 00000 f +0000000148 00000 f +0000000149 00000 f +0000000150 00000 f +0000000151 00000 f +0000000152 00000 f +0000000153 00000 f +0000000154 00000 f +0000000155 00000 f +0000000156 00000 f +0000000157 00000 f +0000000158 00000 f +0000000159 00000 f +0000000160 00000 f +0000000161 00000 f +0000000162 00000 f +0000000163 00000 f +0000000164 00000 f +0000000165 00000 f +0000000166 00000 f +0000000170 00000 f +0000360155 00000 n +0000371785 00000 n +0000371817 00000 n +0000000171 00000 f +0000000172 00000 f +0000000173 00000 f +0000000174 00000 f +0000000175 00000 f +0000000176 00000 f +0000000177 00000 f +0000000178 00000 f +0000000179 00000 f +0000000183 00000 f +0000360227 00000 n +0000371667 00000 n +0000371699 00000 n +0000000184 00000 f +0000000185 00000 f +0000000186 00000 f +0000000187 00000 f +0000000188 00000 f +0000000189 00000 f +0000000190 00000 f +0000000191 00000 f +0000000195 00000 f +0000360301 00000 n +0000371549 00000 n +0000371581 00000 n +0000000196 00000 f +0000000197 00000 f +0000000198 00000 f +0000000199 00000 f +0000000200 00000 f +0000000201 00000 f +0000000202 00000 f +0000000203 00000 f +0000000204 00000 f +0000000205 00000 f +0000000206 00000 f +0000000207 00000 f +0000000208 00000 f +0000000209 00000 f +0000000210 00000 f +0000000211 00000 f +0000000212 00000 f +0000000213 00000 f +0000000214 00000 f +0000000215 00000 f +0000000216 00000 f +0000000217 00000 f +0000000221 00000 f +0000360374 00000 n +0000371431 00000 n +0000371463 00000 n +0000000222 00000 f +0000000223 00000 f +0000000224 00000 f +0000000225 00000 f +0000000226 00000 f +0000000227 00000 f +0000000228 00000 f +0000000229 00000 f +0000000230 00000 f +0000000231 00000 f +0000000232 00000 f +0000000233 00000 f +0000000234 00000 f +0000000235 00000 f +0000000236 00000 f +0000000240 00000 f +0000360446 00000 n +0000371313 00000 n +0000371345 00000 n +0000000241 00000 f +0000000242 00000 f +0000000243 00000 f +0000000244 00000 f +0000000245 00000 f +0000000246 00000 f +0000000247 00000 f +0000000248 00000 f +0000000249 00000 f +0000000250 00000 f +0000000251 00000 f +0000000252 00000 f +0000000253 00000 f +0000000254 00000 f +0000000258 00000 f +0000360520 00000 n +0000371195 00000 n +0000371227 00000 n +0000000259 00000 f +0000000260 00000 f +0000000261 00000 f +0000000262 00000 f +0000000263 00000 f +0000000264 00000 f +0000000265 00000 f +0000000266 00000 f +0000000267 00000 f +0000000268 00000 f +0000000269 00000 f +0000000270 00000 f +0000000271 00000 f +0000000272 00000 f +0000000273 00000 f +0000000274 00000 f +0000000275 00000 f +0000000276 00000 f +0000000277 00000 f +0000000278 00000 f +0000000279 00000 f +0000000280 00000 f +0000000281 00000 f +0000000282 00000 f +0000000283 00000 f +0000000284 00000 f +0000000285 00000 f +0000000286 00000 f +0000000290 00000 f +0000360593 00000 n +0000371077 00000 n +0000371109 00000 n +0000000291 00000 f +0000000292 00000 f +0000000293 00000 f +0000000294 00000 f +0000000295 00000 f +0000000296 00000 f +0000000297 00000 f +0000000298 00000 f +0000000299 00000 f +0000000300 00000 f +0000000301 00000 f +0000000302 00000 f +0000000303 00000 f +0000000304 00000 f +0000000305 00000 f +0000000309 00000 f +0000360665 00000 n +0000370959 00000 n +0000370991 00000 n +0000000310 00000 f +0000000311 00000 f +0000000312 00000 f +0000000313 00000 f +0000000314 00000 f +0000000315 00000 f +0000000316 00000 f +0000000317 00000 f +0000000318 00000 f +0000000319 00000 f +0000000320 00000 f +0000000321 00000 f +0000000322 00000 f +0000000323 00000 f +0000000327 00000 f +0000360739 00000 n +0000370841 00000 n +0000370873 00000 n +0000000328 00000 f +0000000329 00000 f +0000000330 00000 f +0000000331 00000 f +0000000332 00000 f +0000000333 00000 f +0000000334 00000 f +0000000335 00000 f +0000000336 00000 f +0000000337 00000 f +0000000338 00000 f +0000000339 00000 f +0000000340 00000 f +0000000341 00000 f +0000000342 00000 f +0000000343 00000 f +0000000344 00000 f +0000000345 00000 f +0000000346 00000 f +0000000347 00000 f +0000000348 00000 f +0000000349 00000 f +0000000350 00000 f +0000000351 00000 f +0000000352 00000 f +0000000353 00000 f +0000000354 00000 f +0000000355 00000 f +0000000359 00000 f +0000360812 00000 n +0000370723 00000 n +0000370755 00000 n +0000000360 00000 f +0000000361 00000 f +0000000362 00000 f +0000000363 00000 f +0000000364 00000 f +0000000365 00000 f +0000000366 00000 f +0000000367 00000 f +0000000368 00000 f +0000000369 00000 f +0000000370 00000 f +0000000371 00000 f +0000000372 00000 f +0000000373 00000 f +0000000374 00000 f +0000000378 00000 f +0000360884 00000 n +0000370605 00000 n +0000370637 00000 n +0000000379 00000 f +0000000380 00000 f +0000000381 00000 f +0000000382 00000 f +0000000383 00000 f +0000000384 00000 f +0000000385 00000 f +0000000386 00000 f +0000000387 00000 f +0000000388 00000 f +0000000389 00000 f +0000000390 00000 f +0000000391 00000 f +0000000392 00000 f +0000000396 00000 f +0000360958 00000 n +0000370487 00000 n +0000370519 00000 n +0000000397 00000 f +0000000398 00000 f +0000000399 00000 f +0000000400 00000 f +0000000401 00000 f +0000000402 00000 f +0000000403 00000 f +0000000404 00000 f +0000000405 00000 f +0000000406 00000 f +0000000407 00000 f +0000000408 00000 f +0000000409 00000 f +0000000410 00000 f +0000000411 00000 f +0000000412 00000 f +0000000413 00000 f +0000000414 00000 f +0000000415 00000 f +0000000416 00000 f +0000000417 00000 f +0000000418 00000 f +0000000419 00000 f +0000000420 00000 f +0000000421 00000 f +0000000422 00000 f +0000000423 00000 f +0000000424 00000 f +0000000428 00000 f +0000361031 00000 n +0000370369 00000 n +0000370401 00000 n +0000000429 00000 f +0000000430 00000 f +0000000431 00000 f +0000000432 00000 f +0000000433 00000 f +0000000434 00000 f +0000000435 00000 f +0000000436 00000 f +0000000437 00000 f +0000000438 00000 f +0000000439 00000 f +0000000440 00000 f +0000000441 00000 f +0000000442 00000 f +0000000443 00000 f +0000000447 00000 f +0000361103 00000 n +0000370251 00000 n +0000370283 00000 n +0000000448 00000 f +0000000449 00000 f +0000000450 00000 f +0000000451 00000 f +0000000452 00000 f +0000000453 00000 f +0000000454 00000 f +0000000455 00000 f +0000000456 00000 f +0000000457 00000 f +0000000458 00000 f +0000000459 00000 f +0000000460 00000 f +0000000461 00000 f +0000000465 00000 f +0000361175 00000 n +0000370133 00000 n +0000370165 00000 n +0000000466 00000 f +0000000467 00000 f +0000000468 00000 f +0000000469 00000 f +0000000470 00000 f +0000000471 00000 f +0000000472 00000 f +0000000473 00000 f +0000000474 00000 f +0000000475 00000 f +0000000476 00000 f +0000000477 00000 f +0000000478 00000 f +0000000479 00000 f +0000000483 00000 f +0000361249 00000 n +0000370015 00000 n +0000370047 00000 n +0000000484 00000 f +0000000485 00000 f +0000000486 00000 f +0000000487 00000 f +0000000488 00000 f +0000000489 00000 f +0000000490 00000 f +0000000491 00000 f +0000000492 00000 f +0000000493 00000 f +0000000494 00000 f +0000000495 00000 f +0000000496 00000 f +0000000497 00000 f +0000000498 00000 f +0000000499 00000 f +0000000500 00000 f +0000000501 00000 f +0000000502 00000 f +0000000503 00000 f +0000000504 00000 f +0000000505 00000 f +0000000506 00000 f +0000000507 00000 f +0000000508 00000 f +0000000509 00000 f +0000000510 00000 f +0000000511 00000 f +0000000512 00000 f +0000000513 00000 f +0000000514 00000 f +0000000518 00000 f +0000361322 00000 n +0000369897 00000 n +0000369929 00000 n +0000000519 00000 f +0000000520 00000 f +0000000521 00000 f +0000000522 00000 f +0000000523 00000 f +0000000524 00000 f +0000000525 00000 f +0000000526 00000 f +0000000527 00000 f +0000000528 00000 f +0000000529 00000 f +0000000530 00000 f +0000000531 00000 f +0000000532 00000 f +0000000533 00000 f +0000000537 00000 f +0000361394 00000 n +0000369779 00000 n +0000369811 00000 n +0000000538 00000 f +0000000539 00000 f +0000000540 00000 f +0000000541 00000 f +0000000542 00000 f +0000000543 00000 f +0000000544 00000 f +0000000545 00000 f +0000000546 00000 f +0000000547 00000 f +0000000548 00000 f +0000000549 00000 f +0000000550 00000 f +0000000551 00000 f +0000000555 00000 f +0000361466 00000 n +0000369661 00000 n +0000369693 00000 n +0000000556 00000 f +0000000557 00000 f +0000000558 00000 f +0000000559 00000 f +0000000560 00000 f +0000000561 00000 f +0000000562 00000 f +0000000563 00000 f +0000000564 00000 f +0000000565 00000 f +0000000566 00000 f +0000000567 00000 f +0000000568 00000 f +0000000569 00000 f +0000000573 00000 f +0000361540 00000 n +0000369543 00000 n +0000369575 00000 n +0000000574 00000 f +0000000575 00000 f +0000000576 00000 f +0000000577 00000 f +0000000578 00000 f +0000000579 00000 f +0000000580 00000 f +0000000581 00000 f +0000000582 00000 f +0000000583 00000 f +0000000584 00000 f +0000000585 00000 f +0000000586 00000 f +0000000587 00000 f +0000000588 00000 f +0000000589 00000 f +0000000590 00000 f +0000000591 00000 f +0000000592 00000 f +0000000593 00000 f +0000000594 00000 f +0000000595 00000 f +0000000596 00000 f +0000000597 00000 f +0000000598 00000 f +0000000599 00000 f +0000000600 00000 f +0000000601 00000 f +0000000602 00000 f +0000000603 00000 f +0000000604 00000 f +0000000608 00000 f +0000361613 00000 n +0000369425 00000 n +0000369457 00000 n +0000000609 00000 f +0000000610 00000 f +0000000611 00000 f +0000000612 00000 f +0000000613 00000 f +0000000614 00000 f +0000000615 00000 f +0000000616 00000 f +0000000617 00000 f +0000000618 00000 f +0000000619 00000 f +0000000620 00000 f +0000000621 00000 f +0000000622 00000 f +0000000623 00000 f +0000000627 00000 f +0000361685 00000 n +0000369307 00000 n +0000369339 00000 n +0000000628 00000 f +0000000629 00000 f +0000000630 00000 f +0000000631 00000 f +0000000632 00000 f +0000000633 00000 f +0000000634 00000 f +0000000635 00000 f +0000000636 00000 f +0000000637 00000 f +0000000638 00000 f +0000000639 00000 f +0000000640 00000 f +0000000641 00000 f +0000000645 00000 f +0000361757 00000 n +0000369189 00000 n +0000369221 00000 n +0000000646 00000 f +0000000647 00000 f +0000000648 00000 f +0000000649 00000 f +0000000650 00000 f +0000000651 00000 f +0000000652 00000 f +0000000653 00000 f +0000000654 00000 f +0000000655 00000 f +0000000656 00000 f +0000000657 00000 f +0000000658 00000 f +0000000659 00000 f +0000000663 00000 f +0000361831 00000 n +0000369071 00000 n +0000369103 00000 n +0000000664 00000 f +0000000665 00000 f +0000000666 00000 f +0000000667 00000 f +0000000668 00000 f +0000000669 00000 f +0000000670 00000 f +0000000671 00000 f +0000000672 00000 f +0000000673 00000 f +0000000674 00000 f +0000000675 00000 f +0000000676 00000 f +0000000677 00000 f +0000000678 00000 f +0000000679 00000 f +0000000680 00000 f +0000000681 00000 f +0000000682 00000 f +0000000683 00000 f +0000000684 00000 f +0000000685 00000 f +0000000686 00000 f +0000000687 00000 f +0000000688 00000 f +0000000689 00000 f +0000000690 00000 f +0000000691 00000 f +0000000692 00000 f +0000000693 00000 f +0000000694 00000 f +0000000698 00000 f +0000361904 00000 n +0000368953 00000 n +0000368985 00000 n +0000000702 00000 f +0000361975 00000 n +0000368835 00000 n +0000368867 00000 n +0000000703 00000 f +0000000704 00000 f +0000000705 00000 f +0000000706 00000 f +0000000707 00000 f +0000000708 00000 f +0000000709 00000 f +0000000710 00000 f +0000000711 00000 f +0000000712 00000 f +0000000713 00000 f +0000000714 00000 f +0000000715 00000 f +0000000716 00000 f +0000000717 00000 f +0000000721 00000 f +0000362047 00000 n +0000368717 00000 n +0000368749 00000 n +0000000722 00000 f +0000000723 00000 f +0000000724 00000 f +0000000725 00000 f +0000000726 00000 f +0000000727 00000 f +0000000728 00000 f +0000000729 00000 f +0000000730 00000 f +0000000731 00000 f +0000000732 00000 f +0000000733 00000 f +0000000734 00000 f +0000000738 00000 f +0000362119 00000 n +0000368599 00000 n +0000368631 00000 n +0000000739 00000 f +0000000740 00000 f +0000000741 00000 f +0000000742 00000 f +0000000743 00000 f +0000000744 00000 f +0000000745 00000 f +0000000746 00000 f +0000000747 00000 f +0000000748 00000 f +0000000749 00000 f +0000000750 00000 f +0000000751 00000 f +0000000752 00000 f +0000000756 00000 f +0000362193 00000 n +0000368481 00000 n +0000368513 00000 n +0000000757 00000 f +0000000758 00000 f +0000000759 00000 f +0000000760 00000 f +0000000761 00000 f +0000000762 00000 f +0000000763 00000 f +0000000764 00000 f +0000000765 00000 f +0000000766 00000 f +0000000767 00000 f +0000000768 00000 f +0000000769 00000 f +0000000770 00000 f +0000000771 00000 f +0000000772 00000 f +0000000773 00000 f +0000000774 00000 f +0000000775 00000 f +0000000776 00000 f +0000000777 00000 f +0000000778 00000 f +0000000779 00000 f +0000000780 00000 f +0000000781 00000 f +0000000782 00000 f +0000000783 00000 f +0000000784 00000 f +0000000788 00000 f +0000362266 00000 n +0000368363 00000 n +0000368395 00000 n +0000000792 00000 f +0000362337 00000 n +0000368245 00000 n +0000368277 00000 n +0000000793 00000 f +0000000794 00000 f +0000000795 00000 f +0000000796 00000 f +0000000797 00000 f +0000000798 00000 f +0000000799 00000 f +0000000800 00000 f +0000000801 00000 f +0000000802 00000 f +0000000803 00000 f +0000000804 00000 f +0000000805 00000 f +0000000806 00000 f +0000000807 00000 f +0000000811 00000 f +0000362409 00000 n +0000368127 00000 n +0000368159 00000 n +0000000812 00000 f +0000000813 00000 f +0000000814 00000 f +0000000815 00000 f +0000000816 00000 f +0000000817 00000 f +0000000818 00000 f +0000000819 00000 f +0000000820 00000 f +0000000821 00000 f +0000000822 00000 f +0000000823 00000 f +0000000824 00000 f +0000000828 00000 f +0000362481 00000 n +0000368009 00000 n +0000368041 00000 n +0000000829 00000 f +0000000830 00000 f +0000000831 00000 f +0000000832 00000 f +0000000833 00000 f +0000000834 00000 f +0000000835 00000 f +0000000836 00000 f +0000000837 00000 f +0000000838 00000 f +0000000839 00000 f +0000000840 00000 f +0000000841 00000 f +0000000842 00000 f +0000000846 00000 f +0000362555 00000 n +0000367891 00000 n +0000367923 00000 n +0000000847 00000 f +0000000848 00000 f +0000000849 00000 f +0000000850 00000 f +0000000851 00000 f +0000000852 00000 f +0000000853 00000 f +0000000854 00000 f +0000000855 00000 f +0000000856 00000 f +0000000857 00000 f +0000000858 00000 f +0000000859 00000 f +0000000860 00000 f +0000000861 00000 f +0000000862 00000 f +0000000863 00000 f +0000000864 00000 f +0000000865 00000 f +0000000866 00000 f +0000000867 00000 f +0000000868 00000 f +0000000869 00000 f +0000000870 00000 f +0000000871 00000 f +0000000872 00000 f +0000000873 00000 f +0000000874 00000 f +0000000875 00000 f +0000000876 00000 f +0000000877 00000 f +0000000881 00000 f +0000362628 00000 n +0000367773 00000 n +0000367805 00000 n +0000000885 00000 f +0000362699 00000 n +0000367655 00000 n +0000367687 00000 n +0000000886 00000 f +0000000887 00000 f +0000000888 00000 f +0000000889 00000 f +0000000890 00000 f +0000000891 00000 f +0000000892 00000 f +0000000893 00000 f +0000000894 00000 f +0000000895 00000 f +0000000896 00000 f +0000000897 00000 f +0000000898 00000 f +0000000899 00000 f +0000000900 00000 f +0000000904 00000 f +0000362771 00000 n +0000367537 00000 n +0000367569 00000 n +0000000905 00000 f +0000000906 00000 f +0000000907 00000 f +0000000908 00000 f +0000000909 00000 f +0000000910 00000 f +0000000911 00000 f +0000000912 00000 f +0000000913 00000 f +0000000914 00000 f +0000000915 00000 f +0000000916 00000 f +0000000917 00000 f +0000000921 00000 f +0000362843 00000 n +0000367419 00000 n +0000367451 00000 n +0000000922 00000 f +0000000923 00000 f +0000000924 00000 f +0000000925 00000 f +0000000926 00000 f +0000000927 00000 f +0000000928 00000 f +0000000929 00000 f +0000000930 00000 f +0000000931 00000 f +0000000932 00000 f +0000000933 00000 f +0000000934 00000 f +0000000935 00000 f +0000000939 00000 f +0000362917 00000 n +0000367301 00000 n +0000367333 00000 n +0000000940 00000 f +0000000941 00000 f +0000000942 00000 f +0000000943 00000 f +0000000944 00000 f +0000000945 00000 f +0000000946 00000 f +0000000947 00000 f +0000000948 00000 f +0000000949 00000 f +0000000950 00000 f +0000000951 00000 f +0000000952 00000 f +0000000953 00000 f +0000000954 00000 f +0000000955 00000 f +0000000956 00000 f +0000000957 00000 f +0000000958 00000 f +0000000959 00000 f +0000000960 00000 f +0000000961 00000 f +0000000962 00000 f +0000000963 00000 f +0000000964 00000 f +0000000965 00000 f +0000000966 00000 f +0000000967 00000 f +0000000968 00000 f +0000000969 00000 f +0000000970 00000 f +0000000974 00000 f +0000362990 00000 n +0000367183 00000 n +0000367215 00000 n +0000000978 00000 f +0000363061 00000 n +0000367065 00000 n +0000367097 00000 n +0000000979 00000 f +0000000980 00000 f +0000000981 00000 f +0000000982 00000 f +0000000983 00000 f +0000000984 00000 f +0000000985 00000 f +0000000986 00000 f +0000000987 00000 f +0000000988 00000 f +0000000989 00000 f +0000000990 00000 f +0000000991 00000 f +0000000992 00000 f +0000000993 00000 f +0000000997 00000 f +0000363133 00000 n +0000366947 00000 n +0000366979 00000 n +0000000998 00000 f +0000000999 00000 f +0000001000 00000 f +0000001001 00000 f +0000001002 00000 f +0000001003 00000 f +0000001004 00000 f +0000001005 00000 f +0000001006 00000 f +0000001007 00000 f +0000001008 00000 f +0000001009 00000 f +0000001010 00000 f +0000001014 00000 f +0000363205 00000 n +0000366827 00000 n +0000366860 00000 n +0000001015 00000 f +0000001016 00000 f +0000001017 00000 f +0000001018 00000 f +0000001019 00000 f +0000001020 00000 f +0000001021 00000 f +0000001022 00000 f +0000001023 00000 f +0000001024 00000 f +0000001025 00000 f +0000001026 00000 f +0000001027 00000 f +0000001028 00000 f +0000001032 00000 f +0000363282 00000 n +0000366707 00000 n +0000366740 00000 n +0000001033 00000 f +0000001034 00000 f +0000001035 00000 f +0000001036 00000 f +0000001037 00000 f +0000001038 00000 f +0000001039 00000 f +0000001040 00000 f +0000001041 00000 f +0000001042 00000 f +0000001043 00000 f +0000001044 00000 f +0000001045 00000 f +0000001046 00000 f +0000001047 00000 f +0000001048 00000 f +0000001049 00000 f +0000001050 00000 f +0000001051 00000 f +0000001052 00000 f +0000001053 00000 f +0000001055 00000 f +0000001397 00000 n +0000001061 00000 f +0000363358 00000 n +0000363432 00000 n +0000363507 00000 n +0000363582 00000 n +0000363659 00000 n +0000001062 00000 f +0000001063 00000 f +0000001064 00000 f +0000001065 00000 f +0000001066 00000 f +0000001067 00000 f +0000001068 00000 f +0000001069 00000 f +0000001070 00000 f +0000001071 00000 f +0000001072 00000 f +0000001073 00000 f +0000001074 00000 f +0000001075 00000 f +0000001076 00000 f +0000001077 00000 f +0000001078 00000 f +0000001079 00000 f +0000001080 00000 f +0000001081 00000 f +0000001082 00000 f +0000001083 00000 f +0000001084 00000 f +0000001085 00000 f +0000001086 00000 f +0000001087 00000 f +0000001088 00000 f +0000001089 00000 f +0000001090 00000 f +0000001091 00000 f +0000001092 00000 f +0000001093 00000 f +0000001094 00000 f +0000001095 00000 f +0000001096 00000 f +0000001097 00000 f +0000001098 00000 f +0000001099 00000 f +0000001100 00000 f +0000001101 00000 f +0000001102 00000 f +0000001103 00000 f +0000001104 00000 f +0000001105 00000 f +0000001106 00000 f +0000001107 00000 f +0000001108 00000 f +0000001109 00000 f +0000001110 00000 f +0000001111 00000 f +0000001112 00000 f +0000001113 00000 f +0000001114 00000 f +0000001115 00000 f +0000001116 00000 f +0000001117 00000 f +0000001128 00000 f +0000366587 00000 n +0000366620 00000 n +0000366467 00000 n +0000366500 00000 n +0000366347 00000 n +0000366380 00000 n +0000366227 00000 n +0000366260 00000 n +0000366107 00000 n +0000366140 00000 n +0000001129 00000 f +0000001130 00000 f +0000001131 00000 f +0000001132 00000 f +0000001133 00000 f +0000001134 00000 f +0000001135 00000 f +0000001136 00000 f +0000001137 00000 f +0000001144 00000 f +0000363735 00000 n +0000363824 00000 n +0000363898 00000 n +0000363973 00000 n +0000364048 00000 n +0000364125 00000 n +0000001145 00000 f +0000001146 00000 f +0000001147 00000 f +0000001148 00000 f +0000001149 00000 f +0000001150 00000 f +0000001151 00000 f +0000001152 00000 f +0000001153 00000 f +0000001154 00000 f +0000001155 00000 f +0000001156 00000 f +0000001157 00000 f +0000001158 00000 f +0000001159 00000 f +0000001160 00000 f +0000001161 00000 f +0000001162 00000 f +0000001163 00000 f +0000001164 00000 f +0000001165 00000 f +0000001166 00000 f +0000001167 00000 f +0000001168 00000 f +0000001169 00000 f +0000001170 00000 f +0000001171 00000 f +0000001172 00000 f +0000001173 00000 f +0000001174 00000 f +0000001175 00000 f +0000001176 00000 f +0000001177 00000 f +0000001178 00000 f +0000001179 00000 f +0000001180 00000 f +0000001181 00000 f +0000001182 00000 f +0000001183 00000 f +0000001184 00000 f +0000001185 00000 f +0000001186 00000 f +0000001187 00000 f +0000001188 00000 f +0000001189 00000 f +0000001190 00000 f +0000001191 00000 f +0000001192 00000 f +0000001193 00000 f +0000001194 00000 f +0000001195 00000 f +0000001196 00000 f +0000001197 00000 f +0000001198 00000 f +0000001199 00000 f +0000001200 00000 f +0000001213 00000 f +0000365987 00000 n +0000366020 00000 n +0000365867 00000 n +0000365900 00000 n +0000365747 00000 n +0000365780 00000 n +0000365627 00000 n +0000365660 00000 n +0000365507 00000 n +0000365540 00000 n +0000365387 00000 n +0000365420 00000 n +0000001214 00000 f +0000001215 00000 f +0000001216 00000 f +0000001217 00000 f +0000001218 00000 f +0000001219 00000 f +0000001220 00000 f +0000001221 00000 f +0000001242 00000 f +0000000000 00000 f +0000364201 00000 n +0000364290 00000 n +0000364364 00000 n +0000364439 00000 n +0000364514 00000 n +0000364591 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000365267 00000 n +0000365300 00000 n +0000365147 00000 n +0000365180 00000 n +0000365027 00000 n +0000365060 00000 n +0000364907 00000 n +0000364940 00000 n +0000364787 00000 n +0000364820 00000 n +0000364667 00000 n +0000364700 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000165196 00000 n +0000164010 00000 n +0000164099 00000 n +0000164173 00000 n +0000164248 00000 n +0000164323 00000 n +0000164400 00000 n +0000372953 00000 n +0000046731 00000 n +0000167129 00000 n +0000066385 00000 n +0000066270 00000 n +0000049827 00000 n +0000050354 00000 n +0000050894 00000 n +0000051425 00000 n +0000051967 00000 n +0000052501 00000 n +0000053037 00000 n +0000053571 00000 n +0000048764 00000 n +0000049260 00000 n +0000049312 00000 n +0000149504 00000 n +0000149568 00000 n +0000137318 00000 n +0000137382 00000 n +0000122718 00000 n +0000122782 00000 n +0000110491 00000 n +0000110555 00000 n +0000095974 00000 n +0000096038 00000 n +0000083742 00000 n +0000083806 00000 n +0000069074 00000 n +0000069138 00000 n +0000054106 00000 n +0000054170 00000 n +0000054920 00000 n +0000054984 00000 n +0000066206 00000 n +0000066424 00000 n +0000069865 00000 n +0000069929 00000 n +0000083678 00000 n +0000084551 00000 n +0000084615 00000 n +0000095910 00000 n +0000096756 00000 n +0000096820 00000 n +0000110427 00000 n +0000111301 00000 n +0000111365 00000 n +0000122654 00000 n +0000123502 00000 n +0000123566 00000 n +0000137254 00000 n +0000138131 00000 n +0000138195 00000 n +0000149440 00000 n +0000150263 00000 n +0000150327 00000 n +0000163946 00000 n +0000165076 00000 n +0000165109 00000 n +0000164956 00000 n +0000164989 00000 n +0000164836 00000 n +0000164869 00000 n +0000164716 00000 n +0000164749 00000 n +0000164596 00000 n +0000164629 00000 n +0000164476 00000 n +0000164509 00000 n +0000165488 00000 n +0000165798 00000 n +0000167207 00000 n +0000167437 00000 n +0000168418 00000 n +0000175955 00000 n +0000241545 00000 n +0000307135 00000 n +0000373027 00000 n +trailer <<483E7E53040A4057B79E46A3828ABB5E>]>> startxref 373165 %%EOF \ No newline at end of file diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_to_object_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_to_object_big.png new file mode 100644 index 0000000000..ef2615bacc Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_to_object_big.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/typebg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/typebg.gif new file mode 100644 index 0000000000..2fcc77b2e8 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/typebg.gif differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/unselected.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/unselected.png new file mode 100644 index 0000000000..d5ac639405 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/unselected.png differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/valuemembersbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/valuemembersbg.gif new file mode 100644 index 0000000000..2a949311d7 Binary files /dev/null and b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/valuemembersbg.gif differ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/versions.txt b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/versions.txt new file mode 100644 index 0000000000..17d1caeb66 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/versions.txt @@ -0,0 +1 @@ +jquery=1.4.2 diff --git a/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala new file mode 100644 index 0000000000..574d6b04f8 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala @@ -0,0 +1,112 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Manohar Jonnalagedda + */ + +package scala.tools.nsc +package doc +package model + +import base.comment._ + +import reporters.Reporter +import scala.collection._ +import scala.reflect.internal.util.{NoPosition, Position} +import scala.language.postfixOps + +/** The comment parser transforms raw comment strings into `Comment` objects. + * Call `parse` to run the parser. Note that the parser is stateless and + * should only be built once for a given Scaladoc run. + * + * @author Manohar Jonnalagedda + * @author Gilles Dubochet */ +trait CommentFactory extends base.CommentFactoryBase { + thisFactory: ModelFactory with CommentFactory with MemberLookup => + + val global: Global + import global.{ reporter, definitions, Symbol } + + protected val commentCache = mutable.HashMap.empty[(Symbol, TemplateImpl), Comment] + + def addCommentBody(sym: Symbol, inTpl: TemplateImpl, docStr: String, docPos: global.Position): Symbol = { + commentCache += (sym, inTpl) -> parse(docStr, docStr, docPos, None) + sym + } + + def comment(sym: Symbol, currentTpl: Option[DocTemplateImpl], inTpl: DocTemplateImpl): Option[Comment] = { + val key = (sym, inTpl) + if (commentCache isDefinedAt key) + Some(commentCache(key)) + else { + val c = defineComment(sym, currentTpl, inTpl) + if (c isDefined) commentCache += (sym, inTpl) -> c.get + c + } + } + + /** A comment is usualy created by the parser, however for some special + * cases we have to give some `inTpl` comments (parent class for example) + * to the comment of the symbol. + * This function manages some of those cases : Param accessor and Primary constructor */ + def defineComment(sym: Symbol, currentTpl: Option[DocTemplateImpl], inTpl: DocTemplateImpl):Option[Comment] = { + + //param accessor case + // We just need the @param argument, we put it into the body + if( sym.isParamAccessor && + inTpl.comment.isDefined && + inTpl.comment.get.valueParams.isDefinedAt(sym.encodedName)) { + val comContent = Some(inTpl.comment.get.valueParams(sym.encodedName)) + Some(createComment(body0 = comContent)) + } + + // Primary constructor case + // We need some content of the class definition : @constructor for the body, + // @param and @deprecated, we can add some more if necessary + else if (sym.isPrimaryConstructor && inTpl.comment.isDefined ) { + val tplComment = inTpl.comment.get + // If there is nothing to put into the comment there is no need to create it + if(tplComment.constructor.isDefined || + tplComment.throws != Map.empty || + tplComment.valueParams != Map.empty || + tplComment.typeParams != Map.empty || + tplComment.deprecated.isDefined + ) + Some(createComment( body0 = tplComment.constructor, + throws0 = tplComment.throws, + valueParams0 = tplComment.valueParams, + typeParams0 = tplComment.typeParams, + deprecated0 = tplComment.deprecated + )) + else None + } + + //other comment cases + // parse function will make the comment + else { + val rawComment = global.expandedDocComment(sym, inTpl.sym).trim + if (rawComment != "") { + val tplOpt = if (currentTpl.isDefined) currentTpl else Some(inTpl) + val c = parse(rawComment, global.rawDocComment(sym), global.docCommentPos(sym), tplOpt) + Some(c) + } + else None + } + + } + + protected def parse(comment: String, src: String, pos: Position, inTplOpt: Option[DocTemplateImpl] = None): Comment = { + assert(!inTplOpt.isDefined || inTplOpt.get != null) + parseAtSymbol(comment, src, pos, inTplOpt map (_.sym)) + } + + /** Parses a string containing wiki syntax into a `Comment` object. + * Note that the string is assumed to be clean: + * - Removed Scaladoc start and end markers. + * - Removed start-of-line star and one whitespace afterwards (if present). + * - Removed all end-of-line whitespace. + * - Only `endOfLine` is used to mark line endings. */ + def parseWiki(string: String, pos: Position, inTplOpt: Option[DocTemplateImpl]): Body = { + assert(!inTplOpt.isDefined || inTplOpt.get != null) + parseWikiAtSymbol(string,pos, inTplOpt map (_.sym)) + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala b/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala new file mode 100644 index 0000000000..924f203a59 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala @@ -0,0 +1,601 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Manohar Jonnalagedda + * @author Gilles Dubochet + */ + +package scala.tools.nsc +package doc +package model + +import scala.collection._ +import base.comment._ +import diagram._ + +/** An entity in a Scaladoc universe. Entities are declarations in the program and correspond to symbols in the + * compiler. Entities model the following Scala concepts: + * - classes and traits; + * - objects and package; + * - constructors; + * - methods; + * - values, lazy values, and variables; + * - abstract type members and type aliases; + * - type and value parameters; + * - annotations. */ +trait Entity { + /** The name of the entity. Note that the name does not qualify this entity uniquely; use its `qualifiedName` + * instead. */ + def name : String + + /** The qualified name of the entity. This is this entity's name preceded by the qualified name of the template + * of which this entity is a member. The qualified name is unique to this entity. */ + def qualifiedName: String + + /** The template of which this entity is a member. */ + def inTemplate: TemplateEntity + + /** The list of entities such that each is a member of the entity that follows it; the first entity is always this + * entity, the last the root package entity. */ + def toRoot: List[Entity] + + /** The qualified name of this entity. */ + override def toString = qualifiedName + + /** The Scaladoc universe of which this entity is a member. */ + def universe: Universe + + /** The annotations attached to this entity, if any. */ + def annotations: List[Annotation] + + /** The kind of the entity */ + def kind: String + + /** Whether or not the template was defined in a package object */ + def inPackageObject: Boolean + + /** Indicates whether this entity lives in the types namespace (classes, traits, abstract/alias types) */ + def isType: Boolean +} + +object Entity { + private def isDeprecated(x: Entity) = x match { + case x: MemberEntity => x.deprecation.isDefined + case _ => false + } + /** Ordering deprecated things last. */ + implicit lazy val EntityOrdering: Ordering[Entity] = + Ordering[(Boolean, String)] on (x => (isDeprecated(x), x.name)) +} + +/** A template, which is either a class, trait, object or package. Depending on whether documentation is available + * or not, the template will be modeled as a [scala.tools.nsc.doc.model.NoDocTemplate] or a + * [scala.tools.nsc.doc.model.DocTemplateEntity]. */ +trait TemplateEntity extends Entity { + + /** Whether this template is a package (including the root package). */ + def isPackage: Boolean + + /** Whether this template is the root package. */ + def isRootPackage: Boolean + + /** Whether this template is a trait. */ + def isTrait: Boolean + + /** Whether this template is a class. */ + def isClass: Boolean + + /** Whether this template is an object. */ + def isObject: Boolean + + /** Whether documentation is available for this template. */ + def isDocTemplate: Boolean + + /** Whether this template is a case class. */ + def isCaseClass: Boolean + + /** The self-type of this template, if it differs from the template type. */ + def selfType : Option[TypeEntity] +} + + +/** An entity that is a member of a template. All entities, including templates, are member of another entity + * except for parameters and annotations. Note that all members of a template are modelled, including those that are + * inherited and not declared locally. */ +trait MemberEntity extends Entity { + + /** The comment attached to this member, if any. */ + def comment: Option[Comment] + + /** The group this member is from */ + def group: String + + /** The template of which this entity is a member. */ + def inTemplate: DocTemplateEntity + + /** The list of entities such that each is a member of the entity that follows it; the first entity is always this + * member, the last the root package entity. */ + def toRoot: List[MemberEntity] + + /** The templates in which this member has been declared. The first element of the list is the template that contains + * the currently active declaration of this member, subsequent elements are declarations that have been overriden. If + * the first element is equal to `inTemplate`, the member is declared locally, if not, it has been inherited. All + * elements of this list are in the linearization of `inTemplate`. */ + def inDefinitionTemplates: List[TemplateEntity] + + /** The qualified name of the member in its currently active declaration template. */ + def definitionName: String + + /** The visibility of this member. Note that members with restricted visibility may not be modeled in some + * universes. */ + def visibility: Visibility + + /** The flags that have been set for this entity. The following flags are supported: `implicit`, `sealed`, `abstract`, + * and `final`. */ + def flags: List[Paragraph] + + /** Some deprecation message if this member is deprecated, or none otherwise. */ + def deprecation: Option[Body] + + /** Some migration warning if this member has a migration annotation, or none otherwise. */ + def migration: Option[Body] + + /** For members representing values: the type of the value returned by this member; for members + * representing types: the type itself. */ + def resultType: TypeEntity + + /** Whether this member is a method. */ + def isDef: Boolean + + /** Whether this member is a value (this excludes lazy values). */ + def isVal: Boolean + + /** Whether this member is a lazy value. */ + def isLazyVal: Boolean + + /** Whether this member is a variable. */ + def isVar: Boolean + + /** Whether this member is a constructor. */ + def isConstructor: Boolean + + /** Whether this member is an alias type. */ + def isAliasType: Boolean + + /** Whether this member is an abstract type. */ + def isAbstractType: Boolean + + /** Whether this member is abstract. */ + def isAbstract: Boolean + + /** If this symbol is a use case, the useCaseOf will contain the member it was derived from, containing the full + * signature and the complete parameter descriptions. */ + def useCaseOf: Option[MemberEntity] + + /** If this member originates from an implicit conversion, we set the implicit information to the correct origin */ + def byConversion: Option[ImplicitConversion] + + /** The identity of this member, used for linking */ + def signature: String + + /** Compatibility signature, will be removed from future versions */ + def signatureCompat: String + + /** Indicates whether the member is inherited by implicit conversion */ + def isImplicitlyInherited: Boolean + + /** Indicates whether there is another member with the same name in the template that will take precendence */ + def isShadowedImplicit: Boolean + + /** Indicates whether there are other implicitly inherited members that have similar signatures (and thus they all + * become ambiguous) */ + def isAmbiguousImplicit: Boolean + + /** Indicates whether the implicitly inherited member is shadowed or ambiguous in its template */ + def isShadowedOrAmbiguousImplicit: Boolean +} + +object MemberEntity { + // Oh contravariance, contravariance, wherefore art thou contravariance? + // Note: the above works for both the commonly misunderstood meaning of the line and the real one. + implicit lazy val MemberEntityOrdering: Ordering[MemberEntity] = Entity.EntityOrdering on (x => x) +} + +/** An entity that is parameterized by types */ +trait HigherKinded { + + /** The type parameters of this entity. */ + def typeParams: List[TypeParam] +} + + +/** A template (class, trait, object or package) which is referenced in the universe, but for which no further + * documentation is available. Only templates for which a source file is given are documented by Scaladoc. */ +trait NoDocTemplate extends TemplateEntity { + def kind = + if (isClass) "class" + else if (isTrait) "trait" + else if (isObject) "object" + else "" +} + +/** An inherited template that was not documented in its original owner - example: + * in classpath: trait T { class C } -- T (and implicitly C) are not documented + * in the source: trait U extends T -- C appears in U as a MemberTemplateImpl + * -- that is, U has a member for it but C doesn't get its own page */ +trait MemberTemplateEntity extends TemplateEntity with MemberEntity with HigherKinded { + + /** The value parameters of this case class, or an empty list if this class is not a case class. As case class value + * parameters cannot be curried, the outer list has exactly one element. */ + def valueParams: List[List[ValueParam]] + + /** The direct super-type of this template + e.g: {{{class A extends B[C[Int]] with D[E]}}} will have two direct parents: class B and D + NOTE: we are dropping the refinement here! */ + def parentTypes: List[(TemplateEntity, TypeEntity)] +} + +/** A template (class, trait, object or package) for which documentation is available. Only templates for which + * a source file is given are documented by Scaladoc. */ +trait DocTemplateEntity extends MemberTemplateEntity { + + /** The list of templates such that each is a member of the template that follows it; the first template is always + * this template, the last the root package entity. */ + def toRoot: List[DocTemplateEntity] + + /** The source file in which the current template is defined and the line where the definition starts, if they exist. + * A source file exists for all templates, except for those that are generated synthetically by Scaladoc. */ + def inSource: Option[(io.AbstractFile, Int)] + + /** An HTTP address at which the source of this template is available, if it is available. An address is available + * only if the `docsourceurl` setting has been set. */ + def sourceUrl: Option[java.net.URL] + + /** All class, trait and object templates which are part of this template's linearization, in lineratization order. + * This template's linearization contains all of its direct and indirect super-classes and super-traits. */ + def linearizationTemplates: List[TemplateEntity] + + /** All instantiated types which are part of this template's linearization, in lineratization order. + * This template's linearization contains all of its direct and indirect super-types. */ + def linearizationTypes: List[TypeEntity] + + /** All class, trait and object templates for which this template is a direct or indirect super-class or super-trait. + * Only templates for which documentation is available in the universe (`DocTemplateEntity`) are listed. */ + def allSubClasses: List[DocTemplateEntity] + + /** All class, trait and object templates for which this template is a *direct* super-class or super-trait. + * Only templates for which documentation is available in the universe (`DocTemplateEntity`) are listed. */ + def directSubClasses: List[DocTemplateEntity] + + /** All members of this template. If this template is a package, only templates for which documentation is available + * in the universe (`DocTemplateEntity`) are listed. */ + def members: List[MemberEntity] + + /** All templates that are members of this template. If this template is a package, only templates for which + * documentation is available in the universe (`DocTemplateEntity`) are listed. */ + def templates: List[TemplateEntity with MemberEntity] + + /** All methods that are members of this template. */ + def methods: List[Def] + + /** All values, lazy values and variables that are members of this template. */ + def values: List[Val] + + /** All abstract types that are members of this template. */ + def abstractTypes: List[AbstractType] + + /** All type aliases that are members of this template. */ + def aliasTypes: List[AliasType] + + /** The primary constructor of this class, if it has been defined. */ + def primaryConstructor: Option[Constructor] + + /** All constructors of this class, including the primary constructor. */ + def constructors: List[Constructor] + + /** The companion of this template, or none. If a class and an object are defined as a pair of the same name, the + * other entity of the pair is the companion. */ + def companion: Option[DocTemplateEntity] + + /** The implicit conversions this template (class or trait, objects and packages are not affected) */ + def conversions: List[ImplicitConversion] + + /** The shadowing information for the implicitly added members */ + def implicitsShadowing: Map[MemberEntity, ImplicitMemberShadowing] + + /** Classes that can be implcitly converted to this class */ + def incomingImplicitlyConvertedClasses: List[(DocTemplateEntity, ImplicitConversion)] + + /** Classes to which this class can be implicitly converted to + NOTE: Some classes might not be included in the scaladoc run so they will be NoDocTemplateEntities */ + def outgoingImplicitlyConvertedClasses: List[(TemplateEntity, TypeEntity, ImplicitConversion)] + + /** If this template takes place in inheritance and implicit conversion relations, it will be shown in this diagram */ + def inheritanceDiagram: Option[Diagram] + + /** If this template contains other templates, such as classes and traits, they will be shown in this diagram */ + def contentDiagram: Option[Diagram] + + /** Returns the group description taken either from this template or its linearizationTypes */ + def groupDescription(group: String): Option[Body] + + /** Returns the group description taken either from this template or its linearizationTypes */ + def groupPriority(group: String): Int + + /** Returns the group description taken either from this template or its linearizationTypes */ + def groupName(group: String): String +} + +/** A trait template. */ +trait Trait extends MemberTemplateEntity { + def kind = "trait" +} + +/** A class template. */ +trait Class extends MemberTemplateEntity { + override def kind = "class" +} + +/** An object template. */ +trait Object extends MemberTemplateEntity { + def kind = "object" +} + +/** A package template. A package is in the universe if it is declared as a package object, or if it + * contains at least one template. */ +trait Package extends DocTemplateEntity { + + /** The package of which this package is a member. */ + def inTemplate: Package + + /** The package such that each is a member of the package that follows it; the first package is always this + * package, the last the root package. */ + def toRoot: List[Package] + + /** All packages that are member of this package. */ + def packages: List[Package] + + override def kind = "package" +} + + +/** The root package, which contains directly or indirectly all members in the universe. A universe + * contains exactly one root package. */ +trait RootPackage extends Package + + +/** A non-template member (method, value, lazy value, variable, constructor, alias type, and abstract type). */ +trait NonTemplateMemberEntity extends MemberEntity { + /** Whether this member is a use case. A use case is a member which does not exist in the documented code. + * It corresponds to a real member, and provides a simplified, yet compatible signature for that member. */ + def isUseCase: Boolean +} + + +/** A method (`def`) of a template. */ +trait Def extends NonTemplateMemberEntity with HigherKinded { + + /** The value parameters of this method. Each parameter block of a curried method is an element of the list. + * Each parameter block is a list of value parameters. */ + def valueParams : List[List[ValueParam]] + + def kind = "method" +} + + +/** A constructor of a class. */ +trait Constructor extends NonTemplateMemberEntity { + + /** Whether this is the primary constructor of a class. The primary constructor is defined syntactically as part of + * the declaration of the class. */ + def isPrimary: Boolean + + /** The value parameters of this constructor. As constructors cannot be curried, the outer list has exactly one + * element. */ + def valueParams : List[List[ValueParam]] + + def kind = "constructor" +} + + +/** A value (`val`), lazy val (`lazy val`) or variable (`var`) of a template. */ +trait Val extends NonTemplateMemberEntity { + def kind = "[lazy] value/variable" +} + + +/** An abstract type member of a template. */ +trait AbstractType extends MemberTemplateEntity with HigherKinded { + + /** The lower bound for this abstract type, if it has been defined. */ + def lo: Option[TypeEntity] + + /** The upper bound for this abstract type, if it has been defined. */ + def hi: Option[TypeEntity] + + def kind = "abstract type" +} + + +/** An type alias of a template. */ +trait AliasType extends MemberTemplateEntity with HigherKinded { + + /** The type aliased by this type alias. */ + def alias: TypeEntity + + def kind = "type alias" +} + + +/** A parameter to an entity. */ +trait ParameterEntity { + + def name: String +} + + +/** A type parameter to a class, trait, or method. */ +trait TypeParam extends ParameterEntity with HigherKinded { + + /** The variance of this type parameter. Valid values are "+", "-", and the empty string. */ + def variance: String + + /** The lower bound for this type parameter, if it has been defined. */ + def lo: Option[TypeEntity] + + /** The upper bound for this type parameter, if it has been defined. */ + def hi: Option[TypeEntity] +} + + +/** A value parameter to a constructor or method. */ +trait ValueParam extends ParameterEntity { + + /** The type of this value parameter. */ + def resultType: TypeEntity + + /** The devault value of this value parameter, if it has been defined. */ + def defaultValue: Option[TreeEntity] + + /** Whether this value parameter is implicit. */ + def isImplicit: Boolean +} + + +/** An annotation to an entity. */ +trait Annotation extends Entity { + + /** The class of this annotation. */ + def annotationClass: TemplateEntity + + /** The arguments passed to the constructor of the annotation class. */ + def arguments: List[ValueArgument] + + def kind = "annotation" +} + +/** A trait that signals the member results from an implicit conversion */ +trait ImplicitConversion { + + /** The source of the implicit conversion*/ + def source: DocTemplateEntity + + /** The result type after the conversion */ + def targetType: TypeEntity + + /** The components of the implicit conversion type parents */ + def targetTypeComponents: List[(TemplateEntity, TypeEntity)] + + /** The entity for the method that performed the conversion, if it's documented (or just its name, otherwise) */ + def convertorMethod: Either[MemberEntity, String] + + /** A short name of the convertion */ + def conversionShortName: String + + /** A qualified name uniquely identifying the convertion (currently: the conversion method's qualified name) */ + def conversionQualifiedName: String + + /** The entity that performed the conversion */ + def convertorOwner: TemplateEntity + + /** The constraints that the transformations puts on the type parameters */ + def constraints: List[Constraint] + + /** The members inherited by this implicit conversion */ + def members: List[MemberEntity] + + /** Is this a hidden implicit conversion (as specified in the settings) */ + def isHiddenConversion: Boolean +} + +/** Shadowing captures the information that the member is shadowed by some other members + * There are two cases of implicitly added member shadowing: + * 1) shadowing from a original class member (the class already has that member) + * in this case, it won't be possible to call the member directly, the type checker will fail attempting to adapt + * the call arguments (or if they fit it will call the original class' method) + * 2) shadowing from other possible implicit conversions () + * this will result in an ambiguous implicit converion error + */ +trait ImplicitMemberShadowing { + /** The members that shadow the current entry use .inTemplate to get to the template name */ + def shadowingMembers: List[MemberEntity] + + /** The members that ambiguate this implicit conversion + Note: for ambiguatingMembers you have the following invariant: + assert(ambiguatingMembers.foreach(_.byConversion.isDefined) */ + def ambiguatingMembers: List[MemberEntity] + + def isShadowed: Boolean = !shadowingMembers.isEmpty + def isAmbiguous: Boolean = !ambiguatingMembers.isEmpty +} + +/** A trait that encapsulates a constraint necessary for implicit conversion */ +trait Constraint + +/** A constraint involving a type parameter which must be in scope */ +trait ImplicitInScopeConstraint extends Constraint { + /** The type of the implicit value required */ + def implicitType: TypeEntity + + /** toString for debugging */ + override def toString = "an implicit _: " + implicitType.name + " must be in scope" +} + +trait TypeClassConstraint extends ImplicitInScopeConstraint with TypeParamConstraint { + /** Type class name */ + def typeClassEntity: TemplateEntity + + /** toString for debugging */ + override def toString = typeParamName + " is a class of type " + typeClassEntity.qualifiedName + " (" + + typeParamName + ": " + typeClassEntity.name + ")" +} + +trait KnownTypeClassConstraint extends TypeClassConstraint { + /** Type explanation, takes the type parameter name and generates the explanation */ + def typeExplanation: (String) => String + + /** toString for debugging */ + override def toString = typeExplanation(typeParamName) + " (" + typeParamName + ": " + typeClassEntity.name + ")" +} + +/** A constraint involving a type parameter */ +trait TypeParamConstraint extends Constraint { + /** The type parameter involved */ + def typeParamName: String +} + +trait EqualTypeParamConstraint extends TypeParamConstraint { + /** The rhs */ + def rhs: TypeEntity + /** toString for debugging */ + override def toString = typeParamName + " is " + rhs.name + " (" + typeParamName + " =:= " + rhs.name + ")" +} + +trait BoundedTypeParamConstraint extends TypeParamConstraint { + /** The lower bound */ + def lowerBound: TypeEntity + + /** The upper bound */ + def upperBound: TypeEntity + + /** toString for debugging */ + override def toString = typeParamName + " is a superclass of " + lowerBound.name + " and a subclass of " + + upperBound.name + " (" + typeParamName + " >: " + lowerBound.name + " <: " + upperBound.name + ")" +} + +trait LowerBoundedTypeParamConstraint extends TypeParamConstraint { + /** The lower bound */ + def lowerBound: TypeEntity + + /** toString for debugging */ + override def toString = typeParamName + " is a superclass of " + lowerBound.name + " (" + typeParamName + " >: " + + lowerBound.name + ")" +} + +trait UpperBoundedTypeParamConstraint extends TypeParamConstraint { + /** The lower bound */ + def upperBound: TypeEntity + + /** toString for debugging */ + override def toString = typeParamName + " is a subclass of " + upperBound.name + " (" + typeParamName + " <: " + + upperBound.name + ")" +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala new file mode 100755 index 0000000000..1272906df5 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala @@ -0,0 +1,58 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Pedro Furlanetto + */ + +package scala.tools.nsc +package doc +package model + +import scala.collection._ + +object IndexModelFactory { + + def makeIndex(universe: Universe): Index = new Index { + + lazy val firstLetterIndex: Map[Char, SymbolMap] = { + + object result extends mutable.HashMap[Char,SymbolMap] { + + /* symbol name ordering */ + implicit def orderingMap = math.Ordering.String + + def addMember(d: MemberEntity) = { + val firstLetter = { + val ch = d.name.head.toLower + if(ch.isLetterOrDigit) ch else '_' + } + val letter = this.get(firstLetter).getOrElse { + immutable.SortedMap[String, SortedSet[MemberEntity]]() + } + val members = letter.get(d.name).getOrElse { + SortedSet.empty[MemberEntity](Ordering.by { _.toString }) + } + d + this(firstLetter) = letter + (d.name -> members) + } + } + + //@scala.annotation.tailrec // TODO + def gather(owner: DocTemplateEntity): Unit = + for(m <- owner.members if m.inDefinitionTemplates.isEmpty || m.inDefinitionTemplates.head == owner) + m match { + case tpl: DocTemplateEntity => + result.addMember(tpl) + gather(tpl) + case non: MemberEntity if !non.isConstructor => + result.addMember(non) + case x @ _ => + } + + gather(universe.rootPackage) + + result.toMap + + } + + } + +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala new file mode 100644 index 0000000000..23259a4ae8 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala @@ -0,0 +1,63 @@ +package scala.tools.nsc +package doc +package model + +import base._ + +/** This trait extracts all required information for documentation from compilation units */ +trait MemberLookup extends base.MemberLookupBase { + thisFactory: ModelFactory => + + import global._ + import definitions.{ NothingClass, AnyClass, AnyValClass, AnyRefClass, ListClass } + + override def internalLink(sym: Symbol, site: Symbol): Option[LinkTo] = + findTemplateMaybe(sym) match { + case Some(tpl) => Some(LinkToTpl(tpl)) + case None => + findTemplateMaybe(site) flatMap { inTpl => + inTpl.members find (_.asInstanceOf[EntityImpl].sym == sym) map (LinkToMember(_, inTpl)) + } + } + + override def chooseLink(links: List[LinkTo]): LinkTo = { + val mbrs = links.collect { + case lm@LinkToMember(mbr: MemberEntity, _) => (mbr, lm) + } + if (mbrs.isEmpty) + links.head + else + mbrs.min(Ordering[MemberEntity].on[(MemberEntity, LinkTo)](_._1))._2 + } + + override def toString(link: LinkTo) = link match { + case LinkToTpl(tpl: EntityImpl) => tpl.sym.toString + case LinkToMember(mbr: EntityImpl, inTpl: EntityImpl) => + mbr.sym.signatureString + " in " + inTpl.sym.toString + case _ => link.toString + } + + override def findExternalLink(sym: Symbol, name: String): Option[LinkToExternal] = { + val sym1 = + if (sym == AnyClass || sym == AnyRefClass || sym == AnyValClass || sym == NothingClass) ListClass + else if (sym.isPackage) + /* Get package object which has associatedFile ne null */ + sym.info.member(newTermName("package")) + else sym + Option(sym1.associatedFile) flatMap (_.underlyingSource) flatMap { src => + val path = src.path + settings.extUrlMapping get path map { url => + LinkToExternal(name, url + "#" + name) + } + } orElse { + // Deprecated option. + settings.extUrlPackageMapping find { + case (pkg, _) => name startsWith pkg + } map { + case (_, url) => LinkToExternal(name, url + "#" + name) + } + } + } + + override def warnNoLink = !settings.docNoLinkWarnings.value +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala new file mode 100644 index 0000000000..1df725636a --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala @@ -0,0 +1,1045 @@ +/* NSC -- new Scala compiler -- Copyright 2007-2013 LAMP/EPFL */ + +package scala.tools.nsc +package doc +package model + +import base._ +import base.comment._ +import diagram._ + +import scala.collection._ +import scala.util.matching.Regex + +import symtab.Flags + +import io._ + +import model.{ RootPackage => RootPackageEntity } + +/** This trait extracts all required information for documentation from compilation units */ +class ModelFactory(val global: Global, val settings: doc.Settings) { + thisFactory: ModelFactory + with ModelFactoryImplicitSupport + with ModelFactoryTypeSupport + with DiagramFactory + with CommentFactory + with TreeFactory + with MemberLookup => + + import global._ + import definitions.{ ObjectClass, NothingClass, AnyClass, AnyValClass, AnyRefClass, ListClass } + import rootMirror.{ RootPackage, RootClass, EmptyPackage } + + // Defaults for member grouping, that may be overridden by the template + val defaultGroup = "Ungrouped" + val defaultGroupName = "Ungrouped" + val defaultGroupDesc = None + val defaultGroupPriority = 1000 + + def templatesCount = docTemplatesCache.count(_._2.isDocTemplate) - droppedPackages.size + + private var _modelFinished = false + def modelFinished: Boolean = _modelFinished + private var universe: Universe = null + + def makeModel: Option[Universe] = { + val universe = new Universe { thisUniverse => + thisFactory.universe = thisUniverse + val settings = thisFactory.settings + val rootPackage = modelCreation.createRootPackage + } + _modelFinished = true + // complete the links between model entities, everthing that couldn't have been done before + universe.rootPackage.completeModel() + + Some(universe) filter (_.rootPackage != null) + } + + // state: + var ids = 0 + private val droppedPackages = mutable.Set[PackageImpl]() + protected val docTemplatesCache = new mutable.LinkedHashMap[Symbol, DocTemplateImpl] + protected val noDocTemplatesCache = new mutable.LinkedHashMap[Symbol, NoDocTemplateImpl] + def packageDropped(tpl: DocTemplateImpl) = tpl match { + case p: PackageImpl => droppedPackages(p) + case _ => false + } + + def optimize(str: String): String = + if (str.length < 16) str.intern else str + + /* ============== IMPLEMENTATION PROVIDING ENTITY TYPES ============== */ + + abstract class EntityImpl(val sym: Symbol, val inTpl: TemplateImpl) extends Entity { + val name = optimize(sym.nameString) + val universe = thisFactory.universe + + // Debugging: + // assert(id != 36, sym + " " + sym.getClass) + //println("Creating entity #" + id + " [" + kind + " " + qualifiedName + "] for sym " + sym.kindString + " " + sym.ownerChain.reverse.map(_.name).mkString(".")) + + def inTemplate: TemplateImpl = inTpl + def toRoot: List[EntityImpl] = this :: inTpl.toRoot + def qualifiedName = name + def annotations = sym.annotations.map(makeAnnotation) + def inPackageObject: Boolean = sym.owner.isModuleClass && sym.owner.sourceModule.isPackageObject + def isType = sym.name.isTypeName + } + + trait TemplateImpl extends EntityImpl with TemplateEntity { + override def qualifiedName: String = + if (inTemplate == null || inTemplate.isRootPackage) name else optimize(inTemplate.qualifiedName + "." + name) + def isPackage = sym.isPackage + def isTrait = sym.isTrait + def isClass = sym.isClass && !sym.isTrait + def isObject = sym.isModule && !sym.isPackage + def isCaseClass = sym.isCaseClass + def isRootPackage = false + def selfType = if (sym.thisSym eq sym) None else Some(makeType(sym.thisSym.typeOfThis, this)) + } + + abstract class MemberImpl(sym: Symbol, inTpl: DocTemplateImpl) extends EntityImpl(sym, inTpl) with MemberEntity { + lazy val comment = { + // If the current tpl is a DocTemplate, we consider itself as the root for resolving link targets (instead of the + // package the class is in) -- so people can refer to methods directly [[foo]], instead of using [[MyClass.foo]] + // in the doc comment of MyClass + val thisTpl = this match { + case d: DocTemplateImpl => Some(d) + case _ => None + } + if (inTpl != null) thisFactory.comment(sym, thisTpl, inTpl) else None + } + def group = comment flatMap (_.group) getOrElse defaultGroup + override def inTemplate = inTpl + override def toRoot: List[MemberImpl] = this :: inTpl.toRoot + def inDefinitionTemplates = + if (inTpl == null) + List(makeRootPackage) + else + makeTemplate(sym.owner)::(sym.allOverriddenSymbols map { inhSym => makeTemplate(inhSym.owner) }) + def visibility = { + if (sym.isPrivateLocal) PrivateInInstance() + else if (sym.isProtectedLocal) ProtectedInInstance() + else { + val qual = + if (sym.hasAccessBoundary) + Some(makeTemplate(sym.privateWithin)) + else None + if (sym.isPrivate) PrivateInTemplate(inTpl) + else if (sym.isProtected) ProtectedInTemplate(qual getOrElse inTpl) + else qual match { + case Some(q) => PrivateInTemplate(q) + case None => Public() + } + } + } + def flags = { + val fgs = mutable.ListBuffer.empty[Paragraph] + if (sym.isImplicit) fgs += Paragraph(Text("implicit")) + if (sym.isSealed) fgs += Paragraph(Text("sealed")) + if (!sym.isTrait && (sym hasFlag Flags.ABSTRACT)) fgs += Paragraph(Text("abstract")) + /* Resetting the DEFERRED flag is a little trick here for refined types: (example from scala.collections) + * {{{ + * implicit def traversable2ops[T](t: scala.collection.GenTraversableOnce[T]) = new TraversableOps[T] { + * def isParallel = ... + * }}} + * the type the method returns is TraversableOps, which has all-abstract symbols. But in reality, it couldn't have + * any abstract terms, otherwise it would fail compilation. So we reset the DEFERRED flag. */ + if (!sym.isTrait && (sym hasFlag Flags.DEFERRED) && (!isImplicitlyInherited)) fgs += Paragraph(Text("abstract")) + if (!sym.isModule && (sym hasFlag Flags.FINAL)) fgs += Paragraph(Text("final")) + fgs.toList + } + def deprecation = + if (sym.isDeprecated) + Some((sym.deprecationMessage, sym.deprecationVersion) match { + case (Some(msg), Some(ver)) => parseWiki("''(Since version " + ver + ")'' " + msg, NoPosition, Some(inTpl)) + case (Some(msg), None) => parseWiki(msg, NoPosition, Some(inTpl)) + case (None, Some(ver)) => parseWiki("''(Since version " + ver + ")''", NoPosition, Some(inTpl)) + case (None, None) => Body(Nil) + }) + else + comment flatMap { _.deprecated } + def migration = + if(sym.hasMigrationAnnotation) + Some((sym.migrationMessage, sym.migrationVersion) match { + case (Some(msg), Some(ver)) => parseWiki("''(Changed in version " + ver + ")'' " + msg, NoPosition, Some(inTpl)) + case (Some(msg), None) => parseWiki(msg, NoPosition, Some(inTpl)) + case (None, Some(ver)) => parseWiki("''(Changed in version " + ver + ")''", NoPosition, Some(inTpl)) + case (None, None) => Body(Nil) + }) + else + None + + def resultType = { + def resultTpe(tpe: Type): Type = tpe match { // similar to finalResultType, except that it leaves singleton types alone + case PolyType(_, res) => resultTpe(res) + case MethodType(_, res) => resultTpe(res) + case NullaryMethodType(res) => resultTpe(res) + case _ => tpe + } + val tpe = byConversion.fold(sym.tpe) (_.toType memberInfo sym) + makeTypeInTemplateContext(resultTpe(tpe), inTemplate, sym) + } + def isDef = false + def isVal = false + def isLazyVal = false + def isVar = false + def isConstructor = false + def isAliasType = false + def isAbstractType = false + def isAbstract = + // for the explanation of conversion == null see comment on flags + ((!sym.isTrait && ((sym hasFlag Flags.ABSTRACT) || (sym hasFlag Flags.DEFERRED)) && (!isImplicitlyInherited)) || + sym.isAbstractClass || sym.isAbstractType) && !sym.isSynthetic + + def signature = externalSignature(sym) + lazy val signatureCompat = { + + def defParams(mbr: Any): String = mbr match { + case d: MemberEntity with Def => + val paramLists: List[String] = + if (d.valueParams.isEmpty) Nil + else d.valueParams map (ps => ps map (_.resultType.name) mkString ("(",",",")")) + paramLists.mkString + case _ => "" + } + + def tParams(mbr: Any): String = mbr match { + case hk: HigherKinded if !hk.typeParams.isEmpty => + def boundsToString(hi: Option[TypeEntity], lo: Option[TypeEntity]): String = { + def bound0(bnd: Option[TypeEntity], pre: String): String = bnd match { + case None => "" + case Some(tpe) => pre ++ tpe.toString + } + bound0(hi, "<:") ++ bound0(lo, ">:") + } + "[" + hk.typeParams.map(tp => tp.variance + tp.name + tParams(tp) + boundsToString(tp.hi, tp.lo)).mkString(", ") + "]" + case _ => "" + } + + (name + tParams(this) + defParams(this) +":"+ resultType.name).replaceAll("\\s","") // no spaces allowed, they break links + } + // these only apply for NonTemplateMemberEntities + def useCaseOf: Option[MemberEntity] = None + def byConversion: Option[ImplicitConversionImpl] = None + def isImplicitlyInherited = false + def isShadowedImplicit = false + def isAmbiguousImplicit = false + def isShadowedOrAmbiguousImplicit = false + } + + /** A template that is not documented at all. The class is instantiated during lookups, to indicate that the class + * exists, but should not be documented (either it's not included in the source or it's not visible) + */ + class NoDocTemplateImpl(sym: Symbol, inTpl: TemplateImpl) extends EntityImpl(sym, inTpl) with TemplateImpl with HigherKindedImpl with NoDocTemplate { + assert(modelFinished, this) + assert(!(noDocTemplatesCache isDefinedAt sym), (sym, noDocTemplatesCache(sym))) + noDocTemplatesCache += (sym -> this) + def isDocTemplate = false + } + + /** An inherited template that was not documented in its original owner - example: + * in classpath: trait T { class C } -- T (and implicitly C) are not documented + * in the source: trait U extends T -- C appears in U as a MemberTemplateImpl -- that is, U has a member for it + * but C doesn't get its own page + */ + abstract class MemberTemplateImpl(sym: Symbol, inTpl: DocTemplateImpl) extends MemberImpl(sym, inTpl) with TemplateImpl with HigherKindedImpl with MemberTemplateEntity { + // no templates cache for this class, each owner gets its own instance + def isDocTemplate = false + lazy val definitionName = optimize(inDefinitionTemplates.head.qualifiedName + "." + name) + def valueParams: List[List[ValueParam]] = Nil /** TODO, these are now only computed for DocTemplates */ + + def parentTypes = + if (sym.isPackage || sym == AnyClass) List() else { + val tps = (this match { + case a: AliasType => sym.tpe.dealias.parents + case a: AbstractType => sym.info.bounds match { + case TypeBounds(lo, RefinedType(parents, decls)) => parents + case TypeBounds(lo, hi) => hi :: Nil + case _ => Nil + } + case _ => sym.tpe.parents + }) map { _.asSeenFrom(sym.thisType, sym) } + makeParentTypes(RefinedType(tps, EmptyScope), Some(this), inTpl) + } + } + + /** The instantiation of `TemplateImpl` triggers the creation of the following entities: + * All ancestors of the template and all non-package members. + */ + abstract class DocTemplateImpl(sym: Symbol, inTpl: DocTemplateImpl) extends MemberTemplateImpl(sym, inTpl) with DocTemplateEntity { + assert(!modelFinished, (sym, inTpl)) + assert(!(docTemplatesCache isDefinedAt sym), sym) + docTemplatesCache += (sym -> this) + + if (settings.verbose.value) + inform("Creating doc template for " + sym) + + override def toRoot: List[DocTemplateImpl] = this :: inTpl.toRoot + + protected def inSourceFromSymbol(symbol: Symbol) = + if (symbol.sourceFile != null && ! symbol.isSynthetic) + Some((symbol.sourceFile, symbol.pos.line)) + else + None + + def inSource = inSourceFromSymbol(sym) + + def sourceUrl = { + def fixPath(s: String) = s.replaceAll("\\" + java.io.File.separator, "/") + val assumedSourceRoot = fixPath(settings.sourcepath.value) stripSuffix "/" + + if (!settings.docsourceurl.isDefault) + inSource map { case (file, _) => + val filePath = fixPath(file.path).replaceFirst("^" + assumedSourceRoot, "").stripSuffix(".scala") + val tplOwner = this.inTemplate.qualifiedName + val tplName = this.name + val patches = new Regex("""€\{(FILE_PATH|TPL_OWNER|TPL_NAME)\}""") + def substitute(name: String): String = name match { + case "FILE_PATH" => filePath + case "TPL_OWNER" => tplOwner + case "TPL_NAME" => tplName + } + val patchedString = patches.replaceAllIn(settings.docsourceurl.value, m => java.util.regex.Matcher.quoteReplacement(substitute(m.group(1))) ) + new java.net.URL(patchedString) + } + else None + } + + protected def linearizationFromSymbol(symbol: Symbol): List[(TemplateEntity, TypeEntity)] = { + symbol.ancestors map { ancestor => + val typeEntity = makeType(symbol.info.baseType(ancestor), this) + val tmplEntity = makeTemplate(ancestor) match { + case tmpl: DocTemplateImpl => tmpl registerSubClass this ; tmpl + case tmpl => tmpl + } + (tmplEntity, typeEntity) + } + } + + lazy val linearization = linearizationFromSymbol(sym) + def linearizationTemplates = linearization map { _._1 } + def linearizationTypes = linearization map { _._2 } + + /* Subclass cache */ + private lazy val subClassesCache = ( + if (sym == AnyRefClass) null + else mutable.ListBuffer[DocTemplateEntity]() + ) + def registerSubClass(sc: DocTemplateEntity): Unit = { + if (subClassesCache != null) + subClassesCache += sc + } + def allSubClasses = if (subClassesCache == null) Nil else subClassesCache.toList + def directSubClasses = allSubClasses.filter(_.parentTypes.map(_._1).contains(this)) + + /* Implcitly convertible class cache */ + private var implicitlyConvertibleClassesCache: mutable.ListBuffer[(DocTemplateImpl, ImplicitConversionImpl)] = null + def registerImplicitlyConvertibleClass(dtpl: DocTemplateImpl, conv: ImplicitConversionImpl): Unit = { + if (implicitlyConvertibleClassesCache == null) + implicitlyConvertibleClassesCache = mutable.ListBuffer[(DocTemplateImpl, ImplicitConversionImpl)]() + implicitlyConvertibleClassesCache += ((dtpl, conv)) + } + + def incomingImplicitlyConvertedClasses: List[(DocTemplateImpl, ImplicitConversionImpl)] = + if (implicitlyConvertibleClassesCache == null) + List() + else + implicitlyConvertibleClassesCache.toList + + // the implicit conversions are generated eagerly, but the members generated by implicit conversions are added + // lazily, on completeModel + val conversions: List[ImplicitConversionImpl] = + if (settings.docImplicits.value) makeImplicitConversions(sym, this) else Nil + + // members as given by the compiler + lazy val memberSyms = sym.info.members.filter(s => membersShouldDocument(s, this)).toList + + // the inherited templates (classes, traits or objects) + val memberSymsLazy = memberSyms.filter(t => templateShouldDocument(t, this) && !inOriginalOwner(t, this)) + // the direct members (methods, values, vars, types and directly contained templates) + val memberSymsEager = memberSyms.filter(!memberSymsLazy.contains(_)) + // the members generated by the symbols in memberSymsEager + val ownMembers = (memberSymsEager.flatMap(makeMember(_, None, this))) + + // all the members that are documentented PLUS the members inherited by implicit conversions + var members: List[MemberImpl] = ownMembers + + def templates = members collect { case c: TemplateEntity with MemberEntity => c } + def methods = members collect { case d: Def => d } + def values = members collect { case v: Val => v } + def abstractTypes = members collect { case t: AbstractType => t } + def aliasTypes = members collect { case t: AliasType => t } + + /** + * This is the final point in the core model creation: no DocTemplates are created after the model has finished, but + * inherited templates and implicit members are added to the members at this point. + */ + def completeModel(): Unit = { + // DFS completion + // since alias types and abstract types have no own members, there's no reason for them to call completeModel + if (!sym.isAliasType && !sym.isAbstractType) + for (member <- members) + member match { + case d: DocTemplateImpl => d.completeModel() + case _ => + } + + members :::= memberSymsLazy.map(modelCreation.createLazyTemplateMember(_, this)) + + // compute linearization to register subclasses + linearization + outgoingImplicitlyConvertedClasses + + // the members generated by the symbols in memberSymsEager PLUS the members from the usecases + val allMembers = ownMembers ::: ownMembers.flatMap(_.useCaseOf.map(_.asInstanceOf[MemberImpl])).distinct + implicitsShadowing = makeShadowingTable(allMembers, conversions, this) + // finally, add the members generated by implicit conversions + members :::= conversions.flatMap(_.memberImpls) + } + + var implicitsShadowing = Map[MemberEntity, ImplicitMemberShadowing]() + + lazy val outgoingImplicitlyConvertedClasses: List[(TemplateEntity, TypeEntity, ImplicitConversionImpl)] = + conversions flatMap (conv => + if (!implicitExcluded(conv.conversionQualifiedName)) + conv.targetTypeComponents map { + case (template, tpe) => + template match { + case d: DocTemplateImpl if (d != this) => d.registerImplicitlyConvertibleClass(this, conv) + case _ => // nothing + } + (template, tpe, conv) + } + else List() + ) + + override def isDocTemplate = true + private[this] lazy val companionSymbol = + if (sym.isAliasType || sym.isAbstractType) { + inTpl.sym.info.member(sym.name.toTermName) match { + case NoSymbol => NoSymbol + case s => + s.info match { + case ot: OverloadedType => + NoSymbol + case _ => + // that's to navigate from val Foo: FooExtractor to FooExtractor :) + s.info.resultType.typeSymbol + } + } + } + else + sym.companionSymbol + + def companion = + companionSymbol match { + case NoSymbol => None + case comSym if !isEmptyJavaObject(comSym) && (comSym.isClass || comSym.isModule) => + makeTemplate(comSym) match { + case d: DocTemplateImpl => Some(d) + case _ => None + } + case _ => None + } + + def constructors: List[MemberImpl with Constructor] = if (isClass) members collect { case d: Constructor => d } else Nil + def primaryConstructor: Option[MemberImpl with Constructor] = if (isClass) constructors find { _.isPrimary } else None + override def valueParams = + // we don't want params on a class (non case class) signature + if (isCaseClass) primaryConstructor match { + case Some(const) => const.sym.paramss map (_ map (makeValueParam(_, this))) + case None => List() + } + else List.empty + + // These are generated on-demand, make sure you don't call them more than once + def inheritanceDiagram = makeInheritanceDiagram(this) + def contentDiagram = makeContentDiagram(this) + + def groupSearch[T](extractor: Comment => Option[T]): Option[T] = { + val comments = comment +: linearizationTemplates.collect { case dtpl: DocTemplateImpl => dtpl.comment } + comments.flatten.map(extractor).flatten.headOption orElse { + Option(inTpl) flatMap (_.groupSearch(extractor)) + } + } + + def groupDescription(group: String): Option[Body] = groupSearch(_.groupDesc.get(group)) orElse { if (group == defaultGroup) defaultGroupDesc else None } + def groupPriority(group: String): Int = groupSearch(_.groupPrio.get(group)) getOrElse { if (group == defaultGroup) defaultGroupPriority else 0 } + def groupName(group: String): String = groupSearch(_.groupNames.get(group)) getOrElse { if (group == defaultGroup) defaultGroupName else group } + } + + abstract class PackageImpl(sym: Symbol, inTpl: PackageImpl) extends DocTemplateImpl(sym, inTpl) with Package { + override def inTemplate = inTpl + override def toRoot: List[PackageImpl] = this :: inTpl.toRoot + override lazy val (inSource, linearization) = { + val representive = sym.info.members.find { + s => s.isPackageObject + } getOrElse sym + (inSourceFromSymbol(representive), linearizationFromSymbol(representive)) + } + def packages = members collect { case p: PackageImpl if !(droppedPackages contains p) => p } + } + + abstract class RootPackageImpl(sym: Symbol) extends PackageImpl(sym, null) with RootPackageEntity + + abstract class NonTemplateMemberImpl(sym: Symbol, conversion: Option[ImplicitConversionImpl], + override val useCaseOf: Option[MemberEntity], inTpl: DocTemplateImpl) + extends MemberImpl(sym, inTpl) with NonTemplateMemberEntity { + override lazy val comment = { + val inRealTpl = + conversion.fold(Option(inTpl)) { conv => + /* Variable precendence order for implicitly added members: Take the variable defifinitions from ... + * 1. the target of the implicit conversion + * 2. the definition template (owner) + * 3. the current template + */ + findTemplateMaybe(conv.toType.typeSymbol) filterNot (_ == makeRootPackage) orElse ( + findTemplateMaybe(sym.owner) filterNot (_ == makeRootPackage) orElse Option(inTpl) + ) + } + inRealTpl flatMap (thisFactory.comment(sym, None, _)) + } + + override def inDefinitionTemplates = useCaseOf.fold(super.inDefinitionTemplates)(_.inDefinitionTemplates) + + override def qualifiedName = optimize(inTemplate.qualifiedName + "#" + name) + lazy val definitionName = { + val qualifiedName = conversion.fold(inDefinitionTemplates.head.qualifiedName)(_.conversionQualifiedName) + optimize(qualifiedName + "#" + name) + } + def isUseCase = useCaseOf.isDefined + override def byConversion: Option[ImplicitConversionImpl] = conversion + override def isImplicitlyInherited = { assert(modelFinished); conversion.isDefined } + override def isShadowedImplicit = isImplicitlyInherited && inTpl.implicitsShadowing.get(this).map(_.isShadowed).getOrElse(false) + override def isAmbiguousImplicit = isImplicitlyInherited && inTpl.implicitsShadowing.get(this).map(_.isAmbiguous).getOrElse(false) + override def isShadowedOrAmbiguousImplicit = isShadowedImplicit || isAmbiguousImplicit + } + + abstract class NonTemplateParamMemberImpl(sym: Symbol, conversion: Option[ImplicitConversionImpl], + useCaseOf: Option[MemberEntity], inTpl: DocTemplateImpl) + extends NonTemplateMemberImpl(sym, conversion, useCaseOf, inTpl) { + def valueParams = { + val info = conversion.fold(sym.info)(_.toType memberInfo sym) + info.paramss map { ps => (ps.zipWithIndex) map { case (p, i) => + if (p.nameString contains "$") makeValueParam(p, inTpl, optimize("arg" + i)) else makeValueParam(p, inTpl) + }} + } + } + + abstract class ParameterImpl(val sym: Symbol, val inTpl: TemplateImpl) extends ParameterEntity { + val name = optimize(sym.nameString) + } + + private trait AliasImpl { + def sym: Symbol + def inTpl: TemplateImpl + def alias = makeTypeInTemplateContext(sym.tpe.dealias, inTpl, sym) + } + + private trait TypeBoundsImpl { + def sym: Symbol + def inTpl: TemplateImpl + def lo = sym.info.bounds match { + case TypeBounds(lo, hi) if lo.typeSymbol != NothingClass => + Some(makeTypeInTemplateContext(appliedType(lo, sym.info.typeParams map {_.tpe}), inTpl, sym)) + case _ => None + } + def hi = sym.info.bounds match { + case TypeBounds(lo, hi) if hi.typeSymbol != AnyClass => + Some(makeTypeInTemplateContext(appliedType(hi, sym.info.typeParams map {_.tpe}), inTpl, sym)) + case _ => None + } + } + + trait HigherKindedImpl extends HigherKinded { + def sym: Symbol + def inTpl: TemplateImpl + def typeParams = + sym.typeParams map (makeTypeParam(_, inTpl)) + } + /* ============== MAKER METHODS ============== */ + + /** This method makes it easier to work with the different kinds of symbols created by scalac by stripping down the + * package object abstraction and placing members directly in the package. + * + * Here's the explanation of what we do. The code: + * + * package foo { + * object `package` { + * class Bar + * } + * } + * + * will yield this Symbol structure: + * +---------+ (2) + * | | + * +---------------+ +---------- v ------- | ---+ +--------+ (2) + * | package foo#1 <---(1)---- module class foo#2 | | | | + * +---------------+ | +------------------ | -+ | +------------------- v ---+ | + * | | package object foo#3 <-----(1)---- module class package#4 | | + * | +----------------------+ | | +---------------------+ | | + * +--------------------------+ | | class package$Bar#5 | | | + * | +----------------- | -+ | | + * +------------------- | ---+ | + * | | + * +--------+ + * (1) sourceModule + * (2) you get out of owners with .owner + * + * and normalizeTemplate(Bar.owner) will get us the package, instead of the module class of the package object. + */ + def normalizeTemplate(aSym: Symbol): Symbol = aSym match { + case null | rootMirror.EmptyPackage | NoSymbol => + normalizeTemplate(RootPackage) + case ObjectClass => + normalizeTemplate(AnyRefClass) + case _ if aSym.isPackageObject => + normalizeTemplate(aSym.owner) + case _ if aSym.isModuleClass => + normalizeTemplate(aSym.sourceModule) + case _ => + aSym + } + + /** + * These are all model construction methods. Please do not use them directly, they are calling each other recursively + * starting from makeModel. On the other hand, makeTemplate, makeAnnotation, makeMember, makeType should only be used + * after the model was created (modelFinished=true) otherwise assertions will start failing. + */ + object modelCreation { + + def createRootPackage: PackageImpl = docTemplatesCache.get(RootPackage) match { + case Some(root: PackageImpl) => root + case _ => modelCreation.createTemplate(RootPackage, null) match { + case Some(root: PackageImpl) => root + case _ => sys.error("Scaladoc: Unable to create root package!") + } + } + + /** + * Create a template, either a package, class, trait or object + */ + def createTemplate(aSym: Symbol, inTpl: DocTemplateImpl): Option[MemberImpl] = { + // don't call this after the model finished! + assert(!modelFinished, (aSym, inTpl)) + + def createRootPackageComment: Option[Comment] = + if(settings.docRootContent.isDefault) None + else { + import Streamable._ + Path(settings.docRootContent.value) match { + case f : File => { + val rootComment = closing(f.inputStream())(is => parse(slurp(is), "", NoPosition, Option(inTpl))) + Some(rootComment) + } + case _ => None + } + } + + def createDocTemplate(bSym: Symbol, inTpl: DocTemplateImpl): DocTemplateImpl = { + assert(!modelFinished, (bSym, inTpl)) // only created BEFORE the model is finished + if (bSym.isAliasType && bSym != AnyRefClass) + new DocTemplateImpl(bSym, inTpl) with AliasImpl with AliasType { override def isAliasType = true } + else if (bSym.isAbstractType) + new DocTemplateImpl(bSym, inTpl) with TypeBoundsImpl with AbstractType { override def isAbstractType = true } + else if (bSym.isModule) + new DocTemplateImpl(bSym, inTpl) with Object {} + else if (bSym.isTrait) + new DocTemplateImpl(bSym, inTpl) with Trait {} + else if (bSym.isClass || bSym == AnyRefClass) + new DocTemplateImpl(bSym, inTpl) with Class {} + else + sys.error("'" + bSym + "' isn't a class, trait or object thus cannot be built as a documentable template.") + } + + val bSym = normalizeTemplate(aSym) + if (docTemplatesCache isDefinedAt bSym) + return Some(docTemplatesCache(bSym)) + + /* Three cases of templates: + * (1) root package -- special cased for bootstrapping + * (2) package + * (3) class/object/trait + */ + if (bSym == RootPackage) // (1) + Some(new RootPackageImpl(bSym) { + override lazy val comment = createRootPackageComment + override val name = "root" + override def inTemplate = this + override def toRoot = this :: Nil + override def qualifiedName = "_root_" + override def isRootPackage = true + override lazy val memberSyms = + (bSym.info.members ++ EmptyPackage.info.members).toList filter { s => + s != EmptyPackage && s != RootPackage + } + }) + else if (bSym.isPackage) // (2) + if (settings.skipPackage(makeQualifiedName(bSym))) + None + else + inTpl match { + case inPkg: PackageImpl => + val pack = new PackageImpl(bSym, inPkg) {} + // Used to check package pruning works: + //println(pack.qualifiedName) + if (pack.templates.filter(_.isDocTemplate).isEmpty && pack.memberSymsLazy.isEmpty) { + droppedPackages += pack + None + } else + Some(pack) + case _ => + sys.error("'" + bSym + "' must be in a package") + } + else { + // no class inheritance at this point + assert(inOriginalOwner(bSym, inTpl), bSym + " in " + inTpl) + Some(createDocTemplate(bSym, inTpl)) + } + } + + /** + * After the model is completed, no more DocTemplateEntities are created. + * Therefore any symbol that still appears is: + * - MemberTemplateEntity (created here) + * - NoDocTemplateEntity (created in makeTemplate) + */ + def createLazyTemplateMember(aSym: Symbol, inTpl: DocTemplateImpl): MemberImpl = { + + // Code is duplicate because the anonymous classes are created statically + def createNoDocMemberTemplate(bSym: Symbol, inTpl: DocTemplateImpl): MemberTemplateImpl = { + assert(modelFinished) // only created AFTER the model is finished + if (bSym.isModule || (bSym.isAliasType && bSym.tpe.typeSymbol.isModule)) + new MemberTemplateImpl(bSym, inTpl) with Object {} + else if (bSym.isTrait || (bSym.isAliasType && bSym.tpe.typeSymbol.isTrait)) + new MemberTemplateImpl(bSym, inTpl) with Trait {} + else if (bSym.isClass || (bSym.isAliasType && bSym.tpe.typeSymbol.isClass)) + new MemberTemplateImpl(bSym, inTpl) with Class {} + else + sys.error("'" + bSym + "' isn't a class, trait or object thus cannot be built as a member template.") + } + + assert(modelFinished) + val bSym = normalizeTemplate(aSym) + + if (docTemplatesCache isDefinedAt bSym) + docTemplatesCache(bSym) + else + docTemplatesCache.get(bSym.owner) match { + case Some(inTpl) => + val mbrs = inTpl.members.collect({ case mbr: MemberImpl if mbr.sym == bSym => mbr }) + assert(mbrs.length == 1) + mbrs.head + case _ => + // move the class completely to the new location + createNoDocMemberTemplate(bSym, inTpl) + } + } + } + + def makeRootPackage: PackageImpl = docTemplatesCache(RootPackage).asInstanceOf[PackageImpl] + + // TODO: Should be able to override the type + def makeMember(aSym: Symbol, conversion: Option[ImplicitConversionImpl], inTpl: DocTemplateImpl): List[MemberImpl] = { + + def makeMember0(bSym: Symbol, useCaseOf: Option[MemberImpl]): Option[MemberImpl] = { + if (bSym.isGetter && bSym.isLazy) + Some(new NonTemplateMemberImpl(bSym, conversion, useCaseOf, inTpl) with Val { + override lazy val comment = // The analyser does not duplicate the lazy val's DocDef when it introduces its accessor. + thisFactory.comment(bSym.accessed, None, inTpl.asInstanceOf[DocTemplateImpl]) // This hack should be removed after analyser is fixed. + override def isLazyVal = true + }) + else if (bSym.isGetter && bSym.accessed.isMutable) + Some(new NonTemplateMemberImpl(bSym, conversion, useCaseOf, inTpl) with Val { + override def isVar = true + }) + else if (bSym.isMethod && !bSym.hasAccessorFlag && !bSym.isConstructor && !bSym.isModule) { + val cSym = { // This unsightly hack closes issue #4086. + if (bSym == definitions.Object_synchronized) { + val cSymInfo = (bSym.info: @unchecked) match { + case PolyType(ts, MethodType(List(bp), mt)) => + val cp = bp.cloneSymbol.setPos(bp.pos).setInfo(definitions.byNameType(bp.info)) + PolyType(ts, MethodType(List(cp), mt)) + } + bSym.cloneSymbol.setPos(bSym.pos).setInfo(cSymInfo) + } + else bSym + } + Some(new NonTemplateParamMemberImpl(cSym, conversion, useCaseOf, inTpl) with HigherKindedImpl with Def { + override def isDef = true + }) + } + else if (bSym.isConstructor) + if (conversion.isDefined) + None // don't list constructors inherted by implicit conversion + else + Some(new NonTemplateParamMemberImpl(bSym, conversion, useCaseOf, inTpl) with Constructor { + override def isConstructor = true + def isPrimary = sym.isPrimaryConstructor + }) + else if (bSym.isGetter) // Scala field accessor or Java field + Some(new NonTemplateMemberImpl(bSym, conversion, useCaseOf, inTpl) with Val { + override def isVal = true + }) + else if (bSym.isAbstractType && !typeShouldDocument(bSym, inTpl)) + Some(new MemberTemplateImpl(bSym, inTpl) with TypeBoundsImpl with AbstractType { + override def isAbstractType = true + }) + else if (bSym.isAliasType && !typeShouldDocument(bSym, inTpl)) + Some(new MemberTemplateImpl(bSym, inTpl) with AliasImpl with AliasType { + override def isAliasType = true + }) + else if (!modelFinished && (bSym.isPackage || templateShouldDocument(bSym, inTpl))) + modelCreation.createTemplate(bSym, inTpl) + else + None + } + + if (!localShouldDocument(aSym) || aSym.isModuleClass || aSym.isPackageObject || aSym.isMixinConstructor) + Nil + else { + val allSyms = useCases(aSym, inTpl.sym) map { case (bSym, bComment, bPos) => + docComments.put(bSym, DocComment(bComment, bPos)) // put the comment in the list, don't parse it yet, closes SI-4898 + bSym + } + + val member = makeMember0(aSym, None) + if (allSyms.isEmpty) + member.toList + else + // Use cases replace the original definitions - SI-5054 + allSyms flatMap { makeMember0(_, member) } + } + } + + def findMember(aSym: Symbol, inTpl: DocTemplateImpl): Option[MemberImpl] = { + normalizeTemplate(aSym.owner) + inTpl.members.find(_.sym == aSym) + } + + def findTemplateMaybe(aSym: Symbol): Option[DocTemplateImpl] = { + assert(modelFinished) + docTemplatesCache.get(normalizeTemplate(aSym)).filterNot(packageDropped(_)) + } + + def makeTemplate(aSym: Symbol): TemplateImpl = makeTemplate(aSym, None) + + def makeTemplate(aSym: Symbol, inTpl: Option[TemplateImpl]): TemplateImpl = { + assert(modelFinished) + + def makeNoDocTemplate(aSym: Symbol, inTpl: TemplateImpl): NoDocTemplateImpl = + noDocTemplatesCache getOrElse (aSym, new NoDocTemplateImpl(aSym, inTpl)) + + findTemplateMaybe(aSym) getOrElse { + val bSym = normalizeTemplate(aSym) + makeNoDocTemplate(bSym, inTpl getOrElse makeTemplate(bSym.owner)) + } + } + + /** */ + def makeAnnotation(annot: AnnotationInfo): scala.tools.nsc.doc.model.Annotation = { + val aSym = annot.symbol + new EntityImpl(aSym, makeTemplate(aSym.owner)) with scala.tools.nsc.doc.model.Annotation { + lazy val annotationClass = + makeTemplate(annot.symbol) + val arguments = { // lazy + def annotArgs = annot.args match { + case Nil => annot.assocs collect { case (_, LiteralAnnotArg(const)) => Literal(const) } + case xs => xs + } + def noParams = annotArgs map (_ => None) + + val params: List[Option[ValueParam]] = annotationClass match { + case aClass: DocTemplateEntity with Class => + (aClass.primaryConstructor map { _.valueParams.head }) match { + case Some(vps) => vps map { Some(_) } + case _ => noParams + } + case _ => noParams + } + assert(params.length == annotArgs.length, (params, annotArgs)) + + params zip annotArgs flatMap { case (param, arg) => + makeTree(arg) map { tree => + new ValueArgument { + def parameter = param + def value = tree + } + } + } + } + } + } + + /** */ + def makeTypeParam(aSym: Symbol, inTpl: TemplateImpl): TypeParam = + new ParameterImpl(aSym, inTpl) with TypeBoundsImpl with HigherKindedImpl with TypeParam { + def variance: String = { + if (sym hasFlag Flags.COVARIANT) "+" + else if (sym hasFlag Flags.CONTRAVARIANT) "-" + else "" + } + } + + /** */ + def makeValueParam(aSym: Symbol, inTpl: DocTemplateImpl): ValueParam = { + makeValueParam(aSym, inTpl, aSym.nameString) + } + + + /** */ + def makeValueParam(aSym: Symbol, inTpl: DocTemplateImpl, newName: String): ValueParam = + new ParameterImpl(aSym, inTpl) with ValueParam { + override val name = newName + def defaultValue = + if (aSym.hasDefault) { + // units.filter should return only one element + (currentRun.units filter (_.source.file == aSym.sourceFile)).toList match { + case List(unit) => + // SI-4922 `sym == aSym` is insufficent if `aSym` is a clone of symbol + // of the parameter in the tree, as can happen with type parametric methods. + def isCorrespondingParam(sym: Symbol) = ( + sym != null && + sym != NoSymbol && + sym.owner == aSym.owner && + sym.name == aSym.name && + sym.isParamWithDefault + ) + (unit.body find (t => isCorrespondingParam(t.symbol))) match { + case Some(ValDef(_,_,_,rhs)) => makeTree(rhs) + case _ => None + } + case _ => None + } + } + else None + def resultType = + makeTypeInTemplateContext(aSym.tpe, inTpl, aSym) + def isImplicit = aSym.isImplicit + } + + /** */ + def makeTypeInTemplateContext(aType: Type, inTpl: TemplateImpl, dclSym: Symbol): TypeEntity = { + def ownerTpl(sym: Symbol): Symbol = + if (sym.isClass || sym.isModule || sym == NoSymbol) sym else ownerTpl(sym.owner) + val tpe = + if (thisFactory.settings.useStupidTypes.value) aType else { + def ownerTpl(sym: Symbol): Symbol = + if (sym.isClass || sym.isModule || sym == NoSymbol) sym else ownerTpl(sym.owner) + val fixedSym = if (inTpl.sym.isModule) inTpl.sym.moduleClass else inTpl.sym + aType.asSeenFrom(fixedSym.thisType, ownerTpl(dclSym)) + } + makeType(tpe, inTpl) + } + + /** Get the types of the parents of the current class, ignoring the refinements */ + def makeParentTypes(aType: Type, tpl: Option[MemberTemplateImpl], inTpl: TemplateImpl): List[(TemplateEntity, TypeEntity)] = aType match { + case RefinedType(parents, defs) => + val ignoreParents = Set[Symbol](AnyClass, AnyRefClass, ObjectClass) + val filtParents = + // we don't want to expose too many links to AnyRef, that will just be redundant information + tpl match { + case Some(tpl) if (!tpl.sym.isModule && parents.length < 2) || (tpl.sym == AnyValClass) || (tpl.sym == AnyRefClass) || (tpl.sym == AnyClass) => parents + case _ => parents.filterNot((p: Type) => ignoreParents(p.typeSymbol)) + } + + /** Returns: + * - a DocTemplate if the type's symbol is documented + * - a NoDocTemplateMember if the type's symbol is not documented in its parent but in another template + * - a NoDocTemplate if the type's symbol is not documented at all */ + def makeTemplateOrMemberTemplate(parent: Type): TemplateImpl = { + def noDocTemplate = makeTemplate(parent.typeSymbol) + findTemplateMaybe(parent.typeSymbol) match { + case Some(tpl) => tpl + case None => parent match { + case TypeRef(pre, sym, args) => + findTemplateMaybe(pre.typeSymbol) match { + case Some(tpl) => findMember(parent.typeSymbol, tpl).collect({case t: TemplateImpl => t}).getOrElse(noDocTemplate) + case None => noDocTemplate + } + case _ => noDocTemplate + } + } + } + + filtParents.map(parent => { + val templateEntity = makeTemplateOrMemberTemplate(parent) + val typeEntity = makeType(parent, inTpl) + (templateEntity, typeEntity) + }) + case _ => + List((makeTemplate(aType.typeSymbol), makeType(aType, inTpl))) + } + + def makeQualifiedName(sym: Symbol, relativeTo: Option[Symbol] = None): String = { + val stop = relativeTo map (_.ownerChain.toSet) getOrElse Set[Symbol]() + var sym1 = sym + val path = new StringBuilder() + // var path = List[Symbol]() + + while ((sym1 != NoSymbol) && (path.isEmpty || !stop(sym1))) { + val sym1Norm = normalizeTemplate(sym1) + if (!sym1.sourceModule.isPackageObject && sym1Norm != RootPackage) { + if (path.length != 0) + path.insert(0, ".") + path.insert(0, sym1Norm.nameString) + // path::= sym1Norm + } + sym1 = sym1.owner + } + + optimize(path.toString) + //path.mkString(".") + } + + def inOriginalOwner(aSym: Symbol, inTpl: TemplateImpl): Boolean = + normalizeTemplate(aSym.owner) == normalizeTemplate(inTpl.sym) + + def templateShouldDocument(aSym: Symbol, inTpl: DocTemplateImpl): Boolean = + (aSym.isTrait || aSym.isClass || aSym.isModule || typeShouldDocument(aSym, inTpl)) && + localShouldDocument(aSym) && + !isEmptyJavaObject(aSym) && + // either it's inside the original owner or we can document it later: + (!inOriginalOwner(aSym, inTpl) || (aSym.isPackageClass || (aSym.sourceFile != null))) + + def membersShouldDocument(sym: Symbol, inTpl: TemplateImpl) = { + // pruning modules that shouldn't be documented + // Why Symbol.isInitialized? Well, because we need to avoid exploring all the space available to scaladoc + // from the classpath -- scaladoc is a hog, it will explore everything starting from the root package unless we + // somehow prune the tree. And isInitialized is a good heuristic for prunning -- if the package was not explored + // during typer and refchecks, it's not necessary for the current application and there's no need to explore it. + (!sym.isModule || sym.moduleClass.isInitialized) && + // documenting only public and protected members + localShouldDocument(sym) && + // Only this class's constructors are part of its members, inherited constructors are not. + (!sym.isConstructor || sym.owner == inTpl.sym) && + // If the @bridge annotation overrides a normal member, show it + !isPureBridge(sym) + } + + def isEmptyJavaObject(aSym: Symbol): Boolean = + aSym.isModule && aSym.isJavaDefined && + aSym.info.members.exists(s => localShouldDocument(s) && (!s.isConstructor || s.owner == aSym)) + + def localShouldDocument(aSym: Symbol): Boolean = + !aSym.isPrivate && (aSym.isProtected || aSym.privateWithin == NoSymbol) && !aSym.isSynthetic + + /** Filter '@bridge' methods only if *they don't override non-bridge methods*. See SI-5373 for details */ + def isPureBridge(sym: Symbol) = sym.isBridge && sym.allOverriddenSymbols.forall(_.isBridge) + + // the classes that are excluded from the index should also be excluded from the diagrams + def classExcluded(clazz: TemplateEntity): Boolean = settings.hardcoded.isExcluded(clazz.qualifiedName) + + // the implicit conversions that are excluded from the pages should not appear in the diagram + def implicitExcluded(convertorMethod: String): Boolean = settings.hiddenImplicits(convertorMethod) + + // whether or not to create a page for an {abstract,alias} type + def typeShouldDocument(bSym: Symbol, inTpl: DocTemplateImpl) = + (settings.docExpandAllTypes.value && (bSym.sourceFile != null)) || + (bSym.isAliasType || bSym.isAbstractType) && + { val rawComment = global.expandedDocComment(bSym, inTpl.sym) + rawComment.contains("@template") || rawComment.contains("@documentable") } +} + diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala new file mode 100644 index 0000000000..868c2fc3a4 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -0,0 +1,579 @@ +/* NSC -- new Scala compiler -- Copyright 2007-2013 LAMP/EPFL + * + * This trait finds implicit conversions for a class in the default scope and creates scaladoc entries for each of them. + * + * @author Vlad Ureche + * @author Adriaan Moors + */ + +package scala.tools.nsc +package doc +package model + +import scala.collection._ +import symtab.Flags + +/** + * This trait finds implicit conversions for a class in the default scope and creates scaladoc entries for each of them. + * + * Let's take this as an example: + * {{{ + * object Test { + * class A + * + * class B { + * def foo = 1 + * } + * + * class C extends B { + * def bar = 2 + * class implicit + * } + * + * D def conv(a: A) = new C + * } + * }}} + * + * Overview: + * - scaladoc-ing the above classes, `A` will get two more methods: foo and bar, over its default methods + * - the nested classes (specifically `D` above), abstract types, type aliases and constructor members are not added to + * `A` (see makeMember0 in ModelFactory, last 3 cases) + * - the members added by implicit conversion are always listed under the implicit conversion, not under the class they + * actually come from (`foo` will be listed as coming from the implicit conversion to `C` instead of `B`) - see + * `definitionName` in MemberImpl + * + * Internals: + * TODO: Give an overview here + */ +trait ModelFactoryImplicitSupport { + thisFactory: ModelFactory with ModelFactoryTypeSupport with CommentFactory with TreeFactory => + + import global._ + import global.analyzer._ + import global.definitions._ + import settings.hardcoded + + // debugging: + val DEBUG: Boolean = settings.docImplicitsDebug.value + val ERROR: Boolean = true // currently we show all errors + @inline final def debug(msg: => String) = if (DEBUG) settings.printMsg(msg) + @inline final def error(msg: => String) = if (ERROR) settings.printMsg(msg) + + /** This is a flag that indicates whether to eliminate implicits that cannot be satisfied within the current scope. + * For example, if an implicit conversion requires that there is a Numeric[T] in scope: + * {{{ + * class A[T] + * class B extends A[Int] + * class C extends A[String] + * implicit def enrichA[T: Numeric](a: A[T]): D + * }}} + * For B, no constraints are generated as Numeric[Int] is already in the default scope. On the other hand, for the + * conversion from C to D, depending on -implicits-show-all, the conversion can: + * - not be generated at all, since there's no Numeric[String] in scope (if ran without -implicits-show-all) + * - generated with a *weird* constraint, Numeric[String] as the user might add it by hand (if flag is enabled) + */ + class ImplicitNotFound(tpe: Type) extends Exception("No implicit of type " + tpe + " found in scope.") + + /* ============== MAKER METHODS ============== */ + + /** + * Make the implicit conversion objects + * + * A word about the scope of the implicit conversions: currently we look at a very basic context composed of the + * default Scala imports (Predef._ for example) and the companion object of the current class, if one exists. In the + * future we might want to extend this to more complex scopes. + */ + def makeImplicitConversions(sym: Symbol, inTpl: DocTemplateImpl): List[ImplicitConversionImpl] = + // Nothing and Null are somewhat special -- they can be transformed by any implicit conversion available in scope. + // But we don't want that, so we'll simply refuse to find implicit conversions on for Nothing and Null + if (!(sym.isClass || sym.isTrait || sym == AnyRefClass) || sym == NothingClass || sym == NullClass) Nil + else { + val context: global.analyzer.Context = global.analyzer.rootContext(NoCompilationUnit) + + val results = global.analyzer.allViewsFrom(sym.tpe_*, context, sym.typeParams) + var conversions = results.flatMap(result => makeImplicitConversion(sym, result._1, result._2, context, inTpl)) + // also keep empty conversions, so they appear in diagrams + // conversions = conversions.filter(!_.members.isEmpty) + + // Filter out specialized conversions from array + if (sym == ArrayClass) + conversions = conversions.filterNot((conv: ImplicitConversionImpl) => + hardcoded.arraySkipConversions.contains(conv.conversionQualifiedName)) + + // Filter out non-sensical conversions from value types + if (isPrimitiveValueType(sym.tpe_*)) + conversions = conversions.filter((ic: ImplicitConversionImpl) => + hardcoded.valueClassFilter(sym.nameString, ic.conversionQualifiedName)) + + // Put the visible conversions in front + val (ownConversions, commonConversions) = + conversions.partition(!_.isHiddenConversion) + + ownConversions ::: commonConversions + } + + /** makeImplicitConversion performs the heavier lifting to get the implicit listing: + * - for each possible conversion function (also called view) + * * figures out the final result of the view (to what is our class transformed?) + * * figures out the necessary constraints on the type parameters (such as T <: Int) and the context (such as Numeric[T]) + * * lists all inherited members + * + * What? in details: + * - say we start from a class A[T1, T2, T3, T4] + * - we have an implicit function (view) in scope: + * def enrichA[T3 <: Long, T4](a: A[Int, Foo[Bar[X]], T3, T4])(implicit ev1: TypeTag[T4], ev2: Numeric[T4]): EnrichedA + * - A is converted to EnrichedA ONLY if a couple of constraints are satisfied: + * * T1 must be equal to Int + * * T2 must be equal to Foo[Bar[X]] + * * T3 must be upper bounded by Long + * * there must be evidence of Numeric[T4] and a TypeTag[T4] within scope + * - the final type is EnrichedA and A therefore inherits a couple of members from enrichA + * + * How? + * some notes: + * - Scala's type inference will want to solve all type parameters down to actual types, but we only want constraints + * to maintain generality + * - therefore, allViewsFrom wraps type parameters into "untouchable" type variables that only gather constraints, + * but are never solved down to a type + * - these must be reverted back to the type parameters and the constraints must be extracted and simplified (this is + * done by the uniteConstraints and boundedTParamsConstraints. Be sure to check them out + * - we also need to transform implicit parameters in the view's signature into constraints, such that Numeric[T4] + * appears as a constraint + */ + def makeImplicitConversion(sym: Symbol, result: SearchResult, constrs: List[TypeConstraint], context: Context, inTpl: DocTemplateImpl): List[ImplicitConversionImpl] = + if (result.tree == EmptyTree) Nil + else { + // `result` will contain the type of the view (= implicit conversion method) + // the search introduces untouchable type variables, but we want to get back to type parameters + val viewFullType = result.tree.tpe + // set the previously implicit parameters to being explicit + + val (viewSimplifiedType, viewImplicitTypes) = removeImplicitParameters(viewFullType) + + // TODO: Isolate this corner case :) - Predef.<%< and put it in the testsuite + if (viewSimplifiedType.params.length != 1) { + // This is known to be caused by the `<%<` object in Predef: + // {{{ + // sealed abstract class <%<[-From, +To] extends (From => To) with Serializable + // object <%< { + // implicit def conformsOrViewsAs[A <% B, B]: A <%< B = new (A <%< B) {def apply(x: A) = x} + // } + // }}} + // so we just won't generate an implicit conversion for implicit methods that only take implicit parameters + return Nil + } + + // type the view application so we get the exact type of the result (not the formal type) + val viewTree = result.tree.setType(viewSimplifiedType) + val appliedTree = new ApplyImplicitView(viewTree, List(Ident("") setType viewTree.tpe.paramTypes.head)) + val appliedTreeTyped: Tree = { + val newContext = context.makeImplicit(context.ambiguousErrors) + newContext.macrosEnabled = false + val newTyper = global.analyzer.newTyper(newContext) + newTyper.silent(_.typed(appliedTree, EXPRmode, WildcardType), reportAmbiguousErrors = false) match { + + case global.analyzer.SilentResultValue(t: Tree) => t + case global.analyzer.SilentTypeError(err) => + global.reporter.warning(sym.pos, err.toString) + return Nil + } + } + + // now we have the final type: + val toType = wildcardToNothing(typeVarToOriginOrWildcard(appliedTreeTyped.tpe.finalResultType)) + + try { + // Transform bound constraints into scaladoc constraints + val implParamConstraints = makeImplicitConstraints(viewImplicitTypes, sym, context, inTpl) + val boundsConstraints = makeBoundedConstraints(sym.typeParams, constrs, inTpl) + // TODO: no substitution constraints appear in the library and compiler scaladoc. Maybe they can be removed? + val substConstraints = makeSubstitutionConstraints(result.subst, inTpl) + val constraints = implParamConstraints ::: boundsConstraints ::: substConstraints + + List(new ImplicitConversionImpl(sym, result.tree.symbol, toType, constraints, inTpl)) + } catch { + case i: ImplicitNotFound => + //println(" Eliminating: " + toType) + Nil + } + } + + def makeImplicitConstraints(types: List[Type], sym: Symbol, context: Context, inTpl: DocTemplateImpl): List[Constraint] = + types.flatMap((tpe:Type) => { + // TODO: Before creating constraints, map typeVarToOriginOrWildcard on the implicitTypes + val implType = typeVarToOriginOrWildcard(tpe) + val qualifiedName = makeQualifiedName(implType.typeSymbol) + + var available: Option[Boolean] = None + + // see: https://groups.google.com/forum/?hl=en&fromgroups#!topic/scala-internals/gm_fr0RKzC4 + // + // println(implType + " => " + implType.isTrivial) + // var tpes: List[Type] = List(implType) + // while (!tpes.isEmpty) { + // val tpe = tpes.head + // tpes = tpes.tail + // tpe match { + // case TypeRef(pre, sym, args) => + // tpes = pre :: args ::: tpes + // println(tpe + " => " + tpe.isTrivial) + // case _ => + // println(tpe + " (of type" + tpe.getClass + ") => " + tpe.isTrivial) + // } + // } + // println("\n") + + // look for type variables in the type. If there are none, we can decide if the implicit is there or not + if (implType.isTrivial) { + try { + context.flushBuffer() /* any errors here should not prevent future findings */ + // TODO: Not sure this is the right thing to do -- seems similar to what scalac should be doing + val context2 = context.make(context.unit, context.tree, sym.owner, context.scope, context.imports) + val search = inferImplicit(EmptyTree, tpe, false, false, context2, false) + context.flushBuffer() /* any errors here should not prevent future findings */ + + available = Some(search.tree != EmptyTree) + } catch { + case _: TypeError => + } + } + + available match { + case Some(true) => + Nil + case Some(false) if (!settings.docImplicitsShowAll.value) => + // if -implicits-show-all is not set, we get rid of impossible conversions (such as Numeric[String]) + throw new ImplicitNotFound(implType) + case _ => + val typeParamNames = sym.typeParams.map(_.name) + + // TODO: This is maybe the worst hack I ever did - it's as dirty as hell, but it seems to work, so until I + // learn more about symbols, it'll have to do. + implType match { + case TypeRef(pre, sym, List(TypeRef(NoPrefix, targ, Nil))) if (typeParamNames contains targ.name) => + hardcoded.knownTypeClasses.get(qualifiedName) match { + case Some(explanation) => + List(new KnownTypeClassConstraint { + val typeParamName = targ.nameString + lazy val typeExplanation = explanation + lazy val typeClassEntity = makeTemplate(sym) + lazy val implicitType: TypeEntity = makeType(implType, inTpl) + }) + case None => + List(new TypeClassConstraint { + val typeParamName = targ.nameString + lazy val typeClassEntity = makeTemplate(sym) + lazy val implicitType: TypeEntity = makeType(implType, inTpl) + }) + } + case _ => + List(new ImplicitInScopeConstraint{ + lazy val implicitType: TypeEntity = makeType(implType, inTpl) + }) + } + } + }) + + def makeSubstitutionConstraints(subst: TreeTypeSubstituter, inTpl: DocTemplateImpl): List[Constraint] = + (subst.from zip subst.to) map { + case (from, to) => + new EqualTypeParamConstraint { + error("Scaladoc implicits: Unexpected type substitution constraint from: " + from + " to: " + to) + val typeParamName = from.toString + val rhs = makeType(to, inTpl) + } + } + + def makeBoundedConstraints(tparams: List[Symbol], constrs: List[TypeConstraint], inTpl: DocTemplateImpl): List[Constraint] = + (tparams zip constrs) flatMap { + case (tparam, constr) => { + uniteConstraints(constr) match { + case (loBounds, upBounds) => (loBounds filter (_ != NothingClass.tpe), upBounds filter (_ != AnyClass.tpe)) match { + case (Nil, Nil) => + Nil + case (List(lo), List(up)) if (lo == up) => + List(new EqualTypeParamConstraint { + val typeParamName = tparam.nameString + lazy val rhs = makeType(lo, inTpl) + }) + case (List(lo), List(up)) => + List(new BoundedTypeParamConstraint { + val typeParamName = tparam.nameString + lazy val lowerBound = makeType(lo, inTpl) + lazy val upperBound = makeType(up, inTpl) + }) + case (List(lo), Nil) => + List(new LowerBoundedTypeParamConstraint { + val typeParamName = tparam.nameString + lazy val lowerBound = makeType(lo, inTpl) + }) + case (Nil, List(up)) => + List(new UpperBoundedTypeParamConstraint { + val typeParamName = tparam.nameString + lazy val upperBound = makeType(up, inTpl) + }) + case other => + // this is likely an error on the lub/glb side + error("Scaladoc implicits: Error computing lub/glb for: " + (tparam, constr) + ":\n" + other) + Nil + } + } + } + } + + /* ============== IMPLEMENTATION PROVIDING ENTITY TYPES ============== */ + + class ImplicitConversionImpl( + val sym: Symbol, + val convSym: Symbol, + val toType: Type, + val constrs: List[Constraint], + inTpl: DocTemplateImpl) + extends ImplicitConversion { + + def source: DocTemplateEntity = inTpl + + def targetType: TypeEntity = makeType(toType, inTpl) + + def convertorOwner: TemplateEntity = + if (convSym != NoSymbol) + makeTemplate(convSym.owner) + else { + error("Scaladoc implicits: " + toString + " = NoSymbol!") + makeRootPackage + } + + def targetTypeComponents: List[(TemplateEntity, TypeEntity)] = makeParentTypes(toType, None, inTpl) + + def convertorMethod: Either[MemberEntity, String] = { + var convertor: MemberEntity = null + + convertorOwner match { + case doc: DocTemplateImpl => + val convertors = members.collect { case m: MemberImpl if m.sym == convSym => m } + if (convertors.length == 1) + convertor = convertors.head + case _ => + } + if (convertor ne null) + Left(convertor) + else + Right(convSym.nameString) + } + + def conversionShortName = convSym.nameString + + def conversionQualifiedName = makeQualifiedName(convSym) + + lazy val constraints: List[Constraint] = constrs + + lazy val memberImpls: List[MemberImpl] = { + // Obtain the members inherited by the implicit conversion + val memberSyms = toType.members.filter(implicitShouldDocument(_)).toList + + // Debugging part :) + debug(sym.nameString + "\n" + "=" * sym.nameString.length()) + debug(" * conversion " + convSym + " from " + sym.tpe + " to " + toType) + + debug(" -> full type: " + toType) + if (constraints.length != 0) { + debug(" -> constraints: ") + constraints foreach { constr => debug(" - " + constr) } + } + debug(" -> members:") + memberSyms foreach (sym => debug(" - "+ sym.decodedName +" : " + sym.info)) + debug("") + + memberSyms.flatMap({ aSym => + // we can't just pick up nodes from the original template, although that would be very convenient: + // they need the byConversion field to be attached to themselves and the types to be transformed by + // asSeenFrom + + // at the same time, the member itself is in the inTpl, not in the new template -- but should pick up + // variables from the old template. Ugly huh? We'll always create the member inTpl, but it will change + // the template when expanding variables in the comment :) + makeMember(aSym, Some(this), inTpl) + }) + } + + lazy val members: List[MemberEntity] = memberImpls + + def isHiddenConversion = settings.hiddenImplicits(conversionQualifiedName) + + override def toString = "Implcit conversion from " + sym.tpe + " to " + toType + " done by " + convSym + } + + /* ========================= HELPER METHODS ========================== */ + /** + * Computes the shadowing table for all the members in the implicit conversions + * @param members All template's members, including usecases and full signature members + * @param convs All the conversions the template takes part in + * @param inTpl the usual :) + */ + def makeShadowingTable(members: List[MemberImpl], + convs: List[ImplicitConversionImpl], + inTpl: DocTemplateImpl): Map[MemberEntity, ImplicitMemberShadowing] = { + assert(modelFinished) + + val shadowingTable = mutable.Map[MemberEntity, ImplicitMemberShadowing]() + val membersByName: Map[Name, List[MemberImpl]] = members.groupBy(_.sym.name) + val convsByMember = (Map.empty[MemberImpl, ImplicitConversionImpl] /: convs) { + case (map, conv) => map ++ conv.memberImpls.map (_ -> conv) + } + + for (conv <- convs) { + val otherConvMembers: Map[Name, List[MemberImpl]] = convs filterNot (_ == conv) flatMap (_.memberImpls) groupBy (_.sym.name) + + for (member <- conv.memberImpls) { + val sym1 = member.sym + val tpe1 = conv.toType.memberInfo(sym1) + + // check if it's shadowed by a member in the original class. + val shadowed = membersByName.get(sym1.name).toList.flatten filter { other => + !settings.docImplicitsSoundShadowing.value || !isDistinguishableFrom(tpe1, inTpl.sym.info.memberInfo(other.sym)) + } + + // check if it's shadowed by another conversion. + val ambiguous = otherConvMembers.get(sym1.name).toList.flatten filter { other => + val tpe2 = convsByMember(other).toType.memberInfo(other.sym) + !isDistinguishableFrom(tpe1, tpe2) || !isDistinguishableFrom(tpe2, tpe1) + } + + // we finally have the shadowing info + if (!shadowed.isEmpty || !ambiguous.isEmpty) { + val shadowing = new ImplicitMemberShadowing { + def shadowingMembers: List[MemberEntity] = shadowed + def ambiguatingMembers: List[MemberEntity] = ambiguous + } + + shadowingTable += (member -> shadowing) + } + } + } + + shadowingTable.toMap + } + + + /** + * uniteConstraints takes a TypeConstraint instance and simplifies the constraints inside + * + * Normally TypeConstraint contains multiple lower and upper bounds, and we want to reduce this to a lower and an + * upper bound. Here are a couple of catches we need to be aware of: + * - before finding a view (implicit method in scope that maps class A[T1,T2,.. Tn] to something else) the type + * parameters are transformed into "untouchable" type variables so that type inference does not attempt to + * fully solve them down to a type but rather constrains them on both sides just enough for the view to be + * applicable -- now, we want to transform those type variables back to the original type parameters + * - some of the bounds fail type inference and therefore refer to Nothing => when performing unification (lub, glb) + * they start looking ugly => we (unsoundly) transform Nothing to WildcardType so we fool the unification algorithms + * into thinking there's nothing there + * - we don't want the wildcard types surviving the unification so we replace them back to Nothings + */ + def uniteConstraints(constr: TypeConstraint): (List[Type], List[Type]) = + try { + (List(wildcardToNothing(lub(constr.loBounds map typeVarToOriginOrWildcard))), + List(wildcardToNothing(glb(constr.hiBounds map typeVarToOriginOrWildcard)))) + } catch { + // does this actually ever happen? (probably when type vars occur in the bounds) + case x: Throwable => (constr.loBounds.distinct, constr.hiBounds.distinct) + } + + /** + * Make implicits explicit - Not used curently + */ + // object implicitToExplicit extends TypeMap { + // def apply(tp: Type): Type = mapOver(tp) match { + // case MethodType(params, resultType) => + // MethodType(params.map(param => if (param.isImplicit) param.cloneSymbol.resetFlag(Flags.IMPLICIT) else param), resultType) + // case other => + // other + // } + // } + + /** + * removeImplicitParameters transforms implicit parameters from the view result type into constraints and + * returns the simplified type of the view + * + * for the example view: + * implicit def enrichMyClass[T](a: MyClass[T])(implicit ev: Numeric[T]): EnrichedMyClass[T] + * the implicit view result type is: + * (a: MyClass[T])(implicit ev: Numeric[T]): EnrichedMyClass[T] + * and the simplified type will be: + * MyClass[T] => EnrichedMyClass[T] + */ + def removeImplicitParameters(viewType: Type): (Type, List[Type]) = { + + val params = viewType.paramss.flatten + val (normalParams, implParams) = params.partition(!_.isImplicit) + val simplifiedType = MethodType(normalParams, viewType.finalResultType) + val implicitTypes = implParams.map(_.tpe) + + (simplifiedType, implicitTypes) + } + + /** + * typeVarsToOriginOrWildcard transforms the "untouchable" type variables into either their origins (the original + * type parameters) or into wildcard types if nothing matches + */ + object typeVarToOriginOrWildcard extends TypeMap { + def apply(tp: Type): Type = mapOver(tp) match { + case tv: TypeVar => + if (tv.constr.inst.typeSymbol == NothingClass) + WildcardType + else + tv.origin //appliedType(tv.origin.typeConstructor, tv.typeArgs map this) + case other => + if (other.typeSymbol == NothingClass) + WildcardType + else + other + } + } + + /** + * wildcardToNothing transforms wildcard types back to Nothing + */ + object wildcardToNothing extends TypeMap { + def apply(tp: Type): Type = mapOver(tp) match { + case WildcardType => + NothingClass.tpe + case other => + other + } + } + + /** implicitShouldDocument decides whether a member inherited by implicit conversion should be documented */ + def implicitShouldDocument(aSym: Symbol): Boolean = { + // We shouldn't document: + // - constructors + // - common methods (in Any, AnyRef, Object) as they are automatically removed + // - private and protected members (not accessible following an implicit conversion) + // - members starting with _ (usually reserved for internal stuff) + localShouldDocument(aSym) && (!aSym.isConstructor) && (aSym.owner != AnyValClass) && + (aSym.owner != AnyClass) && (aSym.owner != ObjectClass) && + (!aSym.isProtected) && (!aSym.isPrivate) && (!aSym.name.startsWith("_")) && + (aSym.isMethod || aSym.isGetter || aSym.isSetter) && + (aSym.nameString != "getClass") + } + + /* To put it very bluntly: checks if you can call implicitly added method with t1 when t2 is already there in the + * class. We suppose the name of the two members coincides + * + * The trick here is that the resultType does not matter - the condition for removal it that paramss have the same + * structure (A => B => C may not override (A, B) => C) and that all the types involved are + * of the implcit conversion's member are subtypes of the parent members' parameters */ + def isDistinguishableFrom(t1: Type, t2: Type): Boolean = { + // Vlad: I tried using matches but it's not exactly what we need: + // (p: AnyRef)AnyRef matches ((t: String)AnyRef returns false -- but we want that to be true + // !(t1 matches t2) + if (t1.paramss.map(_.length) == t2.paramss.map(_.length)) { + for ((t1p, t2p) <- t1.paramss.flatten zip t2.paramss.flatten) + if (!isSubType(t1 memberInfo t1p, t2 memberInfo t2p)) + return true // if on the corresponding parameter you give a type that is in t1 but not in t2 + // def foo(a: Either[Int, Double]): Int = 3 + // def foo(b: Left[T1]): Int = 6 + // a.foo(Right(4.5d)) prints out 3 :) + false + } else true // the member structure is different foo(3, 5) vs foo(3)(5) + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala new file mode 100644 index 0000000000..99e9059d79 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala @@ -0,0 +1,315 @@ +/* NSC -- new Scala compiler -- Copyright 2007-2013 LAMP/EPFL */ + +package scala.tools.nsc +package doc +package model + +import base._ +import diagram._ + +import scala.collection._ + +/** This trait extracts all required information for documentation from compilation units */ +trait ModelFactoryTypeSupport { + thisFactory: ModelFactory + with ModelFactoryImplicitSupport + with ModelFactoryTypeSupport + with DiagramFactory + with CommentFactory + with TreeFactory + with MemberLookup => + + import global._ + import definitions.{ ObjectClass, NothingClass, AnyClass, AnyValClass, AnyRefClass } + + protected val typeCache = new mutable.LinkedHashMap[Type, TypeEntity] + + /** */ + def makeType(aType: Type, inTpl: TemplateImpl): TypeEntity = { + def createTypeEntity = new TypeEntity { + private var nameBuffer = new StringBuilder + private var refBuffer = new immutable.TreeMap[Int, (LinkTo, Int)] + private def appendTypes0(types: List[Type], sep: String): Unit = types match { + case Nil => + case tp :: Nil => + appendType0(tp) + case tp :: tps => + appendType0(tp) + nameBuffer append sep + appendTypes0(tps, sep) + } + + private def appendType0(tpe: Type): Unit = tpe match { + /* Type refs */ + case tp: TypeRef if definitions.isFunctionType(tp) => + val args = tp.normalize.typeArgs + nameBuffer append '(' + appendTypes0(args.init, ", ") + nameBuffer append ") ⇒ " + appendType0(args.last) + case tp: TypeRef if definitions.isScalaRepeatedParamType(tp) => + appendType0(tp.args.head) + nameBuffer append '*' + case tp: TypeRef if definitions.isByNameParamType(tp) => + nameBuffer append "⇒ " + appendType0(tp.args.head) + case tp: TypeRef if definitions.isTupleType(tp) => + val args = tp.normalize.typeArgs + nameBuffer append '(' + appendTypes0(args, ", ") + nameBuffer append ')' + case TypeRef(pre, aSym, targs) => + val preSym = pre.widen.typeSymbol + + // SI-3314/SI-4888: Classes, Traits and Types can be inherited from a template to another: + // class Enum { abstract class Value } + // class Day extends Enum { object Mon extends Value /*...*/ } + // ===> in such cases we have two options: + // (0) if there's no inheritance taking place (Enum#Value) we can link to the template directly + // (1) if we generate the doc template for Day, we can link to the correct member + // (2) If the symbol comes from an external library for which we know the documentation URL, point to it. + // (3) if we don't generate the doc template, we should at least indicate the correct prefix in the tooltip + val bSym = normalizeTemplate(aSym) + val owner = + if ((preSym != NoSymbol) && /* it needs a prefix */ + (preSym != bSym.owner) && /* prefix is different from owner */ + (aSym == bSym)) /* normalization doesn't play tricks on us */ + preSym + else + bSym.owner + + val link = + findTemplateMaybe(bSym) match { + case Some(bTpl) if owner == bSym.owner => + // (0) the owner's class is linked AND has a template - lovely + bTpl match { + case dtpl: DocTemplateEntity => new LinkToTpl(dtpl) + case _ => new Tooltip(bTpl.qualifiedName) + } + case _ => + val oTpl = findTemplateMaybe(owner) + (oTpl, oTpl flatMap (findMember(bSym, _))) match { + case (Some(oTpl), Some(bMbr)) => + // (1) the owner's class + LinkToMember(bMbr, oTpl) + case _ => + val name = makeQualifiedName(bSym) + if (!bSym.owner.isPackage) + Tooltip(name) + else + findExternalLink(bSym, name).getOrElse ( + // (3) if we couldn't find neither the owner nor external URL to link to, show a tooltip with the qualified name + Tooltip(name) + ) + } + } + + // SI-4360 Showing prefixes when necessary + // We check whether there's any directly accessible type with the same name in the current template OR if the + // type is inherited from one template to another. There may be multiple symbols with the same name in scope, + // but we won't show the prefix if our symbol is among them, only if *it's not* -- that's equal to showing + // the prefix only for ambiguous references, not for overloaded ones. + def needsPrefix: Boolean = { + if ((owner != bSym.owner || preSym.isRefinementClass) && (normalizeTemplate(owner) != inTpl.sym)) + return true + // don't get tricked into prefixng method type params and existentials: + // I tried several tricks BUT adding the method for which I'm creating the type => that simply won't scale, + // as ValueParams are independent of their parent member, and I really don't want to add this information to + // all terms, as we're already over the allowed memory footprint + if (aSym.isTypeParameterOrSkolem || aSym.isExistentiallyBound /* existential or existential skolem */) + return false + + for (tpl <- inTpl.sym.ownerChain) { + tpl.info.member(bSym.name) match { + case NoSymbol => + // No syms with that name, look further inside the owner chain + case sym => + // Symbol found -- either the correct symbol, another one OR an overloaded alternative + if (sym == bSym) + return false + else sym.info match { + case OverloadedType(owner, alternatives) => + return alternatives.contains(bSym) + case _ => + return true + } + } + } + // if it's not found in the owner chain, we can safely leave out the prefix + false + } + + val prefix = + if (!settings.docNoPrefixes.value && needsPrefix && (bSym != AnyRefClass /* which we normalize */)) { + if (!owner.isRefinementClass) { + val qName = makeQualifiedName(owner, Some(inTpl.sym)) + if (qName != "") qName + "." else "" + } + else { + nameBuffer append "(" + appendType0(pre) + nameBuffer append ")#" + "" // we already appended the prefix + } + } else "" + + //DEBUGGING: + //if (makeQualifiedName(bSym) == "pack1.A") println("needsPrefix(" + bSym + ", " + owner + ", " + inTpl.qualifiedName + ") => " + needsPrefix + " and prefix=" + prefix) + + val name = prefix + bSym.nameString + val pos0 = nameBuffer.length + refBuffer += pos0 -> ((link, name.length)) + nameBuffer append name + + if (!targs.isEmpty) { + nameBuffer append '[' + appendTypes0(targs, ", ") + nameBuffer append ']' + } + /* Refined types */ + case RefinedType(parents, defs) => + val ignoreParents = Set[Symbol](AnyClass, ObjectClass) + val filtParents = parents filterNot (x => ignoreParents(x.typeSymbol)) match { + case Nil => parents + case ps => ps + } + appendTypes0(filtParents, " with ") + // XXX Still todo: properly printing refinements. + // Since I didn't know how to go about displaying a multi-line type, I went with + // printing single method refinements (which should be the most common) and printing + // the number of members if there are more. + defs.toList match { + case Nil => () + case x :: Nil => nameBuffer append (" { " + x.defString + " }") + case xs => nameBuffer append (" { ... /* %d definitions in type refinement */ }" format xs.size) + } + /* Eval-by-name types */ + case NullaryMethodType(result) => + nameBuffer append '⇒' + appendType0(result) + + /* Polymorphic types */ + case PolyType(tparams, result) => assert(tparams.nonEmpty) + def typeParamsToString(tps: List[Symbol]): String = if (tps.isEmpty) "" else + tps.map{tparam => + tparam.varianceString + tparam.name + typeParamsToString(tparam.typeParams) + }.mkString("[", ", ", "]") + nameBuffer append typeParamsToString(tparams) + appendType0(result) + + case et@ExistentialType(quantified, underlying) => + + def appendInfoStringReduced(sym: Symbol, tp: Type): Unit = { + if (sym.isType && !sym.isAliasType && !sym.isClass) { + tp match { + case PolyType(tparams, _) => + nameBuffer append "[" + appendTypes0(tparams.map(_.tpe), ", ") + nameBuffer append "]" + case _ => + } + tp.resultType match { + case rt @ TypeBounds(_, _) => + appendType0(rt) + case rt => + nameBuffer append " <: " + appendType0(rt) + } + } else { + // fallback to the Symbol infoString + nameBuffer append sym.infoString(tp) + } + } + + def appendClauses = { + nameBuffer append " forSome {" + var first = true + for (sym <- quantified) { + if (!first) { nameBuffer append ", " } else first = false + if (sym.isSingletonExistential) { + nameBuffer append "val " + nameBuffer append tpnme.dropSingletonName(sym.name) + nameBuffer append ": " + appendType0(dropSingletonType(sym.info.bounds.hi)) + } else { + if (sym.flagString != "") nameBuffer append (sym.flagString + " ") + if (sym.keyString != "") nameBuffer append (sym.keyString + " ") + nameBuffer append sym.varianceString + nameBuffer append sym.nameString + appendInfoStringReduced(sym, sym.info) + } + } + nameBuffer append "}" + } + + underlying match { + case TypeRef(pre, sym, args) if et.isRepresentableWithWildcards => + appendType0(typeRef(pre, sym, Nil)) + nameBuffer append "[" + var first = true + val qset = quantified.toSet + for (arg <- args) { + if (!first) { nameBuffer append ", " } else first = false + arg match { + case TypeRef(_, sym, _) if (qset contains sym) => + nameBuffer append "_" + appendInfoStringReduced(sym, sym.info) + case arg => + appendType0(arg) + } + } + nameBuffer append "]" + case MethodType(_, _) | NullaryMethodType(_) | PolyType(_, _) => + nameBuffer append "(" + appendType0(underlying) + nameBuffer append ")" + appendClauses + case _ => + appendType0(underlying) + appendClauses + } + + case tb@TypeBounds(lo, hi) => + if (tb.lo != TypeBounds.empty.lo) { + nameBuffer append " >: " + appendType0(lo) + } + if (tb.hi != TypeBounds.empty.hi) { + nameBuffer append " <: " + appendType0(hi) + } + // case tpen: ThisType | SingleType | SuperType => + // if (tpen.isInstanceOf[ThisType] && tpen.asInstanceOf[ThisType].sym.isEffectiveRoot) { + // appendType0 typeRef(NoPrefix, sym, Nil) + // } else { + // val underlying = + // val pre = underlying.typeSymbol.skipPackageObject + // if (pre.isOmittablePrefix) pre.fullName + ".type" + // else prefixString + "type" + case tpen@ThisType(sym) => + appendType0(typeRef(NoPrefix, sym, Nil)) + nameBuffer append ".this" + if (!tpen.underlying.typeSymbol.skipPackageObject.isOmittablePrefix) nameBuffer append ".type" + case tpen@SuperType(thistpe, supertpe) => + nameBuffer append "super[" + appendType0(supertpe) + nameBuffer append "]" + case tpen@SingleType(pre, sym) => + appendType0(typeRef(pre, sym, Nil)) + if (!tpen.underlying.typeSymbol.skipPackageObject.isOmittablePrefix) nameBuffer append ".type" + case tpen => + nameBuffer append tpen.toString + } + appendType0(aType) + val refEntity = refBuffer + val name = optimize(nameBuffer.toString) + nameBuffer = null + } + + // SI-4360: Entity caching depends on both the type AND the template it's in, as the prefixes might change for the + // same type based on the template the type is shown in. + if (settings.docNoPrefixes.value) + typeCache.getOrElseUpdate(aType, createTypeEntity) + else createTypeEntity + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/TreeEntity.scala b/src/scaladoc/scala/tools/nsc/doc/model/TreeEntity.scala new file mode 100644 index 0000000000..5b4ec4a40b --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/TreeEntity.scala @@ -0,0 +1,27 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Chris James + */ + +package scala.tools.nsc +package doc +package model + +import scala.collection._ + + +/** A fragment of code. */ +abstract class TreeEntity { + + /** The human-readable representation of this abstract syntax tree. */ + def expression: String + + /** Maps which parts of this syntax tree's name reference entities. The map is indexed by the position of the first + * character that reference some entity, and contains the entity and the position of the last referenced + * character. The referenced character ranges do not to overlap or nest. The map is sorted by position. */ + def refEntity: SortedMap[Int, (Entity, Int)] + + /** The human-readable representation of this abstract syntax tree. */ + override def toString = expression + +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala new file mode 100755 index 0000000000..b972649194 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala @@ -0,0 +1,96 @@ +package scala.tools.nsc +package doc +package model + +import scala.collection._ +import scala.reflect.internal.util.{RangePosition, OffsetPosition, SourceFile} + +/** The goal of this trait is , using makeTree, + * to browse a tree to + * 1- have the String of the complete tree (tree.expression) + * 2- fill references to create hyperLinks later in html.pageTemplate + * + * It is applied in ModelFactory => makeTree + * + */ + +trait TreeFactory { thisTreeFactory: ModelFactory with TreeFactory => + + val global: Global + import global._ + + def makeTree(rhs: Tree): Option[TreeEntity] = { + + val expr = new StringBuilder + var refs = new immutable.TreeMap[Int, (Entity, Int)] // start, (Entity to be linked to , end) + + rhs.pos match { + case pos: RangePosition => { + val source: SourceFile = pos.source + val firstIndex = pos.startOrPoint + val lastIndex = pos.endOrPoint + + assert(firstIndex < lastIndex, "Invalid position indices for tree " + rhs + " (" + firstIndex + ", " + lastIndex + ")") + expr.appendAll(source.content, firstIndex, lastIndex - firstIndex) + + val traverser = new Traverser { + + /** Finds the Entity on which we will later create a link on, + * stores it in tree.refs with its position + */ + def makeLink(rhs: Tree){ + val start = pos.startOrPoint - firstIndex + val end = pos.endOrPoint - firstIndex + if(start != end) { + var asym = rhs.symbol + if (asym.isClass) makeTemplate(asym) match{ + case docTmpl: DocTemplateImpl => + refs += ((start, (docTmpl,end))) + case _ => + } + else if (asym.isTerm && asym.owner.isClass){ + if (asym.isSetter) asym = asym.getter(asym.owner) + makeTemplate(asym.owner) match { + case docTmpl: DocTemplateImpl => + val mbrs: Option[MemberImpl] = findMember(asym, docTmpl) + mbrs foreach { mbr => refs += ((start, (mbr,end))) } + case _ => + } + } + } + } + /** + * Goes through the tree and makes links when a Select occurs, + * The case of New(_) is ignored because the object we want to create a link on + * will be reached with recursivity and we don't want a link on the "new" string + * If a link is not created, its case is probably not defined in here + */ + override def traverse(tree: Tree) = tree match { + case Select(qualifier, name) => + qualifier match { + case New(_) => + case _ => makeLink(tree) + } + traverse(qualifier) + case Ident(_) => makeLink(tree) + case _ => + super.traverse(tree) + } + } + + traverser.traverse(rhs) + + Some(new TreeEntity { + val expression = expr.toString + val refEntity = refs + }) + } + case pos: OffsetPosition => + Some(new TreeEntity { + val expression = rhs.toString + val refEntity = new immutable.TreeMap[Int, (Entity, Int)] + }) + case _ => None + } + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/TypeEntity.scala b/src/scaladoc/scala/tools/nsc/doc/model/TypeEntity.scala new file mode 100644 index 0000000000..cf5c1fb3fb --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/TypeEntity.scala @@ -0,0 +1,27 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Manohar Jonnalagedda + */ + +package scala.tools.nsc +package doc +package model + +import scala.collection._ + +/** A type. Note that types and templates contain the same information only for the simplest types. For example, a type + * defines how a template's type parameters are instantiated (as in `List[Cow]`), what the template's prefix is + * (as in `johnsFarm.Cow`), and supports compound or structural types. */ +abstract class TypeEntity { + + /** The human-readable representation of this type. */ + def name: String + + /** Maps which parts of this type's name reference entities. The map is indexed by the position of the first + * character that reference some entity, and contains the entity and the position of the last referenced + * character. The referenced character ranges do not to overlap or nest. The map is sorted by position. */ + def refEntity: SortedMap[Int, (base.LinkTo, Int)] + + /** The human-readable representation of this type. */ + override def toString = name +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ValueArgument.scala b/src/scaladoc/scala/tools/nsc/doc/model/ValueArgument.scala new file mode 100644 index 0000000000..f712869a4b --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/ValueArgument.scala @@ -0,0 +1,20 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Gilles Dubochet + */ + +package scala.tools.nsc +package doc +package model + + +/** A value that is passed as an argument to a value parameter. */ +trait ValueArgument { + + /** The parameter as argument to which this value is passed, if it is known. */ + def parameter: Option[ValueParam] + + /** The expression that calculates the value. */ + def value: TreeEntity + +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/Visibility.scala b/src/scaladoc/scala/tools/nsc/doc/model/Visibility.scala new file mode 100644 index 0000000000..22580805aa --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/Visibility.scala @@ -0,0 +1,39 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Gilles Dubochet + */ + +package scala.tools.nsc +package doc +package model + +/** An type that represents visibility of members. */ +sealed trait Visibility { + def isProtected: Boolean = false + def isPublic: Boolean = false +} + +/** The visibility of `private[this]` members. */ +case class PrivateInInstance() extends Visibility + +/** The visibility of `protected[this]` members. */ +case class ProtectedInInstance() extends Visibility { + override def isProtected = true +} + +/** The visibility of `private[owner]` members. An unqualified private members + * is encoded with `owner` equal to the members's `inTemplate`. */ +case class PrivateInTemplate(owner: TemplateEntity) extends Visibility + +/** The visibility of `protected[owner]` members. An unqualified protected + * members is encoded with `owner` equal to the members's `inTemplate`. + * Note that whilst the member is visible in any template owned by `owner`, + * it is only visible in subclasses of the member's `inTemplate`. */ +case class ProtectedInTemplate(owner: TemplateEntity) extends Visibility { + override def isProtected = true +} + +/** The visibility of public members. */ +case class Public() extends Visibility { + override def isPublic = true +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala new file mode 100644 index 0000000000..150b293b81 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala @@ -0,0 +1,137 @@ +package scala.tools.nsc.doc +package model +package diagram + +import model._ + +/** + * The diagram base classes + * + * @author Damien Obrist + * @author Vlad Ureche + */ +abstract class Diagram { + def nodes: List[Node] + def edges: List[(Node, List[Node])] + def isContentDiagram = false // Implemented by ContentDiagram + def isInheritanceDiagram = false // Implemented by InheritanceDiagram + def depthInfo: DepthInfo +} + +case class ContentDiagram(nodes:List[/*Class*/Node], edges:List[(Node, List[Node])]) extends Diagram { + override def isContentDiagram = true + lazy val depthInfo = new ContentDiagramDepth(this) +} + +/** A class diagram */ +case class InheritanceDiagram(thisNode: ThisNode, + superClasses: List[/*Class*/Node], + subClasses: List[/*Class*/Node], + incomingImplicits: List[ImplicitNode], + outgoingImplicits: List[ImplicitNode]) extends Diagram { + def nodes = thisNode :: superClasses ::: subClasses ::: incomingImplicits ::: outgoingImplicits + def edges = (thisNode -> (superClasses ::: outgoingImplicits)) :: + (subClasses ::: incomingImplicits).map(_ -> List(thisNode)) + + override def isInheritanceDiagram = true + lazy val depthInfo = new DepthInfo { + def maxDepth = 3 + } +} + +trait DepthInfo { + /** Gives the maximum depth */ + def maxDepth: Int +} + +abstract class Node { + def name = tpe.name + def tpe: TypeEntity + def tpl: Option[TemplateEntity] + /** shortcut to get a DocTemplateEntity */ + def doctpl: Option[DocTemplateEntity] = tpl match { + case Some(tpl) => tpl match { + case d: DocTemplateEntity => Some(d) + case _ => None + } + case _ => None + } + /* shortcuts to find the node type without matching */ + def isThisNode = false + def isNormalNode = false + def isClassNode = if (tpl.isDefined) (tpl.get.isClass || tpl.get.qualifiedName == "scala.AnyRef") else false + def isTraitNode = if (tpl.isDefined) tpl.get.isTrait else false + def isObjectNode= if (tpl.isDefined) tpl.get.isObject else false + def isTypeNode = if (doctpl.isDefined) doctpl.get.isAbstractType || doctpl.get.isAliasType else false + def isOtherNode = !(isClassNode || isTraitNode || isObjectNode || isTypeNode) + def isImplicitNode = false + def isOutsideNode = false + def tooltip: Option[String] +} + +// different matchers, allowing you to use the pattern matcher against any node +// NOTE: A ThisNode or ImplicitNode can at the same time be ClassNode/TraitNode/OtherNode, not exactly according to +// case class specification -- thus a complete match would be: +// node match { +// case ThisNode(tpe, _) => /* case for this node, you can still use .isClass, .isTrait and .isOther */ +// case ImplicitNode(tpe, _) => /* case for an implicit node, you can still use .isClass, .isTrait and .isOther */ +// case _ => node match { +// case ClassNode(tpe, _) => /* case for a non-this, non-implicit Class node */ +// case TraitNode(tpe, _) => /* case for a non-this, non-implicit Trait node */ +// case OtherNode(tpe, _) => /* case for a non-this, non-implicit Other node */ +// } +// } +object Node { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = Some((n.tpe, n.tpl)) } +object ClassNode { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = if (n.isClassNode) Some((n.tpe, n.tpl)) else None } +object TraitNode { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = if (n.isTraitNode) Some((n.tpe, n.tpl)) else None } +object TypeNode { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = if (n.isTypeNode) Some((n.tpe, n.tpl)) else None } +object ObjectNode { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = if (n.isObjectNode) Some((n.tpe, n.tpl)) else None } +object OutsideNode { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = if (n.isOutsideNode) Some((n.tpe, n.tpl)) else None } +object OtherNode { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = if (n.isOtherNode) Some((n.tpe, n.tpl)) else None } + + + +/** The node for the current class */ +case class ThisNode(tpe: TypeEntity, tpl: Option[TemplateEntity])(val tooltip: Option[String] = None) extends Node { override def isThisNode = true } + +/** The usual node */ +case class NormalNode(tpe: TypeEntity, tpl: Option[TemplateEntity])(val tooltip: Option[String] = None) extends Node { override def isNormalNode = true } + +/** A class or trait the thisnode can be converted to by an implicit conversion + * TODO: I think it makes more sense to use the tpe links to templates instead of the TemplateEntity for implicit nodes + * since some implicit conversions convert the class to complex types that cannot be represented as a single tmeplate + */ +case class ImplicitNode(tpe: TypeEntity, tpl: Option[TemplateEntity])(val tooltip: Option[String] = None) extends Node { override def isImplicitNode = true } + +/** An outside node is shown in packages when a class from a different package makes it to the package diagram due to + * its relation to a class in the template (see @contentDiagram hideInheritedNodes annotation) */ +case class OutsideNode(tpe: TypeEntity, tpl: Option[TemplateEntity])(val tooltip: Option[String] = None) extends Node { override def isOutsideNode = true } + + +// Computing and offering node depth information +class ContentDiagramDepth(pack: ContentDiagram) extends DepthInfo { + private[this] var _maxDepth = 0 + private[this] var _nodeDepth = Map[Node, Int]() + private[this] var seedNodes = Set[Node]() + private[this] val invertedEdges: Map[Node, List[Node]] = + pack.edges.flatMap({case (node: Node, outgoing: List[Node]) => outgoing.map((_, node))}).groupBy(_._1).map({case (k, values) => (k, values.map(_._2))}).withDefaultValue(Nil) + private[this] val directEdges: Map[Node, List[Node]] = pack.edges.toMap.withDefaultValue(Nil) + + // seed base nodes, to minimize noise - they can't all have parents, else there would only be cycles + seedNodes ++= pack.nodes.filter(directEdges(_).isEmpty) + + while (!seedNodes.isEmpty) { + var newSeedNodes = Set[Node]() + for (node <- seedNodes) { + val depth = 1 + (-1 :: directEdges(node).map(_nodeDepth.getOrElse(_, -1))).max + if (depth != _nodeDepth.getOrElse(node, -1)) { + _nodeDepth += (node -> depth) + newSeedNodes ++= invertedEdges(node) + if (depth > _maxDepth) _maxDepth = depth + } + } + seedNodes = newSeedNodes + } + + val maxDepth = _maxDepth +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala new file mode 100644 index 0000000000..6395446d3b --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala @@ -0,0 +1,257 @@ +package scala.tools.nsc.doc +package model +package diagram + +import model._ +import java.util.regex.{Pattern, Matcher} +import scala.util.matching.Regex + +/** + * This trait takes care of parsing @{inheritance, content}Diagram annotations + * + * @author Damien Obrist + * @author Vlad Ureche + */ +trait DiagramDirectiveParser { + this: ModelFactory with DiagramFactory with CommentFactory with TreeFactory => + + import this.global.definitions.AnyRefClass + + ///// DIAGRAM FILTERS ////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * The DiagramFilter trait directs the diagram engine about the way the diagram should be displayed + * + * Vlad: There's an explanation I owe to people using diagrams and not finding a way to hide a specific class from + * all diagrams at once. So why did I choose to allow you to only control the diagrams at class level? So, the + * reason is you would break the separate scaladoc compilation: + * If you have an "@diagram hideMyClass" annotation in class A and you run scaladoc on it along with its subclass B + * A will not appear in B's diagram. But if you scaladoc only on B, A's comment will not be parsed and the + * instructions to hide class A from all diagrams will not be available. Thus I prefer to force you to control the + * diagrams of each class locally. The problem does not appear with scalac, as scalac stores all its necessary + * information (like scala signatures) serialized in the .class file. But we couldn't store doc comments in the class + * file, could we? (Turns out we could, but that's another story) + * + * Any flaming for this decision should go to scala-internals@googlegroups.com + */ + trait DiagramFilter { + /** A flag to hide the diagram completely */ + def hideDiagram: Boolean + /** Hide incoming implicit conversions (for type hierarchy diagrams) */ + def hideIncomingImplicits: Boolean + /** Hide outgoing implicit conversions (for type hierarchy diagrams) */ + def hideOutgoingImplicits: Boolean + /** Hide superclasses (for type hierarchy diagrams) */ + def hideSuperclasses: Boolean + /** Hide subclasses (for type hierarchy diagrams) */ + def hideSubclasses: Boolean + /** Show related classes from other objects/traits/packages (for content diagrams) */ + def hideInheritedNodes: Boolean + /** Hide a node from the diagram */ + def hideNode(clazz: Node): Boolean + /** Hide an edge from the diagram */ + def hideEdge(clazz1: Node, clazz2: Node): Boolean + } + + /** Main entry point into this trait: generate the filter for inheritance diagrams */ + def makeInheritanceDiagramFilter(template: DocTemplateImpl): DiagramFilter = { + + val defaultFilter = + if (template.isClass || template.isTrait || template.sym == AnyRefClass) + FullDiagram + else + NoDiagramAtAll + + if (template.comment.isDefined) + makeDiagramFilter(template, template.comment.get.inheritDiagram, defaultFilter, isInheritanceDiagram = true) + else + defaultFilter + } + + /** Main entry point into this trait: generate the filter for content diagrams */ + def makeContentDiagramFilter(template: DocTemplateImpl): DiagramFilter = { + val defaultFilter = if (template.isPackage || template.isObject) FullDiagram else NoDiagramAtAll + if (template.comment.isDefined) + makeDiagramFilter(template, template.comment.get.contentDiagram, defaultFilter, isInheritanceDiagram = false) + else + defaultFilter + } + + protected var tFilter = 0l + protected var tModel = 0l + + /** Show the entire diagram, no filtering */ + case object FullDiagram extends DiagramFilter { + val hideDiagram: Boolean = false + val hideIncomingImplicits: Boolean = false + val hideOutgoingImplicits: Boolean = false + val hideSuperclasses: Boolean = false + val hideSubclasses: Boolean = false + val hideInheritedNodes: Boolean = false + def hideNode(clazz: Node): Boolean = false + def hideEdge(clazz1: Node, clazz2: Node): Boolean = false + } + + /** Hide the diagram completely, no need for special filtering */ + case object NoDiagramAtAll extends DiagramFilter { + val hideDiagram: Boolean = true + val hideIncomingImplicits: Boolean = true + val hideOutgoingImplicits: Boolean = true + val hideSuperclasses: Boolean = true + val hideSubclasses: Boolean = true + val hideInheritedNodes: Boolean = true + def hideNode(clazz: Node): Boolean = true + def hideEdge(clazz1: Node, clazz2: Node): Boolean = true + } + + /** The AnnotationDiagramFilter trait directs the diagram engine according to an annotation + * TODO: Should document the annotation, for now see parseDiagramAnnotation in ModelFactory.scala */ + case class AnnotationDiagramFilter(hideDiagram: Boolean, + hideIncomingImplicits: Boolean, + hideOutgoingImplicits: Boolean, + hideSuperclasses: Boolean, + hideSubclasses: Boolean, + hideInheritedNodes: Boolean, + hideNodesFilter: List[Pattern], + hideEdgesFilter: List[(Pattern, Pattern)]) extends DiagramFilter { + + private[this] def getName(n: Node): String = + if (n.tpl.isDefined) + n.tpl.get.qualifiedName + else + n.name + + def hideNode(clazz: Node): Boolean = { + val qualifiedName = getName(clazz) + for (hideFilter <- hideNodesFilter) + if (hideFilter.matcher(qualifiedName).matches) { + // println(hideFilter + ".matcher(" + qualifiedName + ").matches = " + hideFilter.matcher(qualifiedName).matches) + return true + } + false + } + + def hideEdge(clazz1: Node, clazz2: Node): Boolean = { + val clazz1Name = getName(clazz1) + val clazz2Name = getName(clazz2) + for ((clazz1Filter, clazz2Filter) <- hideEdgesFilter) { + if (clazz1Filter.matcher(clazz1Name).matches && + clazz2Filter.matcher(clazz2Name).matches) { + // println(clazz1Filter + ".matcher(" + clazz1Name + ").matches = " + clazz1Filter.matcher(clazz1Name).matches) + // println(clazz2Filter + ".matcher(" + clazz2Name + ").matches = " + clazz2Filter.matcher(clazz2Name).matches) + return true + } + } + false + } + } + + // TODO: This could certainly be improved -- right now the only regex is *, but there's no way to match a single identifier + private val NodeSpecRegex = "\\\"[A-Za-z\\*][A-Za-z\\.\\*]*\\\"" + private val NodeSpecPattern = Pattern.compile(NodeSpecRegex) + private val EdgeSpecRegex = "\\(" + NodeSpecRegex + "\\s*\\->\\s*" + NodeSpecRegex + "\\)" + // And the composed regexes: + private val HideNodesRegex = new Regex("^hideNodes(\\s*" + NodeSpecRegex + ")+$") + private val HideEdgesRegex = new Regex("^hideEdges(\\s*" + EdgeSpecRegex + ")+$") + + private def makeDiagramFilter(template: DocTemplateImpl, + directives: List[String], + defaultFilter: DiagramFilter, + isInheritanceDiagram: Boolean): DiagramFilter = directives match { + + // if there are no specific diagram directives, return the default filter (either FullDiagram or NoDiagramAtAll) + case Nil => + defaultFilter + + // compute the exact filters. By including the annotation, the diagram is autmatically added + case _ => + tFilter -= System.currentTimeMillis + var hideDiagram0: Boolean = false + var hideIncomingImplicits0: Boolean = false + var hideOutgoingImplicits0: Boolean = false + var hideSuperclasses0: Boolean = false + var hideSubclasses0: Boolean = false + var hideInheritedNodes0: Boolean = false + var hideNodesFilter0: List[Pattern] = Nil + var hideEdgesFilter0: List[(Pattern, Pattern)] = Nil + + def warning(message: String) = { + // we need the position from the package object (well, ideally its comment, but yeah ...) + val sym = if (template.sym.isPackage) template.sym.info.member(global.nme.PACKAGE) else template.sym + assert((sym != global.NoSymbol) || (sym == global.rootMirror.RootPackage)) + global.reporter.warning(sym.pos, message) + } + + def preparePattern(className: String) = + "^" + className.stripPrefix("\"").stripSuffix("\"").replaceAll("\\.", "\\\\.").replaceAll("\\*", ".*") + "$" + + // separate entries: + val entries = directives.foldRight("")(_ + " " + _).split(",").map(_.trim) + for (entry <- entries) + entry match { + case "hideDiagram" => + hideDiagram0 = true + case "hideIncomingImplicits" if isInheritanceDiagram => + hideIncomingImplicits0 = true + case "hideOutgoingImplicits" if isInheritanceDiagram => + hideOutgoingImplicits0 = true + case "hideSuperclasses" if isInheritanceDiagram => + hideSuperclasses0 = true + case "hideSubclasses" if isInheritanceDiagram => + hideSubclasses0 = true + case "hideInheritedNodes" if !isInheritanceDiagram => + hideInheritedNodes0 = true + case HideNodesRegex(last) => + val matcher = NodeSpecPattern.matcher(entry) + while (matcher.find()) { + val classPattern = Pattern.compile(preparePattern(matcher.group())) + hideNodesFilter0 ::= classPattern + } + case HideEdgesRegex(last) => + val matcher = NodeSpecPattern.matcher(entry) + while (matcher.find()) { + val class1Pattern = Pattern.compile(preparePattern(matcher.group())) + assert(matcher.find()) // it's got to be there, just matched it! + val class2Pattern = Pattern.compile(preparePattern(matcher.group())) + hideEdgesFilter0 ::= ((class1Pattern, class2Pattern)) + } + case "" => + // don't need to do anything about it + case _ => + warning("Could not understand diagram annotation in " + template.kind + " " + template.qualifiedName + + ": unmatched entry \"" + entry + "\".\n" + + " This could be because:\n" + + " - you forgot to separate entries by commas\n" + + " - you used a tag that is not allowed in the current context (like @contentDiagram hideSuperclasses)\n"+ + " - you did not use one of the allowed tags (see docs.scala-lang.org for scaladoc annotations)") + } + val result = + if (hideDiagram0) + NoDiagramAtAll + else if ((hideNodesFilter0.isEmpty) && + (hideEdgesFilter0.isEmpty) && + (hideIncomingImplicits0 == false) && + (hideOutgoingImplicits0 == false) && + (hideSuperclasses0 == false) && + (hideSubclasses0 == false) && + (hideInheritedNodes0 == false) && + (hideDiagram0 == false)) + FullDiagram + else + AnnotationDiagramFilter( + hideDiagram = hideDiagram0, + hideIncomingImplicits = hideIncomingImplicits0, + hideOutgoingImplicits = hideOutgoingImplicits0, + hideSuperclasses = hideSuperclasses0, + hideSubclasses = hideSubclasses0, + hideInheritedNodes = hideInheritedNodes0, + hideNodesFilter = hideNodesFilter0, + hideEdgesFilter = hideEdgesFilter0) + + if (settings.docDiagramsDebug.value && result != NoDiagramAtAll && result != FullDiagram) + settings.printMsg(template.kind + " " + template.qualifiedName + " filter: " + result) + tFilter += System.currentTimeMillis + + result + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala new file mode 100644 index 0000000000..ebac25bbe4 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala @@ -0,0 +1,254 @@ +package scala.tools.nsc.doc +package model +package diagram + +import model._ + +// statistics +import html.page.diagram.DiagramStats + +import scala.collection.immutable.SortedMap + +/** + * This trait takes care of generating the diagram for classes and packages + * + * @author Damien Obrist + * @author Vlad Ureche + */ +trait DiagramFactory extends DiagramDirectiveParser { + this: ModelFactory with ModelFactoryTypeSupport with DiagramFactory with CommentFactory with TreeFactory => + + import this.global.definitions._ + import this.global._ + + // the following can used for hardcoding different relations into the diagram, for bootstrapping purposes + def aggregationNode(text: String) = + NormalNode(new TypeEntity { val name = text; val refEntity = SortedMap[Int, (base.LinkTo, Int)]() }, None)() + + /** Create the inheritance diagram for this template */ + def makeInheritanceDiagram(tpl: DocTemplateImpl): Option[Diagram] = { + + tFilter = 0 + tModel = -System.currentTimeMillis + + // the diagram filter + val diagramFilter = makeInheritanceDiagramFilter(tpl) + + def implicitTooltip(from: DocTemplateEntity, to: TemplateEntity, conv: ImplicitConversion) = + Some(from.qualifiedName + " can be implicitly converted to " + conv.targetType + " by the implicit method " + + conv.conversionShortName + " in " + conv.convertorOwner.kind + " " + conv.convertorOwner.qualifiedName) + + val result = + if (diagramFilter == NoDiagramAtAll) + None + else { + // the main node + val thisNode = ThisNode(tpl.resultType, Some(tpl))(Some(tpl.qualifiedName + " (this " + tpl.kind + ")")) + + // superclasses + val superclasses: List[Node] = + tpl.parentTypes.collect { + case p: (TemplateEntity, TypeEntity) if !classExcluded(p._1) => NormalNode(p._2, Some(p._1))() + }.reverse + + // incoming implcit conversions + lazy val incomingImplicitNodes = tpl.incomingImplicitlyConvertedClasses.map { + case (incomingTpl, conv) => + ImplicitNode(makeType(incomingTpl.sym.tpe, tpl), Some(incomingTpl))(implicitTooltip(from=incomingTpl, to=tpl, conv=conv)) + } + + // subclasses + var subclasses: List[Node] = + tpl.directSubClasses.collect { + case d: TemplateImpl if !classExcluded(d) => NormalNode(makeType(d.sym.tpe, tpl), Some(d))() + }.sortBy(_.tpl.get.name)(implicitly[Ordering[String]].reverse) + + // outgoing implicit coversions + lazy val outgoingImplicitNodes = tpl.outgoingImplicitlyConvertedClasses.map { + case (outgoingTpl, outgoingType, conv) => + ImplicitNode(outgoingType, Some(outgoingTpl))(implicitTooltip(from=tpl, to=tpl, conv=conv)) + } + + // TODO: Everyone should be able to use the @{inherit,content}Diagram annotation to change the diagrams. + // Currently, it's possible to leave nodes and edges out, but there's no way to create new nodes and edges + // The implementation would need to add the annotations and the logic to select nodes (or create new ones) + // and add edges to the diagram -- I bet it wouldn't take too long for someone to do it (one or two days + // at most) and it would be a great add to the diagrams. + if (tpl.sym == AnyRefClass) + subclasses = List(aggregationNode("All user-defined classes and traits")) + + val filteredSuperclasses = if (diagramFilter.hideSuperclasses) Nil else superclasses + val filteredIncomingImplicits = if (diagramFilter.hideIncomingImplicits) Nil else incomingImplicitNodes + val filteredSubclasses = if (diagramFilter.hideSubclasses) Nil else subclasses + val filteredImplicitOutgoingNodes = if (diagramFilter.hideOutgoingImplicits) Nil else outgoingImplicitNodes + + // final diagram filter + filterDiagram(InheritanceDiagram(thisNode, filteredSuperclasses.reverse, filteredSubclasses.reverse, filteredIncomingImplicits, filteredImplicitOutgoingNodes), diagramFilter) + } + + tModel += System.currentTimeMillis + DiagramStats.addFilterTime(tFilter) + DiagramStats.addModelTime(tModel-tFilter) + + result + } + + /** Create the content diagram for this template */ + def makeContentDiagram(pack: DocTemplateImpl): Option[Diagram] = { + + tFilter = 0 + tModel = -System.currentTimeMillis + + // the diagram filter + val diagramFilter = makeContentDiagramFilter(pack) + + val result = + if (diagramFilter == NoDiagramAtAll) + None + else { + var mapNodes = Map[TemplateEntity, Node]() + var nodesShown = Set[TemplateEntity]() + var edgesAll = List[(TemplateEntity, List[TemplateEntity])]() + + // classes is the entire set of classes and traits in the package, they are the superset of nodes in the diagram + // we collect classes, traits and objects without a companion, which are usually used as values(e.g. scala.None) + val nodesAll = pack.members collect { + case d: TemplateEntity if ((!diagramFilter.hideInheritedNodes) || (d.inTemplate == pack)) => d + } + + // for each node, add its subclasses + for (node <- nodesAll if !classExcluded(node)) { + node match { + case dnode: MemberTemplateImpl => + var superClasses = dnode.parentTypes.map(_._1).filter(nodesAll.contains(_)) + + // TODO: Everyone should be able to use the @{inherit,content}Diagram annotation to add nodes to diagrams. + if (pack.sym == ScalaPackage) + if (dnode.sym == NullClass) + superClasses = List(makeTemplate(AnyRefClass)) + else if (dnode.sym == NothingClass) + superClasses = (List(NullClass) ::: ScalaValueClasses).map(makeTemplate(_)) + + if (!superClasses.isEmpty) { + nodesShown += dnode + nodesShown ++= superClasses + } + edgesAll ::= dnode -> superClasses + case _ => + } + + mapNodes += node -> ( + if (node.inTemplate == pack && (node.isDocTemplate || node.isAbstractType || node.isAliasType)) + NormalNode(node.resultType, Some(node))() + else + OutsideNode(node.resultType, Some(node))() + ) + } + + if (nodesShown.isEmpty) + None + else { + val nodes = nodesAll.filter(nodesShown.contains(_)).flatMap(mapNodes.get(_)) + val edges = edgesAll.map(pair => (mapNodes(pair._1), pair._2.map(mapNodes(_)))).filterNot(pair => pair._2.isEmpty) + val diagram = + // TODO: Everyone should be able to use the @{inherit,content}Diagram annotation to change the diagrams. + if (pack.sym == ScalaPackage) { + // Tried it, but it doesn't look good: + // var anyRefSubtypes: List[Node] = List(mapNodes(makeTemplate(AnyRefClass))) + // var dirty = true + // do { + // val length = anyRefSubtypes.length + // anyRefSubtypes :::= edges.collect { case p: (Node, List[Node]) if p._2.exists(anyRefSubtypes.contains(_)) => p._1 } + // anyRefSubtypes = anyRefSubtypes.distinct + // dirty = (anyRefSubtypes.length != length) + // } while (dirty) + // println(anyRefSubtypes) + val anyRefSubtypes = Nil + val allAnyRefTypes = aggregationNode("All AnyRef subtypes") + val nullTemplate = makeTemplate(NullClass) + if (nullTemplate.isDocTemplate) + ContentDiagram(allAnyRefTypes::nodes, (mapNodes(nullTemplate), allAnyRefTypes::anyRefSubtypes)::edges.filterNot(_._1.tpl == Some(nullTemplate))) + else + ContentDiagram(nodes, edges) + } else + ContentDiagram(nodes, edges) + + filterDiagram(diagram, diagramFilter) + } + } + + tModel += System.currentTimeMillis + DiagramStats.addFilterTime(tFilter) + DiagramStats.addModelTime(tModel-tFilter) + + result + } + + /** Diagram filtering logic */ + private def filterDiagram(diagram: Diagram, diagramFilter: DiagramFilter): Option[Diagram] = { + tFilter -= System.currentTimeMillis + + val result = + if (diagramFilter == FullDiagram) + Some(diagram) + else if (diagramFilter == NoDiagramAtAll) + None + else { + // Final diagram, with the filtered nodes and edges + diagram match { + case InheritanceDiagram(thisNode, _, _, _, _) if diagramFilter.hideNode(thisNode) => + None + + case InheritanceDiagram(thisNode, superClasses, subClasses, incomingImplicits, outgoingImplicits) => + + def hideIncoming(node: Node): Boolean = + diagramFilter.hideNode(node) || diagramFilter.hideEdge(node, thisNode) + + def hideOutgoing(node: Node): Boolean = + diagramFilter.hideNode(node) || diagramFilter.hideEdge(thisNode, node) + + // println(thisNode) + // println(superClasses.map(cl => "super: " + cl + " " + hideOutgoing(cl)).mkString("\n")) + // println(subClasses.map(cl => "sub: " + cl + " " + hideIncoming(cl)).mkString("\n")) + Some(InheritanceDiagram(thisNode, + superClasses.filterNot(hideOutgoing(_)), + subClasses.filterNot(hideIncoming(_)), + incomingImplicits.filterNot(hideIncoming(_)), + outgoingImplicits.filterNot(hideOutgoing(_)))) + + case ContentDiagram(nodes0, edges0) => + // Filter out all edges that: + // (1) are sources of hidden classes + // (2) are manually hidden by the user + // (3) are destinations of hidden classes + val edges: List[(Node, List[Node])] = + diagram.edges.flatMap({ + case (source, dests) if !diagramFilter.hideNode(source) => + val dests2 = dests.collect({ case dest if (!(diagramFilter.hideEdge(source, dest) || diagramFilter.hideNode(dest))) => dest }) + if (dests2 != Nil) + List((source, dests2)) + else + Nil + case _ => Nil + }) + + // Only show the the non-isolated nodes + // TODO: Decide if we really want to hide package members, I'm not sure that's a good idea (!!!) + // TODO: Does .distinct cause any stability issues? + val sourceNodes = edges.map(_._1) + val sinkNodes = edges.map(_._2).flatten + val nodes = (sourceNodes ::: sinkNodes).distinct + Some(ContentDiagram(nodes, edges)) + } + } + + tFilter += System.currentTimeMillis + + // eliminate all empty diagrams + if (result.isDefined && result.get.edges.forall(_._2.isEmpty)) + None + else + result + } + +} diff --git a/src/scaladoc/scala/tools/partest/ScaladocModelTest.scala b/src/scaladoc/scala/tools/partest/ScaladocModelTest.scala new file mode 100644 index 0000000000..3db9f18484 --- /dev/null +++ b/src/scaladoc/scala/tools/partest/ScaladocModelTest.scala @@ -0,0 +1,203 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author Vlad Ureche + */ + +package scala.tools.partest + +import scala.tools.nsc._ +import scala.tools.nsc.util.CommandLineParser +import scala.tools.nsc.doc.{Settings, DocFactory, Universe} +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.diagram._ +import scala.tools.nsc.doc.base.comment._ +import scala.tools.nsc.reporters.ConsoleReporter + +/** A class for testing scaladoc model generation + * - you need to specify the code in the `code` method + * - you need to override the testModel method to test the model + * - you may specify extra parameters to send to scaladoc in `scaladocSettings` + * {{{ + import scala.tools.nsc.doc.model._ + import scala.tools.partest.ScaladocModelTest + + object Test extends ScaladocModelTest { + + override def code = """ ... """ // or override def resourceFile = ".scala" (from test/scaladoc/resources) + def scaladocSettings = " ... " + def testModel(rootPackage: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + // just need to check the member exists, access methods will throw an error if there's a problem + rootPackage._package("scala")._package("test")._class("C")._method("foo") + } + } + * }}} + */ +abstract class ScaladocModelTest extends DirectTest { + + /** Override this to give scaladoc command line parameters */ + def scaladocSettings: String + + /** Override this to test the model */ + def testModel(root: Package): Unit + + /** Override to feed a file in resources to scaladoc*/ + def resourceFile: String = null + + /** Override to feed code into scaladoc */ + override def code = + if (resourceFile ne null) + io.File(resourcePath + "/" + resourceFile).slurp() + else + sys.error("Scaladoc Model Test: You need to give a file or some code to feed to scaladoc!") + + def resourcePath = io.Directory(sys.props("partest.cwd") + "/../resources") + + // Implementation follows: + override def extraSettings: String = "-usejavacp" + + override def show(): Unit = { + // redirect err to out, for logging + val prevErr = System.err + System.setErr(System.out) + + try { + // 1 - compile with scaladoc and get the model out + val universe = model.getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")}) + // 2 - check the model generated + testModel(universe.rootPackage) + println("Done.") + } catch { + case e: Exception => + println(e) + e.printStackTrace + } + // set err back to the real err handler + System.setErr(prevErr) + } + + private[this] var settings: Settings = null + + // create a new scaladoc compiler + private[this] def newDocFactory: DocFactory = { + settings = new Settings(_ => ()) + settings.scaladocQuietRun = true // yaay, no more "model contains X documentable templates"! + val args = extraSettings + " " + scaladocSettings + new ScalaDoc.Command((CommandLineParser tokenize (args)), settings) // side-effecting, I think + val docFact = new DocFactory(new ConsoleReporter(settings), settings) + docFact + } + + // compile with scaladoc and output the result + def model: Option[Universe] = newDocFactory.makeUniverse(Right(code)) + + // so we don't get the newSettings warning + override def isDebug = false + + + // finally, enable easy navigation inside the entities + object access { + + implicit class TemplateAccess(tpl: DocTemplateEntity) { + def _class(name: String): DocTemplateEntity = getTheFirst(_classes(name), tpl.qualifiedName + ".class(" + name + ")") + def _classes(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case c: DocTemplateEntity with Class => c}) + + def _classMbr(name: String): MemberTemplateEntity = getTheFirst(_classesMbr(name), tpl.qualifiedName + ".classMember(" + name + ")") + def _classesMbr(name: String): List[MemberTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case c: MemberTemplateEntity if c.isClass => c}) + + def _trait(name: String): DocTemplateEntity = getTheFirst(_traits(name), tpl.qualifiedName + ".trait(" + name + ")") + def _traits(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case t: DocTemplateEntity with Trait => t}) + + def _traitMbr(name: String): MemberTemplateEntity = getTheFirst(_traitsMbr(name), tpl.qualifiedName + ".traitMember(" + name + ")") + def _traitsMbr(name: String): List[MemberTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case t: MemberTemplateEntity if t.isTrait => t}) + + def _object(name: String): DocTemplateEntity = getTheFirst(_objects(name), tpl.qualifiedName + ".object(" + name + ")") + def _objects(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case o: DocTemplateEntity with Object => o}) + + def _objectMbr(name: String): MemberTemplateEntity = getTheFirst(_objectsMbr(name), tpl.qualifiedName + ".objectMember(" + name + ")") + def _objectsMbr(name: String): List[MemberTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case o: MemberTemplateEntity if o.isObject => o}) + + def _method(name: String): Def = getTheFirst(_methods(name), tpl.qualifiedName + ".method(" + name + ")") + def _methods(name: String): List[Def] = tpl.methods.filter(_.name == name) + + def _value(name: String): Val = getTheFirst(_values(name), tpl.qualifiedName + ".value(" + name + ")") + def _values(name: String): List[Val] = tpl.values.filter(_.name == name) + + def _conversion(name: String): ImplicitConversion = getTheFirst(_conversions(name), tpl.qualifiedName + ".conversion(" + name + ")") + def _conversions(name: String): List[ImplicitConversion] = tpl.conversions.filter(_.conversionQualifiedName == name) + + def _absType(name: String): MemberEntity = getTheFirst(_absTypes(name), tpl.qualifiedName + ".abstractType(" + name + ")") + def _absTypes(name: String): List[MemberEntity] = tpl.members.filter(mbr => mbr.name == name && mbr.isAbstractType) + + def _absTypeTpl(name: String): DocTemplateEntity = getTheFirst(_absTypeTpls(name), tpl.qualifiedName + ".abstractType(" + name + ")") + def _absTypeTpls(name: String): List[DocTemplateEntity] = tpl.members.collect({ case dtpl: DocTemplateEntity with AbstractType if dtpl.name == name => dtpl }) + + def _aliasType(name: String): MemberEntity = getTheFirst(_aliasTypes(name), tpl.qualifiedName + ".aliasType(" + name + ")") + def _aliasTypes(name: String): List[MemberEntity] = tpl.members.filter(mbr => mbr.name == name && mbr.isAliasType) + + def _aliasTypeTpl(name: String): DocTemplateEntity = getTheFirst(_aliasTypeTpls(name), tpl.qualifiedName + ".aliasType(" + name + ")") + def _aliasTypeTpls(name: String): List[DocTemplateEntity] = tpl.members.collect({ case dtpl: DocTemplateEntity with AliasType if dtpl.name == name => dtpl }) + } + + trait WithMembers { + def members: List[MemberEntity] + def _member(name: String): MemberEntity = getTheFirst(_members(name), this.toString + ".member(" + name + ")") + def _members(name: String): List[MemberEntity] = members.filter(_.name == name) + } + implicit class PackageAccess(pack: Package) extends TemplateAccess(pack) { + def _package(name: String): Package = getTheFirst(_packages(name), pack.qualifiedName + ".package(" + name + ")") + def _packages(name: String): List[Package] = pack.packages.filter(_.name == name) + } + implicit class DocTemplateEntityMembers(val underlying: DocTemplateEntity) extends WithMembers { + def members = underlying.members + } + implicit class ImplicitConversionMembers(val underlying: ImplicitConversion) extends WithMembers { + def members = underlying.members + } + + def getTheFirst[T](list: List[T], expl: String): T = list.length match { + case 1 => list.head + case 0 => sys.error("Error getting " + expl + ": No such element.") + case _ => sys.error("Error getting " + expl + ": " + list.length + " elements with this name. " + + "All elements in list: [" + list.map({ + case ent: Entity => ent.kind + " " + ent.qualifiedName + case other => other.toString + }).mkString(", ") + "]") + } + + def extractCommentText(c: Any) = { + def extractText(body: Any): String = body match { + case s: String => s + case s: Seq[_] => s.toList.map(extractText(_)).mkString + case p: Product => p.productIterator.toList.map(extractText(_)).mkString + case _ => "" + } + c match { + case c: Comment => + extractText(c.body) + case b: Body => + extractText(b) + } + } + + def countLinks(c: Comment, p: EntityLink => Boolean) = { + def countLinks(body: Any): Int = body match { + case el: EntityLink if p(el) => 1 + case s: Seq[_] => s.toList.map(countLinks(_)).sum + case p: Product => p.productIterator.toList.map(countLinks(_)).sum + case _ => 0 + } + countLinks(c.body) + } + + def testDiagram(doc: DocTemplateEntity, diag: Option[Diagram], nodes: Int, edges: Int) = { + assert(diag.isDefined, doc.qualifiedName + " diagram missing") + assert(diag.get.nodes.length == nodes, + doc.qualifiedName + "'s diagram: node count " + diag.get.nodes.length + " == " + nodes) + assert(diag.get.edges.map(_._2.length).sum == edges, + doc.qualifiedName + "'s diagram: edge count " + diag.get.edges.length + " == " + edges) + } + } +} -- cgit v1.2.3