diff --git a/src/closure/README.md b/src/closure/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..d28619bfbb0b10de706cd5985e7a7d042204b2d4
--- /dev/null
+++ b/src/closure/README.md
@@ -0,0 +1 @@
+Google closure exceptions
\ No newline at end of file
diff --git a/src/closure/conf/depswriter/closurebuilder.py b/src/closure/conf/depswriter/closurebuilder.py
new file mode 100755
index 0000000000000000000000000000000000000000..7be7661f76c4e9dad1b1ab31f01f88498eee81d3
--- /dev/null
+++ b/src/closure/conf/depswriter/closurebuilder.py
@@ -0,0 +1,293 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Utility for Closure Library dependency calculation.
+
+ClosureBuilder scans source files to build dependency info.  From the
+dependencies, the script can produce a manifest in dependency order,
+a concatenated script, or compiled output from the Closure Compiler.
+
+Paths to files can be expressed as individual arguments to the tool (intended
+for use with find and xargs).  As a convenience, --root can be used to specify
+all JS files below a directory.
+
+usage: %prog [options] [file1.js file2.js ...]
+"""
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+import io
+import logging
+import optparse
+import os
+import sys
+
+import depstree
+import jscompiler
+import source
+import treescan
+
+
+def _GetOptionsParser():
+  """Get the options parser."""
+
+  parser = optparse.OptionParser(__doc__)
+  parser.add_option('-i',
+                    '--input',
+                    dest='inputs',
+                    action='append',
+                    default=[],
+                    help='One or more input files to calculate dependencies '
+                    'for.  The namespaces in this file will be combined with '
+                    'those given with the -n flag to form the set of '
+                    'namespaces to find dependencies for.')
+  parser.add_option('-n',
+                    '--namespace',
+                    dest='namespaces',
+                    action='append',
+                    default=[],
+                    help='One or more namespaces to calculate dependencies '
+                    'for.  These namespaces will be combined with those given '
+                    'with the -i flag to form the set of namespaces to find '
+                    'dependencies for.  A Closure namespace is a '
+                    'dot-delimited path expression declared with a call to '
+                    'goog.provide() (e.g. "goog.array" or "foo.bar").')
+  parser.add_option('--root',
+                    dest='roots',
+                    action='append',
+                    default=[],
+                    help='The paths that should be traversed to build the '
+                    'dependencies.')
+  parser.add_option('-o',
+                    '--output_mode',
+                    dest='output_mode',
+                    type='choice',
+                    action='store',
+                    choices=['list', 'script', 'compiled'],
+                    default='list',
+                    help='The type of output to generate from this script. '
+                    'Options are "list" for a list of filenames, "script" '
+                    'for a single script containing the contents of all the '
+                    'files, or "compiled" to produce compiled output with '
+                    'the Closure Compiler.  Default is "list".')
+  parser.add_option('-c',
+                    '--compiler_jar',
+                    dest='compiler_jar',
+                    action='store',
+                    help='The location of the Closure compiler .jar file.')
+  parser.add_option('-f',
+                    '--compiler_flags',
+                    dest='compiler_flags',
+                    default=[],
+                    action='append',
+                    help='Additional flags to pass to the Closure compiler. '
+                    'To pass multiple flags, --compiler_flags has to be '
+                    'specified multiple times.')
+  parser.add_option('-j',
+                    '--jvm_flags',
+                    dest='jvm_flags',
+                    default=[],
+                    action='append',
+                    help='Additional flags to pass to the JVM compiler. '
+                    'To pass multiple flags, --jvm_flags has to be '
+                    'specified multiple times.')
+  parser.add_option('--output_file',
+                    dest='output_file',
+                    action='store',
+                    help=('If specified, write output to this path instead of '
+                          'writing to standard output.'))
+
+  return parser
+
+
+def _GetInputByPath(path, sources):
+  """Get the source identified by a path.
+
+  Args:
+    path: str, A path to a file that identifies a source.
+    sources: An iterable collection of source objects.
+
+  Returns:
+    The source from sources identified by path, if found.  Converts to
+    real paths for comparison.
+  """
+  for js_source in sources:
+    # Convert both to real paths for comparison.
+    if os.path.realpath(path) == os.path.realpath(js_source.GetPath()):
+      return js_source
+
+
+def _GetClosureBaseFile(sources):
+  """Given a set of sources, returns the one base.js file.
+
+  Note that if zero or two or more base.js files are found, an error message
+  will be written and the program will be exited.
+
+  Args:
+    sources: An iterable of _PathSource objects.
+
+  Returns:
+    The _PathSource representing the base Closure file.
+  """
+  base_files = [
+      js_source for js_source in sources if _IsClosureBaseFile(js_source)
+  ]
+
+  if not base_files:
+    logging.error('No Closure base.js file found.')
+    sys.exit(1)
+  if len(base_files) > 1:
+    logging.error('More than one Closure base.js files found at these paths:')
+    for base_file in base_files:
+      logging.error(base_file.GetPath())
+    sys.exit(1)
+  return base_files[0]
+
+
+def _IsClosureBaseFile(js_source):
+  """Returns true if the given _PathSource is the Closure base.js source."""
+  return (os.path.basename(js_source.GetPath()) == 'base.js' and
+          js_source.provides == set(['goog']))
+
+
+class _PathSource(source.Source):
+  """Source file subclass that remembers its file path."""
+
+  def __init__(self, path):
+    """Initialize a source.
+
+    Args:
+      path: str, Path to a JavaScript file.  The source string will be read
+        from this file.
+    """
+    super(_PathSource, self).__init__(source.GetFileContents(path))
+
+    self._path = path
+
+  def __str__(self):
+    return 'PathSource %s' % self._path
+
+  def GetPath(self):
+    """Returns the path."""
+    return self._path
+
+
+def _WrapGoogModuleSource(src):
+  return ('goog.loadModule(function(exports) {{'
+          '"use strict";'
+          '{0}'
+          '\n'  # terminate any trailing single line comment.
+          ';return exports'
+          '}});\n').format(src)
+
+
+def main():
+  logging.basicConfig(format=(sys.argv[0] + ': %(message)s'),
+                      level=logging.INFO)
+  options, args = _GetOptionsParser().parse_args()
+
+  # Make our output pipe.
+  if options.output_file:
+    out = io.open(options.output_file, 'wb')
+  else:
+    version = sys.version_info[:2]
+    if version >= (3, 0):
+      # Write bytes to stdout
+      out = sys.stdout.buffer
+    else:
+      out = sys.stdout
+
+  sources = set()
+
+  logging.info('Scanning paths...')
+  for path in options.roots:
+    for js_path in treescan.ScanTreeForJsFiles(path):
+      sources.add(_PathSource(js_path))
+
+  # Add scripts specified on the command line.
+  for js_path in args:
+    sources.add(_PathSource(js_path))
+
+  logging.info('%s sources scanned.', len(sources))
+
+  # Though deps output doesn't need to query the tree, we still build it
+  # to validate dependencies.
+  logging.info('Building dependency tree..')
+  tree = depstree.DepsTree(sources)
+
+  input_namespaces = set()
+  inputs = options.inputs or []
+  for input_path in inputs:
+    js_input = _GetInputByPath(input_path, sources)
+    if not js_input:
+      logging.error('No source matched input %s', input_path)
+      sys.exit(1)
+    input_namespaces.update(js_input.provides)
+
+  input_namespaces.update(options.namespaces)
+
+  if not input_namespaces:
+    logging.error('No namespaces found. At least one namespace must be '
+                  'specified with the --namespace or --input flags.')
+    sys.exit(2)
+
+  # The Closure Library base file must go first.
+  base = _GetClosureBaseFile(sources)
+  deps = [base] + tree.GetDependencies(input_namespaces)
+
+  output_mode = options.output_mode
+  if output_mode == 'list':
+    out.writelines([js_source.GetPath() + '\n' for js_source in deps])
+  elif output_mode == 'script':
+    for js_source in deps:
+      src = js_source.GetSource()
+      if js_source.is_goog_module:
+        src = _WrapGoogModuleSource(src)
+      out.write(src.encode('utf-8') + b'\n')
+  elif output_mode == 'compiled':
+    logging.warning("""\
+Closure Compiler now natively understands and orders Closure dependencies and
+is prefererred over using this script for performing JavaScript compilation.
+
+Please migrate your codebase.
+
+See:
+https://github.com/google/closure-compiler/wiki/Managing-Dependencies
+""")
+
+    # Make sure a .jar is specified.
+    if not options.compiler_jar:
+      logging.error('--compiler_jar flag must be specified if --output is '
+                    '"compiled"')
+      sys.exit(2)
+
+    # Will throw an error if the compilation fails.
+    compiled_source = jscompiler.Compile(options.compiler_jar,
+                                         [js_source.GetPath()
+                                          for js_source in deps],
+                                         jvm_flags=options.jvm_flags,
+                                         compiler_flags=options.compiler_flags)
+
+    logging.info('JavaScript compilation succeeded.')
+    out.write(compiled_source.encode('utf-8'))
+
+  else:
+    logging.error('Invalid value for --output flag.')
+    sys.exit(2)
+
+
+if __name__ == '__main__':
+  main()
diff --git a/src/closure/conf/depswriter/depstree.py b/src/closure/conf/depswriter/depstree.py
new file mode 100755
index 0000000000000000000000000000000000000000..f288dd3aa616a9a69390f5ac6dc4411a3a8a419b
--- /dev/null
+++ b/src/closure/conf/depswriter/depstree.py
@@ -0,0 +1,189 @@
+# Copyright 2009 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Class to represent a full Closure Library dependency tree.
+
+Offers a queryable tree of dependencies of a given set of sources.  The tree
+will also do logical validation to prevent duplicate provides and circular
+dependencies.
+"""
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+class DepsTree(object):
+  """Represents the set of dependencies between source files."""
+
+  def __init__(self, sources):
+    """Initializes the tree with a set of sources.
+
+    Args:
+      sources: A set of JavaScript sources.
+
+    Raises:
+      MultipleProvideError: A namespace is provided by muplitple sources.
+      NamespaceNotFoundError: A namespace is required but never provided.
+    """
+
+    self._sources = sources
+    self._provides_map = dict()
+
+    # Ensure nothing was provided twice.
+    for source in sources:
+      for provide in source.provides:
+        if provide in self._provides_map:
+          raise MultipleProvideError(
+              provide, [self._provides_map[provide], source])
+
+        self._provides_map[provide] = source
+
+    # Check that all required namespaces are provided.
+    for source in sources:
+      for require in source.requires:
+        if require not in self._provides_map:
+          raise NamespaceNotFoundError(require, source)
+
+  def GetDependencies(self, required_namespaces):
+    """Get source dependencies, in order, for the given namespaces.
+
+    Args:
+      required_namespaces: A string (for one) or list (for one or more) of
+        namespaces.
+
+    Returns:
+      A list of source objects that provide those namespaces and all
+      requirements, in dependency order.
+
+    Raises:
+      NamespaceNotFoundError: A namespace is requested but doesn't exist.
+      CircularDependencyError: A cycle is detected in the dependency tree.
+    """
+    if isinstance(required_namespaces, str):
+      required_namespaces = [required_namespaces]
+
+    deps_sources = []
+
+    for namespace in required_namespaces:
+      for source in DepsTree._ResolveDependencies(
+          namespace, [], self._provides_map, []):
+        if source not in deps_sources:
+          deps_sources.append(source)
+
+    return deps_sources
+
+  @staticmethod
+  def _ResolveDependencies(required_namespace, deps_list, provides_map,
+                           traversal_path):
+    """Resolve dependencies for Closure source files.
+
+    Follows the dependency tree down and builds a list of sources in dependency
+    order.  This function will recursively call itself to fill all dependencies
+    below the requested namespaces, and then append its sources at the end of
+    the list.
+
+    Args:
+      required_namespace: String of required namespace.
+      deps_list: List of sources in dependency order.  This function will append
+        the required source once all of its dependencies are satisfied.
+      provides_map: Map from namespace to source that provides it.
+      traversal_path: List of namespaces of our path from the root down the
+        dependency/recursion tree.  Used to identify cyclical dependencies.
+        This is a list used as a stack -- when the function is entered, the
+        current namespace is pushed and popped right before returning.
+        Each recursive call will check that the current namespace does not
+        appear in the list, throwing a CircularDependencyError if it does.
+
+    Returns:
+      The given deps_list object filled with sources in dependency order.
+
+    Raises:
+      NamespaceNotFoundError: A namespace is requested but doesn't exist.
+      CircularDependencyError: A cycle is detected in the dependency tree.
+    """
+
+    source = provides_map.get(required_namespace)
+    if not source:
+      raise NamespaceNotFoundError(required_namespace)
+
+    if required_namespace in traversal_path:
+      traversal_path.append(required_namespace)  # do this *after* the test
+
+      # This must be a cycle.
+      raise CircularDependencyError(traversal_path)
+
+    # If we don't have the source yet, we'll have to visit this namespace and
+    # add the required dependencies to deps_list.
+    if source not in deps_list:
+      traversal_path.append(required_namespace)
+
+      for require in source.requires:
+
+        # Append all other dependencies before we append our own.
+        DepsTree._ResolveDependencies(require, deps_list, provides_map,
+                                      traversal_path)
+      deps_list.append(source)
+
+      traversal_path.pop()
+
+    return deps_list
+
+
+class BaseDepsTreeError(Exception):
+  """Base DepsTree error."""
+
+  def __init__(self):
+    Exception.__init__(self)
+
+
+class CircularDependencyError(BaseDepsTreeError):
+  """Raised when a dependency cycle is encountered."""
+
+  def __init__(self, dependency_list):
+    BaseDepsTreeError.__init__(self)
+    self._dependency_list = dependency_list
+
+  def __str__(self):
+    return ('Encountered circular dependency:\n%s\n' %
+            '\n'.join(self._dependency_list))
+
+
+class MultipleProvideError(BaseDepsTreeError):
+  """Raised when a namespace is provided more than once."""
+
+  def __init__(self, namespace, sources):
+    BaseDepsTreeError.__init__(self)
+    self._namespace = namespace
+    self._sources = sources
+
+  def __str__(self):
+    source_strs = map(str, self._sources)
+
+    return ('Namespace "%s" provided more than once in sources:\n%s\n' %
+            (self._namespace, '\n'.join(source_strs)))
+
+
+class NamespaceNotFoundError(BaseDepsTreeError):
+  """Raised when a namespace is requested but not provided."""
+
+  def __init__(self, namespace, source=None):
+    BaseDepsTreeError.__init__(self)
+    self._namespace = namespace
+    self._source = source
+
+  def __str__(self):
+    msg = 'Namespace "%s" never provided.' % self._namespace
+    if self._source:
+      msg += ' Required in %s' % self._source
+    return msg
diff --git a/src/closure/conf/depswriter/depstree_test.py b/src/closure/conf/depswriter/depstree_test.py
new file mode 100755
index 0000000000000000000000000000000000000000..eb4c99958ec6cabaacd782e49b7a8a16e85c9f61
--- /dev/null
+++ b/src/closure/conf/depswriter/depstree_test.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Unit test for depstree."""
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+import unittest
+
+import depstree
+
+
+def _GetProvides(sources):
+  """Get all namespaces provided by a collection of sources."""
+
+  provides = set()
+  for source in sources:
+    provides.update(source.provides)
+  return provides
+
+
+class MockSource(object):
+  """Mock Source file."""
+
+  def __init__(self, provides, requires):
+    self.provides = set(provides)
+    self.requires = set(requires)
+
+  def __repr__(self):
+    return 'MockSource %s' % self.provides
+
+
+class DepsTreeTestCase(unittest.TestCase):
+  """Unit test for DepsTree.  Tests several common situations and errors."""
+
+  def AssertValidDependencies(self, deps_list):
+    """Validates a dependency list.
+
+    Asserts that a dependency list is valid: For every source in the list,
+    ensure that every require is provided by a source earlier in the list.
+
+    Args:
+      deps_list: A list of sources that should be in dependency order.
+    """
+
+    for i in range(len(deps_list)):
+      source = deps_list[i]
+      previous_provides = _GetProvides(deps_list[:i])
+      for require in source.requires:
+        self.assertTrue(
+            require in previous_provides,
+            'Namespace "%s" not provided before required by %s' % (
+                require, source))
+
+  def testSimpleDepsTree(self):
+    a = MockSource(['A'], ['B', 'C'])
+    b = MockSource(['B'], [])
+    c = MockSource(['C'], ['D'])
+    d = MockSource(['D'], ['E'])
+    e = MockSource(['E'], [])
+
+    tree = depstree.DepsTree([a, b, c, d, e])
+
+    self.AssertValidDependencies(tree.GetDependencies('A'))
+    self.AssertValidDependencies(tree.GetDependencies('B'))
+    self.AssertValidDependencies(tree.GetDependencies('C'))
+    self.AssertValidDependencies(tree.GetDependencies('D'))
+    self.AssertValidDependencies(tree.GetDependencies('E'))
+
+  def testCircularDependency(self):
+    # Circular deps
+    a = MockSource(['A'], ['B'])
+    b = MockSource(['B'], ['C'])
+    c = MockSource(['C'], ['A'])
+
+    tree = depstree.DepsTree([a, b, c])
+
+    self.assertRaises(depstree.CircularDependencyError,
+                      tree.GetDependencies, 'A')
+
+  def testRequiresUndefinedNamespace(self):
+    a = MockSource(['A'], ['B'])
+    b = MockSource(['B'], ['C'])
+    c = MockSource(['C'], ['D'])  # But there is no D.
+
+    def MakeDepsTree():
+      return depstree.DepsTree([a, b, c])
+
+    self.assertRaises(depstree.NamespaceNotFoundError, MakeDepsTree)
+
+  def testDepsForMissingNamespace(self):
+    a = MockSource(['A'], ['B'])
+    b = MockSource(['B'], [])
+
+    tree = depstree.DepsTree([a, b])
+
+    # There is no C.
+    self.assertRaises(depstree.NamespaceNotFoundError,
+                      tree.GetDependencies, 'C')
+
+  def testMultipleRequires(self):
+    a = MockSource(['A'], ['B'])
+    b = MockSource(['B'], ['C'])
+    c = MockSource(['C'], [])
+    d = MockSource(['D'], ['B'])
+
+    tree = depstree.DepsTree([a, b, c, d])
+    self.AssertValidDependencies(tree.GetDependencies(['D', 'A']))
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/src/closure/conf/depswriter/depswriter.py b/src/closure/conf/depswriter/depswriter.py
new file mode 100755
index 0000000000000000000000000000000000000000..a78e0f83c1b315136b043bd6f32415dc881bbb4f
--- /dev/null
+++ b/src/closure/conf/depswriter/depswriter.py
@@ -0,0 +1,212 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Generates out a Closure deps.js file given a list of JavaScript sources.
+
+Paths can be specified as arguments or (more commonly) specifying trees
+with the flags (call with --help for descriptions).
+
+Usage: depswriter.py [path/to/js1.js [path/to/js2.js] ...]
+"""
+
+import json
+import logging
+import optparse
+import os
+import posixpath
+import shlex
+import sys
+
+import source
+import treescan
+
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+def MakeDepsFile(source_map):
+  """Make a generated deps file.
+
+  Args:
+    source_map: A dict map of the source path to source.Source object.
+
+  Returns:
+    str, A generated deps file source.
+  """
+
+  # Write in path alphabetical order
+  paths = sorted(source_map.keys())
+
+  lines = []
+
+  for path in paths:
+    js_source = source_map[path]
+
+    # We don't need to add entries that don't provide anything.
+    if js_source.provides:
+      lines.append(_GetDepsLine(path, js_source))
+
+  return ''.join(lines)
+
+
+def _GetDepsLine(path, js_source):
+  """Get a deps.js file string for a source."""
+
+  provides = _ToJsSrc(sorted(js_source.provides))
+  requires = _ToJsSrc(sorted(js_source.requires))
+  module = 'true' if js_source.is_goog_module else 'false'
+
+  return 'goog.addDependency(\'%s?_\' + sessionStorage[\'build\'], %s, %s, %s);\n' % (
+      path, provides, requires, module)
+
+
+def _ToJsSrc(arr):
+  """Convert a python arr to a js source string."""
+
+  return json.dumps(arr).replace('"', '\'')
+
+
+def _GetOptionsParser():
+  """Get the options parser."""
+
+  parser = optparse.OptionParser(__doc__)
+
+  parser.add_option('--output_file',
+                    dest='output_file',
+                    action='store',
+                    help=('If specified, write output to this path instead of '
+                          'writing to standard output.'))
+  parser.add_option('--root',
+                    dest='roots',
+                    default=[],
+                    action='append',
+                    help='A root directory to scan for JS source files. '
+                    'Paths of JS files in generated deps file will be '
+                    'relative to this path.  This flag may be specified '
+                    'multiple times.')
+  parser.add_option('--root_with_prefix',
+                    dest='roots_with_prefix',
+                    default=[],
+                    action='append',
+                    help='A root directory to scan for JS source files, plus '
+                    'a prefix (if either contains a space, surround with '
+                    'quotes).  Paths in generated deps file will be relative '
+                    'to the root, but preceded by the prefix.  This flag '
+                    'may be specified multiple times.')
+  parser.add_option('--path_with_depspath',
+                    dest='paths_with_depspath',
+                    default=[],
+                    action='append',
+                    help='A path to a source file and an alternate path to '
+                    'the file in the generated deps file (if either contains '
+                    'a space, surround with whitespace). This flag may be '
+                    'specified multiple times.')
+  return parser
+
+
+def _NormalizePathSeparators(path):
+  """Replaces OS-specific path separators with POSIX-style slashes.
+
+  Args:
+    path: str, A file path.
+
+  Returns:
+    str, The path with any OS-specific path separators (such as backslash on
+      Windows) replaced with URL-compatible forward slashes. A no-op on systems
+      that use POSIX paths.
+  """
+  return path.replace(os.sep, posixpath.sep)
+
+
+def _GetRelativePathToSourceDict(root, prefix=''):
+  """Scans a top root directory for .js sources.
+
+  Args:
+    root: str, Root directory.
+    prefix: str, Prefix for returned paths.
+
+  Returns:
+    dict, A map of relative paths (with prefix, if given), to source.Source
+      objects.
+  """
+  # Remember and restore the cwd when we're done. We work from the root so
+  # that paths are relative from the root.
+  start_wd = os.getcwd()
+  os.chdir(root)
+
+  path_to_source = {}
+  for path in treescan.ScanTreeForJsFiles('.'):
+    prefixed_path = _NormalizePathSeparators(os.path.join(prefix, path))
+    path_to_source[prefixed_path] = source.Source(source.GetFileContents(path))
+
+  os.chdir(start_wd)
+
+  return path_to_source
+
+
+def _GetPair(s):
+  """Return a string as a shell-parsed tuple.  Two values expected."""
+  try:
+    # shlex uses '\' as an escape character, so they must be escaped.
+    s = s.replace('\\', '\\\\')
+    first, second = shlex.split(s)
+    return (first, second)
+  except:
+    raise Exception('Unable to parse input line as a pair: %s' % s)
+
+
+def main():
+  """CLI frontend to MakeDepsFile."""
+  logging.basicConfig(format=(sys.argv[0] + ': %(message)s'),
+                      level=logging.INFO)
+  options, args = _GetOptionsParser().parse_args()
+
+  path_to_source = {}
+
+  # Roots without prefixes
+  for root in options.roots:
+    path_to_source.update(_GetRelativePathToSourceDict(root))
+
+  # Roots with prefixes
+  for root_and_prefix in options.roots_with_prefix:
+    root, prefix = _GetPair(root_and_prefix)
+    path_to_source.update(_GetRelativePathToSourceDict(root, prefix=prefix))
+
+  # Source paths
+  for path in args:
+    path_to_source[path] = source.Source(source.GetFileContents(path))
+
+  # Source paths with alternate deps paths
+  for path_with_depspath in options.paths_with_depspath:
+    srcpath, depspath = _GetPair(path_with_depspath)
+    path_to_source[depspath] = source.Source(source.GetFileContents(srcpath))
+
+  # Make our output pipe.
+  if options.output_file:
+    out = open(options.output_file, 'w')
+  else:
+    out = sys.stdout
+
+  out.write(('// This file was autogenerated by %s.\n' %
+             os.path.basename(__file__)))
+  out.write('// Please do not edit.\n')
+
+  out.write(MakeDepsFile(path_to_source))
+
+
+if __name__ == '__main__':
+  main()
diff --git a/src/closure/conf/depswriter/depswriter_test.py b/src/closure/conf/depswriter/depswriter_test.py
new file mode 100755
index 0000000000000000000000000000000000000000..8d9bf3b26b093c53e1552993ae22d8dbd04748f9
--- /dev/null
+++ b/src/closure/conf/depswriter/depswriter_test.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Unit test for depswriter."""
+
+__author__ = 'johnlenz@google.com (John Lenz)'
+
+
+import unittest
+
+import depswriter
+
+
+class MockSource(object):
+  """Mock Source file."""
+
+  def __init__(self, provides, requires):
+    self.provides = set(provides)
+    self.requires = set(requires)
+    self.is_goog_module = False
+
+  def __repr__(self):
+    return 'MockSource %s' % self.provides
+
+
+class DepsWriterTestCase(unittest.TestCase):
+  """Unit test for depswriter."""
+
+  def testMakeDepsFile(self):
+    sources = {}
+    sources['test.js'] = MockSource(['A'], ['B', 'C'])
+    deps = depswriter.MakeDepsFile(sources)
+
+    self.assertEqual(
+        'goog.addDependency(\'test.js\', [\'A\'], [\'B\', \'C\'], false);\n',
+        deps)
+
+  def testMakeDepsFileUnicode(self):
+    sources = {}
+    sources['test.js'] = MockSource([u'A'], [u'B', u'C'])
+    deps = depswriter.MakeDepsFile(sources)
+
+    self.assertEqual(
+        'goog.addDependency(\'test.js\', [\'A\'], [\'B\', \'C\'], false);\n',
+        deps)
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/src/closure/conf/depswriter/jscompiler.py b/src/closure/conf/depswriter/jscompiler.py
new file mode 100755
index 0000000000000000000000000000000000000000..76b0253707a76981e8be38d0bab2a10434911b18
--- /dev/null
+++ b/src/closure/conf/depswriter/jscompiler.py
@@ -0,0 +1,162 @@
+# Copyright 2010 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Utility to use the Closure Compiler CLI from Python."""
+
+import logging
+import os
+import re
+import subprocess
+import tempfile
+
+# Pulls just the major and minor version numbers from the first line of
+# 'java -version'. Versions are in the format of [0-9]+\.[0-9]+\..* See:
+# http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html
+_VERSION_REGEX = re.compile(r'"([0-9]+)\.([0-9]+)')
+
+
+class JsCompilerError(Exception):
+  """Raised if there's an error in calling the compiler."""
+  pass
+
+
+def _GetJavaVersionString():
+  """Get the version string from the Java VM."""
+  return subprocess.check_output(['java', '-version'], stderr=subprocess.STDOUT)
+
+
+def _ParseJavaVersion(version_string):
+  """Returns a 2-tuple for the current version of Java installed.
+
+  Args:
+    version_string: String of the Java version (e.g. '1.7.2-ea').
+
+  Returns:
+    The major and minor versions, as a 2-tuple (e.g. (1, 7)).
+  """
+  match = _VERSION_REGEX.search(version_string)
+  if match:
+    version = tuple(int(x, 10) for x in match.groups())
+    assert len(version) == 2
+    return version
+
+
+def _JavaSupports32BitMode():
+  """Determines whether the JVM supports 32-bit mode on the platform."""
+  # Suppresses process output to stderr and stdout from showing up in the
+  # console as we're only trying to determine 32-bit JVM support.
+  supported = False
+  try:
+    devnull = open(os.devnull, 'wb')
+    return subprocess.call(['java', '-d32', '-version'],
+                           stdout=devnull,
+                           stderr=devnull) == 0
+  except IOError:
+    pass
+  else:
+    devnull.close()
+  return supported
+
+
+def _GetJsCompilerArgs(compiler_jar_path, java_version, jvm_flags):
+  """Assembles arguments for call to JsCompiler."""
+
+  if java_version < (1, 7):
+    raise JsCompilerError('Closure Compiler requires Java 1.7 or higher. '
+                          'Please visit http://www.java.com/getjava')
+
+  args = ['java']
+
+  # Add JVM flags we believe will produce the best performance.  See
+  # https://groups.google.com/forum/#!topic/closure-library-discuss/7w_O9-vzlj4
+
+  # Attempt 32-bit mode if available (Java 7 on Mac OS X does not support 32-bit
+  # mode, for example).
+  if _JavaSupports32BitMode():
+    args += ['-d32']
+
+  # Prefer the "client" VM.
+  args += ['-client']
+
+  # Add JVM flags, if any
+  if jvm_flags:
+    args += jvm_flags
+
+  # Add the application JAR.
+  args += ['-jar', compiler_jar_path]
+
+  return args
+
+
+def _GetFlagFile(source_paths, compiler_flags):
+  """Writes given source paths and compiler flags to a --flagfile.
+
+  The given source_paths will be written as '--js' flags and the compiler_flags
+  are written as-is.
+
+  Args:
+    source_paths: List of string js source paths.
+    compiler_flags: List of string compiler flags.
+
+  Returns:
+    The file to which the flags were written.
+  """
+  args = []
+  for path in source_paths:
+    args += ['--js', path]
+
+  # Add compiler flags, if any.
+  if compiler_flags:
+    args += compiler_flags
+
+  flags_file = tempfile.NamedTemporaryFile(delete=False)
+  flags_file.write(' '.join(args))
+  flags_file.close()
+
+  return flags_file
+
+
+def Compile(compiler_jar_path,
+            source_paths,
+            jvm_flags=None,
+            compiler_flags=None):
+  """Prepares command-line call to Closure Compiler.
+
+  Args:
+    compiler_jar_path: Path to the Closure compiler .jar file.
+    source_paths: Source paths to build, in order.
+    jvm_flags: A list of additional flags to pass on to JVM.
+    compiler_flags: A list of additional flags to pass on to Closure Compiler.
+
+  Returns:
+    The compiled source, as a string, or None if compilation failed.
+  """
+
+  java_version = _ParseJavaVersion(str(_GetJavaVersionString()))
+
+  args = _GetJsCompilerArgs(compiler_jar_path, java_version, jvm_flags)
+
+  # Write source path arguments to flag file for avoiding "The filename or
+  # extension is too long" error in big projects. See
+  # https://github.com/google/closure-library/pull/678
+  flags_file = _GetFlagFile(source_paths, compiler_flags)
+  args += ['--flagfile', flags_file.name]
+
+  logging.info('Compiling with the following command: %s', ' '.join(args))
+
+  try:
+    return subprocess.check_output(args)
+  except subprocess.CalledProcessError:
+    raise JsCompilerError('JavaScript compilation failed.')
+  finally:
+    os.remove(flags_file.name)
diff --git a/src/closure/conf/depswriter/jscompiler_test.py b/src/closure/conf/depswriter/jscompiler_test.py
new file mode 100755
index 0000000000000000000000000000000000000000..6f63e414e852da6faed108b11a39dce8d66790c0
--- /dev/null
+++ b/src/closure/conf/depswriter/jscompiler_test.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Unit test for depstree."""
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+import os
+import unittest
+
+import jscompiler
+
+
+class JsCompilerTestCase(unittest.TestCase):
+  """Unit tests for jscompiler module."""
+
+  def testGetFlagFile(self):
+    flags_file = jscompiler._GetFlagFile(
+        ['path/to/src1.js', 'path/to/src2.js'], ['--test_compiler_flag'])
+
+    def file_get_contents(filename):
+      with open(filename) as f:
+        content = f.read()
+        f.close()
+        return content
+
+    flags_file_content = file_get_contents(flags_file.name)
+    os.remove(flags_file.name)
+
+    self.assertEqual(
+        '--js path/to/src1.js --js path/to/src2.js --test_compiler_flag',
+        flags_file_content)
+
+  def testGetJsCompilerArgs(self):
+
+    original_check = jscompiler._JavaSupports32BitMode
+    jscompiler._JavaSupports32BitMode = lambda: False
+    args = jscompiler._GetJsCompilerArgs('path/to/jscompiler.jar', (1, 7),
+                                         ['--test_jvm_flag'])
+
+    self.assertEqual(
+        ['java', '-client', '--test_jvm_flag', '-jar',
+         'path/to/jscompiler.jar'], args)
+
+    def CheckJava15RaisesError():
+      jscompiler._GetJsCompilerArgs('path/to/jscompiler.jar', (1, 5),
+                                    ['--test_jvm_flag'])
+
+    self.assertRaises(jscompiler.JsCompilerError, CheckJava15RaisesError)
+    jscompiler._JavaSupports32BitMode = original_check
+
+  def testGetJsCompilerArgs32BitJava(self):
+
+    original_check = jscompiler._JavaSupports32BitMode
+
+    # Should include the -d32 flag only if 32-bit Java is supported by the
+    # system.
+    jscompiler._JavaSupports32BitMode = lambda: True
+    args = jscompiler._GetJsCompilerArgs('path/to/jscompiler.jar', (1, 7),
+                                         ['--test_jvm_flag'])
+
+    self.assertEqual(
+        ['java', '-d32', '-client', '--test_jvm_flag', '-jar',
+         'path/to/jscompiler.jar'], args)
+
+    # Should exclude the -d32 flag if 32-bit Java is not supported by the
+    # system.
+    jscompiler._JavaSupports32BitMode = lambda: False
+    args = jscompiler._GetJsCompilerArgs('path/to/jscompiler.jar', (1, 7),
+                                         ['--test_jvm_flag'])
+
+    self.assertEqual(
+        ['java', '-client', '--test_jvm_flag', '-jar',
+         'path/to/jscompiler.jar'], args)
+
+    jscompiler._JavaSupports32BitMode = original_check
+
+  def testGetJavaVersion(self):
+
+    def assertVersion(expected, version_string):
+      self.assertEquals(expected, jscompiler._ParseJavaVersion(version_string))
+
+    assertVersion((1, 7), _TEST_JAVA_VERSION_STRING)
+    assertVersion((1, 6), _TEST_JAVA_NESTED_VERSION_STRING)
+    assertVersion((1, 4), 'java version "1.4.0_03-ea"')
+
+
+_TEST_JAVA_VERSION_STRING = """\
+openjdk version "1.7.0-google-v5"
+OpenJDK Runtime Environment (build 1.7.0-google-v5-64327-39803485)
+OpenJDK Server VM (build 22.0-b10, mixed mode)
+"""
+
+_TEST_JAVA_NESTED_VERSION_STRING = """\
+Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
+java version "1.6.0_35"
+Java(TM) SE Runtime Environment (build 1.6.0_35-b10-428-11M3811)
+Java HotSpot(TM) Client VM (build 20.10-b01-428, mixed mode)
+"""
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/src/closure/conf/depswriter/source.py b/src/closure/conf/depswriter/source.py
new file mode 100755
index 0000000000000000000000000000000000000000..0610e6b644f33774336ea7b4d9f36e2d64c19561
--- /dev/null
+++ b/src/closure/conf/depswriter/source.py
@@ -0,0 +1,132 @@
+# Copyright 2009 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Scans a source JS file for its provided and required namespaces.
+
+Simple class to scan a JavaScript file and express its dependencies.
+"""
+
+__author__ = 'nnaze@google.com'
+
+
+import codecs
+import re
+
+_BASE_REGEX_STRING = r'^\s*goog\.%s\(\s*[\'"](.+)[\'"]\s*\)'
+_MODULE_REGEX = re.compile(_BASE_REGEX_STRING % 'module')
+_PROVIDE_REGEX = re.compile(_BASE_REGEX_STRING % 'provide')
+
+_REQUIRE_REGEX_STRING = (r'^\s*(?:(?:var|let|const)\s+[a-zA-Z_$][a-zA-Z0-9$_]*'
+                         r'\s*=\s*)?goog\.require\(\s*[\'"](.+)[\'"]\s*\)')
+_REQUIRES_REGEX = re.compile(_REQUIRE_REGEX_STRING)
+
+class Source(object):
+  """Scans a JavaScript source for its provided and required namespaces."""
+
+  # Matches a "/* ... */" comment.
+  # Note: We can't definitively distinguish a "/*" in a string literal without a
+  # state machine tokenizer. We'll assume that a line starting with whitespace
+  # and "/*" is a comment.
+  _COMMENT_REGEX = re.compile(
+      r"""
+      ^\s*   # Start of a new line and whitespace
+      /\*    # Opening "/*"
+      .*?    # Non greedy match of any characters (including newlines)
+      \*/    # Closing "*/""",
+      re.MULTILINE | re.DOTALL | re.VERBOSE)
+
+  def __init__(self, source):
+    """Initialize a source.
+
+    Args:
+      source: str, The JavaScript source.
+    """
+
+    self.provides = set()
+    self.requires = set()
+    self.is_goog_module = False
+
+    self._source = source
+    self._ScanSource()
+
+  def GetSource(self):
+    """Get the source as a string."""
+    return self._source
+
+  @classmethod
+  def _StripComments(cls, source):
+    return cls._COMMENT_REGEX.sub('', source)
+
+  @classmethod
+  def _HasProvideGoogFlag(cls, source):
+    """Determines whether the @provideGoog flag is in a comment."""
+    for comment_content in cls._COMMENT_REGEX.findall(source):
+      if '@provideGoog' in comment_content:
+        return True
+
+    return False
+
+  def _ScanSource(self):
+    """Fill in provides and requires by scanning the source."""
+
+    stripped_source = self._StripComments(self.GetSource())
+
+    source_lines = stripped_source.splitlines()
+    for line in source_lines:
+      match = _PROVIDE_REGEX.match(line)
+      if match:
+        self.provides.add(match.group(1))
+      match = _MODULE_REGEX.match(line)
+      if match:
+        self.provides.add(match.group(1))
+        self.is_goog_module = True
+      match = _REQUIRES_REGEX.match(line)
+      if match:
+        self.requires.add(match.group(1))
+
+    # Closure's base file implicitly provides 'goog'.
+    # This is indicated with the @provideGoog flag.
+    if self._HasProvideGoogFlag(self.GetSource()):
+
+      if len(self.provides) or len(self.requires):
+        raise Exception(
+            'Base file should not provide or require namespaces.')
+
+      self.provides.add('goog')
+
+
+def GetFileContents(path):
+  """Get a file's contents as a string.
+
+  Args:
+    path: str, Path to file.
+
+  Returns:
+    str, Contents of file.
+
+  Raises:
+    IOError: An error occurred opening or reading the file.
+
+  """
+  fileobj = None
+  try:
+    fileobj = codecs.open(path, encoding='utf-8-sig')
+    return fileobj.read()
+  except IOError as error:
+    raise IOError('An error occurred opening or reading the file: %s. %s'
+                  % (path, error))
+  finally:
+    if fileobj is not None:
+      fileobj.close()
diff --git a/src/closure/conf/depswriter/source_test.py b/src/closure/conf/depswriter/source_test.py
new file mode 100755
index 0000000000000000000000000000000000000000..eb1591b442c671578bea87ef611d631ce0a8335c
--- /dev/null
+++ b/src/closure/conf/depswriter/source_test.py
@@ -0,0 +1,152 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Unit test for source."""
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+import unittest
+
+import source
+
+
+class SourceTestCase(unittest.TestCase):
+  """Unit test for source.  Tests the parser on a known source input."""
+
+  def testSourceScan(self):
+    test_source = source.Source(_TEST_SOURCE)
+
+    self.assertEqual(set(['foo', 'foo.test']),
+                     test_source.provides)
+    self.assertEqual(set(['goog.dom', 'goog.events.EventType']),
+                     test_source.requires)
+    self.assertFalse(test_source.is_goog_module)
+
+  def testSourceScanBase(self):
+    test_source = source.Source(_TEST_BASE_SOURCE)
+
+    self.assertEqual(set(['goog']),
+                     test_source.provides)
+    self.assertEqual(test_source.requires, set())
+    self.assertFalse(test_source.is_goog_module)
+
+  def testSourceScanBadBase(self):
+
+    def MakeSource():
+      source.Source(_TEST_BAD_BASE_SOURCE)
+
+    self.assertRaises(Exception, MakeSource)
+
+  def testSourceScanGoogModule(self):
+    test_source = source.Source(_TEST_MODULE_SOURCE)
+
+    self.assertEqual(set(['foo']),
+                     test_source.provides)
+    self.assertEqual(set(['bar']),
+                     test_source.requires)
+    self.assertTrue(test_source.is_goog_module)
+
+  def testStripComments(self):
+    self.assertEquals(
+        '\nvar foo = function() {}',
+        source.Source._StripComments((
+            '/* This is\n'
+            '  a comment split\n'
+            '  over multiple lines\n'
+            '*/\n'
+            'var foo = function() {}')))
+
+  def testGoogStatementsInComments(self):
+    test_source = source.Source(_TEST_COMMENT_SOURCE)
+
+    self.assertEqual(set(['foo']),
+                     test_source.provides)
+    self.assertEqual(set(['goog.events.EventType']),
+                     test_source.requires)
+    self.assertFalse(test_source.is_goog_module)
+
+  def testHasProvideGoog(self):
+    self.assertTrue(source.Source._HasProvideGoogFlag(_TEST_BASE_SOURCE))
+    self.assertTrue(source.Source._HasProvideGoogFlag(_TEST_BAD_BASE_SOURCE))
+    self.assertFalse(source.Source._HasProvideGoogFlag(_TEST_COMMENT_SOURCE))
+
+
+_TEST_MODULE_SOURCE = """
+goog.module('foo');
+var b = goog.require('bar');
+"""
+
+
+_TEST_SOURCE = """// Fake copyright notice
+
+/** Very important comment. */
+
+goog.provide('foo');
+goog.provide('foo.test');
+
+goog.require('goog.dom');
+goog.require('goog.events.EventType');
+
+function foo() {
+  // Set bar to seventeen to increase performance.
+  this.bar = 17;
+}
+"""
+
+_TEST_COMMENT_SOURCE = """// Fake copyright notice
+
+goog.provide('foo');
+
+/*
+goog.provide('foo.test');
+ */
+
+/*
+goog.require('goog.dom');
+*/
+
+// goog.require('goog.dom');
+
+goog.require('goog.events.EventType');
+
+function bar() {
+  this.baz = 55;
+}
+"""
+
+_TEST_BASE_SOURCE = """
+/**
+ * @fileoverview The base file.
+ * @provideGoog
+ */
+
+var goog = goog || {};
+"""
+
+_TEST_BAD_BASE_SOURCE = """
+/**
+ * @fileoverview The base file.
+ * @provideGoog
+ */
+
+goog.provide('goog');
+"""
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/src/closure/conf/depswriter/treescan.py b/src/closure/conf/depswriter/treescan.py
new file mode 100755
index 0000000000000000000000000000000000000000..6694593aab0a3ae36a45429f9ca9dead2920b999
--- /dev/null
+++ b/src/closure/conf/depswriter/treescan.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Shared utility functions for scanning directory trees."""
+
+import os
+import re
+
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+# Matches a .js file path.
+_JS_FILE_REGEX = re.compile(r'^.+\.js$')
+
+
+def ScanTreeForJsFiles(root):
+  """Scans a directory tree for JavaScript files.
+
+  Args:
+    root: str, Path to a root directory.
+
+  Returns:
+    An iterable of paths to JS files, relative to cwd.
+  """
+  return ScanTree(root, path_filter=_JS_FILE_REGEX)
+
+
+def ScanTree(root, path_filter=None, ignore_hidden=True):
+  """Scans a directory tree for files.
+
+  Args:
+    root: str, Path to a root directory.
+    path_filter: A regular expression filter.  If set, only paths matching
+      the path_filter are returned.
+    ignore_hidden: If True, do not follow or return hidden directories or files
+      (those starting with a '.' character).
+
+  Yields:
+    A string path to files, relative to cwd.
+  """
+
+  def OnError(os_error):
+    raise os_error
+
+  for dirpath, dirnames, filenames in os.walk(root, onerror=OnError):
+    # os.walk allows us to modify dirnames to prevent decent into particular
+    # directories.  Avoid hidden directories.
+    for dirname in dirnames:
+      if ignore_hidden and dirname.startswith('.'):
+        dirnames.remove(dirname)
+
+    for filename in filenames:
+
+      # nothing that starts with '.'
+      if ignore_hidden and filename.startswith('.'):
+        continue
+
+      fullpath = os.path.join(dirpath, filename)
+
+      if path_filter and not path_filter.match(fullpath):
+        continue
+
+      yield os.path.normpath(fullpath)
diff --git a/src/closure/conf/externs/angular-1.3.js b/src/closure/conf/externs/angular-1.3.js
new file mode 100755
index 0000000000000000000000000000000000000000..c3795d2988ff48a966db4c95bd2c112cb1c73f01
--- /dev/null
+++ b/src/closure/conf/externs/angular-1.3.js
@@ -0,0 +1,2392 @@
+/*
+ * Copyright 2012 The Closure Compiler Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Externs for Angular 1.
+ *
+ * TODO: Mocks.
+ * TODO: Remaining Services:
+ *     $compileProvider
+ *     $cookies
+ *     $cookieStore
+ *     $document
+ *     $httpBackend
+ *     $interpolate
+ *     $locale
+ *     $resource
+ *     $rootElement
+ *     $rootScope
+ *     $rootScopeProvider
+ *
+ * TODO: Resolve two issues with angular.$http
+ *         1) angular.$http isn't declared as a
+ *            callable type. It should be declared as a function, and properties
+ *            added following the technique used by $timeout, $parse and
+ *            $interval.
+ *         2) angular.$http.delete cannot be added as an extern
+ *            as it is a reserved keyword.
+ *            Its use is potentially not supported in IE.
+ *            It may be aliased as 'remove' in a future version.
+ *
+ * @see http://angularjs.org/
+ * @externs
+ */
+
+/**
+ * @typedef {(Window|Document|Element|Array.<Element>|string|!angular.JQLite|
+ *     NodeList|{length: number})}
+ */
+var JQLiteSelector;
+
+/**
+ * @type {Object}
+ * @const
+ */
+var angular = {};
+
+/**
+ * @param {T} self Specifies the object which this should point to when the
+ *     function is run.
+ * @param {?function(this:T, ...)} fn A function to partially apply.
+ * @return {!Function} A partially-applied form of the function bind() was
+ *     invoked as a method of.
+ * @param {...*} args Additional arguments that are partially applied to the
+ *     function.
+ * @template T
+ */
+angular.bind = function(self, fn, args) {};
+
+/** @typedef {{strictDi: (boolean|undefined)}} */
+angular.BootstrapOptions;
+
+/**
+ * @param {Element|HTMLDocument} element
+ * @param {Array.<string|Function>=} opt_modules
+ * @param {angular.BootstrapOptions=} opt_config
+ * @return {!angular.$injector}
+ */
+angular.bootstrap = function(element, opt_modules, opt_config) {};
+
+/**
+ * @param {T} source
+ * @param {(Object|Array)=} opt_dest
+ * @return {T}
+ * @template T
+ */
+angular.copy = function(source, opt_dest) {};
+
+/**
+ * @param {(JQLiteSelector|Object)} element
+ * @param {(JQLiteSelector|Object)=} opt_context
+ * @return {!angular.JQLite}
+ */
+angular.element = function(element, opt_context) {};
+
+/**
+ * @param {*} o1
+ * @param {*} o2
+ * @return {boolean}
+ */
+angular.equals = function(o1, o2) {};
+
+/**
+ * @param {Object} dest
+ * @param {...Object} srcs
+ */
+angular.extend = function(dest, srcs) {};
+
+/**
+ * @param {Object|Array} obj
+ * @param {Function} iterator
+ * @param {Object=} opt_context
+ * @return {Object|Array}
+ */
+angular.forEach = function(obj, iterator, opt_context) {};
+
+/**
+ * @param {string|T} json
+ * @return {Object|Array|Date|T}
+ * @template T
+ */
+angular.fromJson = function(json) {};
+
+/**
+ * @param {*} arg
+ * @return {*}
+ */
+angular.identity = function(arg) {};
+
+/**
+ * @param {Array.<string|Function>} modules
+ * @return {!angular.$injector}
+ */
+angular.injector = function(modules) {};
+
+/**
+ * @param {*} value
+ * @return {boolean}
+ */
+angular.isArray = function(value) {};
+
+/**
+ * @param {*} value
+ * @return {boolean}
+ */
+angular.isDate = function(value) {};
+
+/**
+ * @param {*} value
+ * @return {boolean}
+ */
+angular.isDefined = function(value) {};
+
+/**
+ * @param {*} value
+ * @return {boolean}
+ */
+angular.isElement = function(value) {};
+
+/**
+ * @param {*} value
+ * @return {boolean}
+ */
+angular.isFunction = function(value) {};
+
+/**
+ * @param {*} value
+ * @return {boolean}
+ */
+angular.isNumber = function(value) {};
+
+/**
+ * @param {*} value
+ * @return {boolean}
+ */
+angular.isObject = function(value) {};
+
+/**
+ * @param {*} value
+ * @return {boolean}
+ */
+angular.isString = function(value) {};
+
+/**
+ * @param {*} value
+ * @return {boolean}
+ */
+angular.isUndefined = function(value) {};
+
+/**
+ * @param {string} s
+ * @return {string}
+ */
+angular.lowercase = function(s) {};
+
+angular.mock = {};
+
+/**
+ * @param {string} name
+ * @param {Array.<string>=} opt_requires
+ * @param {(Function|Array.<string|Function>)=} opt_configFn
+ * @return {!angular.Module}
+ */
+angular.module = function(name, opt_requires, opt_configFn) {};
+
+angular.noop = function() {};
+
+/**
+ * @param {Object|Array|Date|string|number} obj
+ * @param {boolean=} opt_pretty
+ * @return {string}
+ */
+angular.toJson = function(obj, opt_pretty) {};
+
+/**
+ * @param {string} s
+ * @return {string}
+ */
+angular.uppercase = function(s) {};
+
+/**
+ * @typedef {{
+ *   enter: (function(!angular.JQLite, !Function): (!Function|undefined)|
+ *       undefined),
+ *   leave: (function(!angular.JQLite, !Function): (!Function|undefined)|
+ *       undefined),
+ *   move: (function(!angular.JQLite, !Function): (!Function|undefined)|
+ *       undefined),
+ *   addClass: (function(!angular.JQLite, !Function): (!Function|undefined)|
+ *       undefined),
+ *   removeClass: (function(!angular.JQLite, !Function): (!Function|undefined)|
+ *       undefined)
+ *   }}
+ */
+angular.Animation;
+
+/**
+ * @param {!angular.JQLite} element
+ * @param {!Function} done
+ * @return {(!Function|undefined)}
+ */
+angular.Animation.enter = function(element, done) {};
+
+/**
+ * @param {!angular.JQLite} element
+ * @param {!Function} done
+ * @return {(!Function|undefined)}
+ */
+angular.Animation.leave = function(element, done) {};
+
+/**
+ * @param {!angular.JQLite} element
+ * @param {!Function} done
+ * @return {(!Function|undefined)}
+ */
+angular.Animation.move = function(element, done) {};
+
+/**
+ * @param {!angular.JQLite} element
+ * @param {!Function} done
+ * @return {(!Function|undefined)}
+ */
+angular.Animation.addClass = function(element, done) {};
+
+/**
+ * @param {!angular.JQLite} element
+ * @param {!Function} done
+ * @return {(!Function|undefined)}
+ */
+angular.Animation.removeClass = function(element, done) {};
+
+/**
+ * @typedef {{
+ *   $attr: Object.<string,string>,
+ *   $normalize: function(string): string,
+ *   $observe: function(string, function(*)): function(),
+ *   $set: function(string, ?(string|boolean), boolean=, string=)
+ *   }}
+ */
+angular.Attributes;
+
+/**
+ * @type {Object.<string, string>}
+ */
+angular.Attributes.$attr;
+
+/**
+ * @param {string} classVal
+ */
+angular.Attributes.$addClass = function(classVal) {};
+
+/**
+ * @param {string} classVal
+ */
+angular.Attributes.$removeClass = function(classVal) {};
+
+/**
+ * @param {string} newClasses
+ * @param {string} oldClasses
+ */
+angular.Attributes.$updateClass = function(newClasses, oldClasses) {};
+
+/**
+ * @param {string} name
+ * @return {string}
+ */
+angular.Attributes.$normalize = function(name) {};
+
+/**
+ * @param {string} key
+ * @param {function(*)} fn
+ * @return {function()}
+ */
+angular.Attributes.$observe = function(key, fn) {};
+
+/**
+ * @param {string} key
+ * @param {?(string|boolean)} value
+ * @param {boolean=} opt_writeAttr
+ * @param {string=} opt_attrName
+ */
+angular.Attributes.$set = function(key, value, opt_writeAttr, opt_attrName) {};
+
+/**
+ * @typedef {{
+ *   pre: (function(
+ *           !angular.Scope=,
+ *           !angular.JQLite=,
+ *           !angular.Attributes=,
+ *           (!Object|!Array.<!Object>)=)|
+ *       undefined),
+ *   post: (function(
+ *           !angular.Scope=,
+ *           !angular.JQLite=,
+ *           !angular.Attributes=,
+ *           (!Object|Array.<!Object>)=)|
+ *       undefined)
+ *   }}
+ */
+angular.LinkingFunctions;
+
+/**
+ * @param {!angular.Scope=} scope
+ * @param {!angular.JQLite=} iElement
+ * @param {!angular.Attributes=} iAttrs
+ * @param {(!Object|!Array.<!Object>)=} controller
+ */
+angular.LinkingFunctions.pre = function(scope, iElement, iAttrs, controller) {};
+
+/**
+ * @param {!angular.Scope=} scope
+ * @param {!angular.JQLite=} iElement
+ * @param {!angular.Attributes=} iAttrs
+ * @param {(!Object|!Array.<!Object>)=} controller
+ */
+angular.LinkingFunctions.post = function(scope, iElement, iAttrs, controller) {
+};
+
+/**
+ * @typedef {{
+ *   bindToController: (boolean|undefined),
+ *   compile: (function(
+ *       !angular.JQLite=, !angular.Attributes=, Function=)|undefined),
+ *   controller: (Function|Array.<string|Function>|string|undefined),
+ *   controllerAs: (string|undefined),
+ *   link: (function(
+ *       !angular.Scope=, !angular.JQLite=, !angular.Attributes=,
+ *       (!Object|!Array.<!Object>)=)|
+ *       !angular.LinkingFunctions|
+ *       undefined),
+ *   name: (string|undefined),
+ *   priority: (number|undefined),
+ *   replace: (boolean|undefined),
+ *   require: (string|Array.<string>|undefined),
+ *   restrict: (string|undefined),
+ *   scope: (boolean|Object.<string, string>|undefined),
+ *   template: (string|
+ *       function(!angular.JQLite=,!angular.Attributes=): string|
+ *       undefined),
+ *   templateNamespace: (string|undefined),
+ *   templateUrl: (string|
+ *       function(!angular.JQLite=,!angular.Attributes=)|
+ *       undefined),
+ *   terminal: (boolean|undefined),
+ *   transclude: (boolean|string|undefined)
+ *   }}
+ */
+angular.Directive;
+
+/**
+ * @param {!angular.JQLite=} tElement
+ * @param {!angular.Attributes=} tAttrs
+ * @param {Function=} transclude
+ * @return {Function|angular.LinkingFunctions|undefined}
+ */
+angular.Directive.compile = function(tElement, tAttrs, transclude) {};
+
+angular.Directive.controller = function() {};
+
+/**
+ * @type {string|undefined}
+ */
+angular.Directive.controllerAs;
+
+/**
+ * @type {(
+ *   function(!angular.Scope=, !angular.JQLite=, !angular.Attributes=,
+ *     (!Object|!Array.<!Object>)=)|
+ *   !angular.LinkingFunctions|
+ *   undefined
+ * )}
+ */
+angular.Directive.link;
+
+/**
+ * @type {(string|undefined)}
+ */
+angular.Directive.name;
+
+/**
+ * @type {(number|undefined)}
+ */
+angular.Directive.priority;
+
+/**
+ * @type {(boolean|undefined)}
+ */
+angular.Directive.replace;
+
+/**
+ * @type {(string|Array.<string>|undefined)}
+ */
+angular.Directive.require;
+
+/**
+ * @type {(string|undefined)}
+ */
+angular.Directive.restrict;
+
+/**
+ * @type {(boolean|Object.<string, string>|undefined)}
+ */
+angular.Directive.scope;
+
+/**
+ * @type {(
+ *   string|
+ *   function(!angular.JQLite=,!angular.Attributes=): string|
+ *   undefined
+ * )}
+ */
+angular.Directive.template;
+
+/**
+ * @type {(string|function(!angular.JQLite=, !angular.Attributes=)|undefined)}
+ */
+angular.Directive.templateUrl;
+
+/**
+ * @type {(boolean|undefined)}
+ */
+angular.Directive.terminal;
+
+/**
+ * @type {(boolean|string|undefined)}
+ */
+angular.Directive.transclude;
+
+/**
+ * @typedef {{
+ *   addClass: function(string): !angular.JQLite,
+ *   after: function(JQLiteSelector): !angular.JQLite,
+ *   append: function(JQLiteSelector): !angular.JQLite,
+ *   attr: function(string, (string|boolean)=):
+ *       (!angular.JQLite|string|boolean),
+ *   bind: function(string, Function): !angular.JQLite,
+ *   children: function(): !angular.JQLite,
+ *   clone: function(): !angular.JQLite,
+ *   contents: function(): !angular.JQLite,
+ *   controller: function(string=): Object,
+ *   css: function((string|!Object), string=): (!angular.JQLite|string),
+ *   data: function(string=, *=): *,
+ *   detach: function(): !angular.JQLite,
+ *   empty: function(): !angular.JQLite,
+ *   eq: function(number): !angular.JQLite,
+ *   find: function(string): !angular.JQLite,
+ *   hasClass: function(string): boolean,
+ *   html: function(string=): (!angular.JQLite|string),
+ *   inheritedData: function(string=, *=): *,
+ *   injector: function(): !angular.$injector,
+ *   isolateScope: function(): (!angular.Scope|undefined),
+ *   length: number,
+ *   next: function(): !angular.JQLite,
+ *   on: function(string, Function): !angular.JQLite,
+ *   off: function(string=, Function=): !angular.JQLite,
+ *   one: function(string, Function): !angular.JQLite,
+ *   parent: function(): !angular.JQLite,
+ *   prepend: function(JQLiteSelector): !angular.JQLite,
+ *   prop: function(string, *=): *,
+ *   ready: function(Function): !angular.JQLite,
+ *   remove: function(): !angular.JQLite,
+ *   removeAttr: function(string): !angular.JQLite,
+ *   removeClass: function(string): !angular.JQLite,
+ *   removeData: function(string=): !angular.JQLite,
+ *   replaceWith: function(JQLiteSelector): !angular.JQLite,
+ *   scope: function(): !angular.Scope,
+ *   text: function(string=): (!angular.JQLite|string),
+ *   toggleClass: function(string, boolean=): !angular.JQLite,
+ *   triggerHandler: function(string, *=): !angular.JQLite,
+ *   unbind: function(string=, Function=): !angular.JQLite,
+ *   val: function(string=): (!angular.JQLite|string),
+ *   wrap: function(JQLiteSelector): !angular.JQLite
+ *   }}
+ */
+angular.JQLite;
+
+/**
+ * @param {string} name
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.addClass = function(name) {};
+
+/**
+ * @param {JQLiteSelector} element
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.after = function(element) {};
+
+/**
+ * @param {JQLiteSelector} element
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.append = function(element) {};
+
+/**
+ * @param {string} name
+ * @param {(string|boolean)=} opt_value
+ * @return {!angular.JQLite|string|boolean}
+ */
+angular.JQLite.attr = function(name, opt_value) {};
+
+/**
+ * @param {string} type
+ * @param {Function} fn
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.bind = function(type, fn) {};
+
+/**
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.children = function() {};
+
+/**
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.clone = function() {};
+
+/**
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.contents = function() {};
+
+/**
+ * @param {string=} opt_name
+ * @return {Object}
+ */
+angular.JQLite.controller = function(opt_name) {};
+
+/**
+ * @param {(string|!Object)} nameOrObject
+ * @param {string=} opt_value
+ * @return {!angular.JQLite|string}
+ */
+angular.JQLite.css = function(nameOrObject, opt_value) {};
+
+/**
+ * @param {string=} opt_key
+ * @param {*=} opt_value
+ * @return {*}
+ */
+angular.JQLite.data = function(opt_key, opt_value) {};
+
+/**
+ * @param {number} index
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.eq = function(index) {};
+
+/**
+ * @param {string} selector
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.find = function(selector) {};
+
+/**
+ * @param {string} name
+ * @return {boolean}
+ */
+angular.JQLite.hasClass = function(name) {};
+
+/**
+ * @param {string=} opt_value
+ * @return {!angular.JQLite|string}
+ */
+angular.JQLite.html = function(opt_value) {};
+
+/**
+ * @param {string=} opt_key
+ * @param {*=} opt_value
+ * @return {*}
+ */
+angular.JQLite.inheritedData = function(opt_key, opt_value) {};
+
+/**
+ * @return {!angular.$injector}
+ */
+angular.JQLite.injector = function() {};
+
+/** @type {number} */
+angular.JQLite.length;
+
+/**
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.next = function() {};
+
+/**
+ * @param {string} type
+ * @param {Function} fn
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.on = function(type, fn) {};
+
+/**
+ * @param {string=} opt_type
+ * @param {Function=} opt_fn
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.off = function(opt_type, opt_fn) {};
+
+/**
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.parent = function() {};
+
+/**
+ * @param {JQLiteSelector} element
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.prepend = function(element) {};
+
+/**
+ * @param {string} name
+ * @param {*=} opt_value
+ * @return {*}
+ */
+angular.JQLite.prop = function(name, opt_value) {};
+
+/**
+ * @param {Function} fn
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.ready = function(fn) {};
+
+/**
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.remove = function() {};
+
+/**
+ * @param {string} name
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.removeAttr = function(name) {};
+
+/**
+ * @param {string} name
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.removeClass = function(name) {};
+
+/**
+ * @param {string=} opt_name
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.removeData = function(opt_name) {};
+
+/**
+ * @param {JQLiteSelector} element
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.replaceWith = function(element) {};
+
+/**
+ * @return {!angular.Scope}
+ */
+angular.JQLite.scope = function() {};
+
+/**
+ * @param {string=} opt_value
+ * @return {!angular.JQLite|string}
+ */
+angular.JQLite.text = function(opt_value) {};
+
+/**
+ * @param {string} name
+ * @param {boolean=} opt_condition
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.toggleClass = function(name, opt_condition) {};
+
+/**
+ * @param {string} type
+ * @param {*=} opt_value
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.triggerHandler = function(type, opt_value) {};
+
+/**
+ * @param {string=} opt_type
+ * @param {Function=} opt_fn
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.unbind = function(opt_type, opt_fn) {};
+
+/**
+ * @param {string=} opt_value
+ * @return {!angular.JQLite|string}
+ */
+angular.JQLite.val = function(opt_value) {};
+
+/**
+ * @param {JQLiteSelector} element
+ * @return {!angular.JQLite}
+ */
+angular.JQLite.wrap = function(element) {};
+
+/**
+ * @typedef {{
+ *   animation:
+ *       function(string, function(...*):angular.Animation):!angular.Module,
+ *   config: function((Function|Array.<string|Function>)):!angular.Module,
+ *   constant: function(string, *):angular.Module,
+ *   controller:
+ *       (function(string, (Function|Array.<string|Function>)):!angular.Module|
+ *       function(!Object.<(Function|Array.<string|Function>)>):
+ *           !angular.Module),
+ *   directive:
+ *       (function(string, (Function|Array.<string|Function>)):!angular.Module|
+ *       function(!Object.<(Function|Array.<string|Function>)>):
+ *           !angular.Module),
+ *   factory:
+ *       function(string, (Function|Array.<string|Function>)):!angular.Module,
+ *   filter:
+ *       function(string, (Function|Array.<string|Function>)):!angular.Module,
+ *   name: string,
+ *   provider: function(string,
+ *       (Object|Function|Array.<string|Function>)):!angular.Module,
+ *   requires: !Array.<string>,
+ *   run: function((Function|Array.<string|Function>)):!angular.Module,
+ *   service:
+ *       function(string, (Function|Array.<string|Function>)):!angular.Module,
+ *   value: function(string, *):!angular.Module
+ *   }}
+ */
+angular.Module;
+
+/**
+ * @param {string} name
+ * @param {function(...*):angular.Animation} animationFactory
+ */
+angular.Module.animation = function(name, animationFactory) {};
+
+/**
+ * @param {Function|Array.<string|Function>} configFn
+ * @return {!angular.Module}
+ */
+angular.Module.config = function(configFn) {};
+
+/**
+ * @param {string} name
+ * @param {*} object
+ * @return {!angular.Module}
+ */
+angular.Module.constant = function(name, object) {};
+
+/**
+ * @param {string} name
+ * @param {Function|Array.<string|Function>} constructor
+ * @return {!angular.Module}
+ */
+angular.Module.controller = function(name, constructor) {};
+
+/**
+ * @param {string} name
+ * @param {Function|Array.<string|Function>} directiveFactory
+ * @return {!angular.Module}
+ */
+angular.Module.directive = function(name, directiveFactory) {};
+
+/**
+ * @param {string} name
+ * @param {Function|Array.<string|Function>} providerFunction
+ * @return {!angular.Module}
+ */
+angular.Module.factory = function(name, providerFunction) {};
+
+/**
+ * @param {string} name
+ * @param {Function|Array.<string|Function>} filterFactory
+ * @return {!angular.Module}
+ */
+angular.Module.filter = function(name, filterFactory) {};
+
+/**
+ * @param {string} name
+ * @param {Function|Array.<string|Function>} providerType
+ * @return {!angular.Module}
+ */
+angular.Module.provider = function(name, providerType) {};
+
+/**
+ * @param {Function|Array.<string|Function>} initializationFn
+ * @return {!angular.Module}
+ */
+angular.Module.run = function(initializationFn) {};
+
+/**
+ * @param {string} name
+ * @param {Function|Array.<string|Function>} constructor
+ * @return {!angular.Module}
+ */
+angular.Module.service = function(name, constructor) {};
+
+/**
+ * @param {string} name
+ * @param {*} object
+ * @return {!angular.Module}
+ */
+angular.Module.value = function(name, object) {};
+
+/**
+ * @type {string}
+ */
+angular.Module.name = '';
+
+/**
+ * @type {Array.<string>}
+ */
+angular.Module.requires;
+
+/**
+ * @typedef {{
+ *   $$phase: string,
+ *   $apply: function((string|function(!angular.Scope))=):*,
+ *   $applyAsync: function((string|function(!angular.Scope))=),
+ *   $broadcast: function(string, ...*),
+ *   $destroy: function(),
+ *   $digest: function(),
+ *   $emit: function(string, ...*),
+ *   $eval: function((string|function(!angular.Scope))=, Object=):*,
+ *   $evalAsync: function((string|function())=),
+ *   $id: string,
+ *   $new: function(boolean=):!angular.Scope,
+ *   $on: function(string, function(!angular.Scope.Event, ...?)):function(),
+ *   $parent: !angular.Scope,
+ *   $root: !angular.Scope,
+ *   $watch: function(
+ *       (string|Function), (string|Function)=, boolean=):function(),
+ *   $watchCollection: function(
+ *       (string|Function), (string|Function)=):function(),
+ *   $watchGroup: function(
+ *       Array.<string|Function>, (string|Function)=):function()
+ *   }}
+ */
+angular.Scope;
+
+/** @type {string} */
+angular.Scope.$$phase;
+
+/**
+ * @param {(string|function(!angular.Scope))=} opt_exp
+ * @return {*}
+ */
+angular.Scope.$apply = function(opt_exp) {};
+
+/**
+ * @param {string} name
+ * @param {...*} args
+ */
+angular.Scope.$broadcast = function(name, args) {};
+
+angular.Scope.$destroy = function() {};
+
+angular.Scope.$digest = function() {};
+
+/**
+ * @param {string} name
+ * @param {...*} args
+ */
+angular.Scope.$emit = function(name, args) {};
+
+/**
+ * @param {(string|function())=} opt_exp
+ * @param {Object=} opt_locals
+ * @return {*}
+ */
+angular.Scope.$eval = function(opt_exp, opt_locals) {};
+
+/**
+ * @param {(string|function())=} opt_exp
+ */
+angular.Scope.$evalAsync = function(opt_exp) {};
+
+/** @type {string} */
+angular.Scope.$id;
+
+/**
+ * @param {boolean=} opt_isolate
+ * @return {!angular.Scope}
+ */
+angular.Scope.$new = function(opt_isolate) {};
+
+/**
+ * @param {string} name
+ * @param {function(!angular.Scope.Event, ...?)} listener
+ * @return {function()}
+ */
+angular.Scope.$on = function(name, listener) {};
+
+/** @type {!angular.Scope} */
+angular.Scope.$parent;
+
+/** @type {!angular.Scope} */
+angular.Scope.$root;
+
+/**
+ * @param {string|!Function} exp
+ * @param {(string|Function)=} opt_listener
+ * @param {boolean=} opt_objectEquality
+ * @return {function()}
+ */
+angular.Scope.$watch = function(exp, opt_listener, opt_objectEquality) {};
+
+/**
+ * @param {string|!Function} exp
+ * @param {(string|Function)=} opt_listener
+ * @return {function()}
+ */
+angular.Scope.$watchCollection = function(exp, opt_listener) {};
+
+/**
+ * @typedef {{
+ *   currentScope: !angular.Scope,
+ *   defaultPrevented: boolean,
+ *   name: string,
+ *   preventDefault: function(),
+ *   stopPropagation: function(),
+ *   targetScope: !angular.Scope
+ *   }}
+ */
+angular.Scope.Event;
+
+/** @type {!angular.Scope} */
+angular.Scope.Event.currentScope;
+
+/** @type {boolean} */
+angular.Scope.Event.defaultPrevented;
+
+/** @type {string} */
+angular.Scope.Event.name;
+
+angular.Scope.Event.preventDefault = function() {};
+
+angular.Scope.Event.stopPropagation = function() {};
+
+/** @type {!angular.Scope} */
+angular.Scope.Event.targetScope;
+
+/**
+ * @type {Object}
+ */
+angular.version = {};
+
+/**
+ * @type {string}
+ */
+angular.version.full = '';
+
+/**
+ * @type {number}
+ */
+angular.version.major = 0;
+
+/**
+ * @type {number}
+ */
+angular.version.minor = 0;
+
+/**
+ * @type {number}
+ */
+angular.version.dot = 0;
+
+/**
+ * @type {string}
+ */
+angular.version.codeName = '';
+
+/******************************************************************************
+ * $anchorScroll Service
+ *****************************************************************************/
+
+/**
+ * @typedef {function()}
+ */
+angular.$anchorScroll;
+
+/******************************************************************************
+ * $anchorScrollProvider Service
+ *****************************************************************************/
+
+/**
+ * @typedef {{
+ *   disableAutoScrolling: function()
+ *   }}
+ */
+angular.$anchorScrollProvider;
+
+/**
+ * @type {function()}
+ */
+angular.$anchorScrollProvider.disableAutoScrolling = function() {};
+
+/******************************************************************************
+ * $animate Service
+ *****************************************************************************/
+
+/**
+ * @constructor
+ */
+angular.$animate;
+
+/**
+ * @param {JQLiteSelector} element
+ * @param {Object} from
+ * @param {Object} to
+ * @param {string=} opt_className
+ * @param {Object.<string, *>=} opt_options
+ * @return {!angular.$q.Promise}
+ */
+angular.$animate.prototype.animate = function(
+    element, from, to, opt_className, opt_options) {};
+
+/**
+ * @param {JQLiteSelector} element
+ * @param {JQLiteSelector} parentElement
+ * @param {JQLiteSelector} afterElement
+ * @param {Object.<string, *>=} opt_options
+ * @return {!angular.$q.Promise}
+ */
+angular.$animate.prototype.enter = function(
+    element, parentElement, afterElement, opt_options) {};
+
+/**
+ * @param {JQLiteSelector} element
+ * @param {Object.<string, *>=} opt_options
+ * @return {!angular.$q.Promise}
+ */
+angular.$animate.prototype.leave = function(element, opt_options) {};
+
+/**
+ * @param {JQLiteSelector} element
+ * @param {JQLiteSelector} parentElement
+ * @param {JQLiteSelector} afterElement
+ * @param {Object.<string, *>=} opt_options
+ * @return {!angular.$q.Promise}
+ */
+angular.$animate.prototype.move = function(
+    element, parentElement, afterElement, opt_options) {};
+
+/**
+ * @param {JQLiteSelector} element
+ * @param {string} className
+ * @param {Object.<string, *>=} opt_options
+ * @return {!angular.$q.Promise}
+ */
+angular.$animate.prototype.addClass = function(
+    element, className, opt_options) {};
+
+/**
+ * @param {JQLiteSelector} element
+ * @param {string} className
+ * @param {Object.<string, *>=} opt_options
+ * @return {!angular.$q.Promise}
+ */
+angular.$animate.prototype.removeClass = function(
+    element, className, opt_options) {};
+
+/**
+ * @param {JQLiteSelector} element
+ * @param {string} add
+ * @param {string} remove
+ * @param {Object.<string, *>=} opt_options
+ * @return {!angular.$q.Promise}
+ */
+angular.$animate.prototype.setClass = function(
+    element, add, remove, opt_options) {};
+
+/**
+ * @param {boolean=} opt_value
+ * @param {JQLiteSelector=} opt_element
+ * @return {boolean}
+ */
+angular.$animate.prototype.enabled = function(opt_value, opt_element) {};
+
+/**
+ * @param {angular.$q.Promise} animationPromise
+ */
+angular.$animate.prototype.cancel = function(animationPromise) {};
+
+/******************************************************************************
+ * $animateProvider Service
+ *****************************************************************************/
+
+/**
+ * @constructor
+ */
+angular.$animateProvider;
+
+/**
+ * @param {string} name
+ * @param {Function} factory
+ */
+angular.$animateProvider.prototype.register = function(name, factory) {};
+
+/**
+ * @param {RegExp=} opt_expression
+ */
+angular.$animateProvider.prototype.classNameFilter = function(
+    opt_expression) {};
+
+/******************************************************************************
+ * $compile Service
+ *****************************************************************************/
+
+/**
+ * @typedef {
+ *   function(
+ *       (JQLiteSelector|Object),
+ *       function(!angular.Scope, Function=)=, number=):
+ *           function(!angular.Scope,
+ *               function(!angular.JQLite, !angular.Scope=)=): !angular.JQLite}
+ */
+angular.$compile;
+
+/******************************************************************************
+ * $cacheFactory Service
+ *****************************************************************************/
+
+/**
+ * @typedef {
+ *   function(string, angular.$cacheFactory.Options=):
+ *       !angular.$cacheFactory.Cache}
+ */
+angular.$cacheFactory;
+
+/**
+ * @typedef {function(string): ?angular.$cacheFactory.Cache}
+ */
+angular.$cacheFactory.get;
+
+/** @typedef {{capacity: (number|undefined)}} */
+angular.$cacheFactory.Options;
+
+/**
+ * @template T
+ * @constructor
+ */
+angular.$cacheFactory.Cache = function() {};
+
+/**
+ * @return {!angular.$cacheFactory.Cache.Info}
+ */
+angular.$cacheFactory.Cache.prototype.info = function() {};
+
+/**
+ * @param {string} key
+ * @param {T} value
+ */
+angular.$cacheFactory.Cache.prototype.put = function(key, value) {};
+
+/**
+ * @param {string} key
+ * @return {T}
+ */
+angular.$cacheFactory.Cache.prototype.get = function(key) {};
+
+/**
+ * @param {string} key
+ */
+angular.$cacheFactory.Cache.prototype.remove = function(key) {};
+
+angular.$cacheFactory.Cache.prototype.removeAll = function() {};
+angular.$cacheFactory.Cache.prototype.destroy = function() {};
+
+/**
+ * @typedef {{
+ *   id: string,
+ *   size: number,
+ *   options: angular.$cacheFactory.Options
+ *   }}
+ */
+angular.$cacheFactory.Cache.Info;
+
+/******************************************************************************
+ * $controller Service
+ *****************************************************************************/
+
+/**
+ * @typedef {function((Function|string), Object):Object}
+ */
+angular.$controller;
+
+/******************************************************************************
+ * $controllerProvider Service
+ *****************************************************************************/
+
+/**
+ * @typedef {{
+ *   register: function((string|Object), (Function|Array)),
+ *   allowGlobals: function()
+ *   }}
+ */
+angular.$controllerProvider;
+
+/******************************************************************************
+ * $exceptionHandler Service
+ *****************************************************************************/
+
+/**
+ * @typedef {function(Error, string=)}
+ */
+angular.$exceptionHandler;
+
+/******************************************************************************
+ * $filter Service
+ *****************************************************************************/
+
+/**
+ * @typedef {function(string): !Function}
+ */
+angular.$filter;
+
+/**
+ * The 'orderBy' filter is available through $filterProvider and AngularJS
+ * injection; but is not accessed through a documented public API of AngularJS.
+ * <p>In current AngularJS version the injection is satisfied by
+ * angular.orderByFunction, where the implementation is found.
+ * <p>See http://docs.angularjs.org/api/ng.filter:orderBy.
+ * @typedef {function(Array,
+ *     (string|function(?):*|Array.<(string|function(?):*)>),
+ *     boolean=): Array}
+ */
+angular.$filter.orderBy;
+
+/******************************************************************************
+ * $filterProvider Service
+ *****************************************************************************/
+
+/**
+ * @typedef {{
+ *   register: function(string, (!Function|!Array.<string|!Function>))
+ *   }}
+ */
+angular.$filterProvider;
+
+/**
+ * @param {string} name
+ * @param {(!Function|!Array.<string|!Function>)} fn
+ */
+angular.$filterProvider.register = function(name, fn) {};
+
+/******************************************************************************
+ * $http Service
+ *****************************************************************************/
+
+/**
+ * This is a typedef because the closure compiler does not allow
+ * defining a type that is a function with properties.
+ * If you are trying to use the $http service as a function, try
+ * using one of the helper functions instead.
+ * @typedef {{
+ *   delete: function(string, angular.$http.Config=):!angular.$http.HttpPromise,
+ *   get: function(string, angular.$http.Config=):!angular.$http.HttpPromise,
+ *   head: function(string, angular.$http.Config=):!angular.$http.HttpPromise,
+ *   jsonp: function(string, angular.$http.Config=):!angular.$http.HttpPromise,
+ *   post: function(string, *, angular.$http.Config=):
+ *       !angular.$http.HttpPromise,
+ *   put: function(string, *, angular.$http.Config=):!angular.$http.HttpPromise,
+ *   defaults: angular.$http.Config,
+ *   pendingRequests: !Array.<angular.$http.Config>
+ * }}
+ */
+angular.$http;
+
+/**
+ * @typedef {{
+ *   cache: (boolean|!angular.$cacheFactory.Cache|undefined),
+ *   data: (string|Object|undefined),
+ *   headers: (Object|undefined),
+ *   method: (string|undefined),
+ *   params: (Object.<(string|Object)>|undefined),
+ *   responseType: (string|undefined),
+ *   timeout: (number|!angular.$q.Promise|undefined),
+ *   transformRequest:
+ *       (function((string|Object), Object):(string|Object)|
+ *       Array.<function((string|Object), Object):(string|Object)>|undefined),
+ *   transformResponse:
+ *       (function((string|Object), Object):(string|Object)|
+ *       Array.<function((string|Object), Object):(string|Object)>|undefined),
+ *   url: (string|undefined),
+ *   withCredentials: (boolean|undefined),
+ *   xsrfCookieName: (string|undefined),
+ *   xsrfHeaderName: (string|undefined)
+ * }}
+ */
+angular.$http.Config;
+
+angular.$http.Config.transformRequest;
+
+angular.$http.Config.transformResponse;
+
+// /**
+//  * This extern is currently incomplete as delete is a reserved word.
+//  * To use delete, index $http.
+//  * Example: $http['delete'](url, opt_config);
+//  * @param {string} url
+//  * @param {angular.$http.Config=} opt_config
+//  * @return {!angular.$http.HttpPromise}
+//  */
+// angular.$http.delete = function(url, opt_config) {};
+
+/**
+ * @param {string} url
+ * @param {angular.$http.Config=} opt_config
+ * @return {!angular.$http.HttpPromise}
+ */
+angular.$http.get = function(url, opt_config) {};
+
+/**
+ * @param {string} url
+ * @param {angular.$http.Config=} opt_config
+ * @return {!angular.$http.HttpPromise}
+ */
+angular.$http.head = function(url, opt_config) {};
+
+/**
+ * @param {string} url
+ * @param {angular.$http.Config=} opt_config
+ * @return {!angular.$http.HttpPromise}
+ */
+angular.$http.jsonp = function(url, opt_config) {};
+
+/**
+ * @param {string} url
+ * @param {*} data
+ * @param {angular.$http.Config=} opt_config
+ * @return {!angular.$http.HttpPromise}
+ */
+angular.$http.post = function(url, data, opt_config) {};
+
+/**
+ * @param {string} url
+ * @param {*} data
+ * @param {angular.$http.Config=} opt_config
+ * @return {!angular.$http.HttpPromise}
+ */
+angular.$http.put = function(url, data, opt_config) {};
+
+/**
+ * @type {angular.$http.Config}
+ */
+angular.$http.defaults;
+
+/**
+ * @type {Array.<angular.$http.Config>}
+ * @const
+ */
+angular.$http.pendingRequests;
+
+/**
+ * @typedef {{
+ *   request: (undefined|(function(!angular.$http.Config):
+ *       !angular.$http.Config|!angular.$q.Promise.<!angular.$http.Config>)),
+ *   requestError: (undefined|(function(Object): !angular.$q.Promise|Object)),
+ *   response: (undefined|(function(!angular.$http.Response):
+ *       !angular.$http.Response|!angular.$q.Promise.<!angular.$http.Response>)),
+ *   responseError: (undefined|(function(Object): !angular.$q.Promise|Object))
+ *   }}
+ */
+angular.$http.Interceptor;
+
+/**
+ * @typedef {{
+ *   defaults: !angular.$http.Config,
+ *   interceptors: !Array.<string|function(...*): !angular.$http.Interceptor>,
+ *   useApplyAsync: function(boolean=):(boolean|!angular.$HttpProvider)
+ * }}
+ */
+angular.$HttpProvider;
+
+/**
+ * @type {angular.$http.Config}
+ */
+angular.$HttpProvider.defaults;
+
+/**
+ * @type {!Array.<string|function(...*): !angular.$http.Interceptor>}
+ */
+angular.$HttpProvider.interceptors;
+
+/**
+ * @param {boolean=} opt_value
+ * @return {boolean|!angular.$HttpProvider}
+ */
+angular.$HttpProvider.useApplyAsync = function(opt_value) {};
+
+/******************************************************************************
+ * $injector Service
+ *****************************************************************************/
+
+/**
+ * @typedef {{
+ *   annotate: function((Function|Array.<string|Function>)):Array.<string>,
+ *   get: function(string):(?),
+ *   has: function(string):boolean,
+ *   instantiate: function(Function, Object=):Object,
+ *   invoke: function(
+ *       (!Function|Array.<string|!Function>), Object=, Object=):(?)
+ *   }}
+ */
+angular.$injector;
+
+/**
+ * @param {(!Function|Array.<string|!Function>)} fn
+ * @return {Array.<string>}
+ */
+angular.$injector.annotate = function(fn) {};
+
+/**
+ * @param {string} name
+ * @return {?}
+ */
+angular.$injector.get = function(name) {};
+
+/**
+ * @param {string} name
+ * @return {boolean}
+ */
+angular.$injector.has = function(name) {};
+
+/**
+ * @param {!Function} type
+ * @param {Object=} opt_locals
+ * @return {Object}
+ */
+angular.$injector.instantiate = function(type, opt_locals) {};
+
+/**
+ * @param {(!Function|Array.<string|!Function>)} fn
+ * @param {Object=} opt_self
+ * @param {Object=} opt_locals
+ * @return {?}
+ */
+angular.$injector.invoke = function(fn, opt_self, opt_locals) {};
+
+/******************************************************************************
+ * $interpolateProvider Service
+ *****************************************************************************/
+
+/**
+ * @typedef {{
+ *   startSymbol: function(string),
+ *   endSymbol: function(string)
+ *   }}
+ */
+angular.$interpolateProvider;
+
+/** @type {function(string)} */
+angular.$interpolateProvider.startSymbol;
+
+/** @type {function(string)} */
+angular.$interpolateProvider.endSymbol;
+
+/******************************************************************************
+ * $interval Service
+ *****************************************************************************/
+
+/**
+ * @typedef {
+ *  function(function(), number=, number=, boolean=):!angular.$q.Promise
+ * }
+ */
+angular.$interval;
+
+/**
+ * Augment the angular.$interval type definition by reopening the type via an
+ * artificial angular.$interval instance.
+ *
+ * This allows us to define methods on function objects which is something
+ * that can't be expressed via typical type annotations.
+ *
+ * @type {angular.$interval}
+ */
+angular.$interval_;
+
+/**
+ * @type {function(!angular.$q.Promise):boolean}
+ */
+angular.$interval_.cancel = function(promise) {};
+
+/******************************************************************************
+ * $location Service
+ *****************************************************************************/
+
+/**
+ * @typedef {{
+ *   absUrl: function():string,
+ *   hash: function(string=):string,
+ *   host: function():string,
+ *   path: function(string=):(string|!angular.$location),
+ *   port: function():number,
+ *   protocol: function():string,
+ *   replace: function(),
+ *   search: function((string|Object.<string, string>)=,
+ *       ?(string|Array.<string>|boolean)=): (!Object|angular.$location),
+ *   url: function(string=):string
+ *   }}
+ */
+angular.$location;
+
+/**
+ * @return {string}
+ */
+angular.$location.absUrl = function() {};
+
+/**
+ * @param {string=} opt_hash
+ * @return {string}
+ */
+angular.$location.hash = function(opt_hash) {};
+
+/**
+ * @return {string}
+ */
+angular.$location.host = function() {};
+
+/**
+ * @param {string=} opt_path
+ * @return {string|!angular.$location}
+ */
+angular.$location.path = function(opt_path) {};
+
+/**
+ * @return {number}
+ */
+angular.$location.port = function() {};
+
+/**
+ * @return {string}
+ */
+angular.$location.protocol = function() {};
+
+/**
+ * @type {function()}
+ */
+angular.$location.replace = function() {};
+
+/**
+ * @param {(string|Object.<string, string>)=} opt_search
+ * @param {?(string|Array.<string>|boolean)=} opt_paramValue
+ * @return {(!Object|angular.$location)}
+ */
+angular.$location.search = function(opt_search, opt_paramValue) {};
+
+/**
+ * @param {string=} opt_url
+ * @return {string}
+ */
+angular.$location.url = function(opt_url) {};
+
+/******************************************************************************
+ * $locationProvider Service
+ *****************************************************************************/
+
+/**
+ * @typedef {{
+ *   enabled: (boolean|undefined),
+ *   requireBase: (boolean|undefined)
+ * }}
+ */
+angular.$locationProvider.html5ModeConfig;
+
+/**
+ * @typedef {{
+ *   hashPrefix:
+ *       function(string=): (string|!angular.$locationProvider),
+ *   html5Mode:
+ *       function(
+ *           (boolean|angular.$locationProvider.html5ModeConfig)=):
+ *               (boolean|!angular.$locationProvider)
+ *   }}
+ */
+angular.$locationProvider;
+
+/**
+ * @param {string=} opt_prefix
+ * @return {string|!angular.$locationProvider}
+ */
+angular.$locationProvider.hashPrefix = function(opt_prefix) {};
+
+/**
+ * @param {(boolean|angular.$locationProvider.html5ModeConfig)=} opt_mode
+ * @return {boolean|!angular.$locationProvider}
+ */
+angular.$locationProvider.html5Mode = function(opt_mode) {};
+
+/******************************************************************************
+ * $log Service
+ *****************************************************************************/
+
+/**
+ * @typedef {{
+ *   error: function(...*),
+ *   info: function(...*),
+ *   log: function(...*),
+ *   warn: function(...*)
+ *   }}
+ */
+angular.$log;
+
+/**
+ * @param {...*} var_args
+ */
+angular.$log.error = function(var_args) {};
+
+/**
+ * @param {...*} var_args
+ */
+angular.$log.info = function(var_args) {};
+
+/**
+ * @param {...*} var_args
+ */
+angular.$log.log = function(var_args) {};
+
+/**
+ * @param {...*} var_args
+ */
+angular.$log.warn = function(var_args) {};
+
+/******************************************************************************
+ * NgModelController
+ *****************************************************************************/
+
+/**
+ * @constructor
+ */
+angular.NgModelController = function() {};
+
+/**
+ * @type {?}
+ */
+angular.NgModelController.prototype.$modelValue;
+
+/**
+ * @type {boolean}
+ */
+angular.NgModelController.prototype.$dirty;
+
+/**
+ * @type {!Object.<boolean>}
+ */
+angular.NgModelController.prototype.$error;
+
+/**
+ * @type {!Array.<function(?):*>}
+ */
+angular.NgModelController.prototype.$formatters;
+
+/**
+ * @type {boolean}
+ */
+angular.NgModelController.prototype.$invalid;
+
+/**
+ * @type {!Array.<function(?):*>}
+ */
+angular.NgModelController.prototype.$parsers;
+
+/**
+ * @type {boolean}
+ */
+angular.NgModelController.prototype.$pristine;
+
+angular.NgModelController.prototype.$render = function() {};
+
+/**
+ * @param {string} key
+ * @param {boolean} isValid
+ */
+angular.NgModelController.prototype.$setValidity = function(key, isValid) {};
+
+/**
+ * @param {?} value
+ */
+angular.NgModelController.prototype.$setViewValue = function(value) {};
+
+/**
+ * @type {boolean}
+ */
+angular.NgModelController.prototype.$valid;
+
+/**
+ * @type {!Array.<function()>}
+ */
+angular.NgModelController.prototype.$viewChangeListeners;
+
+/**
+ * @type {?}
+ */
+angular.NgModelController.prototype.$viewValue;
+
+/**
+ * @type {!Object.<string, function(?, ?):*>}
+ */
+angular.NgModelController.prototype.$validators;
+
+/**
+ * @type {Object.<string, function(?, ?):*>}
+ */
+angular.NgModelController.prototype.$asyncValidators;
+
+/**
+ * @type {boolean}
+ */
+angular.NgModelController.prototype.$untouched;
+
+/**
+ * @type {boolean}
+ */
+angular.NgModelController.prototype.$touched;
+
+/**
+ * @param {?} value
+ */
+angular.NgModelController.prototype.$isEmpty = function(value) {};
+
+/**
+ * @type {function()}
+ */
+angular.NgModelController.prototype.$setPristine = function() {};
+
+/**
+ * @type {function()}
+ */
+angular.NgModelController.prototype.$setDirty = function() {};
+
+/**
+ * @type {function()}
+ */
+angular.NgModelController.prototype.$setUntouched = function() {};
+
+/**
+ * @type {function()}
+ */
+angular.NgModelController.prototype.$setTouched = function() {};
+
+/**
+ * @type {function()}
+ */
+angular.NgModelController.prototype.$rollbackViewValue = function() {};
+
+/**
+ * @type {function()}
+ */
+angular.NgModelController.prototype.$validate = function() {};
+
+/**
+ * @type {function()}
+ */
+angular.NgModelController.prototype.$commitViewValue = function() {};
+
+/******************************************************************************
+ * FormController
+ *****************************************************************************/
+
+/**
+ * @constructor
+ */
+angular.FormController = function() {};
+
+/**
+ * @param {*} control
+ */
+angular.FormController.prototype.$addControl = function(control) {};
+
+/**
+ * @type {function()}
+ */
+angular.FormController.prototype.$rollbackViewValue = function() {};
+
+/**
+ * @type {function()}
+ */
+angular.FormController.prototype.$commitViewValue = function() {};
+
+/**
+ * @type {boolean}
+ */
+angular.FormController.prototype.$dirty;
+
+/**
+ * @type {!Object.<boolean|!Array.<*>>}
+ */
+angular.FormController.prototype.$error;
+
+/**
+ * @type {boolean}
+ */
+angular.FormController.prototype.$invalid;
+
+/**
+ * @type {string}
+ */
+angular.FormController.prototype.$name;
+
+/**
+ * @type {boolean}
+ */
+angular.FormController.prototype.$pristine;
+
+/**
+ * @param {*} control
+ */
+angular.FormController.prototype.$removeControl = function(control) {};
+
+/**
+ * @type {function()}
+ */
+angular.FormController.prototype.$setDirty = function() {};
+
+/**
+ * @type {function()}
+ */
+angular.FormController.prototype.$setPristine = function() {};
+
+/**
+ * @type {function()}
+ */
+angular.FormController.prototype.$setUntouched = function() {};
+
+/**
+ * @type {function()}
+ */
+angular.FormController.prototype.$setSubmitted = function() {};
+
+/**
+ * @type {boolean}
+ */
+angular.FormController.prototype.$submitted;
+
+/**
+ * @param {string} validationToken
+ * @param {boolean} isValid
+ * @param {*} control
+ */
+angular.FormController.prototype.$setValidity = function(
+    validationToken, isValid, control) {};
+
+/**
+ * @type {boolean}
+ */
+angular.FormController.prototype.$valid;
+
+/******************************************************************************
+ * $parse Service
+ *****************************************************************************/
+
+/**
+ * @typedef {function(string):!angular.$parse.Expression}
+ */
+angular.$parse;
+
+/**
+ * @typedef {function((!angular.Scope|!Object), Object=):*}
+ */
+angular.$parse.Expression;
+
+/**
+ * Augment the angular.$parse.Expression type definition by reopening the type
+ * via an artificial angular.$parse instance.
+ *
+ * This allows us to define methods on function objects which is something
+ * that can't be expressed via typical type annotations.
+ *
+ * @type {angular.$parse.Expression}
+ */
+angular.$parse_;
+
+/**
+ * @type {function((!angular.Scope|!Object), *)}
+ */
+angular.$parse_.assign = function(scope, newValue) {};
+
+/******************************************************************************
+ * $provide Service
+ *****************************************************************************/
+
+/**
+ * @typedef {{
+ *   constant: function(string, *): Object,
+ *   decorator: function(string, (!Function|Array.<string|!Function>)),
+ *   factory: function(string, (!Function|Array.<string|!Function>)): Object,
+ *   provider: function(string, (!Function|Array.<string|!Function>)): Object,
+ *   service: function(string, (!Function|Array.<string|!Function>)): Object,
+ *   value: function(string, *): Object
+ *   }}
+ */
+angular.$provide;
+
+/**
+ * @param {string} name
+ * @param {*} object
+ * @return {Object}
+ */
+angular.$provide.constant = function(name, object) {};
+
+/**
+ * @param {string} name
+ * @param {Function|Array.<string|Function>} decorator
+ */
+angular.$provide.decorator = function(name, decorator) {};
+
+/**
+ * @param {string} name
+ * @param {Function|Array.<string|Function>} providerFunction
+ * @return {Object}
+ */
+angular.$provide.factory = function(name, providerFunction) {};
+
+/**
+ * @param {string} name
+ * @param {Function|Array.<string|Function>} providerType
+ * @return {Object}
+ */
+angular.$provide.provider = function(name, providerType) {};
+
+/**
+ * @param {string} name
+ * @param {Function|Array.<string|Function>} constructor
+ * @return {Object}
+ */
+angular.$provide.service = function(name, constructor) {};
+
+/**
+ * @param {string} name
+ * @param {*} object
+ * @return {Object}
+ */
+angular.$provide.value = function(name, object) {};
+
+/******************************************************************************
+ * $route Service
+ *****************************************************************************/
+
+/**
+ * @typedef {{
+ *   reload: function(),
+ *   current: !angular.$route.Route,
+ *   routes: Array.<!angular.$route.Route>
+ * }}
+ */
+angular.$route;
+
+/** @type {function()} */
+angular.$route.reload = function() {};
+
+/**
+ * @param {!Object<string,string>} object
+ */
+angular.$route.updateParams = function(object) {};
+
+/** @type {!angular.$route.Route} */
+angular.$route.current;
+
+/** @type {Array.<!angular.$route.Route>} */
+angular.$route.routes;
+
+/**
+ * @typedef {{
+ *   $route: angular.$routeProvider.Params,
+ *   locals: Object.<string, *>,
+ *   params: Object.<string, string>,
+ *   pathParams: Object.<string, string>,
+ *   scope: Object.<string, *>,
+ *   originalPath: (string|undefined),
+ *   regexp: (RegExp|undefined)
+ * }}
+ */
+angular.$route.Route;
+
+/** @type {angular.$routeProvider.Params} */
+angular.$route.Route.$route;
+
+/** @type {Object.<string, *>} */
+angular.$route.Route.locals;
+
+/** @type {Object.<string, string>} */
+angular.$route.Route.params;
+
+/** @type {Object.<string, string>} */
+angular.$route.Route.pathParams;
+
+/** @type {Object.<string, *>} */
+angular.$route.Route.scope;
+
+/** @type {string|undefined} */
+angular.$route.Route.originalPath;
+
+/** @type {RegExp|undefined} */
+angular.$route.Route.regexp;
+
+/******************************************************************************
+ * $routeParams Service
+ *****************************************************************************/
+
+// TODO: This should be !Object.<string|boolean> because valueless query params
+// (without even an equal sign) come through as boolean "true".
+
+/** @typedef {!Object.<string>} */
+angular.$routeParams;
+
+/******************************************************************************
+ * $routeProvider Service
+ *****************************************************************************/
+
+/**
+ * @typedef {{
+ *   otherwise:
+ *       function(
+ *           (string|!angular.$routeProvider.Params)): !angular.$routeProvider,
+ *   when:
+ *       function(
+ *           string, angular.$routeProvider.Params): !angular.$routeProvider
+ *   }}
+ */
+angular.$routeProvider;
+
+/**
+ * @param {(string|!angular.$routeProvider.Params)} params
+ * @return {!angular.$routeProvider}
+ */
+angular.$routeProvider.otherwise = function(params) {};
+
+/**
+ * @param {string} path
+ * @param {angular.$routeProvider.Params} route
+ * @return {!angular.$routeProvider}
+ */
+angular.$routeProvider.when = function(path, route) {};
+
+/**
+ * @typedef {{
+ *   controller: (Function|Array.<string|Function>|string|undefined),
+ *   controllerAs: (string|undefined),
+ *   template: (string|undefined),
+ *   templateUrl: (string|function(!Object.<string,string>=)|undefined),
+ *   resolve: (Object.<string, (
+ *       string|Function|Array.<string|Function>|!angular.$q.Promise
+ *       )>|undefined),
+ *   redirectTo: (
+ *       string|function(Object.<string>, string, Object): string|undefined),
+ *   reloadOnSearch: (boolean|undefined)
+ *   }}
+ */
+angular.$routeProvider.Params;
+
+/** @type {Function|Array.<string|Function>|string} */
+angular.$routeProvider.Params.controller;
+
+/** @type {string} */
+angular.$routeProvider.Params.controllerAs;
+
+/** @type {string} */
+angular.$routeProvider.Params.template;
+
+/** @type {string|function(!Object.<string,string>=)} */
+angular.$routeProvider.Params.templateUrl;
+
+/**
+ * @type {
+ *   Object.<string, (
+ *       string|Function|Array.<string|Function>|!angular.$q.Promise
+ *       )>}
+ */
+angular.$routeProvider.Params.resolve;
+
+/** @type {string|function(Object.<string>, string, Object): string} */
+angular.$routeProvider.Params.redirectTo;
+
+/** @type {boolean} */
+angular.$routeProvider.Params.reloadOnSearch;
+
+/******************************************************************************
+ * $sanitize Service
+ *****************************************************************************/
+
+/** @typedef {function(string):string} */
+angular.$sanitize;
+
+/******************************************************************************
+ * $sce Service
+ *****************************************************************************/
+
+/**
+ * Ref: http://docs.angularjs.org/api/ng.$sce
+ *
+ * @typedef {{
+ *   HTML: string,
+ *   CSS: string,
+ *   URL: string,
+ *   JS: string,
+ *   RESOURCE_URL: string,
+ *   isEnabled: function(): boolean,
+ *   parseAs: function(string, string): !angular.$parse.Expression,
+ *   getTrusted: function(string, *): string,
+ *   trustAs: function(string, string): *,
+ *   parseAsHtml: function(string): !angular.$parse.Expression,
+ *   parseAsCss: function(string): !angular.$parse.Expression,
+ *   parseAsUrl: function(string): !angular.$parse.Expression,
+ *   parseAsJs: function(string): !angular.$parse.Expression,
+ *   parseAsResourceUrl: function(string): !angular.$parse.Expression,
+ *   getTrustedHtml: function(*): string,
+ *   getTrustedCss: function(*): string,
+ *   getTrustedUrl: function(*): string,
+ *   getTrustedJs: function(*): string,
+ *   getTrustedResourceUrl: function(*): string,
+ *   trustAsHtml: function(string): *,
+ *   trustAsCss: function(string): *,
+ *   trustAsUrl: function(string): *,
+ *   trustAsJs: function(string): *,
+ *   trustAsResourceUrl: function(string): *
+ *   }}
+ *****************************************************************************/
+angular.$sce;
+
+
+/** @const {string} */
+angular.$sce.HTML;
+
+/** @const {string} */
+angular.$sce.CSS;
+
+/** @const {string} */
+angular.$sce.URL;
+
+/** @const {string} */
+angular.$sce.JS;
+
+/** @const {string} */
+angular.$sce.RESOURCE_URL;
+
+/** @return {boolean} */
+angular.$sce.isEnabled = function() {};
+
+/**
+ * @param {string} type
+ * @param {string} expression
+ * @return {!angular.$parse.Expression}
+ */
+angular.$sce.parseAs = function(type, expression) {};
+
+/**
+ * @param {string} type
+ * @param {*} maybeTrusted
+ * @return {string}
+ */
+angular.$sce.getTrusted = function(type, maybeTrusted) {};
+
+/**
+ * @param {string} type
+ * @param {string} trustedValue
+ * @return {*}
+ */
+angular.$sce.trustAs = function(type, trustedValue) {};
+
+/**
+ * @param {string} expression
+ * @return {!angular.$parse.Expression}
+ */
+angular.$sce.parseAsHtml = function(expression) {};
+
+/**
+ * @param {string} expression
+ * @return {!angular.$parse.Expression}
+ */
+angular.$sce.parseAsCss = function(expression) {};
+
+/**
+ * @param {string} expression
+ * @return {!angular.$parse.Expression}
+ */
+angular.$sce.parseAsUrl = function(expression) {};
+
+/**
+ * @param {string} expression
+ * @return {!angular.$parse.Expression}
+ */
+angular.$sce.parseAsJs = function(expression) {};
+
+/**
+ * @param {string} expression
+ * @return {!angular.$parse.Expression}
+ */
+angular.$sce.parseAsResourceUrl = function(expression) {};
+
+/**
+ * @param {*} maybeTrusted
+ * @return {string}
+ */
+angular.$sce.getTrustedHtml = function(maybeTrusted) {};
+
+/**
+ * @param {*} maybeTrusted
+ * @return {string}
+ */
+angular.$sce.getTrustedCss = function(maybeTrusted) {};
+
+/**
+ * @param {*} maybeTrusted
+ * @return {string}
+ */
+angular.$sce.getTrustedUrl = function(maybeTrusted) {};
+
+/**
+ * @param {*} maybeTrusted
+ * @return {string}
+ */
+angular.$sce.getTrustedJs = function(maybeTrusted) {};
+
+/**
+ * @param {*} maybeTrusted
+ * @return {string}
+ */
+angular.$sce.getTrustedResourceUrl = function(maybeTrusted) {};
+
+/**
+ * @param {string} trustedValue
+ * @return {*}
+ */
+angular.$sce.trustAsHtml = function(trustedValue) {};
+
+/**
+ * @param {string} trustedValue
+ * @return {*}
+ */
+angular.$sce.trustAsCss = function(trustedValue) {};
+
+/**
+ * @param {string} trustedValue
+ * @return {*}
+ */
+angular.$sce.trustAsUrl = function(trustedValue) {};
+
+/**
+ * @param {string} trustedValue
+ * @return {*}
+ */
+angular.$sce.trustAsJs = function(trustedValue) {};
+
+/**
+ * @param {string} trustedValue
+ * @return {*}
+ */
+angular.$sce.trustAsResourceUrl = function(trustedValue) {};
+
+/******************************************************************************
+ * $sceDelegate Service
+ *****************************************************************************/
+
+/**
+ * Ref: http://docs.angularjs.org/api/ng/service/$sceDelegate
+ *
+ * @constructor
+ */
+angular.$sceDelegate = function() {};
+
+/**
+ * @param {string} type
+ * @param {*} value
+ * @return {*}
+ */
+angular.$sceDelegate.prototype.trustAs = function(type, value) {};
+
+/**
+ * Note: because this method overrides Object.prototype.valueOf, the value
+ * parameter needs to be annotated as optional to keep the compiler happy (as
+ * otherwise the signature won't match Object.prototype.valueOf).
+ *
+ * @override
+ * @param {*=} value
+ * @return {*}
+ */
+angular.$sceDelegate.prototype.valueOf = function(value) {};
+
+/**
+ * @param {string} type
+ * @param {*} maybeTrusted
+ * @return {*}
+ */
+angular.$sceDelegate.prototype.getTrusted = function(type, maybeTrusted) {};
+
+/******************************************************************************
+ * $sceDelegateProvider Service
+ *****************************************************************************/
+
+/**
+ * Ref: http://docs.angularjs.org/api/ng/provider/$sceDelegateProvider
+ *
+ * @constructor
+ */
+angular.$sceDelegateProvider = function() {};
+
+/**
+ * @param {Array.<string>=} opt_whitelist
+ * @return {!Array.<string>}
+ */
+angular.$sceDelegateProvider.prototype.resourceUrlWhitelist = function(
+    opt_whitelist) {};
+
+/**
+ * @param {Array.<string>=} opt_blacklist
+ * @return {!Array.<string>}
+ */
+angular.$sceDelegateProvider.prototype.resourceUrlBlacklist = function(
+    opt_blacklist) {};
+
+/******************************************************************************
+ * $templateCache Service
+ *****************************************************************************/
+
+/**
+ * @typedef {!angular.$cacheFactory.Cache.<string>}
+ */
+angular.$templateCache;
+
+/******************************************************************************
+ * $timeout Service
+ *****************************************************************************/
+
+/**
+ * @typedef {function(function(), number=, boolean=):!angular.$q.Promise}
+ */
+angular.$timeout;
+
+/**
+ * Augment the angular.$timeout type definition by reopening the type via an
+ * artificial angular.$timeout instance.
+ *
+ * This allows us to define methods on function objects which is something
+ * that can't be expressed via typical type annotations.
+ *
+ * @type {angular.$timeout}
+ */
+angular.$timeout_;
+
+/**
+ * @type {function(angular.$q.Promise=):boolean}
+ */
+angular.$timeout_.cancel = function(promise) {};
+
+/******************************************************************************
+ * $window Service
+ *****************************************************************************/
+
+/** @typedef {!Window} */
+angular.$window;
diff --git a/src/closure/conf/externs/bingmaps.js b/src/closure/conf/externs/bingmaps.js
new file mode 100755
index 0000000000000000000000000000000000000000..99da4d0224839e7e26651f37279d08f2927e73e9
--- /dev/null
+++ b/src/closure/conf/externs/bingmaps.js
@@ -0,0 +1,176 @@
+/**
+ * @externs
+ */
+
+
+
+/**
+ * @constructor
+ */
+var BingMapsCoverageArea = function() {};
+
+
+/**
+ * @type {Array.<number>}
+ */
+BingMapsCoverageArea.prototype.bbox;
+
+
+/**
+ * @type {number}
+ */
+BingMapsCoverageArea.prototype.zoomMax;
+
+
+/**
+ * @type {number}
+ */
+BingMapsCoverageArea.prototype.zoomMin;
+
+
+
+/**
+ * @constructor
+ */
+var BingMapsImageryProvider = function() {};
+
+
+/**
+ * @type {string}
+ */
+BingMapsImageryProvider.prototype.attribution;
+
+
+/**
+ * @type {Array.<BingMapsCoverageArea>}
+ */
+BingMapsImageryProvider.prototype.coverageAreas;
+
+
+
+/**
+ * @constructor
+ */
+var BingMapsImageryMetadataResponse = function() {};
+
+
+/**
+ * @type {string}
+ */
+BingMapsImageryMetadataResponse.prototype.authenticationResultCode;
+
+
+/**
+ * @type {string}
+ */
+BingMapsImageryMetadataResponse.prototype.brandLogoUri;
+
+
+/**
+ * @type {string}
+ */
+BingMapsImageryMetadataResponse.prototype.copyright;
+
+
+/**
+ * @type {Array.<BingMapsResourceSet>}
+ */
+BingMapsImageryMetadataResponse.prototype.resourceSets;
+
+
+/**
+ * @type {number}
+ */
+BingMapsImageryMetadataResponse.prototype.statusCode;
+
+
+/**
+ * @type {string}
+ */
+BingMapsImageryMetadataResponse.prototype.statusDescription;
+
+
+/**
+ * @type {string}
+ */
+BingMapsImageryMetadataResponse.prototype.traceId;
+
+
+
+/**
+ * @constructor
+ */
+var BingMapsResource = function() {};
+
+
+/**
+ * @type {number}
+ */
+BingMapsResource.prototype.imageHeight;
+
+
+/**
+ * @type {string}
+ */
+BingMapsResource.prototype.imageUrl;
+
+
+/**
+ * @type {Array.<string>}
+ */
+BingMapsResource.prototype.imageUrlSubdomains;
+
+
+/**
+ * @type {number}
+ */
+BingMapsResource.prototype.imageWidth;
+
+
+/**
+ * @type {Array.<BingMapsImageryProvider>}
+ */
+BingMapsResource.prototype.imageryProviders;
+
+
+/**
+ * @type {Object}
+ */
+BingMapsResource.prototype.vintageEnd;
+
+
+/**
+ * @type {Object}
+ */
+BingMapsResource.prototype.vintageStart;
+
+
+/**
+ * @type {number}
+ */
+BingMapsResource.prototype.zoomMax;
+
+
+/**
+ * @type {number}
+ */
+BingMapsResource.prototype.zoomMin;
+
+
+
+/**
+ * @constructor
+ */
+var BingMapsResourceSet = function() {};
+
+
+/**
+ * @type {number}
+ */
+BingMapsResourceSet.prototype.estimatedTotal;
+
+
+/**
+ * @type {Array.<BingMapsResource>}
+ */
+BingMapsResourceSet.prototype.resources;
\ No newline at end of file
diff --git a/src/closure/conf/externs/bootstrap.js b/src/closure/conf/externs/bootstrap.js
new file mode 100755
index 0000000000000000000000000000000000000000..fb49fcfded06a098b966e90649ddb20dbd69d2b5
--- /dev/null
+++ b/src/closure/conf/externs/bootstrap.js
@@ -0,0 +1,242 @@
+/**
+ * @fileoverview Externs for Twitter Bootstrap
+ * @see http://twitter.github.com/bootstrap/
+ * 
+ * @author Qamal Kosim-Satyaputra
+ * @externs
+ */
+
+
+
+// --- Modal ---
+
+
+
+/** @constructor */
+jQuery.modal.options = function() {};
+
+/** @type {boolean} */
+jQuery.modal.options.prototype.backdrop;
+
+/** @type {boolean} */
+jQuery.modal.options.prototype.keyboard;
+
+/** @type {boolean} */
+jQuery.modal.options.prototype.show;
+
+/**
+ * @param {=(string|jQuery.modal.options)} opt_eventOrOptions
+ * @return {jQuery}
+ */
+jQuery.prototype.modal = function(opt_eventOrOptions) {};
+
+
+
+// --- Dropdown ---
+
+
+
+/**
+ * @return {jQuery}
+ */
+jQuery.prototype.dropdown = function() {};
+
+
+
+// --- Scroll Spy ---
+
+
+
+/** @constructor */
+jQuery.scrollspy.options = function() {};
+
+/** @type {number} */
+jQuery.scrollspy.options.prototype.offset;
+
+/**
+ * @param {=jQuery.scrollspy.options} opt_options
+ * @return {jQuery}
+ */
+jQuery.prototype.scrollspy = function(opt_options) {};
+
+
+
+// --- Tabs ---
+
+
+
+/**
+ * @param {=string} opt_event
+ * @return {jQuery}
+ */
+jQuery.prototype.tab = function(opt_event) {};
+
+
+
+// --- Tooltips ---
+
+
+
+/** @constructor */
+jQuery.tooltip.options = function() {};
+
+/** @type {boolean} */
+jQuery.tooltip.prototype.animation;
+
+/** @type {string|function} */
+jQuery.tooltip.prototype.placement;
+
+/** @type {string} */
+jQuery.tooltip.prototype.selector;
+
+/** @type {string|function} */
+jQuery.tooltip.prototype.title;
+
+/** @type {string} */
+jQuery.tooltip.prototype.trigger;
+
+/** @type {number|{show: number, hide: number}} */
+jQuery.tooltip.prototype.delay;
+
+/**
+ * @param {=(string|jQuery.tooltip.options)} opt_eventOrOptions
+ * @return {jQuery}
+ */
+jQuery.prototype.tooltip = function(opt_eventOrOptions) {};
+
+
+
+// --- Popovers ---
+
+
+
+/** @constructor */
+jQuery.popover.options = function() {};
+
+/** @type {boolean} */
+jQuery.popover.prototype.animation;
+
+/** @type {string|function} */
+jQuery.popover.prototype.placement;
+
+/** @type {string} */
+jQuery.popover.prototype.selector;
+
+/** @type {string} */
+jQuery.popover.prototype.trigger;
+
+/** @type {string|function} */
+jQuery.popover.prototype.title;
+
+/** @type {string|function} */
+jQuery.popover.prototype.content;
+
+/** @type {number|{show: number, hide: number}} */
+jQuery.popover.prototype.delay;
+
+/**
+ * @param {=(string|jQuery.tooltip.options)} opt_eventOrOptions
+ * @return {jQuery}
+ */
+jQuery.prototype.popover = function(opt_eventOrOptions) {};
+
+
+
+// --- Alerts ---
+
+
+
+/**
+ * @param {=string} opt_event
+ * @return {jQuery}
+ */
+jQuery.prototype.alert = function(opt_event) {};
+
+
+
+// --- Buttons ---
+
+
+
+/**
+ * @param {=string} opt_state
+ * @return {jQuery}
+ */
+jQuery.prototype.button = function(opt_state) {};
+
+
+
+// --- Collapse ---
+
+
+
+/** @constructor */
+jQuery.collapse.options = function() {};
+
+/** @type {jQuerySelector} */
+jQuery.collapse.options.prototype.parent;
+
+/** @type {boolean} */
+jQuery.collapse.options.prototype.toggle;
+
+/**
+ * @param {=(string|jQuery.collapse.options)} opt_eventOrOptions
+ */
+jQuery.prototype.collapse = function(opt_eventOrOptions) {};
+
+
+
+// --- Carousel ---
+
+
+
+/** @constructor */
+jQuery.carousel.options = function() {};
+
+/** @type {number} */
+jQuery.carousel.options.prototype.interval;
+
+/** @type {string} */
+jQuery.carousel.options.prototype.pause;
+
+/**
+ * @param {=(string|jQuery.carousel.options})} opt_eventOrOptions
+ */
+jQuery.prototype.carousel = function(opt_eventOrOptions) {};
+
+
+
+// --- Typeahead ---
+
+
+
+/** @constructor */
+jQuery.typeahead.options = function() {};
+
+/** @type {Array} */
+jQuery.typeahead.options.prototype.source;
+
+/** @type {number} */
+jQuery.typeahead.options.prototype.items;
+
+/** @type {function} */
+jQuery.typeahead.options.prototype.matcher;
+
+/** @type {function} */
+jQuery.typeahead.options.prototype.sorter;
+
+/** @type {function} */
+jQuery.typeahead.options.prototype.highlighter;
+
+/**
+ * @param {=(string|jQuery.typeahead.options)} opt_options
+ * @return {jQuery}
+ */
+jQuery.prototype.typeahead = function(opt_options) {};
+
+/**
+ * @param {Element|jQuery|jQuerySelector}
+ * @param {=jQuery.typeahead.options} opt_options
+ * @return {jQuery}
+ */
+jQuery.prototype.typeahead.Constructor = function(element, opt_options) {};
\ No newline at end of file
diff --git a/src/closure/conf/externs/geojson.js b/src/closure/conf/externs/geojson.js
new file mode 100755
index 0000000000000000000000000000000000000000..6ddf03a3cc7ba7623d5442e065046ce92f482adc
--- /dev/null
+++ b/src/closure/conf/externs/geojson.js
@@ -0,0 +1,171 @@
+/**
+ * @fileoverview Externs for GeoJSON.
+ * @see http://geojson.org/geojson-spec.html
+ * @externs
+ */
+
+
+
+/**
+ * @constructor
+ */
+var GeoJSONObject = function() {};
+
+
+/**
+ * @type {!Array.<number>|undefined}
+ */
+GeoJSONObject.prototype.bbox;
+
+
+/**
+ * @type {string}
+ */
+GeoJSONObject.prototype.type;
+
+
+/**
+ * @type {!GeoJSONCRS|undefined}
+ */
+GeoJSONObject.prototype.crs;
+
+
+
+/**
+ * @constructor
+ */
+var GeoJSONCRS = function() {};
+
+
+/**
+ * CRS type. One of `link` or `name`.
+ * @type {string}
+ */
+GeoJSONCRS.prototype.type;
+
+
+/**
+ * TODO: remove GeoJSONCRSCode when http://jira.codehaus.org/browse/GEOS-5996
+ * is fixed and widely deployed.
+ * @type {!GeoJSONCRSCode|!GeoJSONCRSName|!GeoJSONLink}
+ */
+GeoJSONCRS.prototype.properties;
+
+
+
+/**
+ * `GeoJSONCRSCode` is not part of the GeoJSON specification, but is generated
+ * by GeoServer.
+ * TODO: remove GeoJSONCRSCode when http://jira.codehaus.org/browse/GEOS-5996
+ * is fixed and widely deployed.
+ * @constructor
+ */
+var GeoJSONCRSCode = function() {};
+
+
+
+/**
+ * @constructor
+ */
+var GeoJSONCRSName = function() {};
+
+
+/**
+ * TODO: remove this when http://jira.codehaus.org/browse/GEOS-5996 is fixed
+ * and widely deployed.
+ * @type {string}
+ */
+GeoJSONCRSName.prototype.code;
+
+
+/**
+ * @type {string}
+ */
+GeoJSONCRSName.prototype.name;
+
+
+
+/**
+ * @constructor
+ * @extends {GeoJSONObject}
+ */
+var GeoJSONGeometry = function() {};
+
+
+/**
+ * @type {!Array.<number>|!Array.<!Array.<number>>|
+ *        !Array.<!Array.<!Array.<number>>>}
+ */
+GeoJSONGeometry.prototype.coordinates;
+
+
+
+/**
+ * @constructor
+ * @extends {GeoJSONObject}
+ */
+var GeoJSONGeometryCollection = function() {};
+
+
+/**
+ * @type {!Array.<GeoJSONGeometry>}
+ */
+GeoJSONGeometryCollection.prototype.geometries;
+
+
+
+/**
+ * @constructor
+ * @extends {GeoJSONObject}
+ */
+var GeoJSONFeature = function() {};
+
+
+/**
+ * @type {GeoJSONGeometry|GeoJSONGeometryCollection}
+ */
+GeoJSONFeature.prototype.geometry;
+
+
+/**
+ * @type {number|string|undefined}
+ */
+GeoJSONFeature.prototype.id;
+
+
+/**
+ * @type {Object.<string, *>}
+ */
+GeoJSONFeature.prototype.properties;
+
+
+
+/**
+ * @constructor
+ * @extends {GeoJSONObject}
+ */
+var GeoJSONFeatureCollection = function() {};
+
+
+/**
+ * @type {!Array.<GeoJSONFeature>}
+ */
+GeoJSONFeatureCollection.prototype.features;
+
+
+
+/**
+ * @constructor
+ */
+var GeoJSONLink = function() {};
+
+
+/**
+ * @type {string}
+ */
+GeoJSONLink.prototype.href;
+
+/**
+ * @type {string}
+ */
+GeoJSONLink.prototype.type;
\ No newline at end of file
diff --git a/src/closure/conf/externs/html2canvas.js b/src/closure/conf/externs/html2canvas.js
new file mode 100755
index 0000000000000000000000000000000000000000..d12202e32f6fd2db7b14312b65d06e30b9e94c78
--- /dev/null
+++ b/src/closure/conf/externs/html2canvas.js
@@ -0,0 +1,8 @@
+/**
+ * 
+ * @param {type} arg1
+ * @param {type} arg2
+ * @returns {html2canvas}
+ */
+function html2canvas (arg1, arg2) {};
+
diff --git a/src/closure/conf/externs/jquery-1.9.js b/src/closure/conf/externs/jquery-1.9.js
new file mode 100755
index 0000000000000000000000000000000000000000..72b80b31763c2810407a6faf2644d318d8c34a5b
--- /dev/null
+++ b/src/closure/conf/externs/jquery-1.9.js
@@ -0,0 +1,2166 @@
+/*
+ * Copyright 2011 The Closure Compiler Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Externs for jQuery 1.9.1
+ *
+ * Note that some functions use different return types depending on the number
+ * of parameters passed in. In these cases, you may need to annotate the type
+ * of the result in your code, so the JSCompiler understands which type you're
+ * expecting. For example:
+ *    <code>var elt = /** @type {Element} * / (foo.get(0));</code>
+ *
+ * @see http://api.jquery.com/
+ * @externs
+ */
+
+/**
+ * @typedef {(Window|Document|Element|Array.<Element>|string|jQuery|
+ *     NodeList)}
+ */
+var jQuerySelector;
+
+/** @typedef {function(...)|Array.<function(...)>} */
+var jQueryCallback;
+
+/** @typedef {
+              {
+               accepts: (Object.<string, string>|undefined),
+               async: (?boolean|undefined),
+               beforeSend: (function(jQuery.jqXHR, (jQueryAjaxSettings|Object.<string, *>))|undefined),
+               cache: (?boolean|undefined),
+               complete: (function(jQuery.jqXHR, string)|undefined),
+               contents: (Object.<string, RegExp>|undefined),
+               contentType: (?string|undefined),
+               context: (Object.<?, ?>|jQueryAjaxSettings|undefined),
+               converters: (Object.<string, Function>|undefined),
+               crossDomain: (?boolean|undefined),
+               data: (Object.<?, ?>|?string|Array.<?>|undefined),
+               dataFilter: (function(string, string):?|undefined),
+               dataType: (?string|undefined),
+               error: (function(jQuery.jqXHR, string, string)|undefined),
+               global: (?boolean|undefined),
+               headers: (Object.<?, ?>|undefined),
+               ifModified: (?boolean|undefined),
+               isLocal: (?boolean|undefined),
+               jsonp: (?string|undefined),
+               jsonpCallback: (?string|function()|undefined),
+               mimeType: (?string|undefined),
+               password: (?string|undefined),
+               processData: (?boolean|undefined),
+               scriptCharset: (?string|undefined),
+               statusCode: (Object.<number, function()>|undefined),
+               success: (function(?, string, jQuery.jqXHR)|undefined),
+               timeout: (?number|undefined),
+               traditional: (?boolean|undefined),
+               type: (?string|undefined),
+               url: (?string|undefined),
+               username: (?string|undefined),
+               xhr: (function():(ActiveXObject|XMLHttpRequest)|undefined),
+               xhrFields: (Object.<?, ?>|undefined)
+              }} */
+var jQueryAjaxSettings;
+
+/**
+ * @constructor
+ * @param {(jQuerySelector|Element|Object|Array.<Element>|jQuery|string|
+ *     function())=} arg1
+ * @param {(Element|jQuery|Document|
+ *     Object.<string, (string|function(!jQuery.event=))>)=} arg2
+ * @return {!jQuery}
+ */
+function jQuery(arg1, arg2) {}
+
+/**
+ * @constructor
+ * @extends {jQuery}
+ * @param {(jQuerySelector|Element|Object|Array.<Element>|jQuery|string|
+ *     function())=} arg1
+ * @param {(Element|jQuery|Document|
+ *     Object.<string, (string|function(!jQuery.event=))>)=} arg2
+ * @return {!jQuery}
+ */
+function $(arg1, arg2) {}
+
+/**
+ * @param {(jQuerySelector|Array.<Element>|string|jQuery)} arg1
+ * @param {Element=} context
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.add = function(arg1, context) {};
+
+/**
+ * @param {(jQuerySelector|Array.<Element>|string|jQuery)=} arg1
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.addBack = function(arg1) {};
+
+/**
+ * @param {(string|function(number,String))} arg1
+ * @return {!jQuery}
+ */
+jQuery.prototype.addClass = function(arg1) {};
+
+/**
+ * @param {(string|Element|jQuery|function(number))} arg1
+ * @param {(string|Element|Array.<Element>|jQuery)=} content
+ * @return {!jQuery}
+ */
+jQuery.prototype.after = function(arg1, content) {};
+
+/**
+ * @param {(string|jQueryAjaxSettings|Object.<string,*>)} arg1
+ * @param {(jQueryAjaxSettings|Object.<string, *>)=} settings
+ * @return {jQuery.jqXHR}
+ */
+jQuery.ajax = function(arg1, settings) {};
+
+/**
+ * @param {(string|jQueryAjaxSettings|Object.<string, *>)} arg1
+ * @param {(jQueryAjaxSettings|Object.<string, *>)=} settings
+ * @return {jQuery.jqXHR}
+ */
+$.ajax = function(arg1, settings) {};
+
+/**
+ * @param {function(!jQuery.event,XMLHttpRequest,(jQueryAjaxSettings|Object.<string, *>))} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.ajaxComplete = function(handler) {};
+
+/**
+ * @param {function(!jQuery.event,jQuery.jqXHR,(jQueryAjaxSettings|Object.<string, *>),*)} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.ajaxError = function(handler) {};
+
+/**
+ * @param {(string|function((jQueryAjaxSettings|Object.<string, *>),(jQueryAjaxSettings|Object.<string, *>),jQuery.jqXHR))} dataTypes
+ * @param {function((jQueryAjaxSettings|Object.<string, *>),(jQueryAjaxSettings|Object.<string, *>),jQuery.jqXHR)=} handler
+ */
+jQuery.ajaxPrefilter = function(dataTypes, handler) {};
+
+/**
+ * @param {(string|function((jQueryAjaxSettings|Object.<string, *>),(jQueryAjaxSettings|Object.<string, *>),jQuery.jqXHR))} dataTypes
+ * @param {function((jQueryAjaxSettings|Object.<string, *>),(jQueryAjaxSettings|Object.<string, *>),jQuery.jqXHR)=} handler
+ */
+$.ajaxPrefilter = function(dataTypes, handler) {};
+
+/**
+ * @param {function(!jQuery.event,jQuery.jqXHR,(jQueryAjaxSettings|Object.<string, *>))} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.ajaxSend = function(handler) {};
+
+/** @const {jQueryAjaxSettings|Object.<string, *>} */
+jQuery.ajaxSettings;
+
+/** @const {jQueryAjaxSettings|Object.<string, *>} */
+$.ajaxSettings = {};
+
+/** @type {Object.<string, boolean>} */
+jQuery.ajaxSettings.flatOptions = {};
+
+/** @type {Object.<string, boolean>} */
+$.ajaxSettings.flatOptions = {};
+
+/** @type {boolean} */
+jQuery.ajaxSettings.processData;
+
+/** @type {boolean} */
+$.ajaxSettings.processData;
+
+/** @type {Object.<string, string>} */
+jQuery.ajaxSettings.responseFields = {};
+
+/** @type {Object.<string, string>} */
+$.ajaxSettings.responseFields = {};
+
+/** @param {jQueryAjaxSettings|Object.<string, *>} options */
+jQuery.ajaxSetup = function(options) {};
+
+/** @param {jQueryAjaxSettings|Object.<string, *>} options */
+$.ajaxSetup = function(options) {};
+
+/**
+ * @param {function()} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.ajaxStart = function(handler) {};
+
+/**
+ * @param {function()} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.ajaxStop = function(handler) {};
+
+/**
+ * @param {function(!jQuery.event,XMLHttpRequest,(jQueryAjaxSettings|Object.<string, *>), ?)} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.ajaxSuccess = function(handler) {};
+
+/**
+ * @deprecated Please use .addBack(selector) instead.
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.andSelf = function() {};
+
+/**
+ * @param {Object.<string,*>} properties
+ * @param {(string|number|function()|Object.<string,*>)=} arg2
+ * @param {(string|function())=} easing
+ * @param {function()=} complete
+ * @return {!jQuery}
+ */
+jQuery.prototype.animate = function(properties, arg2, easing, complete) {};
+
+/**
+ * @param {(string|Element|Array.<Element>|jQuery|function(number,string))} arg1
+ * @param {...(string|Element|Array.<Element>|jQuery)} content
+ * @return {!jQuery}
+ */
+jQuery.prototype.append = function(arg1, content) {};
+
+/**
+ * @param {(jQuerySelector|Element|jQuery)} target
+ * @return {!jQuery}
+ */
+jQuery.prototype.appendTo = function(target) {};
+
+/**
+ * @param {(string|Object.<string,*>)} arg1
+ * @param {(string|number|boolean|function(number,string))=} arg2
+ * @return {(string|!jQuery)}
+ */
+jQuery.prototype.attr = function(arg1, arg2) {};
+
+/**
+ * @param {(string|Element|jQuery|function())} arg1
+ * @param {(string|Element|Array.<Element>|jQuery)=} content
+ * @return {!jQuery}
+ */
+jQuery.prototype.before = function(arg1, content) {};
+
+/**
+ * @param {(string|Object.<string, function(!jQuery.event=)>)} arg1
+ * @param {(Object.<string, *>|function(!jQuery.event=)|boolean)=} eventData
+ * @param {(function(!jQuery.event=)|boolean)=} arg3
+ * @return {!jQuery}
+ */
+jQuery.prototype.bind = function(arg1, eventData, arg3) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.blur = function(arg1, handler) {};
+
+/**
+ * @constructor
+ * @private
+ */
+jQuery.callbacks = function () {};
+
+/**
+ * @param {string=} flags
+ * @return {jQuery.callbacks}
+ */
+jQuery.Callbacks = function (flags) {};
+
+/** @param {function()} callbacks */
+jQuery.callbacks.prototype.add = function(callbacks) {};
+
+/** @return {undefined} */
+jQuery.callbacks.prototype.disable = function() {};
+
+/** @return {undefined} */
+jQuery.callbacks.prototype.empty = function() {};
+
+/** @param {...*} var_args */
+jQuery.callbacks.prototype.fire = function(var_args) {};
+
+/** @return {boolean} */
+jQuery.callbacks.prototype.fired = function() {};
+
+/** @param {...*} var_args */
+jQuery.callbacks.prototype.fireWith = function(var_args) {};
+
+/**
+ * @param {function()} callback
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.callbacks.prototype.has = function(callback) {};
+
+/** @return {undefined} */
+jQuery.callbacks.prototype.lock = function() {};
+
+/** @return {boolean} */
+jQuery.callbacks.prototype.locked = function() {};
+
+/** @param {function()} callbacks */
+jQuery.callbacks.prototype.remove = function(callbacks) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.change = function(arg1, handler) {};
+
+/**
+ * @param {jQuerySelector=} selector
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.children = function(selector) {};
+
+/**
+ * @param {string=} queueName
+ * @return {!jQuery}
+ */
+jQuery.prototype.clearQueue = function(queueName) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.click = function(arg1, handler) {};
+
+/**
+ * @param {boolean=} withDataAndEvents
+ * @param {boolean=} deepWithDataAndEvents
+ * @return {!jQuery}
+ * @suppress {checkTypes} see https://code.google.com/p/closure-compiler/issues/detail?id=583
+ */
+jQuery.prototype.clone = function(withDataAndEvents, deepWithDataAndEvents) {};
+
+/**
+ * @param {(jQuerySelector|jQuery|Element|string)} arg1
+ * @param {Element=} context
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.closest = function(arg1, context) {};
+
+/**
+ * @param {Element} container
+ * @param {Element} contained
+ * @return {boolean}
+ */
+jQuery.contains = function(container, contained) {};
+
+/**
+ * @param {Element} container
+ * @param {Element} contained
+ * @return {boolean}
+ */
+$.contains = function(container, contained) {};
+
+/**
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.contents = function() {};
+
+/** @type {Element|Document} */
+jQuery.prototype.context;
+
+/**
+ * @param {(string|Object.<string,*>)} arg1
+ * @param {(string|number|function(number,*))=} arg2
+ * @return {(string|!jQuery)}
+ */
+jQuery.prototype.css = function(arg1, arg2) {};
+
+/** @type {Object.<string, *>} */
+jQuery.cssHooks;
+
+/** @type {Object.<string, *>} */
+$.cssHooks;
+
+/**
+ * @param {Element} elem
+ * @param {string=} key
+ * @param {*=} value
+ * @return {*}
+ */
+jQuery.data = function(elem, key, value) {};
+
+/**
+ * @param {(string|Object.<string, *>)=} arg1
+ * @param {*=} value
+ * @return {*}
+ */
+jQuery.prototype.data = function(arg1, value) {};
+
+/**
+ * @param {Element} elem
+ * @param {string=} key
+ * @param {*=} value
+ * @return {*}
+ */
+$.data = function(elem, key, value) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.dblclick = function(arg1, handler) {};
+
+/**
+ * @constructor
+ * @implements {jQuery.Promise}
+ * @param {function()=} opt_fn
+ * @see http://api.jquery.com/category/deferred-object/
+ */
+jQuery.deferred = function(opt_fn) {};
+
+/**
+ * @constructor
+ * @extends {jQuery.deferred}
+ * @param {function()=} opt_fn
+ * @return {jQuery.Deferred}
+ */
+jQuery.Deferred = function(opt_fn) {};
+
+/**
+ * @constructor
+ * @extends {jQuery.deferred}
+ * @param {function()=} opt_fn
+ * @see http://api.jquery.com/category/deferred-object/
+ */
+$.deferred = function(opt_fn) {};
+
+/**
+ * @constructor
+ * @extends {jQuery.deferred}
+ * @param {function()=} opt_fn
+ * @return {jQuery.deferred}
+ */
+$.Deferred = function(opt_fn) {};
+
+/**
+ * @override
+ * @param {jQueryCallback} alwaysCallbacks
+ * @param {jQueryCallback=} alwaysCallbacks2
+ * @return {jQuery.deferred}
+ */
+jQuery.deferred.prototype.always
+    = function(alwaysCallbacks, alwaysCallbacks2) {};
+
+/**
+ * @override
+ * @param {jQueryCallback} doneCallbacks
+ * @param {jQueryCallback=} doneCallbacks2
+ * @return {jQuery.deferred}
+ */
+jQuery.deferred.prototype.done = function(doneCallbacks, doneCallbacks2) {};
+
+/**
+ * @override
+ * @param {jQueryCallback} failCallbacks
+ * @param {jQueryCallback=} failCallbacks2
+ * @return {jQuery.deferred}
+ */
+jQuery.deferred.prototype.fail = function(failCallbacks, failCallbacks2) {};
+
+/**
+ * @param {...*} var_args
+ * @return {jQuery.deferred}
+ */
+jQuery.deferred.prototype.notify = function(var_args) {};
+
+/**
+ * @param {Object} context
+ * @param {...*} var_args
+ * @return {jQuery.deferred}
+ */
+jQuery.deferred.prototype.notifyWith = function(context, var_args) {};
+
+/**
+ * @deprecated Please use deferred.then() instead.
+ * @override
+ * @param {function()=} doneFilter
+ * @param {function()=} failFilter
+ * @param {function()=} progressFilter
+ * @return {jQuery.Promise}
+ */
+jQuery.deferred.prototype.pipe =
+    function(doneFilter, failFilter, progressFilter) {};
+
+/**
+ * @param {jQueryCallback} progressCallbacks
+ * @return {jQuery.deferred}
+ */
+jQuery.deferred.prototype.progress = function(progressCallbacks) {};
+
+/**
+ * @param {Object=} target
+ * @return {jQuery.Promise}
+ */
+jQuery.deferred.prototype.promise = function(target) {};
+
+/**
+ * @param {...*} var_args
+ * @return {jQuery.deferred}
+ */
+jQuery.deferred.prototype.reject = function(var_args) {};
+
+/**
+ * @param {Object} context
+ * @param {Array.<*>=} args
+ * @return {jQuery.deferred}
+ */
+jQuery.deferred.prototype.rejectWith = function(context, args) {};
+
+/**
+ * @param {...*} var_args
+ * @return {jQuery.deferred}
+ */
+jQuery.deferred.prototype.resolve = function(var_args) {};
+
+/**
+ * @param {Object} context
+ * @param {Array.<*>=} args
+ * @return {jQuery.deferred}
+ */
+jQuery.deferred.prototype.resolveWith = function(context, args) {};
+
+/** @return {string} */
+jQuery.deferred.prototype.state = function() {};
+
+/**
+ * @override
+ * @param {jQueryCallback} doneCallbacks
+ * @param {jQueryCallback=} failCallbacks
+ * @param {jQueryCallback=} progressCallbacks
+ * @return {jQuery.deferred}
+ */
+jQuery.deferred.prototype.then
+    = function(doneCallbacks, failCallbacks, progressCallbacks) {};
+
+/**
+ * @param {number} duration
+ * @param {string=} queueName
+ * @return {!jQuery}
+ */
+jQuery.prototype.delay = function(duration, queueName) {};
+
+/**
+ * @param {string} selector
+ * @param {(string|Object.<string,*>)} arg2
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg3
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.delegate = function(selector, arg2, arg3, handler) {};
+
+/**
+ * @param {Element} elem
+ * @param {string=} queueName
+ */
+jQuery.dequeue = function(elem, queueName) {};
+
+/**
+ * @param {string=} queueName
+ * @return {!jQuery}
+ */
+jQuery.prototype.dequeue = function(queueName) {};
+
+/**
+ * @param {Element} elem
+ * @param {string=} queueName
+ */
+$.dequeue = function(elem, queueName) {};
+
+/**
+ * @param {jQuerySelector=} selector
+ * @return {!jQuery}
+ */
+jQuery.prototype.detach = function(selector) {};
+
+/**
+ * @param {Object} collection
+ * @param {function((number|string),?)} callback
+ * @return {Object}
+ */
+jQuery.each = function(collection, callback) {};
+
+/**
+ * @param {function(number,Element)} fnc
+ * @return {!jQuery}
+ */
+jQuery.prototype.each = function(fnc) {};
+
+/**
+ * @param {Object} collection
+ * @param {function((number|string),?)} callback
+ * @return {Object}
+ */
+$.each = function(collection, callback) {};
+
+/** @return {!jQuery} */
+jQuery.prototype.empty = function() {};
+
+/**
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.end = function() {};
+
+/**
+ * @param {number} arg1
+ * @return {!jQuery}
+ */
+jQuery.prototype.eq = function(arg1) {};
+
+/** @param {string} message */
+jQuery.error = function(message) {};
+
+/**
+ * @deprecated Please use .on( "error", handler ) instead.
+ * @param {(function(!jQuery.event=)|Object.<string, *>)} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.error = function(arg1, handler) {};
+
+/** @param {string} message */
+$.error = function(message) {};
+
+/**
+ * @constructor
+ * @param {string} eventType
+ */
+jQuery.event = function(eventType) {};
+
+/**
+ * @constructor
+ * @extends {jQuery.event}
+ * @param {string} eventType
+ * @param {Object=} properties
+ * @return {jQuery.Event}
+ */
+jQuery.Event = function(eventType, properties) {};
+
+/**
+ * @constructor
+ * @extends {jQuery.event}
+ * @param {string} eventType
+ */
+$.event = function(eventType) {};
+
+/**
+ * @constructor
+ * @extends {jQuery.event}
+ * @param {string} eventType
+ * @param {Object=} properties
+ * @return {$.Event}
+ */
+$.Event = function(eventType, properties) {};
+
+/** @type {Element} */
+jQuery.event.prototype.currentTarget;
+
+/** @type {Object.<string, *>} */
+jQuery.event.prototype.data;
+
+/** @type {Element} */
+jQuery.event.prototype.delegateTarget;
+
+/**
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.event.prototype.isDefaultPrevented = function() {};
+
+/**
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.event.prototype.isImmediatePropagationStopped = function() {};
+
+/**
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.event.prototype.isPropagationStopped = function() {};
+
+/** @type {string} */
+jQuery.event.prototype.namespace;
+
+/** @type {Event} */
+jQuery.event.prototype.originalEvent;
+
+/** @type {number} */
+jQuery.event.prototype.pageX;
+
+/** @type {number} */
+jQuery.event.prototype.pageY;
+
+/** @return {undefined} */
+jQuery.event.prototype.preventDefault = function() {};
+
+/** @type {Object.<string, *>} */
+jQuery.event.prototype.props;
+
+/** @type {Element} */
+jQuery.event.prototype.relatedTarget;
+
+/** @type {*} */
+jQuery.event.prototype.result;
+
+/** @return {undefined} */
+jQuery.event.prototype.stopImmediatePropagation = function() {};
+
+/** @return {undefined} */
+jQuery.event.prototype.stopPropagation = function() {};
+
+/** @type {Element} */
+jQuery.event.prototype.target;
+
+/** @type {number} */
+jQuery.event.prototype.timeStamp;
+
+/** @type {string} */
+jQuery.event.prototype.type;
+
+/** @type {number} */
+jQuery.event.prototype.which;
+
+/**
+ * @param {(Object|boolean)} arg1
+ * @param {...*} var_args
+ * @return {Object}
+ */
+jQuery.extend = function(arg1, var_args) {};
+
+/**
+ * @param {(Object|boolean)} arg1
+ * @param {...*} var_args
+ * @return {Object}
+ */
+jQuery.prototype.extend = function(arg1, var_args) {};
+
+/**
+ * @param {(Object|boolean)} arg1
+ * @param {...*} var_args
+ * @return {Object}
+ */
+$.extend = function(arg1, var_args) {};
+
+/**
+ * @param {(string|number|function())=} duration
+ * @param {(function()|string)=} arg2
+ * @param {function()=} callback
+ * @return {!jQuery}
+ */
+jQuery.prototype.fadeIn = function(duration, arg2, callback) {};
+
+/**
+ * @param {(string|number|function())=} duration
+ * @param {(function()|string)=} arg2
+ * @param {function()=} callback
+ * @return {!jQuery}
+ */
+jQuery.prototype.fadeOut = function(duration, arg2, callback) {};
+
+/**
+ * @param {(string|number)} duration
+ * @param {number} opacity
+ * @param {(function()|string)=} arg3
+ * @param {function()=} callback
+ * @return {!jQuery}
+ */
+jQuery.prototype.fadeTo = function(duration, opacity, arg3, callback) {};
+
+/**
+ * @param {(string|number|function())=} duration
+ * @param {(string|function())=} easing
+ * @param {function()=} callback
+ * @return {!jQuery}
+ */
+jQuery.prototype.fadeToggle = function(duration, easing, callback) {};
+
+/**
+ * @param {(jQuerySelector|function(number,Element)|Element|jQuery)} arg1
+ * @return {!jQuery}
+ * @see http://api.jquery.com/filter/
+ */
+jQuery.prototype.filter = function(arg1) {};
+
+/**
+ * @param {(jQuerySelector|jQuery|Element)} arg1
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.find = function(arg1) {};
+
+/** @return {!jQuery} */
+jQuery.prototype.first = function() {};
+
+/** @see http://docs.jquery.com/Plugins/Authoring */
+jQuery.fn = jQuery.prototype;
+
+/** @see http://docs.jquery.com/Plugins/Authoring */
+$.fn = $.prototype;
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.focus = function(arg1, handler) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.focusin = function(arg1, handler) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.focusout = function(arg1, handler) {};
+
+/** @const */
+jQuery.fx = {};
+
+/** @const */
+$.fx = {};
+
+/** @type {number} */
+jQuery.fx.interval;
+
+/** @type {number} */
+$.fx.interval;
+
+/** @type {boolean} */
+jQuery.fx.off;
+
+/** @type {boolean} */
+$.fx.off;
+
+/**
+ * @param {string} url
+ * @param {(Object.<string,*>|string|
+ *     function(string,string,jQuery.jqXHR))=} data
+ * @param {(function(string,string,jQuery.jqXHR)|string)=} success
+ * @param {string=} dataType
+ * @return {jQuery.jqXHR}
+ */
+jQuery.get = function(url, data, success, dataType) {};
+
+/**
+ * @param {number=} index
+ * @return {(Element|Array.<Element>)}
+ * @nosideeffects
+ */
+jQuery.prototype.get = function(index) {};
+
+/**
+ * @param {string} url
+ * @param {(Object.<string,*>|string|
+ *     function(string,string,jQuery.jqXHR))=} data
+ * @param {(function(string,string,jQuery.jqXHR)|string)=} success
+ * @param {string=} dataType
+ * @return {jQuery.jqXHR}
+ */
+$.get = function(url, data, success, dataType) {};
+
+/**
+ * @param {string} url
+ * @param {(Object.<string,*>|
+ *     function(Object.<string,*>,string,jQuery.jqXHR))=} data
+ * @param {function(Object.<string,*>,string,jQuery.jqXHR)=} success
+ * @return {jQuery.jqXHR}
+ * @see http://api.jquery.com/jquery.getjson/#jQuery-getJSON-url-data-success
+ */
+jQuery.getJSON = function(url, data, success) {};
+
+/**
+ * @param {string} url
+ * @param {(Object.<string,*>|
+ *     function(Object.<string,*>,string,jQuery.jqXHR))=} data
+ * @param {function(Object.<string,*>,string,jQuery.jqXHR)=} success
+ * @return {jQuery.jqXHR}
+ * @see http://api.jquery.com/jquery.getjson/#jQuery-getJSON-url-data-success
+ */
+$.getJSON = function(url, data, success) {};
+
+/**
+ * @param {string} url
+ * @param {function(Node,string,jQuery.jqXHR)=} success
+ * @return {jQuery.jqXHR}
+ */
+jQuery.getScript = function(url, success) {};
+
+/**
+ * @param {string} url
+ * @param {function(Node,string,jQuery.jqXHR)=} success
+ * @return {jQuery.jqXHR}
+ */
+$.getScript = function(url, success) {};
+
+/** @param {string} code */
+jQuery.globalEval = function(code) {};
+
+/** @param {string} code */
+$.globalEval = function(code) {};
+
+/**
+ * @param {Array.<*>} arr
+ * @param {function(*,number)} fnc
+ * @param {boolean=} invert
+ * @return {Array.<*>}
+ */
+jQuery.grep = function(arr, fnc, invert) {};
+
+/**
+ * @param {Array.<*>} arr
+ * @param {function(*,number)} fnc
+ * @param {boolean=} invert
+ * @return {Array.<*>}
+ */
+$.grep = function(arr, fnc, invert) {};
+
+/**
+ * @param {(string|Element)} arg1
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.has = function(arg1) {};
+
+/**
+ * @param {string} className
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.prototype.hasClass = function(className) {};
+
+/**
+ * @param {Element} elem
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.hasData = function(elem) {};
+
+/**
+ * @param {Element} elem
+ * @return {boolean}
+ * @nosideeffects
+ */
+$.hasData = function(elem) {};
+
+/**
+ * @param {(string|number|function(number,number))=} arg1
+ * @return {(number|!jQuery)}
+ */
+jQuery.prototype.height = function(arg1) {};
+
+/**
+ * @param {(string|number|function())=} duration
+ * @param {(function()|string)=} arg2
+ * @param {function()=} callback
+ * @return {!jQuery}
+ */
+jQuery.prototype.hide = function(duration, arg2, callback) {};
+
+/** @param {boolean} hold */
+jQuery.holdReady = function(hold) {};
+
+/** @param {boolean} hold */
+$.holdReady = function(hold) {};
+
+/**
+ * @param {function(!jQuery.event=)} arg1
+ * @param {function(!jQuery.event=)=} handlerOut
+ * @return {!jQuery}
+ */
+jQuery.prototype.hover = function(arg1, handlerOut) {};
+
+/**
+ * @param {(string|function(number,string))=} arg1
+ * @return {(string|!jQuery)}
+ */
+jQuery.prototype.html = function(arg1) {};
+
+/**
+ * @param {*} value
+ * @param {Array.<*>} arr
+ * @param {number=} fromIndex
+ * @return {number}
+ * @nosideeffects
+ */
+jQuery.inArray = function(value, arr, fromIndex) {};
+
+/**
+ * @param {*} value
+ * @param {Array.<*>} arr
+ * @param {number=} fromIndex
+ * @return {number}
+ * @nosideeffects
+ */
+$.inArray = function(value, arr, fromIndex) {};
+
+/**
+ * @param {(jQuerySelector|Element|jQuery)=} arg1
+ * @return {number}
+ */
+jQuery.prototype.index = function(arg1) {};
+
+/**
+ * @return {number}
+ * @nosideeffects
+ */
+jQuery.prototype.innerHeight = function() {};
+
+/**
+ * @return {number}
+ * @nosideeffects
+ */
+jQuery.prototype.innerWidth = function() {};
+
+/**
+ * @param {(jQuerySelector|Element|jQuery)} target
+ * @return {!jQuery}
+ */
+jQuery.prototype.insertAfter = function(target) {};
+
+/**
+ * @param {(jQuerySelector|Element|jQuery)} target
+ * @return {!jQuery}
+ */
+jQuery.prototype.insertBefore = function(target) {};
+
+/**
+ * @param {(jQuerySelector|function(number)|jQuery|Element)} arg1
+ * @return {boolean}
+ */
+jQuery.prototype.is = function(arg1) {};
+
+/**
+ * @param {*} obj
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.isArray = function(obj) {};
+
+/**
+ * @param {*} obj
+ * @return {boolean}
+ * @nosideeffects
+ */
+$.isArray = function(obj) {};
+
+/**
+ * @param {Object} obj
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.isEmptyObject = function(obj) {};
+
+/**
+ * @param {Object} obj
+ * @return {boolean}
+ * @nosideeffects
+ */
+$.isEmptyObject = function(obj) {};
+
+/**
+ * @param {*} obj
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.isFunction = function(obj) {};
+
+/**
+ * @param {*} obj
+ * @return {boolean}
+ * @nosideeffects
+ */
+$.isFunction = function(obj) {};
+
+/**
+ * @param {*} value
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.isNumeric = function(value) {};
+
+/**
+ * @param {*} value
+ * @return {boolean}
+ * @nosideeffects
+ */
+$.isNumeric = function(value) {};
+
+/**
+ * @param {*} obj
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.isPlainObject = function(obj) {};
+
+/**
+ * @param {*} obj
+ * @return {boolean}
+ * @nosideeffects
+ */
+$.isPlainObject = function(obj) {};
+
+/**
+ * @param {*} obj
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.isWindow = function(obj) {};
+
+/**
+ * @param {*} obj
+ * @return {boolean}
+ * @nosideeffects
+ */
+$.isWindow = function(obj) {};
+
+/**
+ * @param {Element} node
+ * @return {boolean}
+ * @nosideeffects
+ */
+jQuery.isXMLDoc = function(node) {};
+
+/**
+ * @param {Element} node
+ * @return {boolean}
+ * @nosideeffects
+ */
+$.isXMLDoc = function(node) {};
+
+/** @type {string} */
+jQuery.prototype.jquery;
+
+/**
+ * @constructor
+ * @extends {XMLHttpRequest}
+ * @implements {jQuery.Promise}
+ * @private
+ * @see http://api.jquery.com/jQuery.ajax/#jqXHR
+ */
+jQuery.jqXHR = function () {};
+
+/**
+ * @override
+ * @param {jQueryCallback} alwaysCallbacks
+ * @param {jQueryCallback=} alwaysCallbacks2
+ * @return {jQuery.jqXHR}
+ */
+jQuery.jqXHR.prototype.always =
+    function(alwaysCallbacks, alwaysCallbacks2) {};
+
+/**
+ * @deprecated
+ * @param {function()} callback
+ * @return {jQuery.jqXHR}
+*/
+jQuery.jqXHR.prototype.complete = function (callback) {};
+
+/**
+ * @override
+ * @param {jQueryCallback} doneCallbacks
+ * @return {jQuery.jqXHR}
+ */
+jQuery.jqXHR.prototype.done = function(doneCallbacks) {};
+
+/**
+ * @deprecated
+ * @param {function()} callback
+ * @return {jQuery.jqXHR}
+*/
+jQuery.jqXHR.prototype.error = function (callback) {};
+
+/**
+ * @override
+ * @param {jQueryCallback} failCallbacks
+ * @return {jQuery.jqXHR}
+ */
+jQuery.jqXHR.prototype.fail = function(failCallbacks) {};
+
+/**
+ * @deprecated
+ * @override
+ */
+jQuery.jqXHR.prototype.onreadystatechange = function (callback) {};
+
+/**
+ * @override
+ * @param {function()=} doneFilter
+ * @param {function()=} failFilter
+ * @param {function()=} progressFilter
+ * @return {jQuery.jqXHR}
+ */
+jQuery.jqXHR.prototype.pipe =
+    function(doneFilter, failFilter, progressFilter) {};
+
+/**
+ * @deprecated
+ * @param {function()} callback
+ * @return {jQuery.jqXHR}
+*/
+jQuery.jqXHR.prototype.success = function (callback) {};
+
+/**
+ * @override
+ * @param {jQueryCallback} doneCallbacks
+ * @param {jQueryCallback=} failCallbacks
+ * @param {jQueryCallback=} progressCallbacks
+ * @return {jQuery.jqXHR}
+ */
+jQuery.jqXHR.prototype.then =
+    function(doneCallbacks, failCallbacks, progressCallbacks) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.keydown = function(arg1, handler) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.keypress = function(arg1, handler) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.keyup = function(arg1, handler) {};
+
+/** @return {!jQuery} */
+jQuery.prototype.last = function() {};
+
+/** @type {number} */
+jQuery.prototype.length;
+
+/**
+ * @deprecated Please avoid the document loading Event invocation of
+ *     .load() and use .on( "load", handler ) instead. (The AJAX
+ *     module invocation signature is OK.)
+ * @param {(function(!jQuery.event=)|Object.<string, *>|string)} arg1
+ * @param {(function(!jQuery.event=)|Object.<string,*>|string)=} arg2
+ * @param {function(string,string,XMLHttpRequest)=} complete
+ * @return {!jQuery}
+ */
+jQuery.prototype.load = function(arg1, arg2, complete) {};
+
+/**
+ * @param {*} obj
+ * @return {Array.<*>}
+ */
+jQuery.makeArray = function(obj) {};
+
+/**
+ * @param {*} obj
+ * @return {Array.<*>}
+ */
+$.makeArray = function(obj) {};
+
+/**
+ * @param {(Array.<*>|Object.<string, *>)} arg1
+ * @param {(function(*,number)|function(*,(string|number)))} callback
+ * @return {Array.<*>}
+ */
+jQuery.map = function(arg1, callback) {};
+
+/**
+ * @param {function(number,Element)} callback
+ * @return {!jQuery}
+ */
+jQuery.prototype.map = function(callback) {};
+
+/**
+ * @param {(Array.<*>|Object.<string, *>)} arg1
+ * @param {(function(*,number)|function(*,(string|number)))} callback
+ * @return {Array.<*>}
+ */
+$.map = function(arg1, callback) {};
+
+/**
+ * @param {Array.<*>} first
+ * @param {Array.<*>} second
+ * @return {Array.<*>}
+ */
+jQuery.merge = function(first, second) {};
+
+/**
+ * @param {Array.<*>} first
+ * @param {Array.<*>} second
+ * @return {Array.<*>}
+ */
+$.merge = function(first, second) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.mousedown = function(arg1, handler) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.mouseenter = function(arg1, handler) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.mouseleave = function(arg1, handler) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.mousemove = function(arg1, handler) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.mouseout = function(arg1, handler) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.mouseover = function(arg1, handler) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.mouseup = function(arg1, handler) {};
+
+/**
+ * @param {jQuerySelector=} selector
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.next = function(selector) {};
+
+/**
+ * @param {string=} selector
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.nextAll = function(selector) {};
+
+/**
+ * @param {(jQuerySelector|Element)=} arg1
+ * @param {jQuerySelector=} filter
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.nextUntil = function(arg1, filter) {};
+
+/**
+ * @param {boolean=} removeAll
+ * @return {Object}
+ */
+jQuery.noConflict = function(removeAll) {};
+
+/**
+ * @param {boolean=} removeAll
+ * @return {Object}
+ */
+$.noConflict = function(removeAll) {};
+
+/**
+ * @return {function()}
+ * @nosideeffects
+ */
+jQuery.noop = function() {};
+
+/**
+ * @return {function()}
+ * @nosideeffects
+ */
+$.noop = function() {};
+
+/**
+ * @param {(jQuerySelector|Array.<Element>|function(number)|jQuery)} arg1
+ * @return {!jQuery}
+ */
+jQuery.prototype.not = function(arg1) {};
+
+/**
+ * @return {number}
+ * @nosideeffects
+ */
+jQuery.now = function() {};
+
+/**
+ * @return {number}
+ * @nosideeffects
+ */
+$.now = function() {};
+
+/**
+ * @param {(string|Object.<string,*>)=} arg1
+ * @param {(string|function(!jQuery.event=))=} selector
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.off = function(arg1, selector, handler) {};
+
+/**
+ * @param {({left:number,top:number}|
+ *     function(number,{top:number,left:number}))=} arg1
+ * @return {({left:number,top:number}|!jQuery)}
+ */
+jQuery.prototype.offset = function(arg1) {};
+
+/**
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.offsetParent = function() {};
+
+/**
+ * @param {(string|Object.<string,*>)} arg1
+ * @param {*=} selector
+ * @param {*=} data
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.on = function(arg1, selector, data, handler) {};
+
+/**
+ * @param {(string|Object.<string,*>)} arg1
+ * @param {*=} arg2
+ * @param {*=} arg3
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.one = function(arg1, arg2, arg3, handler) {};
+
+/**
+ * @param {boolean=} includeMargin
+ * @return {number}
+ * @nosideeffects
+ */
+jQuery.prototype.outerHeight = function(includeMargin) {};
+
+/**
+ * @param {boolean=} includeMargin
+ * @return {number}
+ * @nosideeffects
+ */
+jQuery.prototype.outerWidth = function(includeMargin) {};
+
+/**
+ * @param {(Object.<string, *>|Array.<Object.<string, *>>)} obj
+ * @param {boolean=} traditional
+ * @return {string}
+ */
+jQuery.param = function(obj, traditional) {};
+
+/**
+ * @param {(Object.<string, *>|Array.<Object.<string, *>>)} obj
+ * @param {boolean=} traditional
+ * @return {string}
+ */
+$.param = function(obj, traditional) {};
+
+/**
+ * @param {jQuerySelector=} selector
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.parent = function(selector) {};
+
+/**
+ * @param {jQuerySelector=} selector
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.parents = function(selector) {};
+
+/**
+ * @param {(jQuerySelector|Element)=} arg1
+ * @param {jQuerySelector=} filter
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.parentsUntil = function(arg1, filter) {};
+
+/**
+ * @param {string} data
+ * @param {(Element|boolean)=} context
+ * @param {boolean=} keepScripts
+ * @return {Array.<Element>}
+ */
+jQuery.parseHTML = function(data, context, keepScripts) {};
+
+/**
+ * @param {string} data
+ * @param {(Element|boolean)=} context
+ * @param {boolean=} keepScripts
+ * @return {Array.<Element>}
+ */
+$.parseHTML = function(data, context, keepScripts) {};
+
+/**
+ * @param {string} json
+ * @return {string|number|Object.<string, *>|Array.<?>|boolean}
+ */
+jQuery.parseJSON = function(json) {};
+
+/**
+ * @param {string} json
+ * @return {Object.<string, *>}
+ */
+$.parseJSON = function(json) {};
+
+/**
+ * @param {string} data
+ * @return {Document}
+ */
+jQuery.parseXML = function(data) {};
+
+/**
+ * @param {string} data
+ * @return {Document}
+ */
+$.parseXML = function(data) {};
+
+/**
+ * @return {{left:number,top:number}}
+ * @nosideeffects
+ */
+jQuery.prototype.position = function() {};
+
+/**
+ * @param {string} url
+ * @param {(Object.<string,*>|string|
+ *     function(string,string,jQuery.jqXHR))=} data
+ * @param {(function(string,string,jQuery.jqXHR)|string|null)=} success
+ * @param {string=} dataType
+ * @return {jQuery.jqXHR}
+ */
+jQuery.post = function(url, data, success, dataType) {};
+
+/**
+ * @param {string} url
+ * @param {(Object.<string,*>|string|
+ *     function(string,string,jQuery.jqXHR))=} data
+ * @param {(function(string,string,jQuery.jqXHR)|string|null)=} success
+ * @param {string=} dataType
+ * @return {jQuery.jqXHR}
+ */
+$.post = function(url, data, success, dataType) {};
+
+/**
+ * @param {(string|Element|jQuery|function(number,string))} arg1
+ * @param {(string|Element|jQuery)=} content
+ * @return {!jQuery}
+ */
+jQuery.prototype.prepend = function(arg1, content) {};
+
+/**
+ * @param {(jQuerySelector|Element|jQuery)} target
+ * @return {!jQuery}
+ */
+jQuery.prototype.prependTo = function(target) {};
+
+/**
+ * @param {jQuerySelector=} selector
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.prev = function(selector) {};
+
+/**
+ * @param {jQuerySelector=} selector
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.prevAll = function(selector) {};
+
+/**
+ * @param {(jQuerySelector|Element)=} arg1
+ * @param {jQuerySelector=} filter
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.prevUntil = function(arg1, filter) {};
+
+/**
+ * @param {(string|Object)=} type
+ * @param {Object=} target
+ * @return {jQuery.Promise}
+ */
+jQuery.prototype.promise = function(type, target) {};
+
+/**
+ * @interface
+ * @private
+ * @see http://api.jquery.com/Types/#Promise
+ */
+jQuery.Promise = function () {};
+
+/**
+ * @param {jQueryCallback} alwaysCallbacks
+ * @param {jQueryCallback=} alwaysCallbacks2
+ * @return {jQuery.Promise}
+ */
+jQuery.Promise.prototype.always =
+    function(alwaysCallbacks, alwaysCallbacks2) {};
+
+/**
+ * @param {jQueryCallback} doneCallbacks
+ * @return {jQuery.Promise}
+ */
+jQuery.Promise.prototype.done = function(doneCallbacks) {};
+
+/**
+ * @param {jQueryCallback} failCallbacks
+ * @return {jQuery.Promise}
+ */
+jQuery.Promise.prototype.fail = function(failCallbacks) {};
+
+/**
+ * @param {function()=} doneFilter
+ * @param {function()=} failFilter
+ * @param {function()=} progressFilter
+ * @return {jQuery.Promise}
+ */
+jQuery.Promise.prototype.pipe =
+    function(doneFilter, failFilter, progressFilter) {};
+
+/**
+ * @param {jQueryCallback} doneCallbacks
+ * @param {jQueryCallback=} failCallbacks
+ * @param {jQueryCallback=} progressCallbacks
+ * @return {jQuery.Promise}
+ */
+jQuery.Promise.prototype.then =
+    function(doneCallbacks, failCallbacks, progressCallbacks) {};
+
+/**
+ * @param {(string|Object.<string,*>)} arg1
+ * @param {(string|number|boolean|function(number,String))=} arg2
+ * @return {(string|boolean|!jQuery)}
+ */
+jQuery.prototype.prop = function(arg1, arg2) {};
+
+/**
+ * @param {...*} var_args
+ * @return {function()}
+ */
+jQuery.proxy = function(var_args) {};
+
+/**
+ * @param {...*} var_args
+ * @return {function()}
+ */
+$.proxy = function(var_args) {};
+
+/**
+ * @param {Array.<Element>} elements
+ * @param {string=} name
+ * @param {Array.<*>=} args
+ * @return {!jQuery}
+ */
+jQuery.prototype.pushStack = function(elements, name, args) {};
+
+/**
+ * @param {(string|Array.<function()>|function(function()))=} queueName
+ * @param {(Array.<function()>|function(function()))=} arg2
+ * @return {(Array.<Element>|!jQuery)}
+ */
+jQuery.prototype.queue = function(queueName, arg2) {};
+
+/**
+ * @param {Element} elem
+ * @param {string=} queueName
+ * @param {(Array.<function()>|function())=} arg3
+ * @return {(Array.<Element>|!jQuery)}
+ */
+jQuery.queue = function(elem, queueName, arg3) {};
+
+/**
+ * @param {Element} elem
+ * @param {string=} queueName
+ * @param {(Array.<function()>|function())=} arg3
+ * @return {(Array.<Element>|!jQuery)}
+ */
+$.queue = function(elem, queueName, arg3) {};
+
+/**
+ * @param {function()} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.ready = function(handler) {};
+
+/**
+ * @param {string=} selector
+ * @return {!jQuery}
+ */
+jQuery.prototype.remove = function(selector) {};
+
+/**
+ * @param {string} attributeName
+ * @return {!jQuery}
+ */
+jQuery.prototype.removeAttr = function(attributeName) {};
+
+/**
+ * @param {(string|function(number,string))=} arg1
+ * @return {!jQuery}
+ */
+jQuery.prototype.removeClass = function(arg1) {};
+
+/**
+ * @param {(string|Array.<string>)=} arg1
+ * @return {!jQuery}
+ */
+jQuery.prototype.removeData = function(arg1) {};
+
+/**
+ * @param {Element} elem
+ * @param {string=} name
+ * @return {!jQuery}
+ */
+jQuery.removeData = function(elem, name) {};
+
+/**
+ * @param {Element} elem
+ * @param {string=} name
+ * @return {!jQuery}
+ */
+$.removeData = function(elem, name) {};
+
+/**
+ * @param {string} propertyName
+ * @return {!jQuery}
+ */
+jQuery.prototype.removeProp = function(propertyName) {};
+
+/**
+ * @param {jQuerySelector} target
+ * @return {!jQuery}
+ */
+jQuery.prototype.replaceAll = function(target) {};
+
+/**
+ * @param {(string|Element|jQuery|function())} arg1
+ * @return {!jQuery}
+ */
+jQuery.prototype.replaceWith = function(arg1) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.resize = function(arg1, handler) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.scroll = function(arg1, handler) {};
+
+/**
+ * @param {number=} value
+ * @return {(number|!jQuery)}
+ */
+jQuery.prototype.scrollLeft = function(value) {};
+
+/**
+ * @param {number=} value
+ * @return {(number|!jQuery)}
+ */
+jQuery.prototype.scrollTop = function(value) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.select = function(arg1, handler) {};
+
+/**
+ * @return {string}
+ * @nosideeffects
+ */
+jQuery.prototype.serialize = function() {};
+
+/**
+ * @return {Array.<Object.<string, *>>}
+ * @nosideeffects
+ */
+jQuery.prototype.serializeArray = function() {};
+
+/**
+ * @param {(string|number|function())=} duration
+ * @param {(function()|string)=} arg2
+ * @param {function()=} callback
+ * @return {!jQuery}
+ */
+jQuery.prototype.show = function(duration, arg2, callback) {};
+
+/**
+ * @param {jQuerySelector=} selector
+ * @return {!jQuery}
+ * @nosideeffects
+ */
+jQuery.prototype.siblings = function(selector) {};
+
+/**
+ * @deprecated Please use the .length property instead.
+ * @return {number}
+ * @nosideeffects
+ */
+jQuery.prototype.size = function() {};
+
+/**
+ * @param {number} start
+ * @param {number=} end
+ * @return {!jQuery}
+ */
+jQuery.prototype.slice = function(start, end) {};
+
+/**
+ * @param {(Object.<string,*>|string|number)=} optionsOrDuration
+ * @param {(function()|string)=} completeOrEasing
+ * @param {function()=} complete
+ * @return {!jQuery}
+ */
+jQuery.prototype.slideDown =
+    function(optionsOrDuration, completeOrEasing, complete) {};
+
+/**
+ * @param {(Object.<string,*>|string|number)=} optionsOrDuration
+ * @param {(function()|string)=} completeOrEasing
+ * @param {function()=} complete
+ * @return {!jQuery}
+ */
+jQuery.prototype.slideToggle =
+    function(optionsOrDuration, completeOrEasing, complete) {};
+
+/**
+ * @param {(Object.<string,*>|string|number)=} optionsOrDuration
+ * @param {(function()|string)=} completeOrEasing
+ * @param {function()=} complete
+ * @return {!jQuery}
+ */
+jQuery.prototype.slideUp =
+    function(optionsOrDuration, completeOrEasing, complete) {};
+
+/**
+ * @param {(boolean|string)=} arg1
+ * @param {boolean=} arg2
+ * @param {boolean=} jumpToEnd
+ * @return {!jQuery}
+ */
+jQuery.prototype.stop = function(arg1, arg2, jumpToEnd) {};
+
+/**
+ * @param {(function(!jQuery.event=)|Object.<string, *>)=} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.submit = function(arg1, handler) {};
+
+/** @type {Object.<string, *>}
+ * @deprecated Please try to use feature detection instead.
+ */
+jQuery.support;
+
+/** @type {Object.<string, *>}
+ * @deprecated Please try to use feature detection instead.
+ */
+$.support;
+
+/**
+ * @deprecated Please try to use feature detection instead.
+ * @type {boolean}
+ */
+jQuery.support.boxModel;
+
+/**
+ * @deprecated Please try to use feature detection instead.
+ * @type {boolean}
+ */
+$.support.boxModel;
+
+/** @type {boolean} */
+jQuery.support.changeBubbles;
+
+/** @type {boolean} */
+$.support.changeBubbles;
+
+/** @type {boolean} */
+jQuery.support.cors;
+
+/** @type {boolean} */
+$.support.cors;
+
+/** @type {boolean} */
+jQuery.support.cssFloat;
+
+/** @type {boolean} */
+$.support.cssFloat;
+
+/** @type {boolean} */
+jQuery.support.hrefNormalized;
+
+/** @type {boolean} */
+$.support.hrefNormalized;
+
+/** @type {boolean} */
+jQuery.support.htmlSerialize;
+
+/** @type {boolean} */
+$.support.htmlSerialize;
+
+/** @type {boolean} */
+jQuery.support.leadingWhitespace;
+
+/** @type {boolean} */
+$.support.leadingWhitespace;
+
+/** @type {boolean} */
+jQuery.support.noCloneEvent;
+
+/** @type {boolean} */
+$.support.noCloneEvent;
+
+/** @type {boolean} */
+jQuery.support.opacity;
+
+/** @type {boolean} */
+$.support.opacity;
+
+/** @type {boolean} */
+jQuery.support.style;
+
+/** @type {boolean} */
+$.support.style;
+
+/** @type {boolean} */
+jQuery.support.submitBubbles;
+
+/** @type {boolean} */
+$.support.submitBubbles;
+
+/** @type {boolean} */
+jQuery.support.tbody;
+
+/** @type {boolean} */
+$.support.tbody;
+
+/**
+ * @param {(string|number|boolean|function(number,string))=} arg1
+ * @return {(string|!jQuery)}
+ */
+jQuery.prototype.text = function(arg1) {};
+
+/**
+ * @return {Array.<Element>}
+ * @nosideeffects
+ */
+jQuery.prototype.toArray = function() {};
+
+/**
+ * Refers to the method from the Effects category. There used to be a toggle
+ * method on the Events category which was removed starting version 1.9.
+ * @param {(number|string|Object.<string,*>|boolean)=} arg1
+ * @param {(function()|string)=} arg2
+ * @param {function()=} arg3
+ * @return {!jQuery}
+ */
+jQuery.prototype.toggle = function(arg1, arg2, arg3) {};
+
+/**
+ * @param {(string|boolean|function(number,string,boolean))=} arg1
+ * @param {boolean=} flag
+ * @return {!jQuery}
+ */
+jQuery.prototype.toggleClass = function(arg1, flag) {};
+
+/**
+ * @param {(string|jQuery.event)} arg1
+ * @param {...*} var_args
+ * @return {!jQuery}
+ */
+jQuery.prototype.trigger = function(arg1, var_args) {};
+
+/**
+ * @param {string|jQuery.event} eventType
+ * @param {Array.<*>=} extraParameters
+ * @return {*}
+ */
+jQuery.prototype.triggerHandler = function(eventType, extraParameters) {};
+
+/**
+ * @param {string} str
+ * @return {string}
+ * @nosideeffects
+ */
+jQuery.trim = function(str) {};
+
+/**
+ * @param {string} str
+ * @return {string}
+ * @nosideeffects
+ */
+$.trim = function(str) {};
+
+/**
+ * @param {*} obj
+ * @return {string}
+ * @nosideeffects
+ */
+jQuery.type = function(obj) {};
+
+/**
+ * @param {*} obj
+ * @return {string}
+ * @nosideeffects
+ */
+$.type = function(obj) {};
+
+/**
+ * @param {(string|function(!jQuery.event=)|jQuery.event)=} arg1
+ * @param {(function(!jQuery.event=)|boolean)=} arg2
+ * @return {!jQuery}
+ */
+jQuery.prototype.unbind = function(arg1, arg2) {};
+
+/**
+ * @param {string=} arg1
+ * @param {(string|Object.<string,*>)=} arg2
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.undelegate = function(arg1, arg2, handler) {};
+
+/**
+ * @param {Array.<Element>} arr
+ * @return {Array.<Element>}
+ */
+jQuery.unique = function(arr) {};
+
+/**
+ * @param {Array.<Element>} arr
+ * @return {Array.<Element>}
+ */
+$.unique = function(arr) {};
+
+/**
+ * @deprecated Please use .on( "unload", handler ) instead.
+ * @param {(function(!jQuery.event=)|Object.<string, *>)} arg1
+ * @param {function(!jQuery.event=)=} handler
+ * @return {!jQuery}
+ */
+jQuery.prototype.unload = function(arg1, handler) {};
+
+/** @return {!jQuery} */
+jQuery.prototype.unwrap = function() {};
+
+/**
+ * @param {(string|Array.<string>|function(number,*))=} arg1
+ * @return {(string|number|Array.<string>|!jQuery)}
+ */
+jQuery.prototype.val = function(arg1) {};
+
+/**
+ * Note: The official documentation (https://api.jquery.com/jQuery.when/) says
+ * jQuery.when accepts deferreds, but it actually accepts any type, e.g.:
+ *
+ * jQuery.when(jQuery.ready, jQuery.ajax(''), jQuery('#my-element'), 1)
+ *
+ * If an argument is not an "observable" (a promise-like object) it is wrapped
+ * into a promise.
+ * @param {*} deferred
+ * @param {...*} deferreds
+ * @return {jQuery.Promise}
+ */
+jQuery.when = function(deferred, deferreds) {};
+
+/**
+ * Note: See jQuery.when().
+ * @param {*} deferred
+ * @param {...*} deferreds
+ * @return {jQuery.Promise}
+ */
+$.when = function(deferred, deferreds) {};
+
+/**
+ * @param {(string|number|function(number,number))=} arg1
+ * @return {(number|!jQuery)}
+ */
+jQuery.prototype.width = function(arg1) {};
+
+/**
+ * @param {(string|jQuerySelector|Element|jQuery|function(number))} arg1
+ * @return {!jQuery}
+ */
+jQuery.prototype.wrap = function(arg1) {};
+
+/**
+ * @param {(string|jQuerySelector|Element|jQuery)} wrappingElement
+ * @return {!jQuery}
+ */
+jQuery.prototype.wrapAll = function(wrappingElement) {};
+
+/**
+ * @param {(string|jQuerySelector|Element|jQuery|function(number))} arg1
+ * @return {!jQuery}
+ */
+jQuery.prototype.wrapInner = function(arg1) {};
+
+/**
+ * @param {(string|number|function(number,number))=} arg1
+ * @return {(number|!jQuery)}
+ */
+jQuery.prototype.tooltip = function(arg1) {};
\ No newline at end of file
diff --git a/src/closure/conf/externs/jspdf.js b/src/closure/conf/externs/jspdf.js
new file mode 100755
index 0000000000000000000000000000000000000000..2b5ba6f00f45b775de5e4d9bd0666149dadbc650
--- /dev/null
+++ b/src/closure/conf/externs/jspdf.js
@@ -0,0 +1,51 @@
+/**
+ * 
+ * @param {type} arg1
+ * @returns {jsPDF}
+ */
+function jsPDF (arg1) {};
+
+/**
+ * 
+ * @param {type} arg1
+ * @param {type} arg2
+ * @param {type} arg3
+ * @param {type} arg4
+ * @returns {undefined}
+ */
+jsPDF.prototype.fromHTML = function (arg1, arg2, arg3, arg4) {};
+
+/**
+ * 
+ * @param {type} arg1
+ * @param {type} arg2
+ * @param {type} arg3
+ * @param {type} arg4
+ * @param {type} arg5
+ * @param {type} arg6
+ * @returns {undefined}
+ */
+jsPDF.prototype.addImage = function (arg1, arg2, arg3, arg4, arg5, arg6) {};
+
+/**
+ * 
+ * @param {type} arg1
+ * @returns {undefined}
+ */
+jsPDF.prototype.save = function (arg1) {};
+
+/**
+ * 
+ * @param {type} arg1
+ * @returns {undefined}
+ */
+jsPDF.prototype.setPage = function (arg1) {};
+
+/**
+ * 
+ * @param {type} arg1
+ * @param {type} arg2
+ * @returns {undefined}
+ */
+jsPDF.prototype.addHTML = function (arg1, arg2) {};
+
diff --git a/src/closure/conf/externs/vmap.js b/src/closure/conf/externs/vmap.js
new file mode 100755
index 0000000000000000000000000000000000000000..b799165a0202a74c3d1fe51fe8ad666558122205
--- /dev/null
+++ b/src/closure/conf/externs/vmap.js
@@ -0,0 +1,75 @@
+/**
+ * @author: Armand Bahi
+ * @Description: Fichier contenant les externs: fonctions à ne pas renommer durant la compilation
+ * @externs
+ */
+
+/**
+ * Function for initialise the bootstrap toggle switch checkbox plugin
+ * @constructor
+ * @param {object} arg1
+ */
+function bootstrapToggle(arg1) {}
+
+/**
+ * Function for initialise the bootstrap colorpicker plugin
+ * @constructor
+ * @param {object} arg1
+ */
+function colorpicker(arg1) {}
+
+/**
+ * Function for initialise the bootstrap table plugin
+ * @constructor
+ * @param {object} arg1
+ */
+function bootstrapTable(arg1) {}
+
+/**
+ * @param {object} arg1
+ * @return {!jQuery}
+ */
+function sortable(arg1) {}
+
+/**
+ * 
+ * @param {string} key
+ * @returns {undefined}
+ */
+ol.Object.prototype.get = function (key) {}
+
+/**
+ * Get the collection of layers associated with this map.
+ * @return {!ol.Collection.<ol.layer.Base>} Layers.
+ * @api stable
+ */
+ol.Map.prototype.getLayers = function () {}
+
+/**
+ * Return the visibility of the layer (`true` or `false`).
+ * @return {boolean} The visibility of the layer.
+ * @observable
+ * @api stable
+ */
+ol.layer.Base.prototype.getVisible = function () {}
+
+/**
+ * Set the visibility of the layer (`true` or `false`).
+ * @param {boolean} visible The visibility of the layer.
+ * @observable
+ * @api stable
+ */
+ol.layer.Base.prototype.setVisible = function (visible) {}
+
+/**
+ * The tile related to the event.
+ * @type {ol.Tile}
+ * @api
+ */
+ol.source.TileEvent.tile
+
+/**
+ * @type {string}
+ * @see http://www.w3.org/TR/pointerevents/#the-touch-action-css-property
+ */
+CSSProperties.prototype.touchAction;
\ No newline at end of file