summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Aliases.scala5
-rw-r--r--src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala15
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Context.scala8
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Enclosures.scala3
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Evals.scala2
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Exprs.scala8
-rw-r--r--src/compiler/scala/reflect/macros/runtime/FrontEnds.scala26
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Infrastructure.scala32
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Parsers.scala5
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Reifiers.scala2
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Settings.scala35
-rw-r--r--src/compiler/scala/reflect/macros/runtime/TypeTags.scala9
-rw-r--r--src/compiler/scala/reflect/reify/Reifier.scala2
-rw-r--r--src/compiler/scala/reflect/reify/utils/Extractors.scala18
-rw-r--r--src/compiler/scala/reflect/reify/utils/NodePrinters.scala2
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala6
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala10
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala37
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala5
-rw-r--r--src/compiler/scala/tools/nsc/doc/Settings.scala22
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala3
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Template.scala50
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.js158
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js5442
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js27
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/Entity.scala5
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/LinkTo.scala8
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala133
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala17
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala54
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala13
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala12
-rw-r--r--src/compiler/scala/tools/nsc/settings/Warnings.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala10
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala52
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Checkable.scala284
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala97
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Modes.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala24
-rw-r--r--src/compiler/scala/tools/reflect/FrontEnd.scala50
-rw-r--r--src/compiler/scala/tools/reflect/FrontEnds.scala88
-rw-r--r--src/compiler/scala/tools/reflect/StdTags.scala8
-rw-r--r--src/compiler/scala/tools/reflect/ToolBox.scala3
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala20
-rw-r--r--src/compiler/scala/tools/reflect/package.scala90
57 files changed, 971 insertions, 5987 deletions
diff --git a/src/compiler/scala/reflect/macros/runtime/Aliases.scala b/src/compiler/scala/reflect/macros/runtime/Aliases.scala
index 30e72997f7..ff870e728e 100644
--- a/src/compiler/scala/reflect/macros/runtime/Aliases.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Aliases.scala
@@ -10,17 +10,20 @@ trait Aliases {
override type TermName = universe.TermName
override type TypeName = universe.TypeName
override type Tree = universe.Tree
- // override type Position = universe.Position
+ override type Position = universe.Position
override type Scope = universe.Scope
override type Modifiers = universe.Modifiers
override type Expr[+T] = universe.Expr[T]
override val Expr = universe.Expr
+ def Expr[T: WeakTypeTag](tree: Tree): Expr[T] = universe.Expr[T](mirror, universe.FixedMirrorTreeCreator(mirror, tree))
override type WeakTypeTag[T] = universe.WeakTypeTag[T]
override type TypeTag[T] = universe.TypeTag[T]
override val WeakTypeTag = universe.WeakTypeTag
override val TypeTag = universe.TypeTag
+ def WeakTypeTag[T](tpe: Type): WeakTypeTag[T] = universe.WeakTypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
+ def TypeTag[T](tpe: Type): TypeTag[T] = universe.TypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
override def weakTypeTag[T](implicit attag: WeakTypeTag[T]) = attag
override def typeTag[T](implicit ttag: TypeTag[T]) = ttag
override def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe
diff --git a/src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala b/src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala
deleted file mode 100644
index 78fb7100b0..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait CapturedVariables {
- self: Context =>
-
- import mirror._
- import universe._
-
- def captureVariable(vble: Symbol): Unit = universe.captureVariable(vble)
-
- def referenceCapturedVariable(vble: Symbol): Tree = universe.referenceCapturedVariable(vble)
-
- def capturedVariableType(vble: Symbol): Type = universe.capturedVariableType(vble)
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/macros/runtime/Context.scala b/src/compiler/scala/reflect/macros/runtime/Context.scala
index 8bbfef44a3..8e8b0fcea1 100644
--- a/src/compiler/scala/reflect/macros/runtime/Context.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Context.scala
@@ -5,24 +5,20 @@ import scala.tools.nsc.Global
abstract class Context extends scala.reflect.macros.Context
with Aliases
- with CapturedVariables
- with Infrastructure
with Enclosures
with Names
with Reifiers
with FrontEnds
- with Settings
+ with Infrastructure
with Typers
with Parsers
- with Exprs
- with TypeTags
with Evals
with ExprUtils
with Traces {
val universe: Global
- val mirror: MirrorOf[universe.type] = universe.rootMirror
+ val mirror: universe.Mirror = universe.rootMirror
val callsiteTyper: universe.analyzer.Typer
diff --git a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
index b5c988ca83..be5f2dbe83 100644
--- a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
@@ -19,5 +19,6 @@ trait Enclosures {
val enclosingMacros: List[Context] = this :: universe.analyzer.openMacros // include self
val enclosingMethod: Tree = site.enclMethod.tree
val enclosingPosition: Position = if (enclPoses.isEmpty) NoPosition else enclPoses.head.pos
- val enclosingUnit: CompilationUnit = currentRun.currentUnit
+ val enclosingUnit: CompilationUnit = universe.currentRun.currentUnit
+ val enclosingRun: Run = universe.currentRun
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Evals.scala b/src/compiler/scala/reflect/macros/runtime/Evals.scala
index acafeb5b02..1f7b5f2ff1 100644
--- a/src/compiler/scala/reflect/macros/runtime/Evals.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Evals.scala
@@ -7,7 +7,7 @@ import scala.tools.reflect.ToolBox
trait Evals {
self: Context =>
- private lazy val evalMirror = ru.runtimeMirror(libraryClassLoader)
+ private lazy val evalMirror = ru.runtimeMirror(universe.analyzer.macroClassloader)
private lazy val evalToolBox = evalMirror.mkToolBox()
private lazy val evalImporter = ru.mkImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }]
diff --git a/src/compiler/scala/reflect/macros/runtime/Exprs.scala b/src/compiler/scala/reflect/macros/runtime/Exprs.scala
deleted file mode 100644
index ebf8fa2b96..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/Exprs.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait Exprs {
- self: Context =>
-
- def Expr[T: WeakTypeTag](tree: Tree): Expr[T] = universe.Expr[T](mirror, universe.FixedMirrorTreeCreator(mirror, tree))
-}
diff --git a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala b/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
index 9f328eb82b..a6a198e1b4 100644
--- a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
+++ b/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
@@ -1,28 +1,9 @@
package scala.reflect.macros
package runtime
-trait FrontEnds extends scala.tools.reflect.FrontEnds {
+trait FrontEnds {
self: Context =>
- import universe._
- import mirror._
-
- override type Position = universe.Position
-
- def frontEnd: FrontEnd = wrapReporter(universe.reporter)
-
- def setFrontEnd(frontEnd: FrontEnd): this.type = {
- universe.reporter = wrapFrontEnd(frontEnd)
- this
- }
-
- def withFrontEnd[T](frontEnd: FrontEnd)(op: => T): T = {
- val old = universe.reporter
- setFrontEnd(frontEnd)
- try op
- finally universe.reporter = old
- }
-
def echo(pos: Position, msg: String): Unit = universe.reporter.echo(pos, msg)
def info(pos: Position, msg: String, force: Boolean): Unit = universe.reporter.info(pos, msg, force)
@@ -36,9 +17,4 @@ trait FrontEnds extends scala.tools.reflect.FrontEnds {
def error(pos: Position, msg: String): Unit = callsiteTyper.context.error(pos, msg)
def abort(pos: Position, msg: String): Nothing = throw new AbortMacroException(pos, msg)
-
- def interactive(): Unit = universe.reporter match {
- case reporter: scala.tools.nsc.reporters.AbstractReporter => reporter.displayPrompt()
- case _ => ()
- }
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
index a8cc61e0f9..7781693822 100644
--- a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
@@ -1,36 +1,16 @@
package scala.reflect.macros
package runtime
-import scala.tools.nsc.util.ScalaClassLoader
-
trait Infrastructure {
self: Context =>
- val forJVM: Boolean = universe.forJVM
-
- val forMSIL: Boolean = universe.forMSIL
-
- val forInteractive: Boolean = universe.forInteractive
-
- val forScaladoc: Boolean = universe.forScaladoc
-
- val currentRun: Run = universe.currentRun
-
- val libraryClassPath: List[java.net.URL] = universe.classPath.asURLs
-
- lazy val libraryClassLoader: ClassLoader = universe.analyzer.macroClassloader
-
- type Run = universe.Run
-
- object Run extends RunExtractor {
- def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])] = Some(run.currentUnit, run.units.toList)
+ def settings: List[String] = {
+ val us = universe.settings
+ import us._
+ userSetSettings collectFirst { case x: MultiStringSetting if x.name == XmacroSettings.name => x.value } getOrElse Nil
}
- type CompilationUnit = universe.CompilationUnit
-
- object CompilationUnit extends CompilationUnitExtractor {
- def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)] = Some(compilationUnit.source.file.file, compilationUnit.source.content, compilationUnit.body)
- }
+ def compilerSettings: List[String] = universe.settings.recreateArgs
- val currentMacro: Symbol = expandee.symbol
+ def classPath: List[java.net.URL] = global.classPath.asURLs
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Parsers.scala b/src/compiler/scala/reflect/macros/runtime/Parsers.scala
index 5096526fdb..ab9b94ec9f 100644
--- a/src/compiler/scala/reflect/macros/runtime/Parsers.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Parsers.scala
@@ -10,6 +10,7 @@ trait Parsers {
def parse(code: String): Tree =
// todo. provide decent implementation
+ // see `Typers.typedUseCase` for details
try {
import scala.reflect.runtime.{universe => ru}
val parsed = ru.rootMirror.mkToolBox().parse(code)
@@ -17,9 +18,7 @@ trait Parsers {
importer.importTree(parsed)
} catch {
case ToolBoxError(msg, cause) =>
+ // todo. provide a position
throw new ParseError(universe.NoPosition, msg)
}
-
- case class ParseError(val pos: Position, val msg: String) extends Throwable(msg)
- object ParseError extends ParseErrorExtractor
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Reifiers.scala b/src/compiler/scala/reflect/macros/runtime/Reifiers.scala
index f15a7ad502..9e11e5e26d 100644
--- a/src/compiler/scala/reflect/macros/runtime/Reifiers.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Reifiers.scala
@@ -13,8 +13,6 @@ trait Reifiers {
import universe._
import definitions._
- lazy val runtimeUniverse: Tree = gen.mkRuntimeUniverseRef
-
def reifyTree(universe: Tree, mirror: Tree, tree: Tree): Tree = {
assert(ExprClass != NoSymbol)
val result = scala.reflect.reify.`package`.reifyTree(self.universe)(callsiteTyper, universe, mirror, tree)
diff --git a/src/compiler/scala/reflect/macros/runtime/Settings.scala b/src/compiler/scala/reflect/macros/runtime/Settings.scala
deleted file mode 100644
index e9d9a17b81..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/Settings.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait Settings {
- self: Context =>
-
- def settings: List[String] = {
- val us = universe.settings
- import us._
- userSetSettings collectFirst { case x: MultiStringSetting if x.name == XmacroSettings.name => x.value } getOrElse Nil
- }
-
- def compilerSettings: List[String] = universe.settings.recreateArgs
-
- def setCompilerSettings(options: String): this.type =
- // SI-5925: doesn't work with arguments that contains whitespaces
- setCompilerSettings(options.split(" ").toList)
-
- def setCompilerSettings(options: List[String]): this.type = {
- val settings = new scala.tools.nsc.Settings(_ => ())
- settings.copyInto(universe.settings)
- this
- }
-
- def withCompilerSettings[T](options: String)(op: => T): T =
- // SI-5925: doesn't work with arguments that contains whitespaces
- withCompilerSettings(options.split(" ").toList)(op)
-
- def withCompilerSettings[T](options: List[String])(op: => T): T = {
- val old = options
- setCompilerSettings(options)
- try op
- finally setCompilerSettings(old)
- }
-}
diff --git a/src/compiler/scala/reflect/macros/runtime/TypeTags.scala b/src/compiler/scala/reflect/macros/runtime/TypeTags.scala
deleted file mode 100644
index 19b60159de..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/TypeTags.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait TypeTags {
- self: Context =>
-
- def WeakTypeTag[T](tpe: Type): WeakTypeTag[T] = universe.WeakTypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
- def TypeTag[T](tpe: Type): TypeTag[T] = universe.TypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
-}
diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala
index 6f779be17d..f48fcd8ada 100644
--- a/src/compiler/scala/reflect/reify/Reifier.scala
+++ b/src/compiler/scala/reflect/reify/Reifier.scala
@@ -108,7 +108,7 @@ abstract class Reifier extends States
// needs to be solved some day
// maybe try `resetLocalAttrs` once the dust settles
var importantSymbols = Set[Symbol](
- NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorOfClass,
+ NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorClass,
ApiUniverseClass, JavaUniverseClass, ReflectRuntimePackage, ReflectRuntimeCurrentMirror)
importantSymbols ++= importantSymbols map (_.companionSymbol)
importantSymbols ++= importantSymbols map (_.moduleClass)
diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala
index bf211ceec4..b7206eda0e 100644
--- a/src/compiler/scala/reflect/reify/utils/Extractors.scala
+++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala
@@ -19,7 +19,7 @@ trait Extractors {
// $treecreator1.super.<init>();
// ()
// };
- // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Tree = {
+ // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Tree = {
// val $u: U = $m$untyped.universe;
// val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
// $u.Apply($u.Select($u.Select($u.build.This($m.staticPackage("scala.collection.immutable").moduleClass), $u.newTermName("List")), $u.newTermName("apply")), List($u.Literal($u.Constant(1)), $u.Literal($u.Constant(2))))
@@ -32,7 +32,7 @@ trait Extractors {
// $typecreator1.super.<init>();
// ()
// };
- // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Type = {
+ // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Type = {
// val $u: U = $m$untyped.universe;
// val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
// $u.TypeRef($u.ThisType($m.staticPackage("scala.collection.immutable").moduleClass), $m.staticClass("scala.collection.immutable.List"), List($m.staticClass("scala.Int").toTypeConstructor))
@@ -81,7 +81,7 @@ trait Extractors {
DefDef(NoMods,
reifierName,
List(TypeDef(Modifiers(PARAM), tparamu, List(), TypeBoundsTree(Ident(NothingClass), CompoundTypeTree(Template(List(Ident(reifierUniverse), Ident(SingletonClass)), emptyValDef, List()))))),
- List(List(ValDef(Modifiers(PARAM), nme.MIRROR_UNTYPED, AppliedTypeTree(Ident(MirrorOfClass), List(Ident(tparamu))), EmptyTree))),
+ List(List(ValDef(Modifiers(PARAM), nme.MIRROR_UNTYPED, AppliedTypeTree(Ident(MirrorClass), List(Ident(tparamu))), EmptyTree))),
reifierTpt, reifierBody))))
Block(tpec, ApplyConstructor(Ident(tpec.name), List()))
}
@@ -114,7 +114,7 @@ trait Extractors {
case Select(Select(_, tagFlavor), _) => tagFlavor
case Select(_, tagFlavor) => tagFlavor
}
- Some(universe, mirror, SymbolTable(symbolTable1 ++ symbolTable2), rtree, ttpe.tpe, rtpe, tagFlavor == nme.TypeTag)
+ Some((universe, mirror, SymbolTable(symbolTable1 ++ symbolTable2), rtree, ttpe.tpe, rtpe, tagFlavor == nme.TypeTag))
case _ =>
None
}
@@ -139,7 +139,7 @@ trait Extractors {
case Select(Select(_, tagFlavor), _) => tagFlavor
case Select(_, tagFlavor) => tagFlavor
}
- Some(universe, mirror, SymbolTable(symtab), ttpe.tpe, rtpe, tagFlavor == nme.TypeTag)
+ Some((universe, mirror, SymbolTable(symtab), ttpe.tpe, rtpe, tagFlavor == nme.TypeTag))
case _ =>
None
}
@@ -160,9 +160,9 @@ trait Extractors {
object FreeDef {
def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match {
case FreeTermDef(uref, name, binding, flags, origin) =>
- Some(uref, name, binding, flags, origin)
+ Some((uref, name, binding, flags, origin))
case FreeTypeDef(uref, name, binding, flags, origin) =>
- Some(uref, name, binding, flags, origin)
+ Some((uref, name, binding, flags, origin))
case _ =>
None
}
@@ -207,7 +207,7 @@ trait Extractors {
def unapply(tree: Tree): Option[(Tree, TermName)] = tree match {
case Apply(Select(Select(uref @ Ident(_), build), ident), List(Ident(name: TermName)))
if build == nme.build && ident == nme.Ident && name.startsWith(nme.REIFY_FREE_PREFIX) =>
- Some(uref, name)
+ Some((uref, name))
case _ =>
None
}
@@ -226,7 +226,7 @@ trait Extractors {
Literal(Constant(isClass: Boolean)))))
if uref1.name == nme.UNIVERSE_SHORT && build1 == nme.build && newNestedSymbol == nme.newNestedSymbol &&
uref2.name == nme.UNIVERSE_SHORT && build2 == nme.build && flagsFromBits == nme.flagsFromBits =>
- Some(uref1, name, flags, isClass)
+ Some((uref1, name, flags, isClass))
case _ =>
None
}
diff --git a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
index f0480e0699..000e500c69 100644
--- a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
+++ b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
@@ -75,7 +75,7 @@ trait NodePrinters {
val printout = scala.collection.mutable.ListBuffer[String]();
printout += universe.trim
- if (mirrorIsUsed) printout += mirror.replace("MirrorOf[", "scala.reflect.api.MirrorOf[").trim
+ if (mirrorIsUsed) printout += mirror.replace("Mirror[", "scala.reflect.api.Mirror[").trim
val imports = scala.collection.mutable.ListBuffer[String]();
imports += nme.UNIVERSE_SHORT
// if (buildIsUsed) imports += nme.build
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index 6d3fd2e09e..5a2d5ef165 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -23,7 +23,7 @@ trait CompilationUnits { self: Global =>
/** One unit of compilation that has been submitted to the compiler.
* It typically corresponds to a single file of source code. It includes
* error-reporting hooks. */
- class CompilationUnit(val source: SourceFile) {
+ class CompilationUnit(val source: SourceFile) extends CompilationUnitContextApi {
/** the fresh name creator */
var fresh: FreshNameCreator = new FreshNameCreator.Default
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 58fcee4b30..708824ede1 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1079,12 +1079,12 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
* of what file was being compiled when it broke. Since I really
* really want to know, this hack.
*/
- private var lastSeenSourceFile: SourceFile = NoSourceFile
+ protected var lastSeenSourceFile: SourceFile = NoSourceFile
/** Let's share a lot more about why we crash all over the place.
* People will be very grateful.
*/
- private var lastSeenContext: analyzer.Context = null
+ protected var lastSeenContext: analyzer.Context = null
/** The currently active run
*/
@@ -1204,7 +1204,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** A Run is a single execution of the compiler on a sets of units
*/
- class Run {
+ class Run extends RunContextApi {
/** Have been running into too many init order issues with Run
* during erroneous conditions. Moved all these vals up to the
* top of the file so at least they're not trivially null.
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index eaee39d7e6..a7da857429 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1750,7 +1750,7 @@ self =>
in.nextToken()
if (in.token == SUBTYPE || in.token == SUPERTYPE) wildcardType(start)
else atPos(start) { Bind(tpnme.WILDCARD, EmptyTree) }
- case IDENTIFIER if treeInfo.isVariableName(in.name) =>
+ case IDENTIFIER if nme.isVariableName(in.name) =>
atPos(start) { Bind(identForType(), EmptyTree) }
case _ =>
typ()
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index a1785e5262..69091e4880 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -360,7 +360,7 @@ trait Scanners extends ScannersCommon {
if (ch == '"' && token == IDENTIFIER)
token = INTERPOLATIONID
case '<' => // is XMLSTART?
- def fetchLT = {
+ def fetchLT() = {
val last = if (charOffset >= 2) buf(charOffset - 2) else ' '
nextChar()
last match {
@@ -389,7 +389,7 @@ trait Scanners extends ScannersCommon {
getOperatorRest()
}
case '0' =>
- def fetchZero = {
+ def fetchZero() = {
putChar(ch)
nextChar()
if (ch == 'x' || ch == 'X') {
@@ -416,7 +416,7 @@ trait Scanners extends ScannersCommon {
case '`' =>
getBackquotedIdent()
case '\"' =>
- def fetchDoubleQuote = {
+ def fetchDoubleQuote() = {
if (token == INTERPOLATIONID) {
nextRawChar()
if (ch == '\"') {
@@ -452,7 +452,7 @@ trait Scanners extends ScannersCommon {
}
fetchDoubleQuote
case '\'' =>
- def fetchSingleQuote = {
+ def fetchSingleQuote() = {
nextChar()
if (isIdentifierStart(ch))
charLitOr(getIdentRest)
@@ -500,7 +500,7 @@ trait Scanners extends ScannersCommon {
nextChar()
}
case _ =>
- def fetchOther = {
+ def fetchOther() = {
if (ch == '\u21D2') {
nextChar(); token = ARROW
} else if (ch == '\u2190') {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 5a5059d58c..f9eeb41e6d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -832,15 +832,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
*
* The contents of that attribute are determined by the `String[] exceptions` argument to ASM's ClassVisitor.visitMethod()
* This method returns such list of internal names.
- *
*/
- def getExceptions(excs: List[AnnotationInfo]): List[String] = {
- for (AnnotationInfo(tp, List(exc), _) <- excs.distinct if tp.typeSymbol == ThrowsClass)
- yield {
- val Literal(const) = exc
- javaName(const.typeValue.typeSymbol)
- }
- }
+ def getExceptions(excs: List[AnnotationInfo]): List[String] =
+ for (ThrownException(exc) <- excs.distinct)
+ yield javaName(exc)
/** Whether an annotation should be emitted as a Java annotation
* .initialize: if 'annot' is read from pickle, atp might be un-initialized
@@ -2407,7 +2402,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
(instr.category: @scala.annotation.switch) match {
case icodes.localsCat =>
- def genLocalInstr = (instr: @unchecked) match {
+ def genLocalInstr() = (instr: @unchecked) match {
case THIS(_) => jmethod.visitVarInsn(Opcodes.ALOAD, 0)
case LOAD_LOCAL(local) => jcode.load(indexOf(local), local.kind)
case STORE_LOCAL(local) => jcode.store(indexOf(local), local.kind)
@@ -2440,7 +2435,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
genLocalInstr
case icodes.stackCat =>
- def genStackInstr = (instr: @unchecked) match {
+ def genStackInstr() = (instr: @unchecked) match {
case LOAD_MODULE(module) =>
// assert(module.isModule, "Expected module: " + module)
@@ -2468,7 +2463,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
case icodes.arilogCat => genPrimitive(instr.asInstanceOf[CALL_PRIMITIVE].primitive, instr.pos)
case icodes.castsCat =>
- def genCastInstr = (instr: @unchecked) match {
+ def genCastInstr() = (instr: @unchecked) match {
case IS_INSTANCE(tpe) =>
val jtyp: asm.Type =
@@ -2498,7 +2493,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
genCastInstr
case icodes.objsCat =>
- def genObjsInstr = (instr: @unchecked) match {
+ def genObjsInstr() = (instr: @unchecked) match {
case BOX(kind) =>
val MethodNameAndType(mname, mdesc) = jBoxTo(kind)
@@ -2518,7 +2513,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
genObjsInstr
case icodes.fldsCat =>
- def genFldsInstr = (instr: @unchecked) match {
+ def genFldsInstr() = (instr: @unchecked) match {
case lf @ LOAD_FIELD(field, isStatic) =>
var owner = javaName(lf.hostClass)
@@ -2539,7 +2534,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
genFldsInstr
case icodes.mthdsCat =>
- def genMethodsInstr = (instr: @unchecked) match {
+ def genMethodsInstr() = (instr: @unchecked) match {
/** Special handling to access native Array.clone() */
case call @ CALL_METHOD(definitions.Array_clone, Dynamic) =>
@@ -2552,7 +2547,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
genMethodsInstr
case icodes.arraysCat =>
- def genArraysInstr = (instr: @unchecked) match {
+ def genArraysInstr() = (instr: @unchecked) match {
case LOAD_ARRAY_ITEM(kind) => jcode.aload(kind)
case STORE_ARRAY_ITEM(kind) => jcode.astore(kind)
case CREATE_ARRAY(elem, 1) => jcode newarray elem
@@ -2561,7 +2556,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
genArraysInstr
case icodes.jumpsCat =>
- def genJumpInstr = (instr: @unchecked) match {
+ def genJumpInstr() = (instr: @unchecked) match {
case sw @ SWITCH(tagss, branches) =>
assert(branches.length == tagss.length + 1, sw)
@@ -2691,7 +2686,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
genJumpInstr
case icodes.retCat =>
- def genRetInstr = (instr: @unchecked) match {
+ def genRetInstr() = (instr: @unchecked) match {
case RETURN(kind) => jcode emitRETURN kind
case THROW(_) => emit(Opcodes.ATHROW)
}
@@ -2781,7 +2776,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
case Negation(kind) => jcode.neg(kind)
case Arithmetic(op, kind) =>
- def genArith = {
+ def genArith() = {
op match {
case ADD => jcode.add(kind)
@@ -2811,7 +2806,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
// TODO GenICode uses `toTypeKind` to define that elem, `toValueTypeKind` would be needed instead.
// TODO How about adding some asserts to Logical and similar ones to capture the remaining constraint (UNIT not allowed).
case Logical(op, kind) =>
- def genLogical = op match {
+ def genLogical() = op match {
case AND =>
kind match {
case LONG => emit(Opcodes.LAND)
@@ -2840,7 +2835,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
genLogical
case Shift(op, kind) =>
- def genShift = op match {
+ def genShift() = op match {
case LSL =>
kind match {
case LONG => emit(Opcodes.LSHL)
@@ -2869,7 +2864,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
genShift
case Comparison(op, kind) =>
- def genCompare = op match {
+ def genCompare() = op match {
case CMP =>
(kind: @unchecked) match {
case LONG => emit(Opcodes.LCMP)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 62c281b82f..cb6156c59c 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -606,11 +606,10 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
// put some random value; the actual number is determined at the end
buf putShort 0xbaba.toShort
- for (AnnotationInfo(tp, List(exc), _) <- excs.distinct if tp.typeSymbol == ThrowsClass) {
- val Literal(const) = exc
+ for (ThrownException(exc) <- excs.distinct) {
buf.putShort(
cpool.addClass(
- javaName(const.typeValue.typeSymbol)).shortValue)
+ javaName(exc)).shortValue)
nattr += 1
}
diff --git a/src/compiler/scala/tools/nsc/doc/Settings.scala b/src/compiler/scala/tools/nsc/doc/Settings.scala
index dbbc573299..64a376b96e 100644
--- a/src/compiler/scala/tools/nsc/doc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/doc/Settings.scala
@@ -194,6 +194,12 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_))
"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)",
+ "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)"
@@ -238,6 +244,22 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_))
}
}
+ // TODO: Enable scaladoc to scoop up the package list from another scaladoc site, just as javadoc does
+ // -external-urls 'http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library'
+ // should trigger scaldoc to fetch the package-list file. The steps necessary:
+ // 1 - list all packages generated in scaladoc in the package-list file, exactly as javadoc:
+ // see http://docs.oracle.com/javase/6/docs/api/package-list for http://docs.oracle.com/javase/6/docs/api
+ // 2 - download the file and add the packages to the list
+ lazy val extUrlMapping: Map[String, String] = (Map.empty[String, String] /: docExternalUrls.value) {
+ case (map, binding) =>
+ val idx = binding indexOf "="
+ val pkgs = binding substring (0, idx) split ":"
+ var url = binding substring (idx + 1)
+ val index = "/index.html"
+ url = if (url.endsWith(index)) url else url + index
+ map ++ (pkgs map (_ -> url))
+ }
+
/**
* 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. :)
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
index f7c5611b8a..2c719e5d70 100644
--- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -138,7 +138,8 @@ abstract class HtmlPage extends Page { thisPage =>
<span class="extmbr" name={ mbr.qualifiedName }>{ inlineToHtml(text) }</span>
case Tooltip(tooltip) =>
<span class="extype" name={ tooltip }>{ inlineToHtml(text) }</span>
- // TODO: add case LinkToExternal here
+ case LinkToExternal(name, url) =>
+ <a href={ url } class="extype" target="_top">{ inlineToHtml(text) }</a>
case NoLink =>
inlineToHtml(text)
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
index d4e52ba120..919a45aefc 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
@@ -41,7 +41,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
<script type="text/javascript" src={ relativeLinkTo{List("jquery-ui.js", "lib")} }></script>
<script type="text/javascript" src={ relativeLinkTo{List("template.js", "lib")} }></script>
<script type="text/javascript" src={ relativeLinkTo{List("tools.tooltip.js", "lib")} }></script>
- { if (universe.settings.docDiagrams.isSetByUser) {
+ { if (universe.settings.docDiagrams.value) {
<script type="text/javascript" src={ relativeLinkTo{List("modernizr.custom.js", "lib")} }></script>
<script type="text/javascript" src={ relativeLinkTo{List("diagrams.js", "lib")} } id="diagrams-js"></script>
} else NodeSeq.Empty }
@@ -289,6 +289,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
fullComment={ if(memberComment.filter(_.label=="div").isEmpty) "no" else "yes" }
group={ mbr.group }>
<a id={ mbr.signature }/>
+ <a id={ mbr.signatureCompat }/>
{ signature(mbr, false) }
{ memberComment }
</li>
@@ -645,17 +646,28 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
case _ => NodeSeq.Empty
}
- val typeHierarchy = if (s.docDiagrams.isSetByUser) mbr match {
- case dtpl: DocTemplateEntity if isSelf && !isReduced =>
- makeDiagramHtml(dtpl, dtpl.inheritanceDiagram, "Type Hierarchy", "inheritance-diagram")
- case _ => NodeSeq.Empty
- } else NodeSeq.Empty // diagrams not generated
+ def createDiagram(f: DocTemplateEntity => Option[Diagram], description: String, id: String): NodeSeq =
+ if (s.docDiagrams.value) mbr match {
+ case dtpl: DocTemplateEntity if isSelf && !isReduced =>
+ val diagram = f(dtpl)
+ if (diagram.isDefined) {
+ val s = universe.settings
+ val diagramSvg = generator.generate(diagram.get, tpl, this)
+ if (diagramSvg != NodeSeq.Empty) {
+ <div class="toggleContainer block diagram-container" id={ id + "-container"}>
+ <span class="toggle diagram-link">{ description }</span>
+ <a href="http://docs.scala-lang.org/overviews/scaladoc/usage.html#diagrams" target="_blank" class="diagram-help">Learn more about scaladoc diagrams</a>
+ <div class="diagram" id={ id }>{
+ diagramSvg
+ }</div>
+ </div>
+ } else NodeSeq.Empty
+ } else NodeSeq.Empty
+ case _ => NodeSeq.Empty
+ } else NodeSeq.Empty // diagrams not generated
- val contentHierarchy = if (s.docDiagrams.isSetByUser) mbr match {
- case dtpl: DocTemplateEntity if isSelf && !isReduced =>
- makeDiagramHtml(dtpl, dtpl.contentDiagram, "Content Hierarchy", "content-diagram")
- case _ => NodeSeq.Empty
- } else NodeSeq.Empty // diagrams not generated
+ val typeHierarchy = createDiagram(_.inheritanceDiagram, "Type Hierarchy", "inheritance-diagram")
+ val contentHierarchy = createDiagram(_.contentDiagram, "Content Hierarchy", "content-diagram")
memberComment ++ paramComments ++ attributesBlock ++ linearization ++ subclasses ++ typeHierarchy ++ contentHierarchy
}
@@ -946,22 +958,6 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
scala.xml.Text(ub.typeParamName + " is a subclass of " + ub.upperBound.name + " (" + ub.typeParamName + " <: ") ++
typeToHtml(ub.upperBound, true) ++ scala.xml.Text(")")
}
-
- def makeDiagramHtml(tpl: DocTemplateEntity, diagram: Option[Diagram], description: String, id: String) = {
- if (diagram.isDefined) {
- val s = universe.settings
- val diagramSvg = generator.generate(diagram.get, tpl, this)
- if (diagramSvg != NodeSeq.Empty) {
- <div class="toggleContainer block diagram-container" id={ id + "-container"}>
- <span class="toggle diagram-link">{ description }</span>
- <a href="http://docs.scala-lang.org/overviews/scaladoc/usage.html#diagrams" target="_blank" class="diagram-help">Learn more about scaladoc diagrams</a>
- <div class="diagram" id={ id }>{
- diagramSvg
- }</div>
- </div>
- } else NodeSeq.Empty
- } else NodeSeq.Empty
- }
}
object Template {
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.js b/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.js
index 16ad06c5ac..7c24308023 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.js
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.js
@@ -1,4 +1,154 @@
-/*! jQuery v1.7.2 jquery.com | jquery.org/license */
-(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return 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(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.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):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.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,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(
-a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(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(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(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){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f
-.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[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","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
+e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
+j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
+"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
+true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
+Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
+(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
+a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
+"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return 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(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
+function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
+c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
+L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
+"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
+d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
+a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
+!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
+true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
+parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
+false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
+s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
+applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
+else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
+a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
+w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
+cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
+i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
+" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
+this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
+e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
+c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
+a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
+function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
+k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
+C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
+null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
+e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
+f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
+if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
+"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
+a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
+isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
+{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
+if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
+e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
+"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
+d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
+!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
+toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
+u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
+function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
+if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
+t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
+g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
+for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
+1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
+relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
+l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
+h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
+CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
+g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
+text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
+setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
+h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
+m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
+"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
+h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
+!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
+h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
+q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
+if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
+(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
+function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
+gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
+c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
+{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
+"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
+d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
+a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
+1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
+a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
+""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
+this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
+u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
+1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
+return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
+""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
+c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
+c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
+function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
+Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
+"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
+a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
+a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
+"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
+serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
+function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
+global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
+e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
+"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
+false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
+false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
+c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
+d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
+g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
+1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
+"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
+if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
+this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
+"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
+animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
+j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
+this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
+"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
+c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
+this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
+this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
+e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
+c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
+function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
+this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
+k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
+f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
+c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
+d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
+f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
+"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
+e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js b/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js
index 4e0c9d75c7..4ab99764ce 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js
@@ -1,5448 +1,18 @@
-/**
- * @preserve jquery.layout 1.3.0 - Release Candidate 30.5
- * $Date: 2012-04-14 08:00:00 (Sat, 14 Apr 2012) $
- * $Rev: 303005 $
+/*
+ * jquery.layout 1.3.0 - Release Candidate 29.3
*
- * Copyright (c) 2012
+ * Copyright (c) 2010
* 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.5
- *
* 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
-;
-function isStr (v) { return $.type(v) === "string"; }
-
-function runPluginCallbacks (Instance, a_fn) {
- if ($.isArray(a_fn))
- for (var i=0, c=a_fn.length; i<c; i++) {
- var fn = a_fn[i];
- try {
- if (isStr(fn)) // 'name' of a function
- fn = eval(fn);
- if ($.isFunction(fn))
- fn( Instance );
- } catch (ex) {}
- }
-};
-
-
-
-/*
- * GENERIC $.layout METHODS - used by all layouts
- */
-$.layout = {
-
- version: "1.3.rc30.5"
-, revision: 0.033005 // 1.3.0 final = 1.0300 - major(n+).minor(nn)+patch(nn+)
-
- // LANGUAGE CUSTOMIZATION
-, language: {
- // Tips and messages for resizers, togglers, custom buttons, etc.
- Open: "Open" // eg: "Open Pane"
- , Close: "Close"
- , Resize: "Resize"
- , Slide: "Slide Open"
- , Pin: "Pin"
- , Unpin: "Un-Pin"
- , noRoomToOpenTip: "Not enough room to show this pane."
- , minSizeWarning: "Panel has reached its minimum size"
- , maxSizeWarning: "Panel has reached its maximum size"
- // Developer error messages
- , pane: "pane" // description of "layout pane element"
- , selector: "selector" // description of "jQuery-selector"
- , errButton: "Error Adding Button \n\nInvalid "
- , errContainerMissing: "UI Layout Initialization Error\n\nThe specified layout-container does not exist."
- , errCenterPaneMissing: "UI Layout Initialization Error\n\nThe center-pane element does not exist.\n\nThe center-pane is a required element."
- , errContainerHeight: "UI Layout Initialization Warning\n\nThe layout-container \"CONTAINER\" has no height.\n\nTherefore the layout is 0-height and hence 'invisible'!"
- }
-
- // can update code here if $.browser is phased out
-, browser: {
- mozilla: !!$.browser.mozilla
- , webkit: !!$.browser.webkit || !!$.browser.safari // webkit = jQ 1.4
- , msie: !!$.browser.msie
- , isIE6: !!$.browser.msie && $.browser.version == 6
- , version: $.browser.version // not used in Layout core, but may be used by plugins
- }
-
- // *PREDEFINED* EFFECTS & DEFAULTS
- // MUST list effect here - OR MUST set an fxSettings option (can be an empty hash: {})
-, effects: {
-
- // Pane Open/Close Animations
- slide: {
- all: { duration: "fast" } // eg: duration: 1000, easing: "easeOutBounce"
- , north: { direction: "up" }
- , south: { direction: "down" }
- , east: { direction: "right"}
- , west: { direction: "left" }
- }
- , drop: {
- all: { duration: "slow" }
- , north: { direction: "up" }
- , south: { direction: "down" }
- , east: { direction: "right"}
- , west: { direction: "left" }
- }
- , scale: {
- all: { duration: "fast" }
- }
- // these are not recommended, but can be used
- , blind: {}
- , clip: {}
- , explode: {}
- , fade: {}
- , fold: {}
- , puff: {}
-
- // Pane Resize Animations
- , size: {
- all: { easing: "swing" }
- }
- }
-
- // INTERNAL CONFIG DATA - DO NOT CHANGE THIS!
-, config: {
- optionRootKeys: "effects,panes,north,south,west,east,center".split(",")
- , allPanes: "north,south,west,east,center".split(",")
- , borderPanes: "north,south,west,east".split(",")
- , oppositeEdge: {
- north: "south"
- , south: "north"
- , east: "west"
- , west: "east"
- }
- // offscreen data
- , offscreenCSS: { left: "-99999px", right: "auto" } // used by hide/close if useOffscreenClose=true
- , offscreenReset: "offscreenReset" // key used for data
- // CSS used in multiple places
- , hidden: { visibility: "hidden" }
- , visible: { visibility: "visible" }
- // layout element settings
- , resizers: {
- cssReq: {
- position: "absolute"
- , padding: 0
- , margin: 0
- , fontSize: "1px"
- , textAlign: "left" // to counter-act "center" alignment!
- , overflow: "hidden" // prevent toggler-button from overflowing
- // SEE $.layout.defaults.zIndexes.resizer_normal
- }
- , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
- background: "#DDD"
- , border: "none"
- }
- }
- , togglers: {
- cssReq: {
- position: "absolute"
- , display: "block"
- , padding: 0
- , margin: 0
- , overflow: "hidden"
- , textAlign: "center"
- , fontSize: "1px"
- , cursor: "pointer"
- , zIndex: 1
- }
- , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
- background: "#AAA"
- }
- }
- , content: {
- cssReq: {
- position: "relative" /* contain floated or positioned elements */
- }
- , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
- overflow: "auto"
- , padding: "10px"
- }
- , cssDemoPane: { // DEMO CSS - REMOVE scrolling from 'pane' when it has a content-div
- overflow: "hidden"
- , padding: 0
- }
- }
- , panes: { // defaults for ALL panes - overridden by 'per-pane settings' below
- cssReq: {
- position: "absolute"
- , margin: 0
- // $.layout.defaults.zIndexes.pane_normal
- }
- , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
- padding: "10px"
- , background: "#FFF"
- , border: "1px solid #BBB"
- , overflow: "auto"
- }
- }
- , north: {
- side: "Top"
- , sizeType: "Height"
- , dir: "horz"
- , cssReq: {
- top: 0
- , bottom: "auto"
- , left: 0
- , right: 0
- , width: "auto"
- // height: DYNAMIC
- }
- }
- , south: {
- side: "Bottom"
- , sizeType: "Height"
- , dir: "horz"
- , cssReq: {
- top: "auto"
- , bottom: 0
- , left: 0
- , right: 0
- , width: "auto"
- // height: DYNAMIC
- }
- }
- , east: {
- side: "Right"
- , sizeType: "Width"
- , dir: "vert"
- , cssReq: {
- left: "auto"
- , right: 0
- , top: "auto" // DYNAMIC
- , bottom: "auto" // DYNAMIC
- , height: "auto"
- // width: DYNAMIC
- }
- }
- , west: {
- side: "Left"
- , sizeType: "Width"
- , dir: "vert"
- , cssReq: {
- left: 0
- , right: "auto"
- , top: "auto" // DYNAMIC
- , bottom: "auto" // DYNAMIC
- , height: "auto"
- // width: DYNAMIC
- }
- }
- , center: {
- dir: "center"
- , cssReq: {
- left: "auto" // DYNAMIC
- , right: "auto" // DYNAMIC
- , top: "auto" // DYNAMIC
- , bottom: "auto" // DYNAMIC
- , height: "auto"
- , width: "auto"
- }
- }
- }
-
- // CALLBACK FUNCTION NAMESPACE - used to store reusable callback functions
-, callbacks: {}
-
-, getParentPaneElem: function (el) {
- // must pass either a container or pane element
- var $el = $(el)
- , layout = $el.data("layout") || $el.data("parentLayout");
- if (layout) {
- var $cont = layout.container;
- // see if this container is directly-nested inside an outer-pane
- if ($cont.data("layoutPane")) return $cont;
- var $pane = $cont.closest("."+ $.layout.defaults.panes.paneClass);
- // if a pane was found, return it
- if ($pane.data("layoutPane")) return $pane;
- }
- return null;
- }
-
-, getParentPaneInstance: function (el) {
- // must pass either a container or pane element
- var $pane = $.layout.getParentPaneElem(el);
- return $pane ? $pane.data("layoutPane") : null;
- }
-
-, getParentLayoutInstance: function (el) {
- // must pass either a container or pane element
- var $pane = $.layout.getParentPaneElem(el);
- return $pane ? $pane.data("parentLayout") : null;
- }
-
-, getEventObject: function (evt) {
- return typeof evt === "object" && evt.stopPropagation ? evt : null;
- }
-, parsePaneName: function (evt_or_pane) {
- // getEventObject() automatically calls .stopPropagation(), WHICH MUST BE DONE!
- var evt = $.layout.getEventObject( evt_or_pane );
- if (evt) {
- // ALWAYS stop propagation of events triggered in Layout!
- evt.stopPropagation();
- return $(this).data("layoutEdge");
- }
- else
- return evt_or_pane;
- }
-
-
- // LAYOUT-PLUGIN REGISTRATION
- // more plugins can added beyond this default list
-, plugins: {
- draggable: !!$.fn.draggable // resizing
- , effects: {
- core: !!$.effects // animimations (specific effects tested by initOptions)
- , slide: $.effects && $.effects.slide // default effect
- }
- }
-
-// arrays of plugin or other methods to be triggered for events in *each layout* - will be passed 'Instance'
-, onCreate: [] // runs when layout is just starting to be created - right after options are set
-, onLoad: [] // runs after layout container and global events init, but before initPanes is called
-, onReady: [] // runs after initialization *completes* - ie, after initPanes completes successfully
-, onDestroy: [] // runs after layout is destroyed
-, onUnload: [] // runs after layout is destroyed OR when page unloads
-, afterOpen: [] // runs after setAsOpen() completes
-, afterClose: [] // runs after setAsClosed() completes
-
- /*
- * GENERIC UTILITY METHODS
- */
-
- // calculate and return the scrollbar width, as an integer
-, scrollbarWidth: function () { return window.scrollbarWidth || $.layout.getScrollbarSize('width'); }
-, scrollbarHeight: function () { return window.scrollbarHeight || $.layout.getScrollbarSize('height'); }
-, getScrollbarSize: function (dim) {
- var $c = $('<div style="position: absolute; top: -10000px; left: -10000px; width: 100px; height: 100px; overflow: scroll;"></div>').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) return {};
- if (!$E.jquery) $E = $($E);
- var CSS = {
- display: $E.css('display')
- , visibility: $E.css('visibility')
- };
- if (force || CSS.display === "none") { // only if not *already hidden*
- $E.css({ display: "block", visibility: "hidden" }); // show element 'invisibly' so can be measured
- return CSS;
- }
- else 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;
- });
-
- 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.<Object>} $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) {
- var
- b = $.layout.borderWidth
- , n = $.layout.cssNum
- ;
- // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed
- if (outerWidth <= 0) return 0;
-
- if (!$.support.boxModel) return outerWidth;
-
- // strip border and padding from outerWidth to get CSS Width
- var 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.<Object>} $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) {
- var
- b = $.layout.borderWidth
- , n = $.layout.cssNum
- ;
- // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed
- if (outerHeight <= 0) return 0;
-
- if (!$.support.boxModel) return outerHeight;
-
- // strip border and padding from outerHeight to get CSS Height
- var 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.<Object>} $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 = $.curCSS($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 $.curCSS(el, b+"Style", true) === "none" ? 0 : (parseInt($.curCSS(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=} [debutOpts={}] 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( <object> )"
- , 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('<li style="padding: 4px 10px; margin: 0; border-top: 1px solid #CCC;">'+ info.replace(/\</g,"&lt;").replace(/\>/g,"&gt;") +'</li>');
- }
-
- function createLog () {
- var pos = $.support.fixedPosition ? 'fixed' : 'absolute'
- , $e = $('<div id="layoutLogger" style="position: '+ pos +'; top: 5px; z-index: 999999; max-width: 25%; overflow: hidden; border: 1px solid #000; border-radius: 5px; background: #FBFBFB; box-shadow: 0 2px 10px rgba(0,0,0,0.3);">'
- + '<div style="font-size: 13px; font-weight: bold; padding: 5px 10px; background: #F6F6F6; border-radius: 5px 5px 0 0; cursor: move;">'
- + '<span style="float: right; padding-left: 7px; cursor: pointer;" title="Remove Console" onclick="$(this).closest(\'#layoutLogger\').remove()">X</span>Layout console.log</div>'
- + '<ul style="font-size: 13px; font-weight: none; list-style: none; margin: 0; padding: 0 0 2px;"></ul>'
- + '</div>'
- ).appendTo("body");
- $e.css('left', $(window).width() - $e.outerWidth() - 5)
- if ($.ui.draggable) $e.draggable({ handle: ':first-child' });
- return $e;
- };
- }
-
-};
-
-var lang = $.layout.language; // alias used in defaults...
-
-// DEFAULT OPTIONS - CHANGE IF DESIRED
-$.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
-, autoBindCustomButtons: false // search for buttons with ui-layout-button class and auto-bind them
-, 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'
- }
-/*
- * 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
- , togglerTip_open: lang.Close // Toggler tool-tip (title)
- , togglerTip_closed: lang.Open // ditto
- , 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
- // TIPS & MESSAGES - also see lang object
- , noRoomToOpenTip: lang.noRoomToOpenTip
- , resizerTip: lang.Resize // Resizer tool-tip (title)
- , sliderTip: lang.Slide // resizer-bar triggers 'sliding' when pane is closed
- , 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
- // 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
- // PANE CALLBACKS
- , triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes
- , triggerEventsDuringLiveResize: true // true = trigger onresize callback REPEATEDLY if livePaneResizing==true
- , 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,"
- + "name,zIndex,scrollToBookmarkOnLoad,showErrorMessages,"
- + "resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay,"
- + "onresizeall,onresizeall_start,onresizeall_end,onload,onunload,autoBindCustomButtons").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"
- }
- /**
- * @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<c; i++) { // skip the last key (data)
- k = a[i];
- if (D.branch[ k ] == undefined) { // child-key does not exist
- if (create) {
- D.branch = D.branch[ k ] = {}; // create child-branch
- }
- else // can't go any farther
- D.branch = {}; // branch is undefined
- }
- else
- D.branch = D.branch[ k ]; // get child-branch
- }
- return D;
- };
- }
- /**
- * @param {Object} opts
- */
-, renameAllOptions: function (opts) {
- var ren = $.layout.backwardCompatibility.renameOptions;
- // rename root (layout) options
- ren( opts );
- // rename 'defaults' to 'panes'
- if (opts.defaults) {
- if (typeof opts.panes !== "object")
- opts.panes = {};
- $.extend(true, opts.panes, opts.defaults);
- delete opts.defaults;
- }
- // rename options in the the options.panes key
- if (opts.panes) ren( opts.panes );
- // rename options inside *each pane key*, eg: options.west
- $.each($.layout.config.allPanes, function (i, pane) {
- if (opts[pane]) ren( opts[pane] );
- });
- return opts;
- }
-};
-
-
-
-/* ============================================================
- * BEGIN WIDGET: $( selector ).layout( {options} );
- * ============================================================
- */
-$.fn.layout = function (opts) {
- var
-
- // local aliases to global data
- browser = $.layout.browser
-, lang = $.layout.language // internal alias
-, _c = $.layout.config
-
- // local aliases to utlity methods
-, cssW = $.layout.cssWidth
-, cssH = $.layout.cssHeight
-, elDims = $.layout.getElementDimensions
-, elCSS = $.layout.getElementCSS
-, evtObj = $.layout.getEventObject
-, evtPane = $.layout.parsePaneName
-
-/**
- * options - populated by initOptions()
- */
-, options = $.extend(true, {}, $.layout.defaults)
-, effects = options.effects = $.extend(true, {}, $.layout.effects)
-
-/**
- * layout-state object
- */
-, state = {
- // generate unique ID to use for event.namespace so can unbind only events added by 'this layout'
- id: "layout"+ $.now() // code uses alias: sID
- , initialized: false
- , container: {} // init all keys
- , north: {}
- , south: {}
- , east: {}
- , west: {}
- , center: {}
- }
-
-/**
- * parent/child-layout pointers
- */
-//, hasParentLayout = false - exists ONLY inside Instance so can be set externally
-, children = {
- north: null
- , south: null
- , east: null
- , west: null
- , center: null
- }
-
-/*
- * ###########################
- * INTERNAL HELPER FUNCTIONS
- * ###########################
- */
-
- /**
- * Manages all internal timers
- */
-, timer = {
- data: {}
- , set: function (s, fn, ms) { timer.clear(s); timer.data[s] = setTimeout(fn, ms); }
- , clear: function (s) { var t=timer.data; if (t[s]) {clearTimeout(t[s]); delete t[s];} }
- }
-
-, _log = function (msg, popup) {
- $.layout.msg( options.name +' / '+ msg, (popup && options.showErrorMessages) );
- }
-
- /**
- * Executes a Callback function after a trigger event, like resize, open or close
- *
- * @param {?string} pane This is passed only so we can pass the 'pane object' to the callback
- * @param {(string|function())} fn Accepts a function name, OR a comma-delimited array: [0]=function name, [1]=argument
- */
-, _runCallbacks = function (evtName, pane, skipBoundEvents) {
- var o = pane ? options[pane] : options
- // names like onopen and onopen_end separate are interchangeable in options...
- , long = evtName + (evtName.match(/_/) ? "" : "_end")
- , short = long.match(/_end$/) ? long.substr(0, long.length - 4) : ""
- , fn = o[long]
- , retVal = "NC" // NC = No Callback
- , args = []
- ;
- if (!fn && short)
- fn = o[short];
-
- // first trigger the callback set in the options
- if (fn) {
- //try {
- // convert function name (string) to function object
- if (isStr( fn )) {
- if (fn.match(/,/)) {
- // function name cannot contain a comma,
- // so must be a function name AND a parameter to pass
- args = fn.split(",")
- , fn = eval(args[0]);
- }
- else // just the name of an external function?
- fn = eval(fn);
- }
- // execute the callback, if exists
- if ($.isFunction( fn )) {
- if (args.length)
- retVal = fn(args[1]); // pass the argument parsed from 'list'
- else if (pane && $Ps[pane])
- // pass data: pane-name, pane-element, pane-state, pane-options, and layout-name
- retVal = fn( pane, $Ps[pane], state[pane], options[pane], options.name );
- else // must be a layout/container callback - pass suitable info
- retVal = fn( Instance, state, options, options.name );
- }
- //}
- //catch (ex) {}
- }
-
- // trigger additional events bound directly to the pane
- if (!skipBoundEvents && retVal !== false) {
- if (pane) { // PANE events can be bound to each pane-elements
- $Ps[pane].triggerHandler('layoutpane'+ long, [ pane, $Ps[pane], state[pane], options[pane], options.name ]);
- if (short)
- $Ps[pane].triggerHandler('layoutpane'+ short, [ pane, $Ps[pane], state[pane], options[pane], options.name ]);
- }
- else // LAYOUT events can be bound to the container-element
- $N.triggerHandler('layout'+ long, [ pane, $Ps[pane], state[pane], options[pane], options.name ]);
- }
-
- // ALWAYS resizeChildLayout after a resize event - even during initialization
- if (evtName === "onresize_end" || evtName === "onsizecontent_end")
- resizeChildLayout(pane);
-
- return retVal;
- }
-
-
- /**
- * cure iframe display issues in IE & other browsers
- */
-, _fixIframe = function (pane) {
- if (browser.mozilla) return; // skip FireFox - it auto-refreshes iframes onShow
- var $P = $Ps[pane];
- // if the 'pane' is an iframe, do it
- if (state[pane].tagName === "IFRAME")
- $P.css(_c.hidden).css(_c.visible);
- else // ditto for any iframes INSIDE the pane
- $P.find('IFRAME').css(_c.hidden).css(_c.visible);
- }
-
- /**
- * @param {string} pane Can accept ONLY a 'pane' (east, west, etc)
- * @param {number=} outerSize (optional) Can pass a width, allowing calculations BEFORE element is resized
- * @return {number} Returns the innerHeight/Width of el by subtracting padding and borders
- */
-, cssSize = function (pane, outerSize) {
- var fn = _c[pane].dir=="horz" ? cssH : cssW;
- return fn($Ps[pane], outerSize);
- }
-
- /**
- * @param {string} pane Can accept ONLY a 'pane' (east, west, etc)
- * @return {Object} Returns hash of minWidth & minHeight
- */
-, cssMinDims = function (pane) {
- // minWidth/Height means CSS width/height = 1px
- var $P = $Ps[pane]
- , dir = _c[pane].dir
- , d = {
- minWidth: 1001 - cssW($P, 1000)
- , minHeight: 1001 - cssH($P, 1000)
- }
- ;
- if (dir === "horz") d.minSize = d.minHeight;
- if (dir === "vert") d.minSize = d.minWidth;
- return d;
- }
-
- // TODO: see if these methods can be made more useful...
- // TODO: *maybe* return cssW/H from these so caller can use this info
-
- /**
- * @param {(string|!Object)} el
- * @param {number=} outerWidth
- * @param {boolean=} [autoHide=false]
- */
-, setOuterWidth = function (el, outerWidth, autoHide) {
- var $E = el, w;
- if (isStr(el)) $E = $Ps[el]; // west
- else if (!el.jquery) $E = $(el);
- w = cssW($E, outerWidth);
- $E.css({ width: w });
- if (w > 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 - adjusted for boxModel & browser
- */
-, 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) {
- if (options.showErrorMessages)
- _log( lang.errCenterPaneMissing, true );
- return false;
- }
-
- // 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} 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'
- }
- , name;
- // 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 <HTML> 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 (o.showErrorMessages && sC.innerHeight < 1)
- _log( lang.errContainerHeight.replace(/CONTAINER/, sC.ref), true );
- }
- }
- } 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), process 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<c; i++) {
- key = data[i];
- delete opts.panes[key]; // OK if does not exist
- }
- // REMOVE any layout-options specified under opts.panes
- data = $.layout.optionsMap.layout;
- for (i=0, c=data.length; i<c; i++) {
- key = data[i];
- delete opts.panes[key]; // OK if does not exist
- }
- }
-
- // MOVE any NON-layout-options to opts.panes
- data = $.layout.optionsMap.layout;
- var rootKeys = $.layout.config.optionRootKeys;
- for (key in opts) {
- val = opts[key];
- if ($.inArray(key, rootKeys) < 0 && $.inArray(key, data) < 0) {
- if (!opts.panes[key])
- opts.panes[key] = $.isPlainObject(val) ? $.extend(true, {}, val) : val;
- delete opts[key]
- }
- }
-
- // START by updating ALL options from opts
- $.extend(true, options, opts);
-
- // CREATE final options (and config) for EACH pane
- $.each(_c.allPanes, function (i, pane) {
-
- // apply 'pane-defaults' to CONFIG.[PANE]
- _c[pane] = $.extend( true, {}, _c.panes, _c[pane] );
-
- d = options.panes;
- o = options[pane];
-
- // center-pane uses SOME keys in defaults.panes branch
- if (pane === 'center') {
- // ONLY copy keys from opts.panes listed in: $.layout.optionsMap.center
- data = $.layout.optionsMap.center; // list of 'center-pane keys'
- for (i=0, c=data.length; i<c; i++) { // loop the list...
- key = data[i];
- // only need to use pane-default if pane-specific value not set
- if (!opts.center[key] && (opts.panes[key] || !o[key]))
- o[key] = d[key]; // pane-default
- }
- }
- else {
- // border-panes use ALL keys in defaults.panes branch
- o = options[pane] = $.extend({}, d, o); // re-apply pane-specific opts AFTER pane-defaults
- createFxOptions( pane );
- // ensure all border-pane-specific base-classes exist
- if (!o.resizerClass) o.resizerClass = "ui-layout-resizer";
- if (!o.togglerClass) o.togglerClass = "ui-layout-toggler";
- }
- // ensure we have base pane-class (ALL panes)
- if (!o.paneClass) o.paneClass = "ui-layout-pane";
- });
-
- // update options.zIndexes if a zIndex-option specified
- var zo = opts.zIndex
- , z = options.zIndexes;
- if (zo > 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
- }
-
- 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(
- {}
- , 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;
- }
-
- // DELETE 'panes' key now that we are done - values were copied to EACH pane
- delete options.panes;
- }
-
- /**
- * 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 () {
- // 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: 'manualSizePane'
- , sizePane: 'manualSizePane'
- , 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]
- , 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] = $("<div></div>")
- // INIT TOGGLER BUTTON
- , $T = I.toggler = (o.closable ? $Ts[pane] = $("<div></div>") : false)
- ;
-
- //if (s.isVisible && o.resizable) ... handled by initResizable
- if (!s.isVisible && o.slidable)
- $R.attr("title", o.sliderTip).css("cursor", o.sliderCursor);
-
- $R // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "paneLeft-resizer"
- .attr("id", (o.paneSelector.substr(0,1)=="#" ? o.paneSelector.substr(1) + "-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", (o.paneSelector.substr(0,1)=="#" ? o.paneSelector.substr(1) + "-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
- $("<span>"+ o.togglerContent_open +"</span>")
- .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
- $("<span>"+ o.togglerContent_closed +"</span>")
- .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.resizerTip)
- .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/)) ? lang.maxSizeWarning : lang.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<c; i++) {
- $M = $Ms.eq(i);
- if ($M.data("layoutMask") === pane)
- $Masks = $Masks.add( $M );
- }
- if ($Masks.length)
- return $Masks;
- else
- return createMasks(pane);
- }
-
- /**
- * createMasks
- *
- * Generates both DIV (ALWAYS used) and IFRAME (optional) elements as masks
- * An IFRAME mask is created *under* the DIV when maskObjects=true, because a DIV cannot mask an applet
- */
-, createMasks = function (pane) {
- var
- $P = $Ps[pane]
- , s = state[pane]
- , o = options[pane]
- , z = options.zIndexes
- //, objMask = o.maskObjects && s.tagName != "IFRAME" // check for option
- , $Masks = $([])
- , isIframe, el, $M, css, i
- ;
- if (!o.maskContents && !o.maskObjects) return $Masks;
- // if o.maskObjects=true, then loop TWICE to create BOTH kinds of mask, else only create a DIV
- for (i=0; i < (o.maskObjects ? 2 : 1); i++) {
- isIframe = o.maskObjects && i==0;
- el = document.createElement( isIframe ? "iframe" : "div" );
- $M = $(el).data("layoutMask", pane); // add data to relate mask to pane
- el.className = "ui-layout-mask ui-layout-mask-"+ pane; // for user styling
- css = el.style;
- // styles common to both DIVs and IFRAMES
- css.display = "block";
- css.position = "absolute";
- if (isIframe) { // IFRAME-only props
- el.frameborder = 0;
- el.src = "about:blank";
- css.opacity = 0;
- css.filter = "Alpha(Opacity='0')";
- css.border = 0;
- }
- // if pane is an IFRAME, then must mask the pane itself
- if (s.tagName == "IFRAME") {
- // NOTE sizing done by a subroutine so can be called during live-resizing
- css.zIndex = z.pane_normal+1; // 1-higher than pane
- $N.append( el ); // append to LAYOUT CONTAINER
- }
- // otherwise put masks *inside the pane* to mask its contents
- else {
- $M.addClass("ui-layout-mask-inside-pane");
- css.zIndex = o.maskZindex || z.content_mask; // usually 1, but customizable
- css.top = 0;
- css.left = 0;
- css.width = "100%";
- css.height = "100%";
- $P.append( el ); // append INSIDE pane element
- }
- // add to return object
- $Masks = $Masks.add( el );
- // add Mask to cached array so can be resized & reused
- $Ms = $Ms.add( el );
- }
- return $Masks;
- }
-
-
- /**
- * Destroy this layout and reset all elements
- *
- * @param {boolean=} [destroyChildren=false] Destory Child-Layouts first?
- */
-, destroy = function (destroyChildren) {
- // UNBIND layout events and remove global object
- $(window).unbind("."+ sID); // resize & unload
- $(document).unbind("."+ sID); // keyDown (hotkeys)
-
- // need to look for parent layout BEFORE we remove the container data, else skips a level
- //var parentPane = Instance.hasParentLayout ? $.layout.getParentPaneInstance( $N ) : null;
-
- // reset layout-container
- $N .clearQueue()
- .removeData("layout")
- .removeData("layoutContainer")
- .removeClass(options.containerClass)
- .unbind("."+ sID) // remove ALL Layout events
- ;
-
- // remove all mask elements that have been created
- $Ms.remove();
-
- // loop all panes to remove layout classes, attributes and bindings
- $.each(_c.allPanes, function (i, pane) {
- removePane( pane, false, true, destroyChildren ); // true = skipResize
- });
-
- // do NOT reset container CSS if is a 'pane' (or 'content') in an outer-layout - ie, THIS layout is 'nested'
- var css = "layoutCSS";
- if ($N.data(css) && !$N.data("layoutRole")) // RESET CSS
- $N.css( $N.data(css) ).removeData(css);
-
- // for full-page layouts, also reset the <HTML> CSS
- if (sC.tagName === "BODY" && ($N = $("html")).data(css)) // RESET <HTML> 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} pane The pane to process
- * @param {boolean=} [remove=false] Remove the DOM element?
- * @param {boolean=} [skipResize=false] Skip calling resizeAll()?
- */
-, 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]
- ;
- //alert( '$P.length = '+ $P.length );
- // 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} 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} 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} 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} 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.togglerTip_closed) // 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} 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.noRoomToOpenTip)
- alert(o.noRoomToOpenTip);
- 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.resizerTip);
- 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.togglerTip_open); // 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} 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.sliderTip : "")
- ;
- }
-
- /**
- * 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.togglerTip_open : ""); // 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} 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} 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]
- , 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);
-
- // if showDebugMessages, log attempts and alert the user of this *non-fatal error*
- if (options.showDebugMessages) {
- if ( tries.length === 1) {
- _log(msg, false);
- _log(lastTry, false);
- }
- _log(thisTry, false);
- }
-
- // 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 (options.showDebugMessages && tries.length > 1)
- _log(msg +'\nSee the Error Console for details.', true);
- }
- }
-
- /**
- * @see initPanes(), sizePane(), resizeAll(), open(), close(), hide()
- * @param {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 != minE)
- sizePane('east', newE, true, force, true); // true = skipCallback/noAnimation - initPanes will handle when done
- if (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
- 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'
- */
- if (pane === "center") { // finished processing midPanes
- var b = $.layout.browser;
- var fix = b.isIE6 || (b.msie && !$.support.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 () {
- 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} 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=} [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=} [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} 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.togglerTip_closed : o.togglerTip_open) // may be blank
- .show();
- }
- /**
- * @param {string} 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} 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 (s.isClosed)
- bindStartSlidingEvent(pane, true);
- }
- /**
- * @param {string} 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} 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.resizerTip);
- }
- /**
- * @param {string} 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} 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({}, 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({}, oPane.options, fx);
- state[pane] = $.extend({}, 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) {
- if (options.showErrorMessages)
- _log( lang.errContainerMissing, true );
- return null;
- };
-
- // 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
- // 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
-
-}
-
-
-
-
-/**
- * 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=} opts
- */
- 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");
-
-var lang = $.layout.language;
-
-/*
- * 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.<Object>} 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.showErrorMessages
- ;
- if (!$E.length) { // element not found
- if (err) $.layout.msg(lang.errButton + lang.selector +": "+ selector, true);
- }
- else if ($.inArray(pane, $.layout.config.borderPanes) < 0) { // invalid 'pane' sepecified
- if (err) $.layout.msg(lang.errButton + lang.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", lang.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", lang.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.<Object>} $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
- pin = inst.options[pane].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 ? lang.Unpin : lang.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(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
+ * $Date: 2010-07-13 08:00:00 (Wed, 14 July 2010) $
+ * $Rev: 30293 $
*/
-$.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
+(function($){$.fn.layout=function(opts){var lang={Pane:"Pane",Open:"Open",Close:"Close",Resize:"Resize",Slide:"Slide Open",Pin:"Pin",Unpin:"Un-Pin",selector:"selector",msgNoRoom:"Not enough room to show this pane.",errContainerMissing:"UI Layout Initialization Error\n\nThe specified layout-container does not exist.",errCenterPaneMissing:"UI Layout Initialization Error\n\nThe center-pane element does not exist.\n\nThe center-pane is a required element.",errContainerHeight:"UI Layout Initialization Warning\n\nThe layout-container \"CONTAINER\" has no height.\n\nTherefore the layout is 0-height and hence 'invisible'!",errButton:"Error Adding Button \n\nInvalid "};var options={name:"",scrollToBookmarkOnLoad:true,resizeWithWindow:true,resizeWithWindowDelay:200,resizeWithWindowMaxDelay:0,onresizeall_start:null,onresizeall_end:null,onload:null,onunload:null,autoBindCustomButtons:false,zIndex:null,defaults:{applyDemoStyles:false,closable:true,resizable:true,slidable:true,initClosed:false,initHidden:false,contentSelector:".ui-layout-content",contentIgnoreSelector:".ui-layout-ignore",findNestedContent:false,paneClass:"ui-layout-pane",resizerClass:"ui-layout-resizer",togglerClass:"ui-layout-toggler",buttonClass:"ui-layout-button",minSize:0,maxSize:0,spacing_open:6,spacing_closed:6,togglerLength_open:50,togglerLength_closed:50,togglerAlign_open:"center",togglerAlign_closed:"center",togglerTip_open:lang.Close,togglerTip_closed:lang.Open,togglerContent_open:"",togglerContent_closed:"",resizerDblClickToggle:true,autoResize:true,autoReopen:true,resizerDragOpacity:1,maskIframesOnResize:true,resizeNestedLayout:true,resizeWhileDragging:false,resizeContentWhileDragging:false,noRoomToOpenTip:lang.msgNoRoom,resizerTip:lang.Resize,sliderTip:lang.Slide,sliderCursor:"pointer",slideTrigger_open:"click",slideTrigger_close:"mouseleave",hideTogglerOnSlide:false,preventQuickSlideClose:!!($.browser.webkit||$.browser.safari),showOverflowOnHover:false,enableCursorHotkey:true,customHotkeyModifier:"SHIFT",fxName:"slide",fxSpeed:null,fxSettings:{},fxOpacityFix:true,triggerEventsOnLoad:false,triggerEventsWhileDragging:true,onshow_start:null,onshow_end:null,onhide_start:null,onhide_end:null,onopen_start:null,onopen_end:null,onclose_start:null,onclose_end:null,onresize_start:null,onresize_end:null,onsizecontent_start:null,onsizecontent_end:null,onswap_start:null,onswap_end:null,ondrag_start:null,ondrag_end:null},north:{paneSelector:".ui-layout-north",size:"auto",resizerCursor:"n-resize",customHotkey:""},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},useStateCookie:false,cookie:{name:"",autoSave:true,autoLoad:true,domain:"",path:"",expires:"",secure:false,keys:"north.size,south.size,east.size,west.size,north.isClosed,south.isClosed,east.isClosed,west.isClosed,north.isHidden,south.isHidden,east.isHidden,west.isHidden"}};var effects={slide:{all:{duration:"fast"},north:{direction:"up"},south:{direction:"down"},east:{direction:"right"},west:{direction:"left"}},drop:{all:{duration:"slow"},north:{direction:"up"},south:{direction:"down"},east:{direction:"right"},west:{direction:"left"}},scale:{all:{duration:"fast"}}};var state={id:"layout"+new Date().getTime(),initialized:false,container:{},north:{},south:{},east:{},west:{},center:{},cookie:{}};var _c={allPanes:"north,south,west,east,center",borderPanes:"north,south,west,east",altSide:{north:"south",south:"north",east:"west",west:"east"},hidden:{visibility:"hidden"},visible:{visibility:"visible"},zIndex:{pane_normal:1,resizer_normal:2,iframe_mask:2,pane_sliding:100,pane_animate:1000,resizer_drag:10000},resizers:{cssReq:{position:"absolute",padding:0,margin:0,fontSize:"1px",textAlign:"left",overflow:"hidden"},cssDemo:{background:"#DDD",border:"none"}},togglers:{cssReq:{position:"absolute",display:"block",padding:0,margin:0,overflow:"hidden",textAlign:"center",fontSize:"1px",cursor:"pointer",zIndex:1},cssDemo:{background:"#AAA"}},content:{cssReq:{position:"relative"},cssDemo:{overflow:"auto",padding:"10px"},cssDemoPane:{overflow:"hidden",padding:0}},panes:{cssReq:{position:"absolute",margin:0},cssDemo:{padding:"10px",background:"#FFF",border:"1px solid #BBB",overflow:"auto"}},north:{side:"Top",sizeType:"Height",dir:"horz",cssReq:{top:0,bottom:"auto",left:0,right:0,width:"auto"},pins:[]},south:{side:"Bottom",sizeType:"Height",dir:"horz",cssReq:{top:"auto",bottom:0,left:0,right:0,width:"auto"},pins:[]},east:{side:"Right",sizeType:"Width",dir:"vert",cssReq:{left:"auto",right:0,top:"auto",bottom:"auto",height:"auto"},pins:[]},west:{side:"Left",sizeType:"Width",dir:"vert",cssReq:{left:0,right:"auto",top:"auto",bottom:"auto",height:"auto"},pins:[]},center:{dir:"center",cssReq:{left:"auto",right:"auto",top:"auto",bottom:"auto",height:"auto",width:"auto"}}};var timer={data:{},set:function(s,fn,ms){timer.clear(s);timer.data[s]=setTimeout(fn,ms)},clear:function(s){var t=timer.data;if(t[s]){clearTimeout(t[s]);delete t[s]}}};var isStr=function(o){try{return typeof o=="string"||(typeof o=="object"&&o.constructor.toString().match(/string/i)!==null)}catch(e){return false}};var str=function(o){return isStr(o)?$.trim(o):o==undefined||o==null?"":o};var min=function(x,y){return Math.min(x,y)};var max=function(x,y){return Math.max(x,y)};var _transformData=function(d){var a,json={cookie:{},defaults:{fxSettings:{}},north:{fxSettings:{}},south:{fxSettings:{}},east:{fxSettings:{}},west:{fxSettings:{}},center:{fxSettings:{}}};d=d||{};if(d.effects||d.cookie||d.defaults||d.north||d.south||d.west||d.east||d.center){json=$.extend(true,json,d)}else{$.each(d,function(key,val){a=key.split("__");if(!a[1]||json[a[0]]){json[a[1]?a[0]:"defaults"][a[1]?a[1]:a[0]]=val}})}return json};var _queue=function(action,pane,param){var tried=[];$.each(_c.borderPanes.split(","),function(i,p){if(_c[p].isMoving){bindCallback(p);return false}});function bindCallback(p){var c=_c[p];if(!c.doCallback){c.doCallback=true;c.callback=action+","+pane+","+(param?1:0)}else{tried.push(p);var cbPane=c.callback.split(",")[1];if(cbPane!=pane&&!$.inArray(cbPane,tried)>=0){bindCallback(cbPane)}}}};var _dequeue=function(pane){var c=_c[pane];_c.isLayoutBusy=false;delete c.isMoving;if(!c.doCallback||!c.callback){return}c.doCallback=false;var cb=c.callback.split(","),param=(cb[2]>0?true:false);if(cb[0]=="open"){open(cb[1],param)}else{if(cb[0]=="close"){close(cb[1],param)}}if(!c.doCallback){c.callback=null}};var _execCallback=function(pane,v_fn){if(!v_fn){return}var fn;try{if(typeof v_fn=="function"){fn=v_fn}else{if(!isStr(v_fn)){return}else{if(v_fn.match(/,/)){var args=v_fn.split(","),fn=eval(args[0]);if(typeof fn=="function"&&args.length>1){return fn(args[1])}}else{fn=eval(v_fn)}}}if(typeof fn=="function"){if(pane&&$Ps[pane]){return fn(pane,$Ps[pane],$.extend({},state[pane]),options[pane],options.name)}else{return fn(Instance,$.extend({},state),options,options.name)}}}catch(ex){}};var _showInvisibly=function($E,force){if(!$E){return{}}if(!$E.jquery){$E=$($E)}var CSS={display:$E.css("display"),visibility:$E.css("visibility")};if(force||CSS.display=="none"){$E.css({display:"block",visibility:"hidden"});return CSS}else{return{}}};var _fixIframe=function(pane){if(state.browser.mozilla){return}var $P=$Ps[pane];if(state[pane].tagName=="IFRAME"){$P.css(_c.hidden).css(_c.visible)}else{$P.find("IFRAME").css(_c.hidden).css(_c.visible)}};var _cssNum=function($E,prop){if(!$E.jquery){$E=$($E)}var CSS=_showInvisibly($E);var val=parseInt($.curCSS($E[0],prop,true),10)||0;$E.css(CSS);return val};var _borderWidth=function(E,side){if(E.jquery){E=E[0]}var b="border"+side.substr(0,1).toUpperCase()+side.substr(1);return $.curCSS(E,b+"Style",true)=="none"?0:(parseInt($.curCSS(E,b+"Width",true),10)||0)};var cssW=function(el,outerWidth){var str=isStr(el),$E=str?$Ps[el]:$(el);if(isNaN(outerWidth)){outerWidth=str?getPaneSize(el):$E.outerWidth()}if(outerWidth<=0){return 0}if(!state.browser.boxModel){return outerWidth}var W=outerWidth-_borderWidth($E,"Left")-_borderWidth($E,"Right")-_cssNum($E,"paddingLeft")-_cssNum($E,"paddingRight");return W>0?W:0};var cssH=function(el,outerHeight){var str=isStr(el),$E=str?$Ps[el]:$(el);if(isNaN(outerHeight)){outerHeight=str?getPaneSize(el):$E.outerHeight()}if(outerHeight<=0){return 0}if(!state.browser.boxModel){return outerHeight}var H=outerHeight-_borderWidth($E,"Top")-_borderWidth($E,"Bottom")-_cssNum($E,"paddingTop")-_cssNum($E,"paddingBottom");return H>0?H:0};var cssSize=function(pane,outerSize){if(_c[pane].dir=="horz"){return cssH(pane,outerSize)}else{return cssW(pane,outerSize)}};var cssMinDims=function(pane){var dir=_c[pane].dir,d={minWidth:1001-cssW(pane,1000),minHeight:1001-cssH(pane,1000)};if(dir=="horz"){d.minSize=d.minHeight}if(dir=="vert"){d.minSize=d.minWidth}return d};var setOuterWidth=function(el,outerWidth,autoHide){var $E=el,w;if(isStr(el)){$E=$Ps[el]}else{if(!el.jquery){$E=$(el)}}w=cssW($E,outerWidth);$E.css({width:w});if(w>0){if(autoHide&&$E.data("autoHidden")&&$E.innerHeight()>0){$E.show().data("autoHidden",false);if(!state.browser.mozilla){$E.css(_c.hidden).css(_c.visible)}}}else{if(autoHide&&!$E.data("autoHidden")){$E.hide().data("autoHidden",true)}}};var setOuterHeight=function(el,outerHeight,autoHide){var $E=el,h;if(isStr(el)){$E=$Ps[el]}else{if(!el.jquery){$E=$(el)}}h=cssH($E,outerHeight);$E.css({height:h,visibility:"visible"});if(h>0&&$E.innerWidth()>0){if(autoHide&&$E.data("autoHidden")){$E.show().data("autoHidden",false);if(!state.browser.mozilla){$E.css(_c.hidden).css(_c.visible)}}}else{if(autoHide&&!$E.data("autoHidden")){$E.hide().data("autoHidden",true)}}};var setOuterSize=function(el,outerSize,autoHide){if(_c[pane].dir=="horz"){setOuterHeight(el,outerSize,autoHide)}else{setOuterWidth(el,outerSize,autoHide)}};var _parseSize=function(pane,size,dir){if(!dir){dir=_c[pane].dir}if(isStr(size)&&size.match(/%/)){size=parseInt(size)/100}if(size===0){return 0}else{if(size>=1){return parseInt(size,10)}else{if(size>0){var o=options,avail;if(dir=="horz"){avail=sC.innerHeight-($Ps.north?o.north.spacing_open:0)-($Ps.south?o.south.spacing_open:0)}else{if(dir=="vert"){avail=sC.innerWidth-($Ps.west?o.west.spacing_open:0)-($Ps.east?o.east.spacing_open:0)}}return Math.floor(avail*size)}else{if(pane=="center"){return 0}else{var $P=$Ps[pane],dim=(dir=="horz"?"height":"width"),vis=_showInvisibly($P),s=$P.css(dim);$P.css(dim,"auto");size=(dim=="height")?$P.outerHeight():$P.outerWidth();$P.css(dim,s).css(vis);return size}}}}};var 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{return $P.outerWidth()+oSp}}}};var setSizeLimits=function(pane,slide){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),$P=$Ps[pane],paneSpacing=o.spacing_open,altPane=_c.altSide[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),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),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={},top=sC.insetTop,left=sC.insetLeft,W=sC.innerWidth,H=sC.innerHeight,rW=o.spacing_open;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}};var calcNewCenterPaneDims=function(){var d={top:getPaneSize("north",true),bottom:getPaneSize("south",true),left:getPaneSize("west",true),right:getPaneSize("east",true),width:0,height:0};with(d){width=sC.innerWidth-left-right;height=sC.innerHeight-bottom-top;top+=sC.insetTop;bottom+=sC.insetBottom;left+=sC.insetLeft;right+=sC.insetRight}return d};var getElemDims=function($E){var d={},x=d.css={},i={},b,p,off=$E.offset();d.offsetLeft=off.left;d.offsetTop=off.top;$.each("Left,Right,Top,Bottom".split(","),function(idx,e){b=x["border"+e]=_borderWidth($E,e);p=x["padding"+e]=_cssNum($E,"padding"+e);i[e]=b+p;d["inset"+e]=p});d.offsetWidth=$E.innerWidth(true);d.offsetHeight=$E.innerHeight(true);d.outerWidth=$E.outerWidth();d.outerHeight=$E.outerHeight();d.innerWidth=d.outerWidth-i.Left-i.Right;d.innerHeight=d.outerHeight-i.Top-i.Bottom;x.width=$E.width();x.height=$E.height();return d};var getElemCSS=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};var getHoverClasses=function(el,allStates){var $El=$(el),type=$El.data("layoutRole"),pane=$El.data("layoutEdge"),o=options[pane],root=o[type+"Class"],_pane="-"+pane,_open="-open",_closed="-closed",_slide="-sliding",_hover="-hover ",_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){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)};var addHover=function(evt,el){var e=el||this;$(e).addClass(getHoverClasses(e))};var removeHover=function(evt,el){var e=el||this;$(e).removeClass(getHoverClasses(e,true))};var onResizerEnter=function(evt){$("body").disableSelection();addHover(evt,this)};var onResizerLeave=function(evt,el){var e=el||this,pane=$(e).data("layoutEdge"),name=pane+"ResizerLeave";timer.clear(name);if(!el){removeHover(evt,this);timer.set(name,function(){onResizerLeave(evt,e)},200)}else{if(!state[pane].isResizing){$("body").enableSelection()}}};var _create=function(){initOptions();var o=options;if(false===_execCallback(null,o.onload)){return false}if(!getPane("center").length){alert(lang.errCenterPaneMissing);return null}if(o.useStateCookie&&o.cookie.autoLoad){loadCookie()}state.browser={mozilla:$.browser.mozilla,webkit:$.browser.webkit||$.browser.safari,msie:$.browser.msie,isIE6:$.browser.msie&&$.browser.version==6,boxModel:$.support.boxModel};initContainer();initPanes();initResizable();sizeContent();if(o.scrollToBookmarkOnLoad){with(self.location){if(hash){replace(hash)}}}if(o.autoBindCustomButtons){initButtons()}initHotkeys();if(o.resizeWithWindow&&!$Container.data("layoutRole")){$(window).bind("resize."+sID,windowResize)}$(window).bind("unload."+sID,unload);state.initialized=true};var windowResize=function(){var delay=Number(options.resizeWithWindowDelay)||100;if(delay>0){timer.clear("winResize");timer.set("winResize",function(){timer.clear("winResize");timer.clear("winResizeRepeater");resizeAll()},delay);if(!timer.data.winResizeRepeater){setWindowResizeRepeater()}}};var setWindowResizeRepeater=function(){var delay=Number(options.resizeWithWindowMaxDelay);if(delay>0){timer.set("winResizeRepeater",function(){setWindowResizeRepeater();resizeAll()},delay)}};var unload=function(){var o=options;state.cookie=getState();if(o.useStateCookie&&o.cookie.autoSave){saveCookie()}_execCallback(null,o.onunload)};var initContainer=function(){var $C=$Container,tag=sC.tagName=$C.attr("tagName"),fullPage=(tag=="BODY"),props="position,margin,padding,border",CSS={};sC.selector=$C.selector.split(".slice")[0];sC.ref=tag+"/"+sC.selector;$C.data("layoutContainer",sID).data("layoutName",options.name);if(!$C.data("layoutCSS")){if(fullPage){CSS=$.extend(getElemCSS($C,props),{height:$C.css("height"),overflow:$C.css("overflow"),overflowX:$C.css("overflowX"),overflowY:$C.css("overflowY")});var $H=$("html");$H.data("layoutCSS",{height:"auto",overflow:$H.css("overflow"),overflowX:$H.css("overflowX"),overflowY:$H.css("overflowY")})}else{CSS=getElemCSS($C,props+",top,bottom,left,right,width,height,overflow,overflowX,overflowY")}$C.data("layoutCSS",CSS)}try{if(fullPage){$("html").css({height:"100%",overflow:"hidden",overflowX:"hidden",overflowY:"hidden"});$("body").css({position:"relative",height:"100%",overflow:"hidden",overflowX:"hidden",overflowY:"hidden",margin:0,padding:0,border:"none"})}else{var CSS={overflow:"hidden"},p=$C.css("position"),h=$C.css("height");if(!$C.data("layoutRole")){if(!p||!p.match(/fixed|absolute|relative/)){CSS.position="relative"}}$C.css(CSS);if($C.is(":visible")&&$C.innerHeight()<2){alert(lang.errContainerHeight.replace(/CONTAINER/,sC.ref))}}}catch(ex){}$.extend(state.container,getElemDims($C))};var initHotkeys=function(){$.each(_c.borderPanes.split(","),function(i,pane){var o=options[pane];if(o.enableCursorHotkey||o.customHotkey){$(document).bind("keydown."+sID,keyDown);return false}})};var initOptions=function(){opts=_transformData(opts);var newOpts={applyDefaultStyles:"applyDemoStyles"};renameOpts(opts.defaults);$.each(_c.allPanes.split(","),function(i,pane){renameOpts(opts[pane])});if(opts.effects){$.extend(effects,opts.effects);delete opts.effects}$.extend(options.cookie,opts.cookie);var globals="name,zIndex,scrollToBookmarkOnLoad,resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay,onresizeall,onresizeall_start,onresizeall_end,onload,onunload,autoBindCustomButtons,useStateCookie";$.each(globals.split(","),function(i,key){if(opts[key]!==undefined){options[key]=opts[key]}else{if(opts.defaults[key]!==undefined){options[key]=opts.defaults[key];delete opts.defaults[key]}}});$.each("paneSelector,resizerCursor,customHotkey".split(","),function(i,key){delete opts.defaults[key]});$.extend(true,options.defaults,opts.defaults);_c.center=$.extend(true,{},_c.panes,_c.center);var z=options.zIndex;if(z===0||z>0){_c.zIndex.pane_normal=z;_c.zIndex.resizer_normal=z+1;_c.zIndex.iframe_mask=z+1}$.extend(options.center,opts.center);var o_Center=$.extend(true,{},options.defaults,opts.defaults,options.center);var optionsCenter=("paneClass,contentSelector,applyDemoStyles,triggerEventsOnLoad,showOverflowOnHover,onresize,onresize_start,onresize_end,resizeNestedLayout,resizeContentWhileDragging,onsizecontent,onsizecontent_start,onsizecontent_end").split(",");$.each(optionsCenter,function(i,key){options.center[key]=o_Center[key]});var o,defs=options.defaults;$.each(_c.borderPanes.split(","),function(i,pane){_c[pane]=$.extend(true,{},_c.panes,_c[pane]);o=options[pane]=$.extend(true,{},options.defaults,options[pane],opts.defaults,opts[pane]);if(!o.paneClass){o.paneClass="ui-layout-pane"}if(!o.resizerClass){o.resizerClass="ui-layout-resizer"}if(!o.togglerClass){o.togglerClass="ui-layout-toggler"}$.each(["_open","_close",""],function(i,n){var sName="fxName"+n,sSpeed="fxSpeed"+n,sSettings="fxSettings"+n;o[sName]=opts[pane][sName]||opts[pane].fxName||opts.defaults[sName]||opts.defaults.fxName||o[sName]||o.fxName||defs[sName]||defs.fxName||"none";var fxName=o[sName];if(fxName=="none"||!$.effects||!$.effects[fxName]||(!effects[fxName]&&!o[sSettings]&&!o.fxSettings)){fxName=o[sName]="none"}var fx=effects[fxName]||{},fx_all=fx.all||{},fx_pane=fx[pane]||{};o[sSettings]=$.extend({},fx_all,fx_pane,defs.fxSettings||{},defs[sSettings]||{},o.fxSettings,o[sSettings],opts.defaults.fxSettings,opts.defaults[sSettings]||{},opts[pane].fxSettings,opts[pane][sSettings]||{});o[sSpeed]=opts[pane][sSpeed]||opts[pane].fxSpeed||opts.defaults[sSpeed]||opts.defaults.fxSpeed||o[sSpeed]||o[sSettings].duration||o.fxSpeed||o.fxSettings.duration||defs.fxSpeed||defs.fxSettings.duration||fx_pane.duration||fx_all.duration||"normal"})});function renameOpts(O){for(var key in newOpts){if(O[key]!=undefined){O[newOpts[key]]=O[key];delete O[key]}}}};var getPane=function(pane){var sel=options[pane].paneSelector;if(sel.substr(0,1)==="#"){return $Container.find(sel).eq(0)}else{var $P=$Container.children(sel).eq(0);return $P.length?$P:$Container.children("form:first").children(sel).eq(0)}};var initPanes=function(){$.each(_c.allPanes.split(","),function(idx,pane){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,$C,size,minSize,maxSize;$Cs[pane]=false;$P=$Ps[pane]=getPane(pane);if(!$P.length){$Ps[pane]=false;return true}if(!$P.data("layoutCSS")){var props="position,top,left,bottom,right,width,height,overflow,zIndex,display,backgroundColor,padding,margin,border";$P.data("layoutCSS",getElemCSS($P,props))}$P.data("layoutName",options.name).data("layoutRole","pane").data("layoutEdge",pane).css(c.cssReq).css("zIndex",_c.zIndex.pane_normal).css(o.applyDemoStyles?c.cssDemo:{}).addClass(o.paneClass+" "+o.paneClass+"-"+pane).bind("mouseenter."+sID,addHover).bind("mouseleave."+sID,removeHover);initContent(pane,false);if(!isCenter){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)}}s.tagName=$P.attr("tagName");s.edge=pane;s.noRoom=false;s.isVisible=true;if(!isCenter){s.isClosed=false;s.isSliding=false;s.isResizing=false;s.isHidden=false}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;break;case"east":CSS.right=sC.insetRight;break;case"center":}if(dir=="horz"){CSS.height=max(1,cssH(pane,size))}else{if(dir=="vert"){CSS.width=max(1,cssW(pane,size))}}$P.css(CSS);if(dir!="horz"){sizeMidPanes(pane,true)}$P.css({visibility:"visible",display:"block"});if(o.initClosed&&o.closable){close(pane,true,true)}else{if(o.initHidden||o.initClosed){hide(pane)}}if(o.showOverflowOnHover){$P.hover(allowOverflow,resetOverflow)}});initHandles();$.each(_c.borderPanes.split(","),function(i,pane){if($Ps[pane]&&state[pane].isVisible){setSizeLimits(pane);makePaneFit(pane)}});sizeMidPanes("center");$.each(_c.allPanes.split(","),function(i,pane){var o=options[pane];if($Ps[pane]&&o.triggerEventsOnLoad&&state[pane].isVisible){_execCallback(pane,o.onresize_end||o.onresize)}});if($Container.innerHeight()<2){alert(lang.errContainerHeight.replace(/CONTAINER/,sC.ref))}};var initHandles=function(panes){if(!panes||panes=="all"){panes=_c.borderPanes}$.each(panes.split(","),function(i,pane){var $P=$Ps[pane];$Rs[pane]=false;$Ts[pane]=false;if(!$P){return}var o=options[pane],s=state[pane],c=_c[pane],rClass=o.resizerClass,tClass=o.togglerClass,side=c.side.toLowerCase(),spacing=(s.isVisible?o.spacing_open:o.spacing_closed),_pane="-"+pane,_state=(s.isVisible?"-open":"-closed"),$R=$Rs[pane]=$("<div></div>"),$T=(o.closable?$Ts[pane]=$("<div></div>"):false);if(s.isVisible&&o.resizable){}else{if(!s.isVisible&&o.slidable){$R.attr("title",o.sliderTip).css("cursor",o.sliderCursor)}}$R.attr("id",(o.paneSelector.substr(0,1)=="#"?o.paneSelector.substr(1)+"-resizer":"")).data("layoutRole","resizer").data("layoutEdge",pane).css(_c.resizers.cssReq).css("zIndex",_c.zIndex.resizer_normal).css(o.applyDemoStyles?_c.resizers.cssDemo:{}).addClass(rClass+" "+rClass+_pane).appendTo($Container);if($T){$T.attr("id",(o.paneSelector.substr(0,1)=="#"?o.paneSelector.substr(1)+"-toggler":"")).data("layoutRole","toggler").data("layoutEdge",pane).css(_c.togglers.cssReq).css(o.applyDemoStyles?_c.togglers.cssDemo:{}).addClass(tClass+" "+tClass+_pane).appendTo($R).click(function(evt){toggle(pane);evt.stopPropagation()}).hover(addHover,removeHover);if(o.togglerContent_open){$("<span>"+o.togglerContent_open+"</span>").data("layoutRole","togglerContent").data("layoutEdge",pane).addClass("content content-open").css("display","none").appendTo($T).hover(addHover,removeHover)}if(o.togglerContent_closed){$("<span>"+o.togglerContent_closed+"</span>").data("layoutRole","togglerContent").data("layoutEdge",pane).addClass("content content-closed").css("display","none").appendTo($T).hover(addHover,removeHover)}}if(s.isVisible){setAsOpen(pane)}else{setAsClosed(pane);bindStartSlidingEvent(pane,true)}});sizeHandles("all")};var initContent=function(pane,resize){var o=options[pane],sel=o.contentSelector,$P=$Ps[pane],$C;if(sel){$C=$Cs[pane]=(o.findNestedContent)?$P.find(sel).eq(0):$P.children(sel).eq(0)}if($C&&$C.length){$C.css(_c.content.cssReq);if(o.applyDemoStyles){$C.css(_c.content.cssDemo);$P.css(_c.content.cssDemoPane)}state[pane].content={};if(resize!==false){sizeContent(pane)}}else{$Cs[pane]=false}};var initButtons=function(){var pre="ui-layout-button-",name;$.each("toggle,open,close,pin,toggle-slide,open-slide".split(","),function(i,action){$.each(_c.borderPanes.split(","),function(ii,pane){$("."+pre+action+"-"+pane).each(function(){name=$(this).data("layoutName")||$(this).attr("layoutName");if(name==undefined||name==options.name){if(action.substr("-slide")>0){bindButton(this,action.split("-")[0],pane,true)}else{bindButton(this,action,pane)}}})})})};var initResizable=function(panes){var draggingAvailable=(typeof $.fn.draggable=="function"),$Frames,side;if(!panes||panes=="all"){panes=_c.borderPanes}$.each(panes.split(","),function(idx,pane){var o=options[pane],s=state[pane],c=_c[pane],side=(c.dir=="horz"?"top":"left"),r,live;if(!draggingAvailable||!$Ps[pane]||!o.resizable){o.resizable=false;return true}var $P=$Ps[pane],$R=$Rs[pane],base=o.resizerClass,resizerClass=base+"-drag",resizerPaneClass=base+"-"+pane+"-drag",helperClass=base+"-dragging",helperPaneClass=base+"-"+pane+"-dragging",helperLimitClass=base+"-dragging-limit",helperClassesSet=false;if(!s.isClosed){$R.attr("title",o.resizerTip).css("cursor",o.resizerCursor)}$R.hover(onResizerEnter,onResizerLeave);$R.draggable({containment:$Container[0],axis:(c.dir=="horz"?"y":"x"),delay:0,distance:1,helper:"clone",opacity:o.resizerDragOpacity,addClasses:false,zIndex:_c.zIndex.resizer_drag,start:function(e,ui){o=options[pane];s=state[pane];live=o.resizeWhileDragging;if(false===_execCallback(pane,o.ondrag_start)){return false}_c.isLayoutBusy=true;s.isResizing=true;timer.clear(pane+"_closeSlider");setSizeLimits(pane);r=s.resizerPosition;$R.addClass(resizerClass+" "+resizerPaneClass);helperClassesSet=false;$Frames=$(o.maskIframesOnResize===true?"iframe":o.maskIframesOnResize).filter(":visible");var id,i=0;$Frames.each(function(){id="ui-layout-mask-"+(++i);$(this).data("layoutMaskID",id);$('<div id="'+id+'" class="ui-layout-mask ui-layout-mask-'+pane+'"/>').css({background:"#fff",opacity:"0.001",zIndex:_c.zIndex.iframe_mask,position:"absolute",width:this.offsetWidth+"px",height:this.offsetHeight+"px"}).css($(this).position()).appendTo(this.parentNode)});$("body").disableSelection()},drag:function(e,ui){if(!helperClassesSet){ui.helper.addClass(helperClass+" "+helperPaneClass).children().css("visibility","hidden");helperClassesSet=true;if(s.isSliding){$Ps[pane].css("zIndex",_c.zIndex.pane_sliding)}}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}}if(limit){ui.helper.addClass(helperLimitClass);window.defaultStatus="Panel has reached its "+((limit>0&&pane.match(/north|west/))||(limit<0&&pane.match(/south|east/))?"maximum":"minimum")+" size"}else{ui.helper.removeClass(helperLimitClass);window.defaultStatus=""}if(live){resizePanes(e,ui,pane)}},stop:function(e,ui){$("body").enableSelection();window.defaultStatus="";$R.removeClass(resizerClass+" "+resizerPaneClass+" "+helperLimitClass);s.isResizing=false;_c.isLayoutBusy=false;resizePanes(e,ui,pane,true)}});var resizePanes=function(e,ui,pane,resizingDone){var dragPos=ui.position,c=_c[pane],resizerPos,newSize,i=0;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}if(resizingDone){$("div.ui-layout-mask").each(function(){this.parentNode.removeChild(this)});if(false===_execCallback(pane,o.ondrag_end||o.ondrag)){return false}}else{$Frames.each(function(){$("#"+$(this).data("layoutMaskID")).css($(this).position()).css({width:this.offsetWidth+"px",height:this.offsetHeight+"px"})})}newSize=resizerPos-sC["inset"+c.side];manualSizePane(pane,newSize)}})};var destroy=function(){$(window).unbind("."+sID);$(document).unbind("."+sID);window[sID]=null;var fullPage=(sC.tagName=="BODY"),_open="-open",_sliding="-sliding",_closed="-closed",$P,root,pRoot,pClasses;$.each(_c.allPanes.split(","),function(i,pane){$P=$Ps[pane];if(!$P){return true}if(pane!="center"){if($Ts[pane]){$Ts[pane].remove()}$Rs[pane].remove()}root=options[pane].paneClass;pRoot=root+"-"+pane;pClasses=[root,root+_open,root+_closed,root+_sliding,pRoot,pRoot+_open,pRoot+_closed,pRoot+_sliding];$.merge(pClasses,getHoverClasses($P,true));$P.removeClass(pClasses.join(" ")).removeData("layoutRole").removeData("layoutEdge").unbind("."+sID).unbind("mouseenter").unbind("mouseleave");if(!$P.data("layoutContainer")){$P.css($P.data("layoutCSS"))}});$Container.removeData("layoutContainer");if(!$Container.data("layoutEdge")){$Container.css($Container.data("layoutCSS"))}if(fullPage){$("html").css($("html").data("layoutCSS"))}unload();var n=options.name;if(n&&window[n]){window[n]=null}};var hide=function(pane,noAnimation){var o=options[pane],s=state[pane],$P=$Ps[pane],$R=$Rs[pane];if(!$P||s.isHidden){return}if(state.initialized&&false===_execCallback(pane,o.onhide_start)){return}s.isSliding=false;if($R){$R.hide()}if(!state.initialized||s.isClosed){s.isClosed=true;s.isHidden=true;s.isVisible=false;$P.hide();sizeMidPanes(_c[pane].dir=="horz"?"all":"center");if(state.initialized||o.triggerEventsOnLoad){_execCallback(pane,o.onhide_end||o.onhide)}}else{s.isHiding=true;close(pane,false,noAnimation)}};var show=function(pane,openPane,noAnimation,noAlert){var o=options[pane],s=state[pane],$P=$Ps[pane],$R=$Rs[pane];if(!$P||!s.isHidden){return}if(false===_execCallback(pane,o.onshow_start)){return}s.isSliding=false;s.isShowing=true;if(openPane===false){close(pane,true)}else{open(pane,false,noAnimation,noAlert)}};var toggle=function(pane,slide){if(!isStr(pane)){pane.stopImmediatePropagation();pane=$(this).data("layoutEdge")}var s=state[str(pane)];if(s.isHidden){show(pane)}else{if(s.isClosed){open(pane,!!slide)}else{close(pane)}}};var _closePane=function(pane,setHandles){var $P=$Ps[pane],s=state[pane];$P.hide();s.isClosed=true;s.isVisible=false};var close=function(pane,force,noAnimation,skipCallback){if(!state.initialized){_closePane(pane);return}var $P=$Ps[pane],$R=$Rs[pane],$T=$Ts[pane],o=options[pane],s=state[pane],doFX=!noAnimation&&!s.isClosed&&(o.fxName_close!="none"),isShowing=s.isShowing,isHiding=s.isHiding,wasSliding=s.isSliding;delete s.isShowing;delete s.isHiding;if(!$P||!o.closable){return}else{if(!force&&s.isClosed&&!isShowing){return}}if(_c.isLayoutBusy){_queue("close",pane,force);return}if(!isShowing&&false===_execCallback(pane,o.onclose_start)){return}_c[pane].isMoving=true;_c.isLayoutBusy=true;s.isClosed=true;s.isVisible=false;if(isHiding){s.isHidden=true}else{if(isShowing){s.isHidden=false}}if(s.isSliding){bindStopSlidingEvents(pane,false)}else{sizeMidPanes(_c[pane].dir=="horz"?"all":"center",false)}setAsClosed(pane);if(doFX){lockPaneForFX(pane,true);$P.hide(o.fxName_close,o.fxSettings_close,o.fxSpeed_close,function(){lockPaneForFX(pane,false);close_2()})}else{$P.hide();close_2()}function close_2(){if(s.isClosed){bindStartSlidingEvent(pane,true);var altPane=_c.altSide[pane];if(state[altPane].noRoom){setSizeLimits(altPane);makePaneFit(altPane)}if(!skipCallback&&(state.initialized||o.triggerEventsOnLoad)){if(!isShowing&&!wasSliding){_execCallback(pane,o.onclose_end||o.onclose)}if(isShowing){_execCallback(pane,o.onshow_end||o.onshow)}if(isHiding){_execCallback(pane,o.onhide_end||o.onhide)}}}_dequeue(pane)}};var 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,_open="-open",_sliding="-sliding",_closed="-closed";$R.css(side,sC[inset]).removeClass(rClass+_open+" "+rClass+_pane+_open).removeClass(rClass+_sliding+" "+rClass+_pane+_sliding).addClass(rClass+_closed+" "+rClass+_pane+_closed).unbind("dblclick."+sID);if(o.resizable&&typeof $.fn.draggable=="function"){$R.draggable("disable").removeClass("ui-state-disabled").css("cursor","default").attr("title","")}if($T){$T.removeClass(tClass+_open+" "+tClass+_pane+_open).addClass(tClass+_closed+" "+tClass+_pane+_closed).attr("title",o.togglerTip_closed);$T.children(".content-open").hide();$T.children(".content-closed").css("display","block")}syncPinBtns(pane,false);if(state.initialized){sizeHandles("all")}};var open=function(pane,slide,noAnimation,noAlert){var $P=$Ps[pane],$R=$Rs[pane],$T=$Ts[pane],o=options[pane],s=state[pane],doFX=!noAnimation&&s.isClosed&&(o.fxName_open!="none"),isShowing=s.isShowing;delete s.isShowing;if(!$P||(!o.resizable&&!o.closable)){return}else{if(s.isVisible&&!s.isSliding){return}}if(s.isHidden&&!isShowing){show(pane,true);return}if(_c.isLayoutBusy){_queue("open",pane,slide);return}if(false===_execCallback(pane,o.onopen_start)){return}setSizeLimits(pane,slide);if(s.minSize>s.maxSize){syncPinBtns(pane,false);if(!noAlert&&o.noRoomToOpenTip){alert(o.noRoomToOpenTip)}return}_c[pane].isMoving=true;_c.isLayoutBusy=true;if(slide){bindStopSlidingEvents(pane,true)}else{if(s.isSliding){bindStopSlidingEvents(pane,false)}else{if(o.slidable){bindStartSlidingEvent(pane,false)}}}s.noRoom=false;makePaneFit(pane);s.isVisible=true;s.isClosed=false;if(isShowing){s.isHidden=false}if(doFX){lockPaneForFX(pane,true);$P.show(o.fxName_open,o.fxSettings_open,o.fxSpeed_open,function(){lockPaneForFX(pane,false);open_2()})}else{$P.show();open_2()}function open_2(){if(s.isVisible){_fixIframe(pane);if(!s.isSliding){sizeMidPanes(_c[pane].dir=="vert"?"center":"all",false)}setAsOpen(pane)}_dequeue(pane)}};var 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,_open="-open",_closed="-closed",_sliding="-sliding";$R.css(side,sC[inset]+getPaneSize(pane)).removeClass(rClass+_closed+" "+rClass+_pane+_closed).addClass(rClass+_open+" "+rClass+_pane+_open);if(s.isSliding){$R.addClass(rClass+_sliding+" "+rClass+_pane+_sliding)}else{$R.removeClass(rClass+_sliding+" "+rClass+_pane+_sliding)}if(o.resizerDblClickToggle){$R.bind("dblclick",toggle)}removeHover(0,$R);if(o.resizable&&typeof $.fn.draggable=="function"){$R.draggable("enable").css("cursor",o.resizerCursor).attr("title",o.resizerTip)}else{if(!s.isSliding){$R.css("cursor","default")}}if($T){$T.removeClass(tClass+_closed+" "+tClass+_pane+_closed).addClass(tClass+_open+" "+tClass+_pane+_open).attr("title",o.togglerTip_open);removeHover(0,$T);$T.children(".content-closed").hide();$T.children(".content-open").css("display","block")}syncPinBtns(pane,!s.isSliding);$.extend(s,getElemDims($P));if(state.initialized){sizeHandles("all");sizeContent(pane,true)}if(!skipCallback&&(state.initialized||o.triggerEventsOnLoad)&&$P.is(":visible")){_execCallback(pane,o.onopen_end||o.onopen);if(s.isShowing){_execCallback(pane,o.onshow_end||o.onshow)}if(state.initialized){_execCallback(pane,o.onresize_end||o.onresize)}}};var slideOpen=function(evt_or_pane){var type=typeof evt_or_pane,pane=(type=="string"?evt_or_pane:$(this).data("layoutEdge"));if(type=="object"){evt_or_pane.stopImmediatePropagation()}if(state[pane].isClosed){open(pane,true)}else{bindStopSlidingEvents(pane,true)}};var slideClose=function(evt_or_pane){var $E=(isStr(evt_or_pane)?$Ps[evt_or_pane]:$(this)),pane=$E.data("layoutEdge"),o=options[pane],s=state[pane],$P=$Ps[pane];if(s.isClosed||s.isResizing){return}else{if(o.slideTrigger_close=="click"){close_NOW()}else{if(o.preventQuickSlideClose&&_c.isLayoutBusy){return}else{timer.set(pane+"_closeSlider",close_NOW,300)}}}function close_NOW(e){if(s.isClosed){bindStopSlidingEvents(pane,false)}else{close(pane)}}};var slideToggle=function(pane){toggle(pane,true)};var lockPaneForFX=function(pane,doLock){var $P=$Ps[pane];if(doLock){$P.css({zIndex:_c.zIndex.pane_animate});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{if(pane=="south"){$P.css({top:"auto"})}else{if(pane=="east"){$P.css({left:"auto"})}}var o=options[pane];if(state.browser.msie&&o.fxOpacityFix&&o.fxName_open!="slide"&&$P.css("filter")&&$P.css("opacity")==1){$P[0].style.removeAttribute("filter")}}};var bindStartSlidingEvent=function(pane,enable){var o=options[pane],z=_c.zIndex,$P=$Ps[pane],$R=$Rs[pane],trigger=o.slideTrigger_open;if(!$R||!o.slidable){return}if(trigger.match(/mouseover/)){trigger=o.slideTrigger_open="mouseenter"}else{if(!trigger.match(/click|dblclick|mouseenter/)){trigger=o.slideTrigger_open="click"}}$R.css("zIndex",!enable?z.pane_sliding:z.resizer_normal);$P.css("zIndex",!enable?z.pane_sliding:z.pane_normal);$R[enable?"bind":"unbind"](trigger+"."+sID,slideOpen).css("cursor",enable?o.sliderCursor:"default").attr("title",enable?o.sliderTip:"")};var bindStopSlidingEvents=function(pane,enable){var o=options[pane],s=state[pane],trigger=o.slideTrigger_close,action=(enable?"bind":"unbind"),$P=$Ps[pane],$R=$Rs[pane];s.isSliding=enable;timer.clear(pane+"_closeSlider");if(enable){bindStartSlidingEvent(pane,false)}if(!trigger.match(/click|mouseleave/)){trigger=o.slideTrigger_close="mouseleave"}$R[action](trigger,slideClose);if(trigger=="mouseleave"){$P[action]("mouseleave."+sID,slideClose);$R[action]("mouseenter."+sID,cancelMouseOut);$P[action]("mouseenter."+sID,cancelMouseOut)}if(!enable){timer.clear(pane+"_closeSlider")}else{if(trigger=="click"&&!o.resizable){$R.css("cursor",enable?o.sliderCursor:"default");$R.attr("title",enable?o.togglerTip_open:"")}}function cancelMouseOut(evt){timer.clear(pane+"_closeSlider");evt.stopPropagation()}};var 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;if(pane=="center"||(isSidePane&&s.noVerticalRoom)){hasRoom=s.minHeight<=s.maxHeight&&(isSidePane||s.minWidth<=s.maxWidth);if(hasRoom&&s.noRoom){$P.show();if($R){$R.show()}s.isVisible=true;s.noRoom=false;if(isSidePane){s.noVerticalRoom=false}_fixIframe(pane)}else{if(!hasRoom&&!s.noRoom){$P.hide();if($R){$R.hide()}s.isVisible=false;s.noRoom=true}}}if(pane=="center"){}else{if(s.minSize<=s.maxSize){hasRoom=true;if(s.size>s.maxSize){sizePane(pane,s.maxSize,skipCallback,force)}else{if(s.size<s.minSize){sizePane(pane,s.minSize,skipCallback,force)}else{if($R&&$P.is(":visible")){var side=c.side.toLowerCase(),pos=s.size+sC["inset"+c.side];if(_cssNum($R,side)!=pos){$R.css(side,pos)}}}}if(s.noRoom){if(s.wasOpen&&o.closable){if(o.autoReopen){open(pane,false,true,true)}else{s.noRoom=false}}else{show(pane,s.wasOpen,true,true)}}}else{if(!s.noRoom){s.noRoom=true;s.wasOpen=!s.isClosed&&!s.isSliding;if(o.closable){close(pane,true,true)}else{hide(pane,true)}}}}};var manualSizePane=function(pane,size,skipCallback){var o=options[pane],forceResize=o.resizeWhileDragging&&!_c.isLayoutBusy;o.autoResize=false;sizePane(pane,size,skipCallback,forceResize)};var sizePane=function(pane,size,skipCallback,force){var o=options[pane],s=state[pane],$P=$Ps[pane],$R=$Rs[pane],side=_c[pane].side.toLowerCase(),inset="inset"+_c[pane].side,skipResizeWhileDragging=_c.isLayoutBusy&&!o.triggerEventsWhileDragging,oldSize;setSizeLimits(pane);oldSize=s.size;size=_parseSize(pane,size);size=max(size,_parseSize(pane,o.minSize));size=min(size,s.maxSize);if(size<s.minSize){makePaneFit(pane,false,skipCallback);return}if(!force&&size==oldSize){return}if(!skipCallback&&state.initialized&&s.isVisible){_execCallback(pane,o.onresize_start)}$P.css(_c[pane].sizeType.toLowerCase(),max(1,cssSize(pane,size)));s.size=size;$.extend(s,getElemDims($P));if($R&&$P.is(":visible")){$R.css(side,size+sC[inset])}sizeContent(pane);if(!skipCallback&&!skipResizeWhileDragging&&state.initialized&&s.isVisible){_execCallback(pane,o.onresize_end||o.onresize);if(o.resizeNestedLayout&&$P.data("layoutContainer")){$P.layout().resizeAll()}}if(!skipCallback){if(!s.isSliding){sizeMidPanes(_c[pane].dir=="horz"?"all":"center",skipResizeWhileDragging,force)}sizeHandles("all")}var altPane=_c.altSide[pane];if(size<oldSize&&state[altPane].noRoom){setSizeLimits(altPane);makePaneFit(altPane,false,skipCallback)}};var sizeMidPanes=function(panes,skipCallback,force){if(!panes||panes=="all"){panes="east,west,center"}$.each(panes.split(","),function(i,pane){if(!$Ps[pane]){return}var o=options[pane],s=state[pane],$P=$Ps[pane],$R=$Rs[pane],isCenter=(pane=="center"),hasRoom=true,CSS={},d=calcNewCenterPaneDims();$.extend(s,getElemDims($P));if(pane=="center"){if(!force&&s.isVisible&&d.width==s.outerWidth&&d.height==s.outerHeight){return true}$.extend(s,cssMinDims(pane),{maxWidth:d.width,maxHeight:d.height});CSS=d;CSS.width=cssW(pane,d.width);CSS.height=cssH(pane,d.height);hasRoom=CSS.width>0&&CSS.height>0;if(!hasRoom&&!state.initialized&&o.minWidth>0){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(reqPx==0){if(sizeE!=minE){sizePane("east",newE,true)}if(sizeW!=minW){sizePane("west",newW,true)}sizeMidPanes("center",skipCallback,force);return}}}else{$.extend(s,getElemDims($P),cssMinDims(pane));if(!force&&!s.noVerticalRoom&&d.height==s.outerHeight){return true}CSS.top=d.top;CSS.bottom=d.bottom;CSS.height=cssH(pane,d.height);s.maxHeight=max(0,CSS.height);hasRoom=(s.maxHeight>0);if(!hasRoom){s.noVerticalRoom=true}}if(hasRoom){if(!skipCallback&&state.initialized){_execCallback(pane,o.onresize_start)}$P.css(CSS);$.extend(s,getElemDims($P));if(s.noRoom){makePaneFit(pane)}if(state.initialized){sizeContent(pane)}}else{if(!s.noRoom&&s.isVisible){makePaneFit(pane)}}if(pane=="center"){var b=state.browser;var fix=b.isIE6||(b.msie&&!b.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))}}if(!skipCallback&&state.initialized&&s.isVisible){_execCallback(pane,o.onresize_end||o.onresize);if(o.resizeNestedLayout&&$P.data("layoutContainer")){$P.layout().resizeAll()}}})};var resizeAll=function(){var oldW=sC.innerWidth,oldH=sC.innerHeight;$.extend(state.container,getElemDims($Container));if(!sC.outerHeight){return}if(false===_execCallback(null,options.onresizeall_start)){return false}var shrunkH=(sC.innerHeight<oldH),shrunkW=(sC.innerWidth<oldW),$P,o,s,dir;$.each(["south","north","east","west"],function(i,pane){if(!$Ps[pane]){return}s=state[pane];o=options[pane];dir=_c[pane].dir;if(o.autoResize&&s.size!=o.size){sizePane(pane,o.size,true,true)}else{setSizeLimits(pane);makePaneFit(pane,false,true,true)}});sizeMidPanes("all",true,true);sizeHandles("all");o=options;$.each(_c.allPanes.split(","),function(i,pane){$P=$Ps[pane];if(!$P){return}if(state[pane].isVisible){_execCallback(pane,o[pane].onresize_end||o[pane].onresize)}if(o[pane].resizeNestedLayout&&$P.data("layoutContainer")){$P.layout().resizeAll()}});_execCallback(null,o.onresizeall_end||o.onresizeall)};var sizeContent=function(panes,remeasure){if(!panes||panes=="all"){panes=_c.allPanes}$.each(panes.split(","),function(idx,pane){var $P=$Ps[pane],$C=$Cs[pane],o=options[pane],s=state[pane],m=s.content;if(!$P||!$C||!$P.is(":visible")){return true}if(false===_execCallback(null,o.onsizecontent_start)){return}if(!_c.isLayoutBusy||m.top==undefined||remeasure||o.resizeContentWhileDragging){_measure();if(m.hiddenFooters>0&&$P.css("overflow")=="hidden"){$P.css("overflow","visible");_measure();$P.css("overflow","hidden")}}var newH=s.innerHeight-(m.spaceAbove-s.css.paddingTop)-(m.spaceBelow-s.css.paddingBottom);if(!$C.is(":visible")||m.height!=newH){setOuterHeight($C,newH,true);m.height=newH}if(state.initialized){_execCallback(pane,o.onsizecontent_end||o.onsizecontent);if(o.resizeNestedLayout&&$C.data("layoutContainer")){$C.layout().resizeAll()}}function _below($E){return max(s.css.paddingBottom,(parseInt($E.css("marginBottom"))||0))}function _measure(){var ignore=options[pane].contentIgnoreSelector,$Fs=$C.nextAll().not(ignore||":lt(0)"),$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};m.spaceAbove=m.top;m.bottom=m.top+m.height;if($F.length){m.spaceBelow=($F[0].offsetTop+$F.outerHeight())-m.bottom+_below($F)}else{m.spaceBelow=_below($C)}}})};var sizeHandles=function(panes){if(!panes||panes=="all"){panes=_c.borderPanes}$.each(panes.split(","),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,offset,CSS={};if(spacing==0){$R.hide();return}else{if(!s.noRoom&&!s.isHidden){$R.show()}}if(dir=="horz"){paneLen=$P.outerWidth();s.resizerLength=paneLen;$R.css({width:max(1,cssW($R,paneLen)),height:max(0,cssH($R,spacing)),left:_cssNum($P,"left")})}else{paneLen=$P.outerHeight();s.resizerLength=paneLen;$R.css({height:max(1,cssH($R,paneLen)),width:max(0,cssW($R,spacing)),top:sC.insetTop+getPaneSize("north",true)})}removeHover(o,$R);if($T){if(togLen==0||(s.isSliding&&o.hideTogglerOnSlide)){$T.hide();return}else{$T.show()}if(!(togLen>0)||togLen=="100%"||togLen>paneLen){togLen=paneLen;offset=0}else{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=Math.floor((paneLen-togLen)/2)}}else{var x=parseInt(togAlign);if(togAlign>=0){offset=x}else{offset=paneLen-togLen+x}}}if(dir=="horz"){var width=cssW($T,togLen);$T.css({width:max(0,width),height:max(1,cssH($T,spacing)),left:offset,top:0});$T.children(".content").each(function(){$TC=$(this);$TC.css("marginLeft",Math.floor((width-$TC.outerWidth())/2))})}else{var height=cssH($T,togLen);$T.css({height:max(0,height),width:max(1,cssW($T,spacing)),top:offset,left:0});$T.children(".content").each(function(){$TC=$(this);$TC.css("marginTop",Math.floor((height-$TC.outerHeight())/2))})}removeHover(0,$T)}if(!state.initialized&&o.initHidden){$R.hide();if($T){$T.hide()}}})};var swapPanes=function(pane1,pane2){state[pane1].edge=pane2;state[pane2].edge=pane1;var cancelled=false;if(false===_execCallback(pane1,options[pane1].onswap_start)){cancelled=true}if(!cancelled&&false===_execCallback(pane2,options[pane2].onswap_start)){cancelled=true}if(cancelled){state[pane1].edge=pane1;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;$Ps[pane1]=false;$Ps[pane2]=false;state[pane1]={};state[pane2]={};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;move(oPane1,pane2);move(oPane2,pane1);oPane1=oPane2=sizes=null;if($Ps[pane1]){$Ps[pane1].css(_c.visible)}if($Ps[pane2]){$Ps[pane2].css(_c.visible)}resizeAll();_execCallback(pane1,options[pane1].onswap_end||options[pane1].onswap);_execCallback(pane2,options[pane2].onswap_end||options[pane2].onswap);return;function copy(n){var $P=$Ps[n],$C=$Cs[n];return !$P?false:{pane:n,P:$P?$P[0]:false,C:$C?$C[0]:false,state:$.extend({},state[n]),options:$.extend({},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,s=$.extend({},state[pane]),o=options[pane],fx={resizerCursor:o.resizerCursor},re,size,pos;$.each("fxName,fxSpeed,fxSettings".split(","),function(i,k){fx[k]=o[k];fx[k+"_open"]=o[k+"_open"];fx[k+"_close"]=o[k+"_close"]});$Ps[pane]=$(P).data("layoutEdge",pane).css(_c.hidden).css(c.cssReq);$Cs[pane]=C?$(C):false;options[pane]=$.extend({},oPane.options,fx);state[pane]=$.extend({},oPane.state);re=new RegExp(o.paneClass+"-"+oldPane,"g");P.className=P.className.replace(re,o.paneClass+"-"+pane);initHandles(pane);initResizable(pane);if(c.dir!=_c[oldPane].dir){size=sizes[pane]||0;setSizeLimits(pane);size=max(size,state[pane].minSize);manualSizePane(pane,size,true)}else{$Rs[pane].css(side,sC[inset]+(state[pane].isVisible?getPaneSize(pane):0))}if(oPane.state.isVisible&&!s.isVisible){setAsOpen(pane,true)}else{setAsClosed(pane,true);bindStartSlidingEvent(pane,true)}oPane=null}};function keyDown(evt){if(!evt){return true}var code=evt.keyCode;if(code<33){return true}var PANE={38:"north",40:"south",37:"west",39:"east"},ALT=evt.altKey,SHIFT=evt.shiftKey,CTRL=evt.ctrlKey,CURSOR=(CTRL&&code>=37&&code<=40),o,k,m,pane;if(CURSOR&&options[PANE[code]].enableCursorHotkey){pane=PANE[code]}else{if(CTRL||SHIFT){$.each(_c.borderPanes.split(","),function(i,p){o=options[p];k=o.customHotkey;m=o.customHotkeyModifier;if((SHIFT&&m=="SHIFT")||(CTRL&&m=="CTRL")||(CTRL&&SHIFT)){if(k&&code==(isNaN(k)||k<=9?k.toUpperCase().charCodeAt(0):k)){pane=p;return false}}})}}if(!pane||!$Ps[pane]||!options[pane].closable||state[pane].isHidden){return true}toggle(pane);evt.stopPropagation();evt.returnValue=false;return false}function allowOverflow(el){if(this&&this.tagName){el=this}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}})}}if(!$P||!$P.length){return}var pane=$P.data("layoutEdge"),s=state[pane];if(s.cssSaved){resetOverflow(pane)}if(s.isSliding||s.isResizing||s.isClosed){s.cssSaved=false;return}var newCSS={zIndex:(_c.zIndex.pane_normal+2)},curCSS={},of=$P.css("overflow"),ofX=$P.css("overflowX"),ofY=$P.css("overflowY");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"}s.cssSaved=curCSS;$P.css(newCSS);$.each(_c.allPanes.split(","),function(i,p){if(p!=pane){resetOverflow(p)}})}function resetOverflow(el){if(this&&this.tagName){el=this}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}})}}if(!$P||!$P.length){return}var pane=$P.data("layoutEdge"),s=state[pane],CSS=s.cssSaved||{};if(!s.isSliding&&!s.isResizing){$P.css("zIndex",_c.zIndex.pane_normal)}$P.css(CSS);s.cssSaved=false}function getBtn(selector,pane,action){var $E=$(selector);if(!$E.length){alert(lang.errButton+lang.selector+": "+selector)}else{if(_c.borderPanes.indexOf(pane)==-1){alert(lang.errButton+lang.Pane.toLowerCase()+": "+pane)}else{var btn=options[pane].buttonClass+"-"+action;$E.addClass(btn+" "+btn+"-"+pane).data("layoutName",options.name);return $E}}return false}function bindButton(selector,action,pane){switch(action.toLowerCase()){case"toggle":addToggleBtn(selector,pane);break;case"open":addOpenBtn(selector,pane);break;case"close":addCloseBtn(selector,pane);break;case"pin":addPinBtn(selector,pane);break;case"toggle-slide":addToggleBtn(selector,pane,true);break;case"open-slide":addOpenBtn(selector,pane,true);break}}function addToggleBtn(selector,pane,slide){var $E=getBtn(selector,pane,"toggle");if($E){$E.click(function(evt){toggle(pane,!!slide);evt.stopPropagation()})}}function addOpenBtn(selector,pane,slide){var $E=getBtn(selector,pane,"open");if($E){$E.attr("title",lang.Open).click(function(evt){open(pane,!!slide);evt.stopPropagation()})}}function addCloseBtn(selector,pane){var $E=getBtn(selector,pane,"close");if($E){$E.attr("title",lang.Close).click(function(evt){close(pane);evt.stopPropagation()})}}function addPinBtn(selector,pane){var $E=getBtn(selector,pane,"pin");if($E){var s=state[pane];$E.click(function(evt){setPinState($(this),pane,(s.isSliding||s.isClosed));if(s.isSliding||s.isClosed){open(pane)}else{close(pane)}evt.stopPropagation()});setPinState($E,pane,(!s.isClosed&&!s.isSliding));_c[pane].pins.push(selector)}}function syncPinBtns(pane,doPin){$.each(_c[pane].pins,function(i,selector){setPinState($(selector),pane,doPin)})}function setPinState($Pin,pane,doPin){var updown=$Pin.attr("pin");if(updown&&doPin==(updown=="down")){return}var pin=options[pane].buttonClass+"-pin",side=pin+"-"+pane,UP=pin+"-up "+side+"-up",DN=pin+"-down "+side+"-down";$Pin.attr("pin",doPin?"down":"up").attr("title",doPin?lang.Unpin:lang.Pin).removeClass(doPin?UP:DN).addClass(doPin?DN:UP)}function isCookiesEnabled(){return(navigator.cookieEnabled!=0)}function getCookie(opts){var o=$.extend({},options.cookie,opts||{}),name=o.name||options.name||"Layout",c=document.cookie,cs=c?c.split(";"):[],pair;for(var i=0,n=cs.length;i<n;i++){pair=$.trim(cs[i]).split("=");if(pair[0]==name){return decodeJSON(decodeURIComponent(pair[1]))}}return""}function saveCookie(keys,opts){var o=$.extend({},options.cookie,opts||{}),name=o.name||options.name||"Layout",params="",date="",clear=false;if(o.expires.toUTCString){date=o.expires}else{if(typeof o.expires=="number"){date=new Date();if(o.expires>0){date.setDate(date.getDate()+o.expires)}else{date.setYear(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"}if(clear){state.cookie={};document.cookie=name+"="+params}else{state.cookie=getState(keys||o.keys);document.cookie=name+"="+encodeURIComponent(encodeJSON(state.cookie))+params}return $.extend({},state.cookie)}function deleteCookie(){saveCookie("",{expires:-1})}function loadCookie(opts){var o=getCookie(opts);if(o){state.cookie=$.extend({},o);loadState(o)}return o}function loadState(opts){$.extend(true,options,opts)}function getState(keys){var data={},alt={isClosed:"initClosed",isHidden:"initHidden"},pair,pane,key,val;if(!keys){keys=options.cookie.keys}if($.isArray(keys)){keys=keys.join(",")}keys=keys.replace(/__/g,".").split(",");for(var i=0,n=keys.length;i<n;i++){pair=keys[i].split(".");pane=pair[0];key=pair[1];if(_c.allPanes.indexOf(pane)<0){continue}val=state[pane][key];if(val==undefined){continue}if(key=="isClosed"&&state[pane]["isSliding"]){val=true}(data[pane]||(data[pane]={}))[alt[key]?alt[key]:key]=val}return data}function encodeJSON(JSON){return parse(JSON);function parse(h){var D=[],i=0,k,v,t;for(k in h){v=h[k];t=typeof v;if(t=="string"){v='"'+v+'"'}else{if(t=="object"){v=parse(v)}}D[i++]='"'+k+'":'+v}return"{"+D.join(",")+"}"}}function decodeJSON(str){try{return window["eval"]("("+str+")")||{}}catch(e){return{}}}var $Container=$(this).eq(0);if(!$Container.length){return null}if($Container.data("layoutContainer")){return $.extend({},window[$Container.data("layoutContainer")])}var $Ps={},$Cs={},$Rs={},$Ts={},sC=state.container,sID=state.id;_create();var Instance={options:options,state:state,container:$Container,panes:$Ps,contents:$Cs,resizers:$Rs,togglers:$Ts,toggle:toggle,hide:hide,show:show,open:open,close:close,slideOpen:slideOpen,slideClose:slideClose,slideToggle:slideToggle,initContent:initContent,sizeContent:sizeContent,sizePane:manualSizePane,swapPanes:swapPanes,resizeAll:resizeAll,destroy:destroy,setSizeLimits:setSizeLimits,bindButton:bindButton,addToggleBtn:addToggleBtn,addOpenBtn:addOpenBtn,addCloseBtn:addCloseBtn,addPinBtn:addPinBtn,allowOverflow:allowOverflow,resetOverflow:resetOverflow,encodeJSON:encodeJSON,decodeJSON:decodeJSON,getState:getState,getCookie:getCookie,saveCookie:saveCookie,deleteCookie:deleteCookie,loadCookie:loadCookie,loadState:loadState,cssWidth:cssW,cssHeight:cssH};window[sID]=Instance;return Instance}})(jQuery);
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js
index 5920fdfdb2..6d1caf6d50 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js
@@ -2,6 +2,22 @@
// 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';
@@ -101,6 +117,12 @@ $(document).ready(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() {
@@ -116,6 +138,11 @@ $(document).ready(function(){
});
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() {
diff --git a/src/compiler/scala/tools/nsc/doc/model/Entity.scala b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
index 6d193c30f7..a63849e3f6 100644
--- a/src/compiler/scala/tools/nsc/doc/model/Entity.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
@@ -196,6 +196,9 @@ trait MemberEntity extends Entity {
/** 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
@@ -625,4 +628,4 @@ trait UpperBoundedTypeParamConstraint extends TypeParamConstraint {
/** toString for debugging */
override def toString = typeParamName + " is a subclass of " + upperBound.name + " (" + typeParamName + " <: " +
upperBound.name + ")"
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/doc/model/LinkTo.scala b/src/compiler/scala/tools/nsc/doc/model/LinkTo.scala
index 664567872e..737c6a7577 100644
--- a/src/compiler/scala/tools/nsc/doc/model/LinkTo.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/LinkTo.scala
@@ -9,10 +9,10 @@ package model
import scala.collection._
abstract sealed class LinkTo
-case class LinkToTpl(tpl: DocTemplateEntity) extends LinkTo
-case class LinkToMember(mbr: MemberEntity, inTpl: DocTemplateEntity) extends LinkTo
-case class Tooltip(name: String) extends LinkTo { def this(tpl: TemplateEntity) = this(tpl.qualifiedName) }
-// case class LinkToExternal(name: String, url: String) extends LinkTo // for SI-191, whenever Manohar will have time
+final case class LinkToTpl(tpl: DocTemplateEntity) extends LinkTo
+final case class LinkToMember(mbr: MemberEntity, inTpl: DocTemplateEntity) extends LinkTo
+final case class Tooltip(name: String) extends LinkTo { def this(tpl: TemplateEntity) = this(tpl.qualifiedName) }
+final case class LinkToExternal(name: String, url: String) extends LinkTo
case object NoLink extends LinkTo // you should use Tooltip if you have a name from the user, this is only in case all fails
object LinkToTpl {
diff --git a/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala b/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala
index ab14498a7c..7ab73cceff 100644
--- a/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala
@@ -11,6 +11,7 @@ trait MemberLookup {
thisFactory: ModelFactory =>
import global._
+ import rootMirror.RootPackage, rootMirror.EmptyPackage
def makeEntityLink(title: Inline, pos: Position, query: String, inTplOpt: Option[DocTemplateImpl]) =
new EntityLink(title) { lazy val link = memberLookup(pos, query, inTplOpt) }
@@ -21,23 +22,44 @@ trait MemberLookup {
var members = breakMembers(query)
//println(query + " => " + members)
- // (1) Lookup in the root package, as most of the links are qualified
- var linkTo: List[LinkTo] = lookupInRootPackage(pos, members)
+ // (1) First look in the root package, as most of the links are qualified
+ val fromRoot = lookupInRootPackage(pos, members)
- // (2) Recursively go into each
- if (inTplOpt.isDefined) {
- var currentTpl = inTplOpt.get
- while (currentTpl != null && !currentTpl.isRootPackage && (linkTo.isEmpty)) {
- linkTo = lookupInTemplate(pos, members, currentTpl)
- currentTpl = currentTpl.inTemplate
- }
+ // (2) Or recursively go into each containing template.
+ val fromParents = inTplOpt.fold(Stream.empty[DocTemplateImpl]) { tpl =>
+ Stream.iterate(tpl)(_.inTemplate)
+ }.takeWhile (tpl => tpl != null && !tpl.isRootPackage).map { tpl =>
+ lookupInTemplate(pos, members, tpl.asInstanceOf[EntityImpl].sym)
}
- // (3) Look at external links
- if (linkTo.isEmpty) {
- // TODO: IF THIS IS THE ROOT PACKAGE, LOOK AT EXTERNAL LINKS
+ val syms = (fromRoot +: fromParents) find (!_.isEmpty) getOrElse Nil
+ val linkTo = createLinks(syms) match {
+ case Nil if !syms.isEmpty =>
+ // (3) Look at external links
+ syms.flatMap { case (sym, owner) =>
+
+ // reconstruct the original link
+ def linkName(sym: Symbol) = {
+ def isRoot(s: Symbol) = s.isRootSymbol || s.isEmptyPackage || s.isEmptyPackageClass
+ 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(linkName(sym))
+ else if (owner.isClass || owner.isModule || owner.isTrait || owner.isPackage)
+ findExternalLink(linkName(owner) + "@" + externalSignature(sym))
+ else
+ None
+ }
+ case links => links
}
+ //println(createLinks(syms))
+ //println(linkTo)
+
// (4) if we still haven't found anything, create a tooltip, if we found too many, report
if (linkTo.isEmpty){
if (!settings.docNoLinkWarnings.value)
@@ -97,9 +119,23 @@ trait MemberLookup {
private object OnlyType extends SearchStrategy
private object OnlyTerm extends SearchStrategy
- private def lookupInRootPackage(pos: Position, members: List[String]) = lookupInTemplate(pos, members, makeRootPackage)
+ private def lookupInRootPackage(pos: Position, members: List[String]) =
+ if (members.length == 1)
+ lookupInTemplate(pos, members, EmptyPackage) ::: lookupInTemplate(pos, members, RootPackage)
+ else
+ lookupInTemplate(pos, members, RootPackage)
- private def lookupInTemplate(pos: Position, members: List[String], inTpl: DocTemplateImpl): List[LinkTo] = {
+ private def createLinks(syms: List[(Symbol, Symbol)]): List[LinkTo] =
+ syms.flatMap { case (sym, owner) =>
+ if (sym.isClass || sym.isModule || sym.isTrait || sym.isPackage)
+ findTemplateMaybe(sym) map (LinkToTpl(_))
+ else
+ findTemplateMaybe(owner) flatMap { inTpl =>
+ inTpl.members find (_.asInstanceOf[EntityImpl].sym == sym) map (LinkToMember(_, inTpl))
+ }
+ }
+
+ 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:
@@ -108,53 +144,56 @@ trait MemberLookup {
// * 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 Nil => Nil
case mbrName::Nil =>
- var members = lookupInTemplate(pos, mbrName, inTpl, OnlyType)
- if (members.isEmpty)
- members = lookupInTemplate(pos, mbrName, inTpl, OnlyTerm)
-
- members.map(_ match {
- case tpl: DocTemplateEntity => LinkToTpl(tpl)
- case mbr => LinkToMember(mbr, inTpl)
- })
+ 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 filter {sym => sym.isPackage || sym.isClass || sym.isModule} flatMap (lookupInTemplate(pos, rest, _))
- def completeSearch(mbrs: List[MemberImpl]) =
- mbrs.collect({case d:DocTemplateImpl => d}).flatMap(tpl => lookupInTemplate(pos, rest, tpl))
-
- var members = completeSearch(lookupInTemplate(pos, tplName, inTpl, OnlyTerm))
- if (members.isEmpty)
- members = completeSearch(lookupInTemplate(pos, tplName, inTpl, OnlyType))
-
- members
+ completeSearch(lookupInTemplate(pos, tplName, container, OnlyTerm)) match {
+ case Nil => completeSearch(lookupInTemplate(pos, tplName, container, OnlyType))
+ case syms => syms
+ }
}
- //println("lookupInTemplate(" + members + ", " + inTpl + ") => " + result)
+ //println("lookupInTemplate(" + members + ", " + container + ") => " + result)
result
}
- private def lookupInTemplate(pos: Position, member: String, inTpl: DocTemplateImpl, strategy: SearchStrategy): List[MemberImpl] = {
+ 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).alternatives
+ def termSyms = cleanupBogusClasses(syms(newTermName(name)))
+ def typeSyms = cleanupBogusClasses(syms(newTypeName(name)))
+
val result = if (member.endsWith("$"))
- inTpl.members.filter(mbr => (mbr.name == name) && (mbr.isTerm))
+ termSyms
else if (member.endsWith("!"))
- inTpl.members.filter(mbr => (mbr.name == name) && (mbr.isType))
+ typeSyms
else if (member.endsWith("*"))
- inTpl.members.filter(mbr => (mbr.signature.startsWith(name)))
- else {
+ cleanupBogusClasses(container.info.nonPrivateDecls) filter signatureMatch
+ else
if (strategy == BothTypeAndTerm)
- inTpl.members.filter(_.name == name)
+ termSyms ::: typeSyms
else if (strategy == OnlyType)
- inTpl.members.filter(mbr => (mbr.name == name) && (mbr.isType))
+ typeSyms
else if (strategy == OnlyTerm)
- inTpl.members.filter(mbr => (mbr.name == name) && (mbr.isTerm))
+ termSyms
else
Nil
- }
- //println("lookupInTemplate(" + member + ", " + inTpl + ") => " + result)
+ //println("lookupInTemplate(" + member + ", " + container + ") => " + result)
result
}
@@ -170,7 +209,11 @@ trait MemberLookup {
if ((query.charAt(index) == '.' || query.charAt(index) == '#') &&
((index == 0) || (query.charAt(index-1) != '\\'))) {
- members ::= query.substring(last_index, index).replaceAll("\\\\([#\\.])", "$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
@@ -184,4 +227,4 @@ trait MemberLookup {
object MemberLookup {
private[this] var _showExplanation = true
def showExplanation: Boolean = if (_showExplanation) { _showExplanation = false; true } else false
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index a987da8ba6..86bf1f1efd 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -209,7 +209,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
((!sym.isTrait && ((sym hasFlag Flags.ABSTRACT) || (sym hasFlag Flags.DEFERRED)) && (!isImplicitlyInherited)) ||
sym.isAbstractClass || sym.isAbstractType) && !sym.isSynthetic
def isTemplate = false
- lazy val signature = {
+ def signature = externalSignature(sym)
+ lazy val signatureCompat = {
def defParams(mbr: Any): String = mbr match {
case d: MemberEntity with Def =>
@@ -402,7 +403,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
* 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 = {
+ 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)
@@ -1082,5 +1083,17 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
(settings.docExpandAllTypes.value && (bSym.sourceFile != null)) ||
{ val rawComment = global.expandedDocComment(bSym, inTpl.sym)
rawComment.contains("@template") || rawComment.contains("@documentable") }
+
+ def findExternalLink(name: String): Option[LinkTo] =
+ settings.extUrlMapping find {
+ case (pkg, _) => name startsWith pkg
+ } map {
+ case (_, url) => LinkToExternal(name, url + "#" + name)
+ }
+
+ def externalSignature(sym: Symbol) = {
+ sym.info // force it, otherwise we see lazy types
+ (sym.nameString + sym.signatureString).replaceAll("\\s", "")
+ }
}
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala
index 6c80c85efe..c67a398bb7 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala
@@ -30,7 +30,7 @@ trait ModelFactoryTypeSupport {
import definitions.{ ObjectClass, NothingClass, AnyClass, AnyValClass, AnyRefClass }
import rootMirror.{ RootPackage, RootClass, EmptyPackage }
- protected var typeCache = new mutable.LinkedHashMap[Type, TypeEntity]
+ protected val typeCache = new mutable.LinkedHashMap[Type, TypeEntity]
/** */
def makeType(aType: Type, inTpl: TemplateImpl): TypeEntity = {
@@ -77,7 +77,8 @@ trait ModelFactoryTypeSupport {
// ===> 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 we don't generate the doc template, we should at least indicate the correct prefix in the tooltip
+ // (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 */
@@ -87,20 +88,27 @@ trait ModelFactoryTypeSupport {
else
bSym.owner
- val bTpl = findTemplateMaybe(bSym)
val link =
- if (owner == bSym.owner && bTpl.isDefined)
- // (0) the owner's class is linked AND has a template - lovely
- LinkToTpl(bTpl.get)
- else {
- val oTpl = findTemplateMaybe(owner)
- val bMbr = oTpl.map(findMember(bSym, _))
- if (oTpl.isDefined && bMbr.isDefined && bMbr.get.isDefined)
- // (1) the owner's class
- LinkToMember(bMbr.get.get, oTpl.get) //ugh
- else
- // (2) if we still couldn't find the owner, show a tooltip with the qualified name
- Tooltip(makeQualifiedName(bSym))
+ findTemplateMaybe(bSym) match {
+ case Some(bTpl) if owner == bSym.owner =>
+ // (0) the owner's class is linked AND has a template - lovely
+ LinkToTpl(bTpl)
+ 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(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
@@ -308,16 +316,8 @@ trait ModelFactoryTypeSupport {
// 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) {
- val cached = typeCache.get(aType)
- cached match {
- case Some(typeEntity) =>
- typeEntity
- case None =>
- val typeEntity = createTypeEntity
- typeCache += aType -> typeEntity
- typeEntity
- }
- } else createTypeEntity
+ if (settings.docNoPrefixes.value)
+ typeCache.getOrElseUpdate(aType, createTypeEntity)
+ else createTypeEntity
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
index 47eea52095..1baa7f9831 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
@@ -760,7 +760,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
}
def link(): Inline = {
- val SchemeUri = """([^:]+:.*)""".r
+ val SchemeUri = """([a-z]+:.*)""".r
jump("[[")
var parens = 1
readUntil { parens += 1; !check("[") }
diff --git a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala b/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala
index fa698afaa6..db2d0c0175 100644
--- a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala
@@ -150,7 +150,7 @@ trait DiagramFactory extends DiagramDirectiveParser {
if (nodesShown.isEmpty)
None
else {
- val nodes = nodesAll.filter(nodesShown.contains(_)).map(mapNodes(_))
+ 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.
diff --git a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
index dfbbb6ff88..7d332d9f7f 100644
--- a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
+++ b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
@@ -35,7 +35,7 @@ trait ScratchPadMaker { self: Global =>
private def literal(str: String) = "\"\"\""+str+"\"\"\""
- private val prologue = "import scala.runtime.WorksheetSupport._; def main(args: Array[String])=$execute{"
+ private val prologue = ";import scala.runtime.WorksheetSupport._; def main(args: Array[String])=$execute{"
private val epilogue = "}"
@@ -117,12 +117,13 @@ trait ScratchPadMaker { self: Global =>
super.traverse(tree)
case ModuleDef(_, name, Template(_, _, body)) =>
val topLevel = objectName.isEmpty
- if (topLevel) objectName = tree.symbol.fullName
- body foreach traverseStat
- if (skipped != 0) { // don't issue prologue and epilogue if there are no instrumented statements
- applyPendingPatches(skipped)
- if (topLevel)
+ if (topLevel) {
+ objectName = tree.symbol.fullName
+ body foreach traverseStat
+ if (skipped != 0) { // don't issue prologue and epilogue if there are no instrumented statements
+ applyPendingPatches(skipped)
patches += Patch(skipped, epilogue)
+ }
}
case _ =>
}
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index af77d3fe3f..40e520076a 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -21,7 +21,7 @@ trait Patterns extends ast.TreeDSL {
import definitions._
import CODE._
import Debug._
- import treeInfo.{ unbind, isStar, isVarPattern, isVariableName }
+ import treeInfo.{ unbind, isStar, isVarPattern }
type PatternMatch = MatchMatrix#PatternMatch
private type PatternVar = MatrixContext#PatternVar
@@ -366,7 +366,7 @@ trait Patterns extends ast.TreeDSL {
lazy val Select(qualifier, name) = select
def pathSegments = getPathSegments(tree)
def backticked: Option[String] = qualifier match {
- case _: This if isVariableName(name) => Some("`%s`".format(name))
+ case _: This if nme.isVariableName(name) => Some("`%s`".format(name))
case _ => None
}
override def covers(sym: Symbol) = newMatchesPattern(sym, tree.tpe)
@@ -388,11 +388,11 @@ trait Patterns extends ast.TreeDSL {
lazy val UnApply(unfn, args) = tree
lazy val Apply(fn, _) = unfn
lazy val MethodType(List(arg, _*), _) = fn.tpe
-
+
// Covers if the symbol matches the unapply method's argument type,
// and the return type of the unapply is Some.
override def covers(sym: Symbol) = newMatchesPattern(sym, arg.tpe)
-
+
// TODO: for alwaysCovers:
// fn.tpe.finalResultType.typeSymbol == SomeClass
@@ -451,7 +451,7 @@ trait Patterns extends ast.TreeDSL {
(sym.tpe.baseTypeSeq exists (_ matchesPattern pattp))
}
}
-
+
def sym = tree.symbol
def tpe = tree.tpe
def isEmpty = tree.isEmpty
@@ -496,4 +496,4 @@ trait Patterns extends ast.TreeDSL {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala
index 16f8685a87..72284cc940 100644
--- a/src/compiler/scala/tools/nsc/settings/Warnings.scala
+++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala
@@ -18,6 +18,7 @@ trait Warnings {
// These warnings are all so noisy as to be useless in their
// present form, but have the potential to offer useful info.
protected def allWarnings = lintWarnings ++ List(
+ warnDeadCode,
warnSelectNullable,
warnValueDiscard,
warnNumericWiden
@@ -25,7 +26,7 @@ trait Warnings {
// These warnings should be pretty quiet unless you're doing
// something inadvisable.
protected def lintWarnings = List(
- warnDeadCode,
+ // warnDeadCode,
warnInaccessible,
warnNullaryOverride,
warnNullaryUnit,
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index f7c3a55954..369b6aa77d 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -219,7 +219,7 @@ abstract class SymbolLoaders {
/**
* Load contents of a package
*/
- class PackageLoader(classpath: ClassPath[platform.BinaryRepr]) extends SymbolLoader {
+ class PackageLoader(classpath: ClassPath[platform.BinaryRepr]) extends SymbolLoader with FlagAgnosticCompleter {
protected def description = "package loader "+ classpath.name
protected def doComplete(root: Symbol) {
@@ -242,7 +242,7 @@ abstract class SymbolLoaders {
}
}
- class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader {
+ class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader with FlagAssigningCompleter {
private object classfileParser extends ClassfileParser {
val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global
}
@@ -267,7 +267,7 @@ abstract class SymbolLoaders {
override def sourcefile: Option[AbstractFile] = classfileParser.srcfile
}
- class MsilFileLoader(msilFile: MsilFile) extends SymbolLoader {
+ class MsilFileLoader(msilFile: MsilFile) extends SymbolLoader with FlagAssigningCompleter {
private def typ = msilFile.msilType
private object typeParser extends clr.TypeParser {
val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global
@@ -277,14 +277,14 @@ abstract class SymbolLoaders {
protected def doComplete(root: Symbol) { typeParser.parse(typ, root) }
}
- class SourcefileLoader(val srcfile: AbstractFile) extends SymbolLoader {
+ class SourcefileLoader(val srcfile: AbstractFile) extends SymbolLoader with FlagAssigningCompleter {
protected def description = "source file "+ srcfile.toString
override def fromSource = true
override def sourcefile = Some(srcfile)
protected def doComplete(root: Symbol): Unit = global.currentRun.compileLate(srcfile)
}
- object moduleClassLoader extends SymbolLoader {
+ object moduleClassLoader extends SymbolLoader with FlagAssigningCompleter {
protected def description = "module class loader"
protected def doComplete(root: Symbol) { root.sourceModule.initialize }
}
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index a356b70e62..8fd8dfaf83 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -844,7 +844,7 @@ abstract class ClassfileParser {
GenPolyType(ownTypeParams, tpe)
} // sigToType
- class TypeParamsType(override val typeParams: List[Symbol]) extends LazyType {
+ class TypeParamsType(override val typeParams: List[Symbol]) extends LazyType with FlagAgnosticCompleter {
override def complete(sym: Symbol) { throw new AssertionError("cyclic type dereferencing") }
}
@@ -1228,7 +1228,7 @@ abstract class ClassfileParser {
}
}
- class LazyAliasType(alias: Symbol) extends LazyType {
+ class LazyAliasType(alias: Symbol) extends LazyType with FlagAgnosticCompleter {
override def complete(sym: Symbol) {
sym setInfo createFromClonedSymbols(alias.initialize.typeParams, alias.tpe)(typeFun)
}
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
index 18b95ba191..1d2ffd2a73 100644
--- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
@@ -64,7 +64,7 @@ abstract class TypeParser {
busy = false
}
- class TypeParamsType(override val typeParams: List[Symbol]) extends LazyType {
+ class TypeParamsType(override val typeParams: List[Symbol]) extends LazyType with FlagAgnosticCompleter {
override def complete(sym: Symbol) { throw new AssertionError("cyclic type dereferencing") }
}
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index ab0a8756a4..18db1e6ab4 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -132,7 +132,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
* - for every interface member of iface: its implementation method, if one is needed
* - every former member of iface that is implementation only
*/
- private class LazyImplClassType(iface: Symbol) extends LazyType {
+ private class LazyImplClassType(iface: Symbol) extends LazyType with FlagAgnosticCompleter {
/** Compute the decls of implementation class implClass,
* given the decls ifaceDecls of its interface.
*/
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 072d823c60..3ac7dd2a8f 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -225,6 +225,24 @@ abstract class Erasure extends AddInterfaces
} else {
boxedSig(tp)
}
+ def classSig = {
+ val preRebound = pre.baseType(sym.owner) // #2585
+ dotCleanup(
+ (
+ if (needsJavaSig(preRebound)) {
+ val s = jsig(preRebound, existentiallyBound)
+ if (s.charAt(0) == 'L') s.substring(0, s.length - 1) + "." + sym.javaSimpleName
+ else fullNameInSig(sym)
+ }
+ else fullNameInSig(sym)
+ ) + (
+ if (args.isEmpty) "" else
+ "<"+(args map argSig).mkString+">"
+ ) + (
+ ";"
+ )
+ )
+ }
// If args isEmpty, Array is being used as a type constructor
if (sym == ArrayClass && args.nonEmpty) {
@@ -248,25 +266,21 @@ abstract class Erasure extends AddInterfaces
else if (sym == UnitClass) jsig(BoxedUnitClass.tpe)
else abbrvTag(sym).toString
}
- else if (sym.isClass) {
- val preRebound = pre.baseType(sym.owner) // #2585
- dotCleanup(
- (
- if (needsJavaSig(preRebound)) {
- val s = jsig(preRebound, existentiallyBound)
- if (s.charAt(0) == 'L') s.substring(0, s.length - 1) + "." + sym.javaSimpleName
- else fullNameInSig(sym)
- }
- else fullNameInSig(sym)
- ) + (
- if (args.isEmpty) "" else
- "<"+(args map argSig).mkString+">"
- ) + (
- ";"
- )
- )
+ else if (sym.isDerivedValueClass) {
+ val unboxed = sym.derivedValueClassUnbox.info.finalResultType
+ val unboxedSeen = (tp memberType sym.derivedValueClassUnbox).finalResultType
+ def unboxedMsg = if (unboxed == unboxedSeen) "" else s", seen within ${sym.simpleName} as $unboxedSeen"
+ logResult(s"Erasure of value class $sym (underlying type $unboxed$unboxedMsg) is") {
+ if (isPrimitiveValueType(unboxedSeen) && !primitiveOK)
+ classSig
+ else
+ jsig(unboxedSeen, existentiallyBound, toplevel, primitiveOK)
+ }
}
- else jsig(erasure(sym0)(tp), existentiallyBound, toplevel, primitiveOK)
+ else if (sym.isClass)
+ classSig
+ else
+ jsig(erasure(sym0)(tp), existentiallyBound, toplevel, primitiveOK)
case PolyType(tparams, restpe) =>
assert(tparams.nonEmpty)
val poly = if (toplevel) polyParamSig(tparams) else ""
@@ -649,7 +663,7 @@ abstract class Erasure extends AddInterfaces
/** Generate a synthetic cast operation from tree.tpe to pt.
* @pre pt eq pt.normalize
*/
- private def cast(tree: Tree, pt: Type): Tree = {
+ private def cast(tree: Tree, pt: Type): Tree = logResult(s"cast($tree, $pt)") {
if (pt.typeSymbol == UnitClass) {
// See SI-4731 for one example of how this occurs.
log("Attempted to cast to Unit: " + tree)
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 5a3db26e30..d3a5cebea0 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -185,7 +185,7 @@ abstract class UnCurry extends InfoTransform
* try {
* body
* } catch {
- * case ex: NonLocalReturnControl[_] =>
+ * case ex: NonLocalReturnControl[T @unchecked] =>
* if (ex.key().eq(key)) ex.value()
* else throw ex
* }
@@ -195,7 +195,8 @@ abstract class UnCurry extends InfoTransform
localTyper typed {
val extpe = nonLocalReturnExceptionType(meth.tpe.finalResultType)
val ex = meth.newValue(nme.ex, body.pos) setInfo extpe
- val pat = gen.mkBindForCase(ex, NonLocalReturnControlClass, List(meth.tpe.finalResultType))
+ val argType = meth.tpe.finalResultType withAnnotation (AnnotationInfo marker UncheckedClass.tpe)
+ val pat = gen.mkBindForCase(ex, NonLocalReturnControlClass, List(argType))
val rhs = (
IF ((ex DOT nme.key)() OBJ_EQ Ident(key))
THEN ((ex DOT nme.value)())
diff --git a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
new file mode 100644
index 0000000000..7e15cf91a7
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
@@ -0,0 +1,284 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2012 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package typechecker
+
+import scala.collection.{ mutable, immutable }
+import scala.collection.mutable.ListBuffer
+import scala.util.control.ControlThrowable
+import symtab.Flags._
+import scala.annotation.tailrec
+import Checkability._
+
+/** On pattern matcher checkability:
+ *
+ * Consider a pattern match of this form: (x: X) match { case _: P => }
+ *
+ * There are four possibilities to consider:
+ * [P1] X will always conform to P
+ * [P2] x will never conform to P
+ * [P3] X <: P if some runtime test is true
+ * [P4] X cannot be checked against P
+ *
+ * The first two cases correspond to those when there is enough
+ * static information to say X <: P or that (x ∈ X) ⇒ (x ∉ P).
+ * The fourth case includes unknown abstract types or structural
+ * refinements appearing within a pattern.
+ *
+ * The third case is the interesting one. We designate another type, XR,
+ * which is essentially the intersection of X and |P|, where |P| is
+ * the erasure of P. If XR <: P, then no warning is emitted.
+ *
+ * Examples of how this info is put to use:
+ * sealed trait A[T] ; class B[T] extends A[T]
+ * def f(x: B[Int]) = x match { case _: A[Int] if true => }
+ * def g(x: A[Int]) = x match { case _: B[Int] => }
+ *
+ * `f` requires no warning because X=B[Int], P=A[Int], and B[Int] <:< A[Int].
+ * `g` requires no warning because X=A[Int], P=B[Int], XR=B[Int], and B[Int] <:< B[Int].
+ * XR=B[Int] because a value of type A[Int] which is tested to be a B can
+ * only be a B[Int], due to the definition of B (B[T] extends A[T].)
+ *
+ * This is something like asSeenFrom, only rather than asking what a type looks
+ * like from the point of view of one of its base classes, we ask what it looks
+ * like from the point of view of one of its subclasses.
+ */
+trait Checkable {
+ self: Analyzer =>
+
+ import global._
+ import definitions._
+ import CheckabilityChecker.{ isNeverSubType, isNeverSubClass }
+
+ /** The applied type of class 'to' after inferring anything
+ * possible from the knowledge that 'to' must also be of the
+ * type given in 'from'.
+ */
+ def propagateKnownTypes(from: Type, to: Symbol): Type = {
+ def tparams = to.typeParams
+ val tvars = tparams map (p => TypeVar(p))
+ val tvarType = appliedType(to, tvars: _*)
+ val bases = from.baseClasses filter (to.baseClasses contains _)
+
+ bases foreach { bc =>
+ val tps1 = (from baseType bc).typeArgs
+ val tps2 = (tvarType baseType bc).typeArgs
+ (tps1, tps2).zipped foreach (_ =:= _)
+ // Alternate, variance respecting formulation causes
+ // neg/unchecked3.scala to fail (abstract types). TODO -
+ // figure it out. It seems there is more work to do if I
+ // allow for variance, because the constraints accumulate
+ // as bounds and "tvar.instValid" is false.
+ //
+ // foreach3(tps1, tps2, bc.typeParams)((tp1, tp2, tparam) =>
+ // if (tparam.initialize.isCovariant) tp1 <:< tp2
+ // else if (tparam.isContravariant) tp2 <:< tp1
+ // else tp1 =:= tp2
+ // )
+ }
+
+ val resArgs = tparams zip tvars map {
+ case (_, tvar) if tvar.instValid => tvar.constr.inst
+ case (tparam, _) => tparam.tpe
+ }
+ appliedType(to, resArgs: _*)
+ }
+
+ private def isUnwarnableTypeArgSymbol(sym: Symbol) = (
+ sym.isTypeParameter // dummy
+ || (sym.name.toTermName == nme.WILDCARD) // _
+ || nme.isVariableName(sym.name) // type variable
+ )
+ private def isUnwarnableTypeArg(arg: Type) = (
+ uncheckedOk(arg) // @unchecked T
+ || isUnwarnableTypeArgSymbol(arg.typeSymbolDirect) // has to be direct: see pos/t1439
+ )
+ private def uncheckedOk(tp: Type) = tp hasAnnotation UncheckedClass
+
+ private def typeArgsInTopLevelType(tp: Type): List[Type] = {
+ val tps = tp match {
+ case RefinedType(parents, _) => parents flatMap typeArgsInTopLevelType
+ case TypeRef(_, ArrayClass, arg :: Nil) => typeArgsInTopLevelType(arg)
+ case TypeRef(pre, sym, args) => typeArgsInTopLevelType(pre) ++ args
+ case ExistentialType(tparams, underlying) => tparams.map(_.tpe) ++ typeArgsInTopLevelType(underlying)
+ case _ => Nil
+ }
+ tps filterNot isUnwarnableTypeArg
+ }
+
+ private class CheckabilityChecker(val X: Type, val P: Type) {
+ def Xsym = X.typeSymbol
+ def Psym = P.typeSymbol
+ def XR = propagateKnownTypes(X, Psym)
+ // sadly the spec says (new java.lang.Boolean(true)).isInstanceOf[scala.Boolean]
+ def P1 = X matchesPattern P
+ def P2 = !Psym.isPrimitiveValueClass && isNeverSubType(X, P)
+ def P3 = isNonRefinementClassType(P) && (XR matchesPattern P)
+ def P4 = !(P1 || P2 || P3)
+
+ def summaryString = f"""
+ |Checking checkability of (x: $X) against pattern $P
+ |[P1] $P1%-6s X <: P // $X <: $P
+ |[P2] $P2%-6s x ∉ P // (x ∈ $X) ⇒ (x ∉ $P)
+ |[P3] $P3%-6s XR <: P // $XR <: $P
+ |[P4] $P4%-6s None of the above // !(P1 || P2 || P3)
+ """.stripMargin.trim
+
+ val result = (
+ if (X.isErroneous || P.isErroneous) CheckabilityError
+ else if (P1) StaticallyTrue
+ else if (P2) StaticallyFalse
+ else if (P3) RuntimeCheckable
+ else if (uncheckableType == NoType) {
+ // Avoid warning (except ourselves) if we can't pinpoint the uncheckable type
+ debugwarn("Checkability checker says 'Uncheckable', but uncheckable type cannot be found:\n" + summaryString)
+ CheckabilityError
+ }
+ else Uncheckable
+ )
+ lazy val uncheckableType = if (Psym.isAbstractType) P else {
+ val possibles = typeArgsInTopLevelType(P).toSet
+ val opt = possibles find { targ =>
+ // Create a derived type with every possibly uncheckable type replaced
+ // with a WildcardType, except for 'targ'. If !(XR <: derived) then
+ // 'targ' is uncheckable.
+ val derived = P map (tp => if (possibles(tp) && !(tp =:= targ)) WildcardType else tp)
+ !(XR <:< derived)
+ }
+ opt getOrElse NoType
+ }
+
+ def neverSubClass = isNeverSubClass(Xsym, Psym)
+ def neverMatches = result == StaticallyFalse
+ def isUncheckable = result == Uncheckable
+ def uncheckableMessage = uncheckableType match {
+ case NoType => "something"
+ case tp @ RefinedType(_, _) => "refinement " + tp
+ case TypeRef(_, sym, _) if sym.isAbstractType => "abstract type " + sym.name
+ case tp => "non-variable type argument " + tp
+ }
+ }
+
+ /** X, P, [P1], etc. are all explained at the top of the file.
+ */
+ private object CheckabilityChecker {
+ /** A knowable class is one which is either effectively final
+ * itself, or sealed with only knowable children.
+ */
+ def isKnowable(sym: Symbol): Boolean = /*logResult(s"isKnowable($sym)")*/(
+ sym.initialize.isEffectivelyFinal // pesky .initialize requirement, or we receive lies about isSealed
+ || sym.isSealed && (sym.children forall isKnowable)
+ )
+ def knownSubclasses(sym: Symbol): List[Symbol] = /*logResult(s"knownSubclasses($sym)")*/(sym :: {
+ if (sym.isSealed) sym.children.toList flatMap knownSubclasses
+ else Nil
+ })
+ def excludable(s1: Symbol, s2: Symbol) = /*logResult(s"excludable($s1, $s2)")*/(
+ isKnowable(s1)
+ && !(s2 isSubClass s1)
+ && knownSubclasses(s1).forall(child => !(child isSubClass s2))
+ )
+
+ /** Given classes A and B, can it be shown that nothing which is
+ * an A will ever be a subclass of something which is a B? This
+ * entails not only showing that !(A isSubClass B) but that the
+ * same is true of all their subclasses. Restated for symmetry:
+ * the same value cannot be a member of both A and B.
+ *
+ * 1) A must not be a subclass of B, nor B of A (the trivial check)
+ * 2) One of A or B must be completely knowable (see isKnowable)
+ * 3) Assuming A is knowable, the proposition is true if
+ * !(A' isSubClass B) for all A', where A' is a subclass of A.
+ *
+ * Due to symmetry, the last condition applies as well in reverse.
+ */
+ def isNeverSubClass(sym1: Symbol, sym2: Symbol) = /*logResult(s"isNeverSubClass($sym1, $sym2)")*/(
+ sym1.isClass
+ && sym2.isClass
+ && (excludable(sym1, sym2) || excludable(sym2, sym1))
+ )
+ private def isNeverSubArgs(tps1: List[Type], tps2: List[Type], tparams: List[Symbol]): Boolean = /*logResult(s"isNeverSubArgs($tps1, $tps2, $tparams)")*/ {
+ def isNeverSubArg(t1: Type, t2: Type, variance: Int) = {
+ if (variance > 0) isNeverSubType(t2, t1)
+ else if (variance < 0) isNeverSubType(t1, t2)
+ else isNeverSameType(t1, t2)
+ }
+ exists3(tps1, tps2, tparams map (_.variance))(isNeverSubArg)
+ }
+ private def isNeverSameType(tp1: Type, tp2: Type): Boolean = (tp1, tp2) match {
+ case (TypeRef(_, sym1, args1), TypeRef(_, sym2, args2)) =>
+ ( isNeverSubClass(sym1, sym2)
+ || isNeverSubClass(sym2, sym1)
+ || ((sym1 == sym2) && isNeverSubArgs(args1, args2, sym1.typeParams))
+ )
+ case _ =>
+ false
+ }
+ // Important to dealias at any entry point (this is the only one at this writing.)
+ def isNeverSubType(tp1: Type, tp2: Type): Boolean = /*logResult(s"isNeverSubType($tp1, $tp2)")*/((tp1.dealias, tp2.dealias) match {
+ case (TypeRef(_, sym1, args1), TypeRef(_, sym2, args2)) =>
+ isNeverSubClass(sym1, sym2) || {
+ (sym1 isSubClass sym2) && {
+ val tp1seen = tp1 baseType sym2
+ isNeverSubArgs(tp1seen.typeArgs, args2, sym2.typeParams)
+ }
+ }
+ case _ => false
+ })
+ }
+
+ trait InferCheckable {
+ self: Inferencer =>
+
+ /** TODO: much better error positions.
+ * Kind of stuck right now because they just pass us the one tree.
+ * TODO: Eliminate inPattern, canRemedy, which have no place here.
+ */
+ def checkCheckable(tree: Tree, P0: Type, X0: Type, inPattern: Boolean, canRemedy: Boolean = false) {
+ if (uncheckedOk(P0)) return
+ def where = if (inPattern) "pattern " else ""
+
+ // singleton types not considered here
+ val P = P0.widen
+ val X = X0.widen
+
+ P match {
+ // Prohibit top-level type tests for these, but they are ok nested (e.g. case Foldable[Nothing] => ... )
+ case TypeRef(_, NothingClass | NullClass | AnyValClass, _) =>
+ InferErrorGen.TypePatternOrIsInstanceTestError(tree, P)
+ // If top-level abstract types can be checked using a classtag extractor, don't warn about them
+ case TypeRef(_, sym, _) if sym.isAbstractType && canRemedy =>
+ ;
+ // Matching on types like case _: AnyRef { def bippy: Int } => doesn't work -- yet.
+ case RefinedType(_, decls) if !decls.isEmpty =>
+ getContext.unit.warning(tree.pos, s"a pattern match on a refinement type is unchecked")
+ case _ =>
+ val checker = new CheckabilityChecker(X, P)
+ log(checker.summaryString)
+ if (checker.neverMatches) {
+ val addendum = if (checker.neverSubClass) "" else " (but still might match its erasure)"
+ getContext.unit.warning(tree.pos, s"fruitless type test: a value of type $X cannot also be a $P$addendum")
+ }
+ else if (checker.isUncheckable) {
+ val msg = (
+ if (checker.uncheckableType =:= P) s"abstract type $where$P"
+ else s"${checker.uncheckableMessage} in type $where$P"
+ )
+ getContext.unit.warning(tree.pos, s"$msg is unchecked since it is eliminated by erasure")
+ }
+ }
+ }
+ }
+}
+
+private[typechecker] final class Checkability(val value: Int) extends AnyVal { }
+private[typechecker] object Checkability {
+ val StaticallyTrue = new Checkability(0)
+ val StaticallyFalse = new Checkability(1)
+ val RuntimeCheckable = new Checkability(2)
+ val Uncheckable = new Checkability(3)
+ val CheckabilityError = new Checkability(4)
+}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 22077303a4..0c3dcb9342 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -17,7 +17,7 @@ import scala.annotation.tailrec
* @author Martin Odersky
* @version 1.0
*/
-trait Infer {
+trait Infer extends Checkable {
self: Analyzer =>
import global._
@@ -254,7 +254,7 @@ trait Infer {
private val stdErrorValue = stdErrorClass.newErrorValue(nme.ERROR)
/** The context-dependent inferencer part */
- class Inferencer(context: Context) extends InferencerContextErrors {
+ class Inferencer(context: Context) extends InferencerContextErrors with InferCheckable {
import InferErrorGen._
/* -- Error Messages --------------------------------------------------- */
@@ -1341,99 +1341,6 @@ trait Infer {
check(tp, Nil)
}
- // if top-level abstract types can be checked using a classtag extractor, don't warn about them
- def checkCheckable(tree: Tree, typeToTest: Type, typeEnsured: Type, inPattern: Boolean, canRemedy: Boolean = false) = {
- log(s"checkCheckable($tree, $typeToTest, $typeEnsured, inPattern = $inPattern, canRemedy = $canRemedy")
-
- sealed abstract class TypeConformance(check: (Type, Type) => Boolean) {
- def apply(t1: Type, t2: Type): Boolean = check(t1, t2) && {
- log(s"Skipping unchecked for statically verifiable condition $t1 ${this} $t2")
- true
- }
- }
- // I tried to use varianceInType to track the variance implications
- // but I could not make it work.
- case object =:= extends TypeConformance(_ =:= _)
- case object <:< extends TypeConformance(_ <:< _)
- case object >:> extends TypeConformance((t1, t2) => t2 <:< t1)
- case object =!= extends TypeConformance((t1, t2) => false)
-
- var bound: List[Symbol] = Nil
- var warningMessages: List[String] = Nil
-
- def isLocalBinding(sym: Symbol) = (
- sym.isAbstractType && (
- (bound contains sym)
- || (sym.name == tpnme.WILDCARD)
- || {
- val e = context.scope.lookupEntry(sym.name)
- (e ne null) && e.sym == sym && !e.sym.isTypeParameterOrSkolem && e.owner == context.scope
- }
- )
- )
- def check(tp0: Type, pt: Type, conformance: TypeConformance): Boolean = {
- val tp = tp0.normalize
- // Set the warning message to be issued when the top-level call fails.
- def warn(what: String): Boolean = {
- warningMessages ::= what
- false
- }
- def checkArg(param: Symbol, arg: Type) = {
- def conforms = (
- if (param.isCovariant) <:<
- else if (param.isContravariant) >:>
- else =:=
- )
- (arg hasAnnotation UncheckedClass) || {
- arg.withoutAnnotations match {
- case TypeRef(_, sym, args) =>
- ( isLocalBinding(sym)
- || arg.typeSymbol.isTypeParameterOrSkolem
- || (sym.name == tpnme.WILDCARD) // avoid spurious warnings on HK types
- || check(arg, param.tpeHK, conforms)
- || warn("non-variable type argument " + arg)
- )
- case _ =>
- warn("non-variable type argument " + arg)
- }
- }
- }
-
- // Checking if pt (the expected type of the pattern, and the type
- // we are guaranteed) conforms to tp (the type expressed in the pattern's
- // type test.) If it does, then even if the type being checked for appears
- // to be uncheckable, it is not a warning situation, because it is indeed
- // checked: not at runtime, but statically.
- conformance.apply(pt, tp) || (tp match {
- case SingleType(pre, _) => check(pre, pt, =:=)
- case ExistentialType(quantified, tp1) => bound :::= quantified ; check(tp1, pt, <:<)
- case ThisType(_) | NoPrefix => true
- case RefinedType(parents, decls) if decls.isEmpty => parents forall (p => check(p, pt, <:<))
- case RefinedType(_, _) => warn("refinement " + tp)
- case TypeRef(_, ArrayClass, arg :: Nil) => check(arg, NoType, =!=)
- case TypeRef(_, NonLocalReturnControlClass, _) => true // no way to suppress unchecked warnings on try/catch
- // we only use the extractor for top-level type tests, type arguments remain unchecked
- case TypeRef(_, sym, _) if sym.isAbstractType => isLocalBinding(sym) || canRemedy || warn("abstract type " + tp)
- case TypeRef(_, _, Nil) => false // leaf node
- case TypeRef(pre, sym, args) => forall2(sym.typeParams, args)(checkArg) && check(pre, pt.prefix, =:=)
- case _ => warn("type " + tp)
- })
- }
- typeToTest match {
- // Prohibit top-level type tests for these, but they are
- // acceptable nested (e.g. case Foldable[Nothing] => ... )
- case TypeRef(_, NothingClass | NullClass | AnyValClass, _) =>
- TypePatternOrIsInstanceTestError(tree, typeToTest)
- case _ =>
- def where = ( if (inPattern) "pattern " else "" ) + typeToTest
- if (check(typeToTest, typeEnsured, =:=)) ()
- // Note that this is a regular warning, not an uncheckedWarning,
- // which is now the province of such notifications as "pattern matcher
- // exceeded its analysis budget."
- else warningMessages foreach (m =>
- context.unit.warning(tree.pos, s"$m in type $where is unchecked since it is eliminated by erasure"))
- }
- }
/** Type intersection of simple type tp1 with general type tp2.
* The result eliminates some redundancies.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index f9a35ba9a0..bcc37e8b37 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -354,7 +354,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
macroTraceVerbose("tparams are: ")(tparams)
macroTraceVerbose("vparamss are: ")(vparamss)
macroTraceVerbose("retTpe is: ")(retTpe)
- macroTraceVerbose("macroImplSig is: ")(paramss, implRetTpe)
+ macroTraceVerbose("macroImplSig is: ")((paramss, implRetTpe))
}
/** Verifies that the body of a macro def typechecks to a reference to a static public non-overloaded method,
diff --git a/src/compiler/scala/tools/nsc/typechecker/Modes.scala b/src/compiler/scala/tools/nsc/typechecker/Modes.scala
index e9ea99faab..d942d080cb 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Modes.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Modes.scala
@@ -86,6 +86,10 @@ trait Modes {
*/
final val TYPEPATmode = 0x10000
+ /** RETmode is set when we are typing a return expression.
+ */
+ final val RETmode = 0x20000
+
final private val StickyModes = EXPRmode | PATTERNmode | TYPEmode | ALTmode
final def onlyStickyModes(mode: Int) =
@@ -133,4 +137,4 @@ trait Modes {
def modeString(mode: Int): String =
if (mode == 0) "NOmode"
else (modeNameMap filterKeys (bit => inAllModes(mode, bit))).values mkString " "
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 9e66d696cb..1b2225f5f2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1506,7 +1506,7 @@ trait Namers extends MethodSynthesis {
/** A class representing a lazy type with known type parameters.
*/
- class PolyTypeCompleter(tparams: List[TypeDef], restp: TypeCompleter, owner: Tree, ctx: Context) extends LockingTypeCompleter {
+ class PolyTypeCompleter(tparams: List[TypeDef], restp: TypeCompleter, owner: Tree, ctx: Context) extends LockingTypeCompleter with FlagAgnosticCompleter {
private val ownerSym = owner.symbol
override val typeParams = tparams map (_.symbol) //@M
override val tree = restp.tree
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index d0b715d502..2282f62152 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -1589,7 +1589,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
object EqualityCond {
private val uniques = new scala.collection.mutable.HashMap[(Tree, Tree), EqualityCond]
def apply(testedPath: Tree, rhs: Tree): EqualityCond = uniques getOrElseUpdate((testedPath, rhs), new EqualityCond(testedPath, rhs))
- def unapply(c: EqualityCond) = Some(c.testedPath, c.rhs)
+ def unapply(c: EqualityCond) = Some((c.testedPath, c.rhs))
}
class EqualityCond(val testedPath: Tree, val rhs: Tree) extends Cond {
override def toString = testedPath +" == "+ rhs +"#"+ id
@@ -1607,7 +1607,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
object TypeCond {
private val uniques = new scala.collection.mutable.HashMap[(Tree, Type), TypeCond]
def apply(testedPath: Tree, pt: Type): TypeCond = uniques getOrElseUpdate((testedPath, pt), new TypeCond(testedPath, pt))
- def unapply(c: TypeCond) = Some(c.testedPath, c.pt)
+ def unapply(c: TypeCond) = Some((c.testedPath, c.pt))
}
class TypeCond(val testedPath: Tree, val pt: Type) extends Cond {
override def toString = testedPath +" : "+ pt +"#"+ id
@@ -1645,7 +1645,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
def unapply(xtm: ExtractorTreeMaker): Option[(Tree, Symbol)] = xtm match {
case ExtractorTreeMaker(extractor, None, nextBinder) if irrefutableExtractorType(extractor.tpe) =>
- Some(extractor, nextBinder)
+ Some((extractor, nextBinder))
case _ =>
None
}
@@ -1864,7 +1864,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
def registerEquality(c: Const): Unit
// call this to indicate null is part of the domain
- def registerNull: Unit
+ def registerNull(): Unit
// can this variable be null?
def mayBeNull: Boolean
@@ -2279,7 +2279,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
val staticTpCheckable: Type = checkableType(staticTp)
private[this] var _mayBeNull = false
- def registerNull: Unit = { ensureCanModify; if (NullTp <:< staticTpCheckable) _mayBeNull = true }
+ def registerNull(): Unit = { ensureCanModify; if (NullTp <:< staticTpCheckable) _mayBeNull = true }
def mayBeNull: Boolean = _mayBeNull
// case None => domain is unknown,
@@ -2676,7 +2676,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
case UnitClass =>
Some(List(UnitClass.tpe))
case BooleanClass =>
- Some(List(ConstantType(Constant(true)), ConstantType(Constant(false))))
+ Some((List(ConstantType(Constant(true)), ConstantType(Constant(false)))))
// TODO case _ if tp.isTupleType => // recurse into component types
case modSym: ModuleClassSymbol =>
Some(List(tp))
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 84ec86b194..e3f5214581 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1631,12 +1631,14 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
case NullaryMethodType(restpe) if restpe.typeSymbol == UnitClass =>
// this may be the implementation of e.g. a generic method being parameterized
// on Unit, in which case we had better let it slide.
- if (sym.isGetter || sym.allOverriddenSymbols.exists(over => !(over.tpe.resultType =:= sym.tpe.resultType))) ()
- else unit.warning(sym.pos,
- "side-effecting nullary methods are discouraged: suggest defining as `def %s()` instead".format(
- sym.name.decode)
+ val isOk = (
+ sym.isGetter
+ || sym.allOverriddenSymbols.exists(over => !(over.tpe.resultType =:= sym.tpe.resultType))
+ || (sym.name containsName nme.DEFAULT_GETTER_STRING)
)
- case _ => ()
+ if (!isOk)
+ unit.warning(sym.pos, s"side-effecting nullary methods are discouraged: suggest defining as `def ${sym.name.decode}()` instead")
+ case _ => ()
}
// Verify classes extending AnyVal meet the requirements
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index af89af74d0..c25b6c3726 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -253,12 +253,6 @@ trait Typers extends Modes with Adaptations with Tags {
result
}
}
- def isNonRefinementClassType(tpe: Type) = tpe match {
- case SingleType(_, sym) => sym.isModuleClass
- case TypeRef(_, sym, _) => sym.isClass && !sym.isRefinementClass
- case ErrorType => true
- case _ => false
- }
private def errorNotClass(tpt: Tree, found: Type) = { ClassTypeRequiredError(tpt, found); false }
private def errorNotStable(tpt: Tree, found: Type) = { TypeNotAStablePrefixError(tpt, found); false }
@@ -3768,9 +3762,13 @@ trait Typers extends Modes with Adaptations with Tags {
if (fun.symbol == Predef_classOf)
typedClassOf(tree, args.head, true)
else {
- if (!isPastTyper && fun.symbol == Any_isInstanceOf && !targs.isEmpty)
- checkCheckable(tree, targs.head, AnyClass.tpe, inPattern = false)
-
+ if (!isPastTyper && fun.symbol == Any_isInstanceOf && targs.nonEmpty) {
+ val scrutineeType = fun match {
+ case Select(qual, _) => qual.tpe
+ case _ => AnyClass.tpe
+ }
+ checkCheckable(tree, targs.head, scrutineeType, inPattern = false)
+ }
val resultpe = restpe.instantiateTypeParams(tparams, targs)
//@M substitution in instantiateParams needs to be careful!
//@M example: class Foo[a] { def foo[m[x]]: m[a] = error("") } (new Foo[Int]).foo[List] : List[Int]
@@ -3780,7 +3778,8 @@ trait Typers extends Modes with Adaptations with Tags {
//println("instantiating type params "+restpe+" "+tparams+" "+targs+" = "+resultpe)
treeCopy.TypeApply(tree, fun, args) setType resultpe
}
- } else {
+ }
+ else {
TypedApplyWrongNumberOfTpeParametersError(tree, fun)
}
case ErrorType =>
@@ -4177,7 +4176,7 @@ trait Typers extends Modes with Adaptations with Tags {
ReturnWithoutTypeError(tree, enclMethod.owner)
} else {
context.enclMethod.returnsSeen = true
- val expr1: Tree = typed(expr, EXPRmode | BYVALmode, restpt.tpe)
+ val expr1: Tree = typed(expr, EXPRmode | BYVALmode | RETmode, restpt.tpe)
// Warn about returning a value if no value can be returned.
if (restpt.tpe.typeSymbol == UnitClass) {
// The typing in expr1 says expr is Unit (it has already been coerced if
@@ -4186,7 +4185,8 @@ trait Typers extends Modes with Adaptations with Tags {
if (typed(expr).tpe.typeSymbol != UnitClass)
unit.warning(tree.pos, "enclosing method " + name + " has result type Unit: return value discarded")
}
- treeCopy.Return(tree, checkDead(expr1)) setSymbol enclMethod.owner setType NothingClass.tpe
+ treeCopy.Return(tree, checkDead(expr1)).setSymbol(enclMethod.owner)
+ .setType(adaptTypeOfReturn(expr1, restpt.tpe, NothingClass.tpe))
}
}
}
diff --git a/src/compiler/scala/tools/reflect/FrontEnd.scala b/src/compiler/scala/tools/reflect/FrontEnd.scala
new file mode 100644
index 0000000000..f0d3d5973d
--- /dev/null
+++ b/src/compiler/scala/tools/reflect/FrontEnd.scala
@@ -0,0 +1,50 @@
+package scala.tools
+package reflect
+
+import scala.reflect.internal.util.Position
+
+trait FrontEnd {
+ object severity extends Enumeration
+ class Severity(val id: Int) extends severity.Value {
+ var count: Int = 0
+ override def toString() = this match {
+ case INFO => "INFO"
+ case WARNING => "WARNING"
+ case ERROR => "ERROR"
+ case _ => "<unknown>"
+ }
+ }
+ val INFO = new Severity(0)
+ val WARNING = new Severity(1)
+ val ERROR = new Severity(2)
+
+ def hasErrors = ERROR.count > 0
+ def hasWarnings = WARNING.count > 0
+
+ case class Info(val pos: Position, val msg: String, val severity: Severity)
+ val infos = new scala.collection.mutable.LinkedHashSet[Info]
+
+ /** Handles incoming info */
+ def log(pos: Position, msg: String, severity: Severity) {
+ infos += new Info(pos, msg, severity)
+ severity.count += 1
+ display(infos.last)
+ }
+
+ /** Displays incoming info */
+ def display(info: Info): Unit
+
+ /** Services a request to drop into interactive mode */
+ def interactive(): Unit
+
+ /** Refreshes the UI */
+ def flush(): Unit = {}
+
+ /** Resets the reporter */
+ def reset(): Unit = {
+ INFO.count = 0
+ WARNING.count = 0
+ ERROR.count = 0
+ infos.clear()
+ }
+}
diff --git a/src/compiler/scala/tools/reflect/FrontEnds.scala b/src/compiler/scala/tools/reflect/FrontEnds.scala
deleted file mode 100644
index d0c3c1c774..0000000000
--- a/src/compiler/scala/tools/reflect/FrontEnds.scala
+++ /dev/null
@@ -1,88 +0,0 @@
-package scala.tools
-package reflect
-
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import scala.reflect.ClassTag
-
-trait FrontEnds extends scala.reflect.api.FrontEnds {
-
- type Position = scala.reflect.internal.util.Position
-
- def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd = {
- val settings = new Settings()
- if (minSeverity <= 0) settings.verbose.value = true
- if (minSeverity > 1) settings.nowarn.value = true
- wrapReporter(new ConsoleReporter(settings))
- }
-
- abstract class FrontEndToReporterProxy(val frontEnd: FrontEnd) extends AbstractReporter {
- import frontEnd.{Severity => ApiSeverity}
- val API_INFO = frontEnd.INFO
- val API_WARNING = frontEnd.WARNING
- val API_ERROR = frontEnd.ERROR
-
- type NscSeverity = Severity
- val NSC_INFO = INFO
- val NSC_WARNING = WARNING
- val NSC_ERROR = ERROR
-
- def display(pos: Position, msg: String, nscSeverity: NscSeverity): Unit =
- frontEnd.log(pos, msg, nscSeverity match {
- case NSC_INFO => API_INFO
- case NSC_WARNING => API_WARNING
- case NSC_ERROR => API_ERROR
- })
-
- def displayPrompt(): Unit =
- frontEnd.interactive()
-
- override def flush(): Unit = {
- super.flush()
- frontEnd.flush()
- }
-
- override def reset(): Unit = {
- super.reset()
- frontEnd.reset()
- }
- }
-
- def wrapFrontEnd(frontEnd: FrontEnd): Reporter = new FrontEndToReporterProxy(frontEnd) {
- val settings = new Settings()
- settings.verbose.value = true
- settings.nowarn.value = false
- }
-
- class ReporterToFrontEndProxy(val reporter: Reporter) extends FrontEnd {
- val API_INFO = INFO
- val API_WARNING = WARNING
- val API_ERROR = ERROR
-
- override def hasErrors = reporter.hasErrors
- override def hasWarnings = reporter.hasWarnings
-
- def display(info: Info): Unit = info.severity match {
- case API_INFO => reporter.info(info.pos, info.msg, false)
- case API_WARNING => reporter.warning(info.pos, info.msg)
- case API_ERROR => reporter.error(info.pos, info.msg)
- }
-
- def interactive(): Unit = reporter match {
- case reporter: AbstractReporter => reporter.displayPrompt()
- case _ => // do nothing
- }
-
- override def flush(): Unit = {
- super.flush()
- reporter.flush()
- }
-
- override def reset(): Unit = {
- super.reset()
- reporter.reset()
- }
- }
-
- def wrapReporter(reporter: Reporter): FrontEnd = new ReporterToFrontEndProxy(reporter)
-}
diff --git a/src/compiler/scala/tools/reflect/StdTags.scala b/src/compiler/scala/tools/reflect/StdTags.scala
index 94fd8e1fe8..a3bc9b9bd1 100644
--- a/src/compiler/scala/tools/reflect/StdTags.scala
+++ b/src/compiler/scala/tools/reflect/StdTags.scala
@@ -3,7 +3,7 @@ package reflect
import java.lang.{Class => jClass}
import scala.reflect.{ClassTag, classTag}
-import scala.reflect.api.{MirrorOf, TypeCreator, Universe => ApiUniverse}
+import scala.reflect.api.{Mirror, TypeCreator, Universe => ApiUniverse}
// [Eugene++] Before 2.10 is released, I suggest we don't rely on automated type tag generation
// sure, it's convenient, but then refactoring reflection / reification becomes a pain
@@ -11,13 +11,13 @@ import scala.reflect.api.{MirrorOf, TypeCreator, Universe => ApiUniverse}
trait StdTags {
val u: ApiUniverse with Singleton
- val m: MirrorOf[u.type]
+ val m: Mirror[u.type]
lazy val tagOfListOfString: u.TypeTag[List[String]] =
u.TypeTag[List[String]](
m,
new TypeCreator {
- def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Type = {
+ def apply[U <: ApiUniverse with Singleton](m: Mirror[U]): U # Type = {
val u = m.universe
val pre = u.ThisType(m.staticPackage("scala.collection.immutable").moduleClass.asInstanceOf[u.Symbol])
u.TypeRef(pre, u.definitions.ListClass, List(u.definitions.StringClass.toTypeConstructor))
@@ -28,7 +28,7 @@ trait StdTags {
u.TypeTag[T](
m,
new TypeCreator {
- def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Type =
+ def apply[U <: ApiUniverse with Singleton](m: Mirror[U]): U # Type =
m.staticClass(classTag[T].runtimeClass.getName).toTypeConstructor.asInstanceOf[U # Type]
})
lazy val tagOfInt = u.TypeTag.Int
diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala
index f627699597..ab814b617d 100644
--- a/src/compiler/scala/tools/reflect/ToolBox.scala
+++ b/src/compiler/scala/tools/reflect/ToolBox.scala
@@ -15,6 +15,9 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
*
* Accumulates and displays warnings and errors, can drop to interactive mode (if supported).
* The latter can be useful to study the typechecker or to debug complex macros.
+ *
+ * [[scala.tools.reflect]] provides two predefined front ends that can be created using
+ * [[scala.tools.reflect.mkSilentFrontEnd]] and [[scala.tools.reflect.mkConsoleFrontEnd]].
*/
def frontEnd: FrontEnd
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index f985eedf99..95135b84e0 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -46,6 +46,20 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
newTermName("__wrapper$" + wrapCount + "$" + java.util.UUID.randomUUID.toString.replace("-", ""))
}
+ // should be called after every use of ToolBoxGlobal in order to prevent leaks
+ // there's the `withCleanupCaches` method defined below, which provides a convenient interface for that
+ def cleanupCaches(): Unit = {
+ perRunCaches.clearAll()
+ undoLog.clear()
+ analyzer.lastTreeToTyper = EmptyTree
+ lastSeenSourceFile = NoSourceFile
+ lastSeenContext = null
+ }
+
+ def withCleanupCaches[T](body: => T): T =
+ try body
+ finally cleanupCaches()
+
def verify(expr: Tree): Unit = {
// Previously toolboxes used to typecheck their inputs before compiling.
// Actually, the initial demo by Martin first typechecked the reified tree,
@@ -320,7 +334,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val errorFn: String => Unit = msg => frontEnd.log(scala.reflect.internal.util.NoPosition, msg, frontEnd.ERROR)
val command = new CompilerCommand(arguments.toList, errorFn)
command.settings.outputDirs setSingleOutput virtualDirectory
- val instance = new ToolBoxGlobal(command.settings, new FrontEndToReporterProxy(frontEnd) { val settings = command.settings })
+ val instance = new ToolBoxGlobal(command.settings, frontEndToReporter(frontEnd, command.settings))
if (frontEnd.hasErrors) {
var msg = "reflective compilation has failed: cannot initialize the compiler: " + EOL + EOL
msg += frontEnd.infos map (_.msg) mkString EOL
@@ -337,7 +351,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
lazy val importer = compiler.mkImporter(u)
lazy val exporter = importer.reverse
- def typeCheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = {
+ def typeCheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = compiler.withCleanupCaches {
if (compiler.settings.verbose.value) println("importing "+tree+", expectedType = "+expectedType)
var ctree: compiler.Tree = importer.importTree(tree)
var cexpectedType: compiler.Type = importer.importType(expectedType)
@@ -357,7 +371,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
inferImplicit(tree, viewTpe, isView = true, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos)
}
- private def inferImplicit(tree: u.Tree, pt: u.Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: u.Position): u.Tree = {
+ private def inferImplicit(tree: u.Tree, pt: u.Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: u.Position): u.Tree = compiler.withCleanupCaches {
if (compiler.settings.verbose.value) println("importing "+pt, ", tree = "+tree+", pos = "+pos)
var ctree: compiler.Tree = importer.importTree(tree)
var cpt: compiler.Type = importer.importType(pt)
diff --git a/src/compiler/scala/tools/reflect/package.scala b/src/compiler/scala/tools/reflect/package.scala
index 901071d91a..8a1e3628e2 100644
--- a/src/compiler/scala/tools/reflect/package.scala
+++ b/src/compiler/scala/tools/reflect/package.scala
@@ -6,9 +6,12 @@
package scala.tools
import scala.reflect.api.JavaUniverse
+import scala.reflect.internal.util.Position
import scala.language.implicitConversions
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
-package object reflect extends FrontEnds {
+package object reflect {
// [todo: can we generalize this?
import scala.reflect.runtime.{universe => ru}
implicit def ToolBox(mirror0: ru.Mirror): ToolBoxFactory[ru.type] =
@@ -17,9 +20,92 @@ package object reflect extends FrontEnds {
}
// todo. replace this with an implicit class, once the pesky warning is gone
+ // we don't provide `Eval` for trees, because it's unclear where to get an evaluation mirror from
implicit def Eval[T](expr: JavaUniverse # Expr[T]): Eval[T] = new Eval[T](expr)
- // we don't provide `Eval` for trees, because it's unclear where to get an evaluation mirror from
+ /** Creates a UI-less reporter that simply accumulates all the messages
+ */
+ def mkSilentFrontEnd(): FrontEnd = new FrontEnd {
+ def display(info: Info) {}
+ def interactive() {}
+ }
+
+ /** Creates a reporter that prints messages to the console according to the settings.
+ *
+ * ``minSeverity'' determines minimum severity of the messages to be printed.
+ * 0 stands for INFO, 1 stands for WARNING and 2 stands for ERROR.
+ */
+ // todo. untangle warningsAsErrors from Reporters. I don't feel like moving this flag here!
+ def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd = {
+ val settings = new Settings()
+ if (minSeverity <= 0) settings.verbose.value = true
+ if (minSeverity > 1) settings.nowarn.value = true
+ reporterToFrontEnd(new ConsoleReporter(settings))
+ }
+
+ private[reflect] def reporterToFrontEnd(reporter: Reporter): FrontEnd = new FrontEnd {
+ val API_INFO = INFO
+ val API_WARNING = WARNING
+ val API_ERROR = ERROR
+
+ override def hasErrors = reporter.hasErrors
+ override def hasWarnings = reporter.hasWarnings
+
+ def display(info: Info): Unit = info.severity match {
+ case API_INFO => reporter.info(info.pos, info.msg, false)
+ case API_WARNING => reporter.warning(info.pos, info.msg)
+ case API_ERROR => reporter.error(info.pos, info.msg)
+ }
+
+ def interactive(): Unit = reporter match {
+ case reporter: AbstractReporter => reporter.displayPrompt()
+ case _ => // do nothing
+ }
+
+ override def flush(): Unit = {
+ super.flush()
+ reporter.flush()
+ }
+
+ override def reset(): Unit = {
+ super.reset()
+ reporter.reset()
+ }
+ }
+
+ private[reflect] def frontEndToReporter(frontEnd: FrontEnd, settings0: Settings): Reporter = new AbstractReporter {
+ val settings = settings0
+
+ import frontEnd.{Severity => ApiSeverity}
+ val API_INFO = frontEnd.INFO
+ val API_WARNING = frontEnd.WARNING
+ val API_ERROR = frontEnd.ERROR
+
+ type NscSeverity = Severity
+ val NSC_INFO = INFO
+ val NSC_WARNING = WARNING
+ val NSC_ERROR = ERROR
+
+ def display(pos: Position, msg: String, nscSeverity: NscSeverity): Unit =
+ frontEnd.log(pos, msg, nscSeverity match {
+ case NSC_INFO => API_INFO
+ case NSC_WARNING => API_WARNING
+ case NSC_ERROR => API_ERROR
+ })
+
+ def displayPrompt(): Unit =
+ frontEnd.interactive()
+
+ override def flush(): Unit = {
+ super.flush()
+ frontEnd.flush()
+ }
+
+ override def reset(): Unit = {
+ super.reset()
+ frontEnd.reset()
+ }
+ }
}
package reflect {