Showing preview only (1,347K chars total). Download the full file or copy to clipboard to get everything.
Repository: sinacloud/sae-python-dev-guide
Branch: master
Commit: d60f361535ea
Files: 158
Total size: 1.2 MB
Directory structure:
gitextract_f045oq39/
├── .gitignore
├── README
├── dev_server/
│ ├── README
│ ├── bundle_local.py
│ ├── cloudsql.py
│ ├── dev_server.py
│ ├── sae/
│ │ ├── __init__.py
│ │ ├── _restful_mysql/
│ │ │ ├── __init__.py
│ │ │ ├── _mysql.py
│ │ │ ├── _mysql_exceptions.py
│ │ │ ├── connections.py
│ │ │ ├── constants/
│ │ │ │ ├── CLIENT.py
│ │ │ │ ├── CR.py
│ │ │ │ ├── ER.py
│ │ │ │ ├── FIELD_TYPE.py
│ │ │ │ ├── FLAG.py
│ │ │ │ ├── REFRESH.py
│ │ │ │ └── __init__.py
│ │ │ ├── converters.py
│ │ │ ├── cursors.py
│ │ │ ├── monkey.py
│ │ │ ├── release.py
│ │ │ └── times.py
│ │ ├── channel.js
│ │ ├── channel.py
│ │ ├── channel.src.js
│ │ ├── conf.py
│ │ ├── const.py
│ │ ├── core.py
│ │ ├── ext/
│ │ │ ├── __init__.py
│ │ │ ├── django/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── mail/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── backend.py
│ │ │ │ └── storage/
│ │ │ │ ├── __init__.py
│ │ │ │ └── backend.py
│ │ │ ├── shell.py
│ │ │ └── storage/
│ │ │ ├── __init__.py
│ │ │ └── monkey.py
│ │ ├── kvdb.py
│ │ ├── mail.py
│ │ ├── memcache.py
│ │ ├── sae_signature.py
│ │ ├── storage.py
│ │ ├── taskqueue.py
│ │ └── util.py
│ ├── saecloud
│ └── setup.py
├── docs/
│ ├── Makefile
│ ├── conf.py
│ ├── exts/
│ │ └── chinese_search.py
│ ├── faq.rst
│ ├── index.rst
│ ├── quickstart.rst
│ ├── runtime.rst
│ ├── service.rst
│ ├── static/
│ │ └── memcache.html
│ ├── theme/
│ │ └── nature/
│ │ ├── layout.html
│ │ ├── static/
│ │ │ ├── nature.css_t
│ │ │ └── sae.js
│ │ └── theme.conf
│ └── tools.rst
└── examples/
├── apibus/
│ └── apibus_handler.py
├── bottle/
│ ├── README
│ └── index.wsgi
├── django/
│ ├── 1.2.7/
│ │ ├── README
│ │ ├── config.yaml
│ │ ├── index.wsgi
│ │ ├── mysite/
│ │ │ ├── __init__.py
│ │ │ ├── demo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── tests.py
│ │ │ │ └── views.py
│ │ │ ├── manage.py
│ │ │ ├── settings.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ └── static/
│ │ ├── css/
│ │ │ ├── base.css
│ │ │ ├── changelists.css
│ │ │ ├── dashboard.css
│ │ │ ├── forms.css
│ │ │ ├── ie.css
│ │ │ ├── login.css
│ │ │ ├── rtl.css
│ │ │ └── widgets.css
│ │ └── js/
│ │ ├── SelectBox.js
│ │ ├── SelectFilter2.js
│ │ ├── actions.js
│ │ ├── admin/
│ │ │ ├── DateTimeShortcuts.js
│ │ │ ├── RelatedObjectLookups.js
│ │ │ └── ordering.js
│ │ ├── calendar.js
│ │ ├── collapse.js
│ │ ├── compress.py
│ │ ├── core.js
│ │ ├── dateparse.js
│ │ ├── getElementsBySelector.js
│ │ ├── inlines.js
│ │ ├── jquery.init.js
│ │ ├── jquery.js
│ │ ├── prepopulate.js
│ │ ├── timeparse.js
│ │ └── urlify.js
│ └── 1.4/
│ ├── README
│ ├── config.yaml
│ ├── db.sql
│ ├── index.wsgi
│ ├── manage.py
│ ├── mysite/
│ │ ├── __init__.py
│ │ ├── settings.py
│ │ ├── templates/
│ │ │ ├── 404.html
│ │ │ └── 500.html
│ │ ├── urls.py
│ │ └── wsgi.py
│ └── polls/
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── templates/
│ │ ├── detail.html
│ │ ├── index.html
│ │ └── results.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── flask/
│ ├── README
│ ├── app.py
│ ├── index.wsgi
│ └── myapp.py
├── helloworld/
│ └── 1/
│ └── index.wsgi
├── matplotshell/
│ ├── README
│ ├── config.yaml
│ └── index.wsgi
├── renren/
│ ├── config.yaml
│ ├── db.sql
│ ├── error.html
│ ├── index.wsgi
│ ├── oauth.html
│ └── renrenoauth.py
├── segment/
│ ├── config.yaml
│ └── index.wsgi
├── static-site/
│ ├── README
│ ├── config.yaml
│ └── www/
│ └── index.html
├── tornado/
│ ├── async/
│ │ ├── config.yaml
│ │ └── index.wsgi
│ └── wsgi/
│ ├── README
│ └── index.wsgi
├── trac/
│ ├── README.md
│ ├── config.yaml
│ ├── index.wsgi
│ ├── project/
│ │ ├── README
│ │ ├── VERSION
│ │ ├── conf/
│ │ │ ├── trac.ini
│ │ │ └── trac.ini.sample
│ │ └── templates/
│ │ └── site.html.sample
│ └── setup.sql
├── webpy/
│ ├── index.wsgi
│ └── templates/
│ └── hello.html
└── weibo/
├── appstack.py
└── index.wsgi
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
build/*
docs/_build/*
dev_server/build/*
dev_server/sae_python_dev.egg-info/*
*~
*.DS_Store
*.default
*.types
*.pyc
*.egg
*.pdf
*.bak
*.doc
*.ppt
*.xls
*.mht
*.mp3
*.mp4
*.wma
*.rar
*.zip
*.7z
*.xz
*.map
*.log
*.txt
*.swp
*.gz
*.ko
*.so
.tmp*
.svn
.cvs
================================================
FILE: README
================================================
Copyright © 2011 新浪网研发中心. All rights reserved.
SAE Python Team
================================================
FILE: dev_server/README
================================================
SAE Python development server - experimental
All Rights Reserved 2011
SAE Python Team
目前支持的服务包括:mysql, taskqueue, memcache, storage, mail。
大部分的服务直接运行dev_server.py进行调试就可以了,部分服务需要做一些配置。
注意: 本工具仅为应用开发便利之用,对sae python环境的模拟并不完整。
Install
--------------
sudo python setup.py install
基本使用
------------
使用svn检出app代码之后,建立以数字为标识的发布目录,切换到发布目录:
$ pwd
/home/jaime/source/blackfire/1
编辑index.wsgi和config.yaml:
$ vi index.wsgi
import sae
def app(environ, start_response):
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
start_response(status, response_headers)
return ['Hello, world! reloading test3']
application = sae.create_wsgi_app(app)
$ vi config.yaml
---
name: blackfire
version: 1
...
运行dev_server.py:
$ dev_server.py
MySQL config not found: app.py
Start development server on http://localhost:8080/
访问 http://localhost:8080 端口就可以看到Hello, world!了。
使用MySQL服务
----------------
配置好MySQL本地开发server,使用 `--mysql` 参数运行dev_server.py。
$ dev_server.py --mysql=user:password@host:port
现在你可以在应用代码中像在SAE线上环境一样使用MySQL服务了。dev_server.py默认使用
名为 `app_应用名` 的数据库。
使用storage服务
---------------
使用 `--storage-path` 参数运行dev_server.py。
$ dev_server.py --storage-path=/path/to/local/storage/data
本地的storage服务使用以下的目录结构来模拟线上的storage。
storage-path/
domain1/
key1
key2
domain2/
domain3/
--storage-path配置的路径下每个子文件夹会映射为storage中的一个domain,而每个子文
件夹下的文件映射为domain下的一个key,其内容为对应key的数据。
.. note:
为方便调试,dev_server自带的sae.storage在某个domain不存在的情况下会自动创建
该domain。线上环境中的domain需要在sae后台面板中手动创建。
使用pylibmc
--------------
dev_server自带了一个dummy pylibmc,所以无须安装pylibmc就可以直接使用memcache服务
了。该模块将所有的数据存贮在内存中,dev_server.py进程结束时,所有的数据都会丢失
。
使用kvdb
----------------
kvdb默认数据存在内存中,dev_server.py进程结束时,数据会全部丢失,如果需要保存数据,
请使用如下命令行启动dev_server.py
$ dev_server.py --kvdb-file=/path/to/kvdb/local/file
================================================
FILE: dev_server/bundle_local.py
================================================
#!/usr/bin/env python
"""Create a local bundle for your virtualenv environment
Export all the packages listed in requirements.txt to ./virtualenv.bundle
directory
Then you can create a .zip file before uploading them to sae
Usage: bundle_local -r requirements.txt
"""
from optparse import OptionParser
import os
import sys
import pip.util
import shutil
TMP = 'virtualenv.bundle'
ZIP_FILE = TMP + '.zip'
def main():
parser = OptionParser()
parser.add_option("-r", dest="requirements",
help="The requirements.txt file outputed by pip freeze")
(options, args) = parser.parse_args()
if not options.requirements:
print 'requirements.txt not found'
sys.exit(-1)
if os.path.exists(TMP):
shutil.rmtree(TMP)
os.mkdir(TMP)
shutil.copy2(options.requirements, os.path.join(TMP, 'requirements.txt'))
# Get all installed packages on system
installed_dists = {}
for dist in pip.util.get_installed_distributions():
installed_dists[dist.project_name] = dist
# Get the dists in requirements.txt
dists = []
for line in open(options.requirements, 'r').readlines():
if line.strip() or line.startswith('#'):
pass
pkg = line.split('==')[0]
if pkg not in installed_dists:
raise Exception('%s not installed' % pkg)
dists.append(installed_dists[pkg])
top_levels = []
for dist in dists:
mods = [(dist.location, mod) for mod in dist.get_metadata('top_level.txt').splitlines()]
top_levels += mods
top_levels = list(set(top_levels))
copy_modules(top_levels, TMP)
def copy_modules(mod_paths, dest):
for loc, mod in mod_paths:
if os.path.isdir(loc):
src = os.path.join(loc, mod)
if os.path.isdir(src):
shutil.copytree(src, os.path.join(dest, mod), ignore=shutil.ignore_patterns('*.pyc'))
else:
# Single file module
shutil.copy2(src + '.py', dest)
else:
# Egg file ?
import zipfile
zf = zipfile.ZipFile(loc)
members = filter(lambda f: f.startswith(mod), zf.namelist())
for m in members:
zf.extract(m, dest)
zf.close()
if __name__ == '__main__':
main()
================================================
FILE: dev_server/cloudsql.py
================================================
#!/usr/bin/env python
# Copyright (C) 2012-2013 SINA, All rights reserved.
"""Command line client for SAE MySQL Service. """
import sys
import os
import logging
import optparse
import sae._restful_mysql
import sae._restful_mysql._mysql_exceptions
sys.modules['_mysql_exceptions'] = sae._restful_mysql._mysql_exceptions
from grizzled import db
from grizzled.db import mysql
import prettytable
import sqlcmd
from sqlcmd import config
logging.basicConfig(level=logging.WARNING)
sqlcmd.log = logging.getLogger('cloudsql')
sqlcmd.DEFAULT_CONFIG_DIR = os.path.expanduser('~/.saecloud')
sqlcmd.RC_FILE = os.path.join(sqlcmd.DEFAULT_CONFIG_DIR, 'cloudsql.config')
sqlcmd.HISTORY_FILE_FORMAT = os.path.join(sqlcmd.DEFAULT_CONFIG_DIR, '%s.hist')
sqlcmd.INTRO = 'SAE MySQL Client\n\nType "help" or "?" for help.\n'
DEFAULT_ENCODING = 'utf-8'
USAGE = '%prog [options] database_name'
DEFAULT_SAE_MYSQL_HOST = 'w.rdc.sae.sina.com.cn'
DEFAULT_SAE_MYSQL_PORT = 3307
DEFAULT_SAE_MYSQL_DB_PREFIX = 'app_'
class CloudSqlDriver(mysql.MySQLDriver):
"""Grizzled DB Driver for Cloud SAE MySQL Service."""
NAME = 'cloudsql'
def get_import(self):
return sae._restful_mysql
def get_display_name(self):
return 'Cloud SQL'
def do_connect(self, host, port, user, password, database):
# Fix grizzled's mysql driver which omit the port argument when connecting.
dbi = self.get_import()
port = port and int(port) or 3306
return dbi.connect(host=host, user=user, passwd=password, db=database, port=port)
class CloudSqlCmd(sqlcmd.SQLCmd):
"""The SQLCmd command interpreter for Cloud SQL."""
sqlcmd.SQLCmd.MAIN_PROMPT = 'mysql> '
sqlcmd.SQLCmd.CONTINUATION_PROMPT = ' -> '
sqlcmd.SQLCmd.NO_SEMI_NEEDED.update(
['about', 'desc', 'describe', 'echo', 'exit', 'h', 'hist',
'history', 'load', 'run', 'r', 'redo', 'set', 'show', 'var', 'vars'])
for method in ['do_dot_connect', 'do_dot_desc', 'do_begin']:
delattr(sqlcmd.SQLCmd, method)
for cmd in ['show', 'describe', 'echo', 'load', 'run', 'exit', 'h',
'hist', 'history', 'var', 'vars', 'about']:
method = 'do_dot_' + cmd
setattr(sqlcmd.SQLCmd, method.replace('dot_', ''), getattr(
sqlcmd.SQLCmd, method))
delattr(sqlcmd.SQLCmd, method)
method = 'complete_dot_' + cmd
if hasattr(sqlcmd.SQLCmd, method):
setattr(sqlcmd.SQLCmd, method.replace('dot_', ''), getattr(
sqlcmd.SQLCmd, method))
delattr(sqlcmd.SQLCmd, method)
def do_redo(self, args):
# XXX: Fix global name 'do_r' is not defined problem in sqlcmd
self.do_r(args)
def _SQLCmd__set_setting(self, varname, value):
# XXX: Fix bool object has no lower attribute in sqlcmd
return sqlcmd.SQLCmd._SQLCmd__set_setting(self, varname, str(value))
def do_desc(self, args):
self.do_describe(args, cmd='.desc')
complete_desc = sqlcmd.SQLCmd.complete_dot_desc
def do_load(self, args):
self.do_run(args)
def preloop(self, *args, **kwargs):
sqlcmd.SQLCmd.preloop(self, *args, **kwargs)
# Just exit if the connect failed
if self._SQLCmd__db is None: sys.exit(1)
def __init__(self, *args, **kwargs):
sqlcmd.SQLCmd.__init__(self, *args, **kwargs)
self.prompt = sqlcmd.SQLCmd.MAIN_PROMPT
self.output_encoding = DEFAULT_ENCODING
def set_output_encoding(self, encoding):
self.output_encoding = encoding
def _build_table(self, cursor):
"""Builds an output PrettyTable from the results in the given cursor."""
if not cursor.description:
return None
column_names = [column[0] for column in cursor.description]
table = prettytable.PrettyTable(column_names)
rows = cursor.fetchall()
if not rows:
return table
for i, col in enumerate(rows[0]):
table.align[column_names[i]] = isinstance(col, basestring) and 'l' or 'r'
for row in rows: table.add_row(row)
return table
def _SQLCmd__handle_select(self, args, cursor, command='select'):
"""Overrides SQLCmd.__handle_select to display output with prettytable."""
self._SQLCmd__exec_SQL(cursor, command, args)
table = self._build_table(cursor)
if table:
output = table.get_string()
if isinstance(output, unicode):
print output.encode(self.output_encoding)
else:
print output
def _create_config_dir():
"""Creates the sqlcmd config directory if necessary."""
directory = sqlcmd.DEFAULT_CONFIG_DIR
if not os.access(directory, os.R_OK | os.W_OK | os.X_OK):
old_umask = os.umask(077)
os.makedirs(sqlcmd.DEFAULT_CONFIG_DIR)
os.umask(old_umask)
def main(argv):
parser = optparse.OptionParser(usage=USAGE)
parser.add_option('-u', '--username', dest='username',
help='MySQL username to use when connecting to the server.')
parser.add_option('-p', '--password', dest='password',
help='MySQL password to use when connecting to the server.')
parser.add_option('-e', '--output_encoding', dest='output_encoding',
default=DEFAULT_ENCODING,
help='Output encoding. Defaults to %s.' % DEFAULT_ENCODING)
(options, args) = parser.parse_args(argv[1:])
if len(args) != 1:
parser.print_help(sys.stderr)
return 1
if not options.username or not options.password:
print >>sys.stderr, 'Error: username or password is missing.\n'
return 1
if args[0].startswith(DEFAULT_SAE_MYSQL_DB_PREFIX):
database_name = args[0]
else:
database_name = DEFAULT_SAE_MYSQL_DB_PREFIX + args[0]
instance_alias = database_name
_create_config_dir()
db.add_driver(CloudSqlDriver.NAME, CloudSqlDriver)
sql_cmd_config = config.SQLCmdConfig(None)
sql_cmd_config.add('__cloudsql__', instance_alias,
DEFAULT_SAE_MYSQL_HOST , DEFAULT_SAE_MYSQL_PORT, database_name,
CloudSqlDriver.NAME, options.username, options.password)
sql_cmd = CloudSqlCmd(sql_cmd_config)
sql_cmd.set_output_encoding(options.output_encoding)
sql_cmd.set_database(instance_alias)
sql_cmd.cmdloop()
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))
================================================
FILE: dev_server/dev_server.py
================================================
#!/usr/bin/env python
"""Simple development server
Make sure you're use python 2.7 for developing
"""
import sys
import os
import os.path
import re
import imp
import yaml
from optparse import OptionParser
from sae.util import search_file_bottom_up
from sae.channel import _channel_wrapper
def setup_sae_environ(conf):
# Add dummy pylibmc module
import sae.memcache
sys.modules['pylibmc'] = sae.memcache
# Save kvdb data in this file else the data will lost
# when the dev_server.py is down
if conf.kvdb:
print 'KVDB: ', conf.kvdb
os.environ['sae.kvdb.file'] = conf.kvdb
# Add app_root to sys.path
cwd = os.getcwd()
if cwd not in sys.path:
sys.path.insert(0, cwd)
try:
appname = str(conf.name)
appversion = str(conf.version)
except AttributeError:
raise AttributeError('`name` or `version` not found in `config.yaml`')
if conf.mysql:
import sae.const
p = re.compile('^(.+):(.+)@(.+):(\d+)$')
m = p.match(conf.mysql)
if not m:
raise Exception("Invalid mysql configuration")
user, password, host, port = m.groups()
dbname = 'app_' + appname
sae.const.MYSQL_DB = dbname
sae.const.MYSQL_USER = user
sae.const.MYSQL_PASS = password
sae.const.MYSQL_PORT = port
sae.const.MYSQL_HOST = host
sae.const.MYSQL_HOST_S = host
print 'MySQL: %s.%s' % (conf.mysql, dbname)
else:
print 'MySQL config not found'
if conf.storage:
os.environ['sae.storage.path'] = os.path.abspath(conf.storage)
# Add custom environment variable
os.environ['HTTP_HOST'] = '%s:%d' % (conf.host, conf.port)
os.environ['APP_NAME'] = appname
os.environ['APP_VERSION'] = appversion
class Worker:
def __init__(self, conf, app):
self.conf = conf
self.application = app
self.collect_statifiles()
def collect_statifiles(self):
self.static_files = {}
if hasattr(self.conf, 'handlers'):
for h in self.conf.handlers:
url = h['url']
if h.has_key('static_dir'):
self.static_files[url] = os.path.join(app_root, h['static_dir'])
elif h.has_key('static_path'):
self.static_files[url] = os.path.join(app_root, h['static_path'])
if not len(self.static_files):
self.static_files.update({
'/static': os.path.join(app_root, 'static'),
'/media': os.path.join(app_root, 'media'),
'/favicon.ico': os.path.join(app_root, 'favicon.ico'),
})
import sae
self.static_files['/_sae/channel/api.js'] = os.path.join(os.path.dirname(sae.__file__), 'channel.js')
if self.conf.storage:
# stor dispatch: for test usage only
self.static_files['/stor-stub/'] = os.path.abspath(self.conf.storage)
def run(self):
raise NotImplementedError()
class WsgiWorker(Worker):
def run(self):
# FIXME: All files under current directory
files = ['index.wsgi']
# XXX:
# when django template renders `environ` in its 500 page, it will
# try to call `environ['werkzeug.server.shutdown'` and cause the
# server exit unexpectedly.
# See: https://docs.djangoproject.com/en/dev/ref/templates/api/#variables-and-lookups
def wrap(app):
def _(environ, start_response):
try:
del environ['werkzeug.server.shutdown']
except KeyError:
pass
return app(environ, start_response)
return _
if 'WERKZEUG_RUN_MAIN' in os.environ:
os.environ['sae.run_main'] = '1'
self.application = _channel_wrapper(self.application)
from werkzeug.serving import run_simple
run_simple(self.conf.host, self.conf.port,
wrap(self.application),
use_reloader = True,
use_debugger = True,
extra_files = files,
static_files = self.static_files)
class TornadoWorker(Worker):
def run(self):
import tornado.autoreload
tornado.autoreload.watch('index.wsgi')
import re
from tornado.web import URLSpec, StaticFileHandler
# The user should not use `tornado.web.Application.add_handlers`
# since here in SAE one application only has a single host, so here
# we can just use the first host_handers.
handlers = self.application.handlers[0][1]
for prefix, path in self.static_files.iteritems():
pattern = re.escape(prefix) + r"(.*)"
handlers.insert(0, URLSpec(pattern, StaticFileHandler, {"path": path}))
os.environ['sae.run_main'] = '1'
import tornado.ioloop
from tornado.httpserver import HTTPServer
server = HTTPServer(self.application, xheaders=True)
server.listen(self.conf.port, self.conf.host)
tornado.ioloop.IOLoop.instance().start()
def main(options):
conf_path = os.path.join(app_root, 'config.yaml')
conf = yaml.load(open(conf_path, "r"))
options.__dict__.update(conf)
conf = options
# if env `WERKZEUG_RUN_MAIN` is not defined, then we are in
# the reloader process.
# if os.environ.get('WERKZEUG_RUN_MAIN', False):
setup_sae_environ(conf)
try:
index = imp.load_source('index', 'index.wsgi')
except IOError:
print >>sys.stderr, "Seems you don't have an index.wsgi"
return
if not hasattr(index, 'application'):
print >>sys.stderr, "application not found in index.wsgi"
return
if not callable(index.application):
print >>sys.stderr, "application is not a callable"
return
application = index.application
cls_name = getattr(conf, 'worker', 'wsgi').capitalize() + 'Worker'
try:
globals().get(cls_name, WsgiWorker)(conf, application).run()
except KeyboardInterrupt:
pass
if __name__ == '__main__':
parser = OptionParser()
parser.add_option("-p", "--port", type="int", dest="port", default="8080",
help="Which port to listen")
parser.add_option("--host", dest="host", default="localhost",
help="Which host to listen")
parser.add_option("--mysql", dest="mysql", help="Mysql configuration: user:password@host:port")
parser.add_option("--storage-path", dest="storage", help="Directory used as local stoarge")
parser.add_option("--kvdb-file", dest="kvdb", help="File to save kvdb data")
(options, args) = parser.parse_args()
app_root = search_file_bottom_up('config.yaml')
if app_root is None:
print >> sys.stderr, \
'Error: Not an app directory(or any of the parent directories)'
sys.exit(1)
if app_root != os.getcwd(): os.chdir(app_root)
main(options)
================================================
FILE: dev_server/sae/__init__.py
================================================
"""SAE Python
Jaime Chen<chenzheng2@staff.sina.com.cn> 2011
"""
import core
def create_wsgi_app(app):
return app
def dev_server(conf):
core.environ = conf
import sys, os.path
_PYTHON_VERSION = 'python%d.%d' % (sys.version_info[0], sys.version_info[1])
def add_vendor_dir(path, index=1):
"""Insert site dir or virtualenv at a given index in sys.path.
Args:
path: relative path to a site dir or virtualenv.
index: sys.path position to insert the site dir.
Raises:
ValueError: path doesn't exist.
"""
venv_path = os.path.join(path, 'lib', _PYTHON_VERSION, 'site-packages')
if os.path.isdir(venv_path):
site_dir = venv_path
elif os.path.isdir(path):
site_dir = path
else:
raise ValueError('virtualenv: cannot access %s: '
'No such virtualenv or site directory' % path)
sys_path = sys.path[:]
del sys.path[index:]
import site
site.addsitedir(site_dir)
sys.path.extend(sys_path[index:])
================================================
FILE: dev_server/sae/_restful_mysql/__init__.py
================================================
"""MySQLdb - A DB API v2.0 compatible interface to MySQL.
This package is a wrapper around _mysql, which mostly implements the
MySQL C API.
connect() -- connects to server
See the C API specification and the MySQL documentation for more info
on other items.
For information on how MySQLdb handles type conversion, see the
MySQLdb.converters module.
"""
__revision__ = """$Revision: 603 $"""[11:-2]
from release import __version__, version_info, __author__
import _mysql
if version_info != _mysql.version_info:
raise ImportError("this is MySQLdb version %s, but _mysql is version %r" %
(version_info, _mysql.version_info))
threadsafety = 1
apilevel = "2.0"
paramstyle = "format"
from _mysql import *
from constants import FIELD_TYPE
from times import Date, Time, Timestamp, \
DateFromTicks, TimeFromTicks, TimestampFromTicks
try:
frozenset
except NameError:
from sets import ImmutableSet as frozenset
class DBAPISet(frozenset):
"""A special type of set for which A == x is true if A is a
DBAPISet and x is a member of that set."""
def __eq__(self, other):
if isinstance(other, DBAPISet):
return not self.difference(other)
return other in self
STRING = DBAPISet([FIELD_TYPE.ENUM, FIELD_TYPE.STRING,
FIELD_TYPE.VAR_STRING])
BINARY = DBAPISet([FIELD_TYPE.BLOB, FIELD_TYPE.LONG_BLOB,
FIELD_TYPE.MEDIUM_BLOB, FIELD_TYPE.TINY_BLOB])
NUMBER = DBAPISet([FIELD_TYPE.DECIMAL, FIELD_TYPE.DOUBLE, FIELD_TYPE.FLOAT,
FIELD_TYPE.INT24, FIELD_TYPE.LONG, FIELD_TYPE.LONGLONG,
FIELD_TYPE.TINY, FIELD_TYPE.YEAR])
DATE = DBAPISet([FIELD_TYPE.DATE, FIELD_TYPE.NEWDATE])
TIME = DBAPISet([FIELD_TYPE.TIME])
TIMESTAMP = DBAPISet([FIELD_TYPE.TIMESTAMP, FIELD_TYPE.DATETIME])
DATETIME = TIMESTAMP
ROWID = DBAPISet()
def test_DBAPISet_set_equality():
assert STRING == STRING
def test_DBAPISet_set_inequality():
assert STRING != NUMBER
def test_DBAPISet_set_equality_membership():
assert FIELD_TYPE.VAR_STRING == STRING
def test_DBAPISet_set_inequality_membership():
assert FIELD_TYPE.DATE != STRING
def Binary(x):
return str(x)
def Connect(*args, **kwargs):
"""Factory function for connections.Connection."""
from connections import Connection
return Connection(*args, **kwargs)
connect = Connection = Connect
__all__ = [ 'BINARY', 'Binary', 'Connect', 'Connection', 'DATE',
'Date', 'Time', 'Timestamp', 'DateFromTicks', 'TimeFromTicks',
'TimestampFromTicks', 'DataError', 'DatabaseError', 'Error',
'FIELD_TYPE', 'IntegrityError', 'InterfaceError', 'InternalError',
'MySQLError', 'NULL', 'NUMBER', 'NotSupportedError', 'DBAPISet',
'OperationalError', 'ProgrammingError', 'ROWID', 'STRING', 'TIME',
'TIMESTAMP', 'Warning', 'apilevel', 'connect', 'connections',
'constants', 'converters', 'cursors', 'debug', 'escape', 'escape_dict',
'escape_sequence', 'escape_string', 'get_client_info',
'paramstyle', 'string_literal', 'threadsafety', 'version_info']
================================================
FILE: dev_server/sae/_restful_mysql/_mysql.py
================================================
# Copyright (C) 2012-2013 SINA, All rights reserved.
from _mysql_exceptions import *
"""An proxy for the MySQL C API
Translate the _mysql C API call into restfull call
"""
import types
import pickle
import urllib2
from release import __version__, version_info
import logging
logger = logging.getLogger('sae._mysql')
NULL = 'NULL'
_SAE_MYSQL_API_BACKEND = 'http://2.python.sinaapp.com/api/mysql/'
# refs:
# http://www.python.org/dev/peps/pep-0249
# http://mysql-python.sourceforge.net/MySQLdb.html#mysql
class connection(object):
def __init__(self, *args, **kwargs):
self.converter = kwargs.pop('conv', {})
self._conn_args = args
self._conn_kwargs = kwargs
self._conn_id = None
self._rows = None
self._description = None
self._description_flags = None
self._rowcount = None
self._warnings = None
self._info = None
self._lastrowid = None
self._open_connection()
def open(self):
pass
def close(self):
self._conn_id = None
def shutdown(self):
pass
def select_db(self, *args):
self._request('select_db', args)
def change_user(self):
pass
def character_set_name(self):
if not hasattr(self, '_charset'):
self._charset = self._request('character_set_name')
return self._charset
def set_character_set(self, charset):
if getattr(self, '_charset', None) != charset:
self._request('set_character_set', charset)
self._charset = charset
def set_server_option(self, *args, **kws):
logging.warning('Ignored set_server_option: %s, %s', args, kws)
def query(self, query):
retval = self._request('query', query=query)
self._rows = retval['rows']
self._description = retval['description']
self._description_flags = retval['description_flags']
self._rowcount = retval['rowcount']
self._warnings = retval['warnings']
self._info = retval['info']
self._lastrowid = retval['lastrowid']
def commit(self):
pass
def rollback(self):
pass
def autocommit(self, value):
pass
def use_result(self):
return self.store_result()
def store_result(self):
if self._rows:
return StoreResult(self, self._rows, self.converter,
self._description, self._description_flags)
else:
return None
def next_result(self, *args, **kws):
# TODO
return -1
def affected_rows(self):
return self._rowcount
def insert_id(self):
return self._lastrowid
def info(self):
return self._info
def get_host_info(self):
return self._host_info
def get_proto_info(self):
return self._proto_info
def get_server_info(self):
return self._server_info
def ping(self):
pass
def escape(self, item, dct=None):
return escape(item, dct or self.converter)
def escape_string(self, str):
return escape_string(str)
def string_literal(self, obj):
return '\'%s\'' % escape_string(str(obj))
def _open_connection(self):
retval = self._request('open', *self._conn_args, **self._conn_kwargs)
self._conn_id = retval['connection_id']
self._host_info = retval['host_info']
self._proto_info = retval['proto_info']
self._server_info = retval['server_info']
self.server_capabilities = retval['server_capabilities']
def _request(self, op, *args, **kwargs):
req = {
'connection_id': self._conn_id,
'op': op, 'args': args, 'kwargs': kwargs
}
logger.debug('REQ: %s', req)
payload = pickle.dumps(req)
body = urllib2.urlopen(_SAE_MYSQL_API_BACKEND, payload).read()
rep = pickle.loads(body)
logger.debug('REP: %s', rep)
if rep.get('sql_exception'):
raise rep.get('sql_exception')
return rep.get('result')
def _mysql_rows_to_python(rows, conv, field_info, how):
def row_to_python0(row):
nrow = []
for i, v in enumerate(row):
# XXX: NULL is always converted to None, so here we
# do not need to do it again.
nrow.append(None if v is None else conv[i](v))
return tuple(nrow)
def row_to_python1(row):
nrow = {}
for i, v in enumerate(row):
# XXX: NULL is always converted to None, so here we
# do not need to do it again.
nrow[field_info[i][0]] = None if v is None else conv[i](v)
return nrow
if how:
return tuple(row_to_python1(r) for r in rows)
else:
return tuple(row_to_python0(r) for r in rows)
class StoreResult:
def __init__(self, conn, rows, conv, description, description_flags):
self.conn = conn
self.current = 0
self.description = description
self.description_flags = description_flags
self._cached = rows
self._init_conv(conv)
def _init_conv(self, conv):
# _mysql.c:_mysql_ResultObject_Initialize
self.converter = []
for n, i in enumerate(self.description):
c = conv.get(i[1], str) # search by field.type
if isinstance(c, list):
nc = None
mask = self.description_flags[n]
for j in c:
if isinstance(j[0], int):
if mask & j[0]: # search by field.flags
nc = j[1]
break
else:
nc = j[1]
break # wildcard
c = nc if nc is not None else str
self.converter.append(c)
def fetch_row(self, maxrows=1, how=0):
if maxrows == 0:
retval = self._cached
self._cached = ()
else:
retval = self._cached[self.current:maxrows]
self.current += maxrows
return _mysql_rows_to_python(retval, self.converter, self.description, how)
def describe(self):
return self.description
def field_flags(self):
return self.description_flags
connect = connection
def get_client_info():
return '5.1.67'
def escape(item, dct):
return _escape_item(item, dct)
def _escape_item(val, dct):
d = dct.get(type(val)) or dct.get(types.StringType)
return d(val, dct)
# Copied from pymysql
# See: https://github.com/petehunt/PyMySQL/blob/master/pymysql/converters.py
import re
ESCAPE_REGEX = re.compile(r"[\0\n\r\032\'\"\\]", re.IGNORECASE)
def escape_string(value):
def rep(m):
n = m.group(0)
if n == "\0":
return "\\0"
elif n == "\n":
return "\\n"
elif n == "\r":
return "\\r"
elif n == "\032":
return "\\Z"
else:
return "\\"+n
s = re.sub(ESCAPE_REGEX, rep, value)
return s
def string_literal(obj):
return '\'%s\'' % escape_string(str(obj))
def escape_dict(val, dct):
n = {}
for k, v in val.items():
quoted = _escape_item(v)
n[k] = quoted
return n
def escape_sequence(val, dct):
return tuple(_escape_item(v, dct) for v in val)
================================================
FILE: dev_server/sae/_restful_mysql/_mysql_exceptions.py
================================================
"""_mysql_exceptions: Exception classes for _mysql and MySQLdb.
These classes are dictated by the DB API v2.0:
http://www.python.org/topics/database/DatabaseAPI-2.0.html
"""
from exceptions import Exception, StandardError, Warning
class MySQLError(StandardError):
"""Exception related to operation with MySQL."""
class Warning(Warning, MySQLError):
"""Exception raised for important warnings like data truncations
while inserting, etc."""
class Error(MySQLError):
"""Exception that is the base class of all other error exceptions
(not Warning)."""
class InterfaceError(Error):
"""Exception raised for errors that are related to the database
interface rather than the database itself."""
class DatabaseError(Error):
"""Exception raised for errors that are related to the
database."""
class DataError(DatabaseError):
"""Exception raised for errors that are due to problems with the
processed data like division by zero, numeric value out of range,
etc."""
class OperationalError(DatabaseError):
"""Exception raised for errors that are related to the database's
operation and not necessarily under the control of the programmer,
e.g. an unexpected disconnect occurs, the data source name is not
found, a transaction could not be processed, a memory allocation
error occurred during processing, etc."""
class IntegrityError(DatabaseError):
"""Exception raised when the relational integrity of the database
is affected, e.g. a foreign key check fails, duplicate key,
etc."""
class InternalError(DatabaseError):
"""Exception raised when the database encounters an internal
error, e.g. the cursor is not valid anymore, the transaction is
out of sync, etc."""
class ProgrammingError(DatabaseError):
"""Exception raised for programming errors, e.g. table not found
or already exists, syntax error in the SQL statement, wrong number
of parameters specified, etc."""
class NotSupportedError(DatabaseError):
"""Exception raised in case a method or database API was used
which is not supported by the database, e.g. requesting a
.rollback() on a connection that does not support transaction or
has transactions turned off."""
del Exception, StandardError
================================================
FILE: dev_server/sae/_restful_mysql/connections.py
================================================
"""
This module implements connections for MySQLdb. Presently there is
only one class: Connection. Others are unlikely. However, you might
want to make your own subclasses. In most cases, you will probably
override Connection.default_cursor with a non-standard Cursor class.
"""
import cursors
from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \
DatabaseError, OperationalError, IntegrityError, InternalError, \
NotSupportedError, ProgrammingError
import types, _mysql
import re
def defaulterrorhandler(connection, cursor, errorclass, errorvalue):
"""
If cursor is not None, (errorclass, errorvalue) is appended to
cursor.messages; otherwise it is appended to
connection.messages. Then errorclass is raised with errorvalue as
the value.
You can override this with your own error handler by assigning it
to the instance.
"""
error = errorclass, errorvalue
if cursor:
cursor.messages.append(error)
else:
connection.messages.append(error)
del cursor
del connection
raise errorclass, errorvalue
re_numeric_part = re.compile(r"^(\d+)")
def numeric_part(s):
"""Returns the leading numeric part of a string.
>>> numeric_part("20-alpha")
20
>>> numeric_part("foo")
>>> numeric_part("16b")
16
"""
m = re_numeric_part.match(s)
if m:
return int(m.group(1))
return None
class Connection(_mysql.connection):
"""MySQL Database Connection Object"""
default_cursor = cursors.Cursor
def __init__(self, *args, **kwargs):
"""
Create a connection to the database. It is strongly recommended
that you only use keyword parameters. Consult the MySQL C API
documentation for more information.
host
string, host to connect
user
string, user to connect as
passwd
string, password to use
db
string, database to use
port
integer, TCP/IP port to connect to
unix_socket
string, location of unix_socket to use
conv
conversion dictionary, see MySQLdb.converters
connect_timeout
number of seconds to wait before the connection attempt
fails.
compress
if set, compression is enabled
named_pipe
if set, a named pipe is used to connect (Windows only)
init_command
command which is run once the connection is created
read_default_file
file from which default client values are read
read_default_group
configuration group to use from the default file
cursorclass
class object, used to create cursors (keyword only)
use_unicode
If True, text-like columns are returned as unicode objects
using the connection's character set. Otherwise, text-like
columns are returned as strings. columns are returned as
normal strings. Unicode objects will always be encoded to
the connection's character set regardless of this setting.
charset
If supplied, the connection character set will be changed
to this character set (MySQL-4.1 and newer). This implies
use_unicode=True.
sql_mode
If supplied, the session SQL mode will be changed to this
setting (MySQL-4.1 and newer). For more details and legal
values, see the MySQL documentation.
client_flag
integer, flags to use or 0
(see MySQL docs or constants/CLIENTS.py)
ssl
dictionary or mapping, contains SSL connection parameters;
see the MySQL documentation for more details
(mysql_ssl_set()). If this is set, and the client does not
support SSL, NotSupportedError will be raised.
local_infile
integer, non-zero enables LOAD LOCAL INFILE; zero disables
There are a number of undocumented, non-standard methods. See the
documentation for the MySQL C API for some hints on what they do.
"""
from constants import CLIENT, FIELD_TYPE
from converters import conversions
from weakref import proxy, WeakValueDictionary
import types
kwargs2 = kwargs.copy()
if kwargs.has_key('conv'):
conv = kwargs['conv']
else:
conv = conversions
conv2 = {}
for k, v in conv.items():
if isinstance(k, int) and isinstance(v, list):
conv2[k] = v[:]
else:
conv2[k] = v
kwargs2['conv'] = conv2
self.cursorclass = kwargs2.pop('cursorclass', self.default_cursor)
charset = kwargs2.pop('charset', '')
if charset:
use_unicode = True
else:
use_unicode = False
use_unicode = kwargs2.pop('use_unicode', use_unicode)
sql_mode = kwargs2.pop('sql_mode', '')
client_flag = kwargs.get('client_flag', 0)
client_version = tuple([ numeric_part(n) for n in _mysql.get_client_info().split('.')[:2] ])
if client_version >= (4, 1):
client_flag |= CLIENT.MULTI_STATEMENTS
if client_version >= (5, 0):
client_flag |= CLIENT.MULTI_RESULTS
kwargs2['client_flag'] = client_flag
super(Connection, self).__init__(*args, **kwargs2)
self.encoders = dict([ (k, v) for k, v in conv.items()
if type(k) is not int ])
self._server_version = tuple([ numeric_part(n) for n in self.get_server_info().split('.')[:2] ])
db = proxy(self)
def _get_string_literal():
def string_literal(obj, dummy=None):
return db.string_literal(obj)
return string_literal
def _get_unicode_literal():
def unicode_literal(u, dummy=None):
return db.literal(u.encode(unicode_literal.charset))
return unicode_literal
def _get_string_decoder():
def string_decoder(s):
return s.decode(string_decoder.charset)
return string_decoder
string_literal = _get_string_literal()
self.unicode_literal = unicode_literal = _get_unicode_literal()
self.string_decoder = string_decoder = _get_string_decoder()
if not charset:
charset = self.character_set_name()
self.set_character_set(charset)
if sql_mode:
self.set_sql_mode(sql_mode)
if use_unicode:
self.converter[FIELD_TYPE.STRING].append((None, string_decoder))
self.converter[FIELD_TYPE.VAR_STRING].append((None, string_decoder))
self.converter[FIELD_TYPE.VARCHAR].append((None, string_decoder))
self.converter[FIELD_TYPE.BLOB].append((None, string_decoder))
self.encoders[types.StringType] = string_literal
self.encoders[types.UnicodeType] = unicode_literal
self._transactional = self.server_capabilities & CLIENT.TRANSACTIONS
if self._transactional:
# PEP-249 requires autocommit to be initially off
self.autocommit(False)
self.messages = []
def cursor(self, cursorclass=None):
"""
Create a cursor on which queries may be performed. The
optional cursorclass parameter is used to create the
Cursor. By default, self.cursorclass=cursors.Cursor is
used.
"""
return (cursorclass or self.cursorclass)(self)
def __enter__(self): return self.cursor()
def __exit__(self, exc, value, tb):
if exc:
self.rollback()
else:
self.commit()
def literal(self, o):
"""
If o is a single object, returns an SQL literal as a string.
If o is a non-string sequence, the items of the sequence are
converted and returned as a sequence.
Non-standard. For internal use; do not use this in your
applications.
"""
return self.escape(o, self.encoders)
def begin(self):
"""Explicitly begin a connection. Non-standard.
DEPRECATED: Will be removed in 1.3.
Use an SQL BEGIN statement instead."""
from warnings import warn
warn("begin() is non-standard and will be removed in 1.3",
DeprecationWarning, 2)
self.query("BEGIN")
if not hasattr(_mysql.connection, 'warning_count'):
def warning_count(self):
"""Return the number of warnings generated from the
last query. This is derived from the info() method."""
from string import atoi
info = self.info()
if info:
return atoi(info.split()[-1])
else:
return 0
def set_character_set(self, charset):
"""Set the connection character set to charset. The character
set can only be changed in MySQL-4.1 and newer. If you try
to change the character set from the current value in an
older version, NotSupportedError will be raised."""
if self.character_set_name() != charset:
try:
super(Connection, self).set_character_set(charset)
except AttributeError:
if self._server_version < (4, 1):
raise NotSupportedError("server is too old to set charset")
self.query('SET NAMES %s' % charset)
self.store_result()
self.string_decoder.charset = charset
self.unicode_literal.charset = charset
def set_sql_mode(self, sql_mode):
"""Set the connection sql_mode. See MySQL documentation for
legal values."""
if self._server_version < (4, 1):
raise NotSupportedError("server is too old to set sql_mode")
self.query("SET SESSION sql_mode='%s'" % sql_mode)
self.store_result()
def show_warnings(self):
"""Return detailed information about warnings as a
sequence of tuples of (Level, Code, Message). This
is only supported in MySQL-4.1 and up. If your server
is an earlier version, an empty sequence is returned."""
if self._server_version < (4,1): return ()
self.query("SHOW WARNINGS")
r = self.store_result()
warnings = r.fetch_row(0)
return warnings
Warning = Warning
Error = Error
InterfaceError = InterfaceError
DatabaseError = DatabaseError
DataError = DataError
OperationalError = OperationalError
IntegrityError = IntegrityError
InternalError = InternalError
ProgrammingError = ProgrammingError
NotSupportedError = NotSupportedError
errorhandler = defaulterrorhandler
================================================
FILE: dev_server/sae/_restful_mysql/constants/CLIENT.py
================================================
"""MySQL CLIENT constants
These constants are used when creating the connection. Use bitwise-OR
(|) to combine options together, and pass them as the client_flags
parameter to MySQLdb.Connection. For more information on these flags,
see the MySQL C API documentation for mysql_real_connect().
"""
LONG_PASSWORD = 1
FOUND_ROWS = 2
LONG_FLAG = 4
CONNECT_WITH_DB = 8
NO_SCHEMA = 16
COMPRESS = 32
ODBC = 64
LOCAL_FILES = 128
IGNORE_SPACE = 256
CHANGE_USER = 512
INTERACTIVE = 1024
SSL = 2048
IGNORE_SIGPIPE = 4096
TRANSACTIONS = 8192 # mysql_com.h was WRONG prior to 3.23.35
RESERVED = 16384
SECURE_CONNECTION = 32768
MULTI_STATEMENTS = 65536
MULTI_RESULTS = 131072
================================================
FILE: dev_server/sae/_restful_mysql/constants/CR.py
================================================
"""MySQL Connection Errors
Nearly all of these raise OperationalError. COMMANDS_OUT_OF_SYNC
raises ProgrammingError.
"""
MIN_ERROR = 2000
MAX_ERROR = 2999
UNKNOWN_ERROR = 2000
SOCKET_CREATE_ERROR = 2001
CONNECTION_ERROR = 2002
CONN_HOST_ERROR = 2003
IPSOCK_ERROR = 2004
UNKNOWN_HOST = 2005
SERVER_GONE_ERROR = 2006
VERSION_ERROR = 2007
OUT_OF_MEMORY = 2008
WRONG_HOST_INFO = 2009
LOCALHOST_CONNECTION = 2010
TCP_CONNECTION = 2011
SERVER_HANDSHAKE_ERR = 2012
SERVER_LOST = 2013
COMMANDS_OUT_OF_SYNC = 2014
NAMEDPIPE_CONNECTION = 2015
NAMEDPIPEWAIT_ERROR = 2016
NAMEDPIPEOPEN_ERROR = 2017
NAMEDPIPESETSTATE_ERROR = 2018
CANT_READ_CHARSET = 2019
NET_PACKET_TOO_LARGE = 2020
================================================
FILE: dev_server/sae/_restful_mysql/constants/ER.py
================================================
"""MySQL ER Constants
These constants are error codes for the bulk of the error conditions
that may occur.
"""
HASHCHK = 1000
NISAMCHK = 1001
NO = 1002
YES = 1003
CANT_CREATE_FILE = 1004
CANT_CREATE_TABLE = 1005
CANT_CREATE_DB = 1006
DB_CREATE_EXISTS = 1007
DB_DROP_EXISTS = 1008
DB_DROP_DELETE = 1009
DB_DROP_RMDIR = 1010
CANT_DELETE_FILE = 1011
CANT_FIND_SYSTEM_REC = 1012
CANT_GET_STAT = 1013
CANT_GET_WD = 1014
CANT_LOCK = 1015
CANT_OPEN_FILE = 1016
FILE_NOT_FOUND = 1017
CANT_READ_DIR = 1018
CANT_SET_WD = 1019
CHECKREAD = 1020
DISK_FULL = 1021
DUP_KEY = 1022
ERROR_ON_CLOSE = 1023
ERROR_ON_READ = 1024
ERROR_ON_RENAME = 1025
ERROR_ON_WRITE = 1026
FILE_USED = 1027
FILSORT_ABORT = 1028
FORM_NOT_FOUND = 1029
GET_ERRNO = 1030
ILLEGAL_HA = 1031
KEY_NOT_FOUND = 1032
NOT_FORM_FILE = 1033
NOT_KEYFILE = 1034
OLD_KEYFILE = 1035
OPEN_AS_READONLY = 1036
OUTOFMEMORY = 1037
OUT_OF_SORTMEMORY = 1038
UNEXPECTED_EOF = 1039
CON_COUNT_ERROR = 1040
OUT_OF_RESOURCES = 1041
BAD_HOST_ERROR = 1042
HANDSHAKE_ERROR = 1043
DBACCESS_DENIED_ERROR = 1044
ACCESS_DENIED_ERROR = 1045
NO_DB_ERROR = 1046
UNKNOWN_COM_ERROR = 1047
BAD_NULL_ERROR = 1048
BAD_DB_ERROR = 1049
TABLE_EXISTS_ERROR = 1050
BAD_TABLE_ERROR = 1051
NON_UNIQ_ERROR = 1052
SERVER_SHUTDOWN = 1053
BAD_FIELD_ERROR = 1054
WRONG_FIELD_WITH_GROUP = 1055
WRONG_GROUP_FIELD = 1056
WRONG_SUM_SELECT = 1057
WRONG_VALUE_COUNT = 1058
TOO_LONG_IDENT = 1059
DUP_FIELDNAME = 1060
DUP_KEYNAME = 1061
DUP_ENTRY = 1062
WRONG_FIELD_SPEC = 1063
PARSE_ERROR = 1064
EMPTY_QUERY = 1065
NONUNIQ_TABLE = 1066
INVALID_DEFAULT = 1067
MULTIPLE_PRI_KEY = 1068
TOO_MANY_KEYS = 1069
TOO_MANY_KEY_PARTS = 1070
TOO_LONG_KEY = 1071
KEY_COLUMN_DOES_NOT_EXITS = 1072
BLOB_USED_AS_KEY = 1073
TOO_BIG_FIELDLENGTH = 1074
WRONG_AUTO_KEY = 1075
READY = 1076
NORMAL_SHUTDOWN = 1077
GOT_SIGNAL = 1078
SHUTDOWN_COMPLETE = 1079
FORCING_CLOSE = 1080
IPSOCK_ERROR = 1081
NO_SUCH_INDEX = 1082
WRONG_FIELD_TERMINATORS = 1083
BLOBS_AND_NO_TERMINATED = 1084
TEXTFILE_NOT_READABLE = 1085
FILE_EXISTS_ERROR = 1086
LOAD_INFO = 1087
ALTER_INFO = 1088
WRONG_SUB_KEY = 1089
CANT_REMOVE_ALL_FIELDS = 1090
CANT_DROP_FIELD_OR_KEY = 1091
INSERT_INFO = 1092
INSERT_TABLE_USED = 1093
NO_SUCH_THREAD = 1094
KILL_DENIED_ERROR = 1095
NO_TABLES_USED = 1096
TOO_BIG_SET = 1097
NO_UNIQUE_LOGFILE = 1098
TABLE_NOT_LOCKED_FOR_WRITE = 1099
TABLE_NOT_LOCKED = 1100
BLOB_CANT_HAVE_DEFAULT = 1101
WRONG_DB_NAME = 1102
WRONG_TABLE_NAME = 1103
TOO_BIG_SELECT = 1104
UNKNOWN_ERROR = 1105
UNKNOWN_PROCEDURE = 1106
WRONG_PARAMCOUNT_TO_PROCEDURE = 1107
WRONG_PARAMETERS_TO_PROCEDURE = 1108
UNKNOWN_TABLE = 1109
FIELD_SPECIFIED_TWICE = 1110
INVALID_GROUP_FUNC_USE = 1111
UNSUPPORTED_EXTENSION = 1112
TABLE_MUST_HAVE_COLUMNS = 1113
RECORD_FILE_FULL = 1114
UNKNOWN_CHARACTER_SET = 1115
TOO_MANY_TABLES = 1116
TOO_MANY_FIELDS = 1117
TOO_BIG_ROWSIZE = 1118
STACK_OVERRUN = 1119
WRONG_OUTER_JOIN = 1120
NULL_COLUMN_IN_INDEX = 1121
CANT_FIND_UDF = 1122
CANT_INITIALIZE_UDF = 1123
UDF_NO_PATHS = 1124
UDF_EXISTS = 1125
CANT_OPEN_LIBRARY = 1126
CANT_FIND_DL_ENTRY = 1127
FUNCTION_NOT_DEFINED = 1128
HOST_IS_BLOCKED = 1129
HOST_NOT_PRIVILEGED = 1130
PASSWORD_ANONYMOUS_USER = 1131
PASSWORD_NOT_ALLOWED = 1132
PASSWORD_NO_MATCH = 1133
UPDATE_INFO = 1134
CANT_CREATE_THREAD = 1135
WRONG_VALUE_COUNT_ON_ROW = 1136
CANT_REOPEN_TABLE = 1137
INVALID_USE_OF_NULL = 1138
REGEXP_ERROR = 1139
MIX_OF_GROUP_FUNC_AND_FIELDS = 1140
NONEXISTING_GRANT = 1141
TABLEACCESS_DENIED_ERROR = 1142
COLUMNACCESS_DENIED_ERROR = 1143
ILLEGAL_GRANT_FOR_TABLE = 1144
GRANT_WRONG_HOST_OR_USER = 1145
NO_SUCH_TABLE = 1146
NONEXISTING_TABLE_GRANT = 1147
NOT_ALLOWED_COMMAND = 1148
SYNTAX_ERROR = 1149
DELAYED_CANT_CHANGE_LOCK = 1150
TOO_MANY_DELAYED_THREADS = 1151
ABORTING_CONNECTION = 1152
NET_PACKET_TOO_LARGE = 1153
NET_READ_ERROR_FROM_PIPE = 1154
NET_FCNTL_ERROR = 1155
NET_PACKETS_OUT_OF_ORDER = 1156
NET_UNCOMPRESS_ERROR = 1157
NET_READ_ERROR = 1158
NET_READ_INTERRUPTED = 1159
NET_ERROR_ON_WRITE = 1160
NET_WRITE_INTERRUPTED = 1161
TOO_LONG_STRING = 1162
TABLE_CANT_HANDLE_BLOB = 1163
TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164
DELAYED_INSERT_TABLE_LOCKED = 1165
WRONG_COLUMN_NAME = 1166
WRONG_KEY_COLUMN = 1167
WRONG_MRG_TABLE = 1168
DUP_UNIQUE = 1169
BLOB_KEY_WITHOUT_LENGTH = 1170
PRIMARY_CANT_HAVE_NULL = 1171
TOO_MANY_ROWS = 1172
REQUIRES_PRIMARY_KEY = 1173
NO_RAID_COMPILED = 1174
UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175
KEY_DOES_NOT_EXITS = 1176
CHECK_NO_SUCH_TABLE = 1177
CHECK_NOT_IMPLEMENTED = 1178
CANT_DO_THIS_DURING_AN_TRANSACTION = 1179
ERROR_DURING_COMMIT = 1180
ERROR_DURING_ROLLBACK = 1181
ERROR_DURING_FLUSH_LOGS = 1182
ERROR_DURING_CHECKPOINT = 1183
NEW_ABORTING_CONNECTION = 1184
DUMP_NOT_IMPLEMENTED = 1185
FLUSH_MASTER_BINLOG_CLOSED = 1186
INDEX_REBUILD = 1187
MASTER = 1188
MASTER_NET_READ = 1189
MASTER_NET_WRITE = 1190
FT_MATCHING_KEY_NOT_FOUND = 1191
LOCK_OR_ACTIVE_TRANSACTION = 1192
UNKNOWN_SYSTEM_VARIABLE = 1193
CRASHED_ON_USAGE = 1194
CRASHED_ON_REPAIR = 1195
WARNING_NOT_COMPLETE_ROLLBACK = 1196
TRANS_CACHE_FULL = 1197
SLAVE_MUST_STOP = 1198
SLAVE_NOT_RUNNING = 1199
BAD_SLAVE = 1200
MASTER_INFO = 1201
SLAVE_THREAD = 1202
TOO_MANY_USER_CONNECTIONS = 1203
SET_CONSTANTS_ONLY = 1204
LOCK_WAIT_TIMEOUT = 1205
LOCK_TABLE_FULL = 1206
READ_ONLY_TRANSACTION = 1207
DROP_DB_WITH_READ_LOCK = 1208
CREATE_DB_WITH_READ_LOCK = 1209
WRONG_ARGUMENTS = 1210
NO_PERMISSION_TO_CREATE_USER = 1211
UNION_TABLES_IN_DIFFERENT_DIR = 1212
LOCK_DEADLOCK = 1213
TABLE_CANT_HANDLE_FT = 1214
CANNOT_ADD_FOREIGN = 1215
NO_REFERENCED_ROW = 1216
ROW_IS_REFERENCED = 1217
CONNECT_TO_MASTER = 1218
QUERY_ON_MASTER = 1219
ERROR_WHEN_EXECUTING_COMMAND = 1220
WRONG_USAGE = 1221
WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222
CANT_UPDATE_WITH_READLOCK = 1223
MIXING_NOT_ALLOWED = 1224
DUP_ARGUMENT = 1225
USER_LIMIT_REACHED = 1226
SPECIFIC_ACCESS_DENIED_ERROR = 1227
LOCAL_VARIABLE = 1228
GLOBAL_VARIABLE = 1229
NO_DEFAULT = 1230
WRONG_VALUE_FOR_VAR = 1231
WRONG_TYPE_FOR_VAR = 1232
VAR_CANT_BE_READ = 1233
CANT_USE_OPTION_HERE = 1234
NOT_SUPPORTED_YET = 1235
MASTER_FATAL_ERROR_READING_BINLOG = 1236
SLAVE_IGNORED_TABLE = 1237
INCORRECT_GLOBAL_LOCAL_VAR = 1238
WRONG_FK_DEF = 1239
KEY_REF_DO_NOT_MATCH_TABLE_REF = 1240
OPERAND_COLUMNS = 1241
SUBQUERY_NO_1_ROW = 1242
UNKNOWN_STMT_HANDLER = 1243
CORRUPT_HELP_DB = 1244
CYCLIC_REFERENCE = 1245
AUTO_CONVERT = 1246
ILLEGAL_REFERENCE = 1247
DERIVED_MUST_HAVE_ALIAS = 1248
SELECT_REDUCED = 1249
TABLENAME_NOT_ALLOWED_HERE = 1250
NOT_SUPPORTED_AUTH_MODE = 1251
SPATIAL_CANT_HAVE_NULL = 1252
COLLATION_CHARSET_MISMATCH = 1253
SLAVE_WAS_RUNNING = 1254
SLAVE_WAS_NOT_RUNNING = 1255
TOO_BIG_FOR_UNCOMPRESS = 1256
ZLIB_Z_MEM_ERROR = 1257
ZLIB_Z_BUF_ERROR = 1258
ZLIB_Z_DATA_ERROR = 1259
CUT_VALUE_GROUP_CONCAT = 1260
WARN_TOO_FEW_RECORDS = 1261
WARN_TOO_MANY_RECORDS = 1262
WARN_NULL_TO_NOTNULL = 1263
WARN_DATA_OUT_OF_RANGE = 1264
WARN_DATA_TRUNCATED = 1265
WARN_USING_OTHER_HANDLER = 1266
CANT_AGGREGATE_2COLLATIONS = 1267
DROP_USER = 1268
REVOKE_GRANTS = 1269
CANT_AGGREGATE_3COLLATIONS = 1270
CANT_AGGREGATE_NCOLLATIONS = 1271
VARIABLE_IS_NOT_STRUCT = 1272
UNKNOWN_COLLATION = 1273
SLAVE_IGNORED_SSL_PARAMS = 1274
SERVER_IS_IN_SECURE_AUTH_MODE = 1275
WARN_FIELD_RESOLVED = 1276
BAD_SLAVE_UNTIL_COND = 1277
MISSING_SKIP_SLAVE = 1278
UNTIL_COND_IGNORED = 1279
WRONG_NAME_FOR_INDEX = 1280
WRONG_NAME_FOR_CATALOG = 1281
WARN_QC_RESIZE = 1282
BAD_FT_COLUMN = 1283
UNKNOWN_KEY_CACHE = 1284
WARN_HOSTNAME_WONT_WORK = 1285
UNKNOWN_STORAGE_ENGINE = 1286
WARN_DEPRECATED_SYNTAX = 1287
NON_UPDATABLE_TABLE = 1288
FEATURE_DISABLED = 1289
OPTION_PREVENTS_STATEMENT = 1290
DUPLICATED_VALUE_IN_TYPE = 1291
TRUNCATED_WRONG_VALUE = 1292
TOO_MUCH_AUTO_TIMESTAMP_COLS = 1293
INVALID_ON_UPDATE = 1294
UNSUPPORTED_PS = 1295
GET_ERRMSG = 1296
GET_TEMPORARY_ERRMSG = 1297
UNKNOWN_TIME_ZONE = 1298
WARN_INVALID_TIMESTAMP = 1299
INVALID_CHARACTER_STRING = 1300
WARN_ALLOWED_PACKET_OVERFLOWED = 1301
CONFLICTING_DECLARATIONS = 1302
SP_NO_RECURSIVE_CREATE = 1303
SP_ALREADY_EXISTS = 1304
SP_DOES_NOT_EXIST = 1305
SP_DROP_FAILED = 1306
SP_STORE_FAILED = 1307
SP_LILABEL_MISMATCH = 1308
SP_LABEL_REDEFINE = 1309
SP_LABEL_MISMATCH = 1310
SP_UNINIT_VAR = 1311
SP_BADSELECT = 1312
SP_BADRETURN = 1313
SP_BADSTATEMENT = 1314
UPDATE_LOG_DEPRECATED_IGNORED = 1315
UPDATE_LOG_DEPRECATED_TRANSLATED = 1316
QUERY_INTERRUPTED = 1317
SP_WRONG_NO_OF_ARGS = 1318
SP_COND_MISMATCH = 1319
SP_NORETURN = 1320
SP_NORETURNEND = 1321
SP_BAD_CURSOR_QUERY = 1322
SP_BAD_CURSOR_SELECT = 1323
SP_CURSOR_MISMATCH = 1324
SP_CURSOR_ALREADY_OPEN = 1325
SP_CURSOR_NOT_OPEN = 1326
SP_UNDECLARED_VAR = 1327
SP_WRONG_NO_OF_FETCH_ARGS = 1328
SP_FETCH_NO_DATA = 1329
SP_DUP_PARAM = 1330
SP_DUP_VAR = 1331
SP_DUP_COND = 1332
SP_DUP_CURS = 1333
SP_CANT_ALTER = 1334
SP_SUBSELECT_NYI = 1335
STMT_NOT_ALLOWED_IN_SF_OR_TRG = 1336
SP_VARCOND_AFTER_CURSHNDLR = 1337
SP_CURSOR_AFTER_HANDLER = 1338
SP_CASE_NOT_FOUND = 1339
FPARSER_TOO_BIG_FILE = 1340
FPARSER_BAD_HEADER = 1341
FPARSER_EOF_IN_COMMENT = 1342
FPARSER_ERROR_IN_PARAMETER = 1343
FPARSER_EOF_IN_UNKNOWN_PARAMETER = 1344
VIEW_NO_EXPLAIN = 1345
FRM_UNKNOWN_TYPE = 1346
WRONG_OBJECT = 1347
NONUPDATEABLE_COLUMN = 1348
VIEW_SELECT_DERIVED = 1349
VIEW_SELECT_CLAUSE = 1350
VIEW_SELECT_VARIABLE = 1351
VIEW_SELECT_TMPTABLE = 1352
VIEW_WRONG_LIST = 1353
WARN_VIEW_MERGE = 1354
WARN_VIEW_WITHOUT_KEY = 1355
VIEW_INVALID = 1356
SP_NO_DROP_SP = 1357
SP_GOTO_IN_HNDLR = 1358
TRG_ALREADY_EXISTS = 1359
TRG_DOES_NOT_EXIST = 1360
TRG_ON_VIEW_OR_TEMP_TABLE = 1361
TRG_CANT_CHANGE_ROW = 1362
TRG_NO_SUCH_ROW_IN_TRG = 1363
NO_DEFAULT_FOR_FIELD = 1364
DIVISION_BY_ZERO = 1365
TRUNCATED_WRONG_VALUE_FOR_FIELD = 1366
ILLEGAL_VALUE_FOR_TYPE = 1367
VIEW_NONUPD_CHECK = 1368
VIEW_CHECK_FAILED = 1369
PROCACCESS_DENIED_ERROR = 1370
RELAY_LOG_FAIL = 1371
PASSWD_LENGTH = 1372
UNKNOWN_TARGET_BINLOG = 1373
IO_ERR_LOG_INDEX_READ = 1374
BINLOG_PURGE_PROHIBITED = 1375
FSEEK_FAIL = 1376
BINLOG_PURGE_FATAL_ERR = 1377
LOG_IN_USE = 1378
LOG_PURGE_UNKNOWN_ERR = 1379
RELAY_LOG_INIT = 1380
NO_BINARY_LOGGING = 1381
RESERVED_SYNTAX = 1382
WSAS_FAILED = 1383
DIFF_GROUPS_PROC = 1384
NO_GROUP_FOR_PROC = 1385
ORDER_WITH_PROC = 1386
LOGGING_PROHIBIT_CHANGING_OF = 1387
NO_FILE_MAPPING = 1388
WRONG_MAGIC = 1389
PS_MANY_PARAM = 1390
KEY_PART_0 = 1391
VIEW_CHECKSUM = 1392
VIEW_MULTIUPDATE = 1393
VIEW_NO_INSERT_FIELD_LIST = 1394
VIEW_DELETE_MERGE_VIEW = 1395
CANNOT_USER = 1396
XAER_NOTA = 1397
XAER_INVAL = 1398
XAER_RMFAIL = 1399
XAER_OUTSIDE = 1400
XAER_RMERR = 1401
XA_RBROLLBACK = 1402
NONEXISTING_PROC_GRANT = 1403
PROC_AUTO_GRANT_FAIL = 1404
PROC_AUTO_REVOKE_FAIL = 1405
DATA_TOO_LONG = 1406
SP_BAD_SQLSTATE = 1407
STARTUP = 1408
LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR = 1409
CANT_CREATE_USER_WITH_GRANT = 1410
WRONG_VALUE_FOR_TYPE = 1411
TABLE_DEF_CHANGED = 1412
SP_DUP_HANDLER = 1413
SP_NOT_VAR_ARG = 1414
SP_NO_RETSET = 1415
CANT_CREATE_GEOMETRY_OBJECT = 1416
FAILED_ROUTINE_BREAK_BINLOG = 1417
BINLOG_UNSAFE_ROUTINE = 1418
BINLOG_CREATE_ROUTINE_NEED_SUPER = 1419
EXEC_STMT_WITH_OPEN_CURSOR = 1420
STMT_HAS_NO_OPEN_CURSOR = 1421
COMMIT_NOT_ALLOWED_IN_SF_OR_TRG = 1422
NO_DEFAULT_FOR_VIEW_FIELD = 1423
SP_NO_RECURSION = 1424
TOO_BIG_SCALE = 1425
TOO_BIG_PRECISION = 1426
M_BIGGER_THAN_D = 1427
WRONG_LOCK_OF_SYSTEM_TABLE = 1428
CONNECT_TO_FOREIGN_DATA_SOURCE = 1429
QUERY_ON_FOREIGN_DATA_SOURCE = 1430
FOREIGN_DATA_SOURCE_DOESNT_EXIST = 1431
FOREIGN_DATA_STRING_INVALID_CANT_CREATE = 1432
FOREIGN_DATA_STRING_INVALID = 1433
CANT_CREATE_FEDERATED_TABLE = 1434
TRG_IN_WRONG_SCHEMA = 1435
STACK_OVERRUN_NEED_MORE = 1436
TOO_LONG_BODY = 1437
WARN_CANT_DROP_DEFAULT_KEYCACHE = 1438
TOO_BIG_DISPLAYWIDTH = 1439
XAER_DUPID = 1440
DATETIME_FUNCTION_OVERFLOW = 1441
CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG = 1442
VIEW_PREVENT_UPDATE = 1443
PS_NO_RECURSION = 1444
SP_CANT_SET_AUTOCOMMIT = 1445
MALFORMED_DEFINER = 1446
VIEW_FRM_NO_USER = 1447
VIEW_OTHER_USER = 1448
NO_SUCH_USER = 1449
FORBID_SCHEMA_CHANGE = 1450
ROW_IS_REFERENCED_2 = 1451
NO_REFERENCED_ROW_2 = 1452
SP_BAD_VAR_SHADOW = 1453
TRG_NO_DEFINER = 1454
OLD_FILE_FORMAT = 1455
SP_RECURSION_LIMIT = 1456
SP_PROC_TABLE_CORRUPT = 1457
ERROR_LAST = 1457
================================================
FILE: dev_server/sae/_restful_mysql/constants/FIELD_TYPE.py
================================================
"""MySQL FIELD_TYPE Constants
These constants represent the various column (field) types that are
supported by MySQL.
"""
DECIMAL = 0
TINY = 1
SHORT = 2
LONG = 3
FLOAT = 4
DOUBLE = 5
NULL = 6
TIMESTAMP = 7
LONGLONG = 8
INT24 = 9
DATE = 10
TIME = 11
DATETIME = 12
YEAR = 13
NEWDATE = 14
VARCHAR = 15
BIT = 16
NEWDECIMAL = 246
ENUM = 247
SET = 248
TINY_BLOB = 249
MEDIUM_BLOB = 250
LONG_BLOB = 251
BLOB = 252
VAR_STRING = 253
STRING = 254
GEOMETRY = 255
CHAR = TINY
INTERVAL = ENUM
================================================
FILE: dev_server/sae/_restful_mysql/constants/FLAG.py
================================================
"""MySQL FLAG Constants
These flags are used along with the FIELD_TYPE to indicate various
properties of columns in a result set.
"""
NOT_NULL = 1
PRI_KEY = 2
UNIQUE_KEY = 4
MULTIPLE_KEY = 8
BLOB = 16
UNSIGNED = 32
ZEROFILL = 64
BINARY = 128
ENUM = 256
AUTO_INCREMENT = 512
TIMESTAMP = 1024
SET = 2048
NUM = 32768
PART_KEY = 16384
GROUP = 32768
UNIQUE = 65536
================================================
FILE: dev_server/sae/_restful_mysql/constants/REFRESH.py
================================================
"""MySQL REFRESH Constants
These constants seem to mostly deal with things internal to the
MySQL server. Forget you saw this.
"""
GRANT = 1
LOG = 2
TABLES = 4
HOSTS = 8
STATUS = 16
THREADS = 32
SLAVE = 64
MASTER = 128
READ_LOCK = 16384
FAST = 32768
================================================
FILE: dev_server/sae/_restful_mysql/constants/__init__.py
================================================
__all__ = ['CR', 'FIELD_TYPE','CLIENT','REFRESH','ER','FLAG']
================================================
FILE: dev_server/sae/_restful_mysql/converters.py
================================================
"""MySQLdb type conversion module
This module handles all the type conversions for MySQL. If the default
type conversions aren't what you need, you can make your own. The
dictionary conversions maps some kind of type to a conversion function
which returns the corresponding value:
Key: FIELD_TYPE.* (from MySQLdb.constants)
Conversion function:
Arguments: string
Returns: Python object
Key: Python type object (from types) or class
Conversion function:
Arguments: Python object of indicated type or class AND
conversion dictionary
Returns: SQL literal value
Notes: Most conversion functions can ignore the dictionary, but
it is a required parameter. It is necessary for converting
things like sequences and instances.
Don't modify conversions if you can avoid it. Instead, make copies
(with the copy() method), modify the copies, and then pass them to
MySQL.connect().
"""
from _mysql import string_literal, escape_sequence, escape_dict, escape, NULL
from constants import FIELD_TYPE, FLAG
from times import *
import types
import array
try:
set
except NameError:
from sets import Set as set
def Bool2Str(s, d): return str(int(s))
def Str2Set(s):
return set([ i for i in s.split(',') if i ])
def Set2Str(s, d):
return string_literal(','.join(s), d)
def Thing2Str(s, d):
"""Convert something into a string via str()."""
return str(s)
def Unicode2Str(s, d):
"""Convert a unicode object to a string using the default encoding.
This is only used as a placeholder for the real function, which
is connection-dependent."""
return s.encode()
Long2Int = Thing2Str
def Float2Str(o, d):
return '%.15g' % o
def None2NULL(o, d):
"""Convert None to NULL."""
return NULL # duh
def Thing2Literal(o, d):
"""Convert something into a SQL string literal. If using
MySQL-3.23 or newer, string_literal() is a method of the
_mysql.MYSQL object, and this function will be overridden with
that method when the connection is created."""
return string_literal(o, d)
def Instance2Str(o, d):
"""
Convert an Instance to a string representation. If the __str__()
method produces acceptable output, then you don't need to add the
class to conversions; it will be handled by the default
converter. If the exact class is not found in d, it will use the
first class it can find for which o is an instance.
"""
if d.has_key(o.__class__):
return d[o.__class__](o, d)
cl = filter(lambda x,o=o:
type(x) is types.ClassType
and isinstance(o, x), d.keys())
if not cl and hasattr(types, 'ObjectType'):
cl = filter(lambda x,o=o:
type(x) is types.TypeType
and isinstance(o, x)
and d[x] is not Instance2Str,
d.keys())
if not cl:
return d[types.StringType](o,d)
d[o.__class__] = d[cl[0]]
return d[cl[0]](o, d)
def char_array(s):
return array.array('c', s)
def array2Str(o, d):
return Thing2Literal(o.tostring(), d)
conversions = {
types.IntType: Thing2Str,
types.LongType: Long2Int,
types.FloatType: Float2Str,
types.NoneType: None2NULL,
types.TupleType: escape_sequence,
types.ListType: escape_sequence,
types.DictType: escape_dict,
types.InstanceType: Instance2Str,
array.ArrayType: array2Str,
types.StringType: Thing2Literal, # default
types.UnicodeType: Unicode2Str,
types.ObjectType: Instance2Str,
types.BooleanType: Bool2Str,
DateTimeType: DateTime2literal,
DateTimeDeltaType: DateTimeDelta2literal,
set: Set2Str,
FIELD_TYPE.TINY: int,
FIELD_TYPE.SHORT: int,
FIELD_TYPE.LONG: long,
FIELD_TYPE.FLOAT: float,
FIELD_TYPE.DOUBLE: float,
FIELD_TYPE.DECIMAL: float,
FIELD_TYPE.NEWDECIMAL: float,
FIELD_TYPE.LONGLONG: long,
FIELD_TYPE.INT24: int,
FIELD_TYPE.YEAR: int,
FIELD_TYPE.SET: Str2Set,
FIELD_TYPE.TIMESTAMP: mysql_timestamp_converter,
FIELD_TYPE.DATETIME: DateTime_or_None,
FIELD_TYPE.TIME: TimeDelta_or_None,
FIELD_TYPE.DATE: Date_or_None,
FIELD_TYPE.BLOB: [
(FLAG.BINARY, str),
],
FIELD_TYPE.STRING: [
(FLAG.BINARY, str),
],
FIELD_TYPE.VAR_STRING: [
(FLAG.BINARY, str),
],
FIELD_TYPE.VARCHAR: [
(FLAG.BINARY, str),
],
}
try:
from decimal import Decimal
conversions[FIELD_TYPE.DECIMAL] = Decimal
conversions[FIELD_TYPE.NEWDECIMAL] = Decimal
except ImportError:
pass
================================================
FILE: dev_server/sae/_restful_mysql/cursors.py
================================================
"""MySQLdb Cursors
This module implements Cursors of various types for MySQLdb. By
default, MySQLdb uses the Cursor class.
"""
import re
import sys
from types import ListType, TupleType, UnicodeType
restr = (r"\svalues\s*"
r"(\(((?<!\\)'[^\)]*?\)[^\)]*(?<!\\)?'"
r"|[^\(\)]|"
r"(?:\([^\)]*\))"
r")+\))")
insert_values= re.compile(restr)
from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \
DatabaseError, OperationalError, IntegrityError, InternalError, \
NotSupportedError, ProgrammingError
class BaseCursor(object):
"""A base for Cursor classes. Useful attributes:
description
A tuple of DB API 7-tuples describing the columns in
the last executed query; see PEP-249 for details.
description_flags
Tuple of column flags for last query, one entry per column
in the result set. Values correspond to those in
MySQLdb.constants.FLAG. See MySQL documentation (C API)
for more information. Non-standard extension.
arraysize
default number of rows fetchmany() will fetch
"""
from _mysql_exceptions import MySQLError, Warning, Error, InterfaceError, \
DatabaseError, DataError, OperationalError, IntegrityError, \
InternalError, ProgrammingError, NotSupportedError
_defer_warnings = False
def __init__(self, connection):
from weakref import proxy
self.connection = proxy(connection)
self.description = None
self.description_flags = None
self.rowcount = -1
self.arraysize = 1
self._executed = None
self.lastrowid = None
self.messages = []
self.errorhandler = connection.errorhandler
self._result = None
self._warnings = 0
self._info = None
self.rownumber = None
def __del__(self):
self.close()
self.errorhandler = None
self._result = None
def close(self):
"""Close the cursor. No further queries will be possible."""
if not self.connection: return
while self.nextset(): pass
self.connection = None
def _check_executed(self):
if not self._executed:
self.errorhandler(self, ProgrammingError, "execute() first")
def _warning_check(self):
from warnings import warn
if self._warnings:
warnings = self._get_db().show_warnings()
if warnings:
# This is done in two loops in case
# Warnings are set to raise exceptions.
for w in warnings:
self.messages.append((self.Warning, w))
for w in warnings:
warn(w[-1], self.Warning, 3)
elif self._info:
self.messages.append((self.Warning, self._info))
warn(self._info, self.Warning, 3)
def nextset(self):
"""Advance to the next result set.
Returns None if there are no more result sets.
"""
if self._executed:
self.fetchall()
del self.messages[:]
db = self._get_db()
nr = db.next_result()
if nr == -1:
return None
self._do_get_result()
self._post_get_result()
self._warning_check()
return 1
def _post_get_result(self): pass
def _do_get_result(self):
db = self._get_db()
self._result = self._get_result()
self.rowcount = db.affected_rows()
self.rownumber = 0
self.description = self._result and self._result.describe() or None
self.description_flags = self._result and self._result.field_flags() or None
self.lastrowid = db.insert_id()
self._warnings = db.warning_count()
self._info = db.info()
def setinputsizes(self, *args):
"""Does nothing, required by DB API."""
def setoutputsizes(self, *args):
"""Does nothing, required by DB API."""
def _get_db(self):
if not self.connection:
self.errorhandler(self, ProgrammingError, "cursor closed")
return self.connection
def execute(self, query, args=None):
"""Execute a query.
query -- string, query to execute on server
args -- optional sequence or mapping, parameters to use with query.
Note: If args is a sequence, then %s must be used as the
parameter placeholder in the query. If a mapping is used,
%(key)s must be used as the placeholder.
Returns long integer rows affected, if any
"""
del self.messages[:]
db = self._get_db()
charset = db.character_set_name()
if isinstance(query, unicode):
query = query.encode(charset)
if args is not None:
query = query % db.literal(args)
try:
r = self._query(query)
except TypeError, m:
if m.args[0] in ("not enough arguments for format string",
"not all arguments converted"):
self.messages.append((ProgrammingError, m.args[0]))
self.errorhandler(self, ProgrammingError, m.args[0])
else:
self.messages.append((TypeError, m))
self.errorhandler(self, TypeError, m)
except:
exc, value, tb = sys.exc_info()
del tb
self.messages.append((exc, value))
self.errorhandler(self, exc, value)
self._executed = query
if not self._defer_warnings: self._warning_check()
return r
def executemany(self, query, args):
"""Execute a multi-row query.
query -- string, query to execute on server
args
Sequence of sequences or mappings, parameters to use with
query.
Returns long integer rows affected, if any.
This method improves performance on multiple-row INSERT and
REPLACE. Otherwise it is equivalent to looping over args with
execute().
"""
del self.messages[:]
db = self._get_db()
if not args: return
charset = db.character_set_name()
if isinstance(query, unicode): query = query.encode(charset)
m = insert_values.search(query)
if not m:
r = 0
for a in args:
r = r + self.execute(query, a)
return r
p = m.start(1)
e = m.end(1)
qv = m.group(1)
try:
q = [ qv % db.literal(a) for a in args ]
except TypeError, msg:
if msg.args[0] in ("not enough arguments for format string",
"not all arguments converted"):
self.errorhandler(self, ProgrammingError, msg.args[0])
else:
self.errorhandler(self, TypeError, msg)
except:
exc, value, tb = sys.exc_info()
del tb
self.errorhandler(self, exc, value)
r = self._query('\n'.join([query[:p], ',\n'.join(q), query[e:]]))
if not self._defer_warnings: self._warning_check()
return r
def callproc(self, procname, args=()):
"""Execute stored procedure procname with args
procname -- string, name of procedure to execute on server
args -- Sequence of parameters to use with procedure
Returns the original args.
Compatibility warning: PEP-249 specifies that any modified
parameters must be returned. This is currently impossible
as they are only available by storing them in a server
variable and then retrieved by a query. Since stored
procedures return zero or more result sets, there is no
reliable way to get at OUT or INOUT parameters via callproc.
The server variables are named @_procname_n, where procname
is the parameter above and n is the position of the parameter
(from zero). Once all result sets generated by the procedure
have been fetched, you can issue a SELECT @_procname_0, ...
query using .execute() to get any OUT or INOUT values.
Compatibility warning: The act of calling a stored procedure
itself creates an empty result set. This appears after any
result sets generated by the procedure. This is non-standard
behavior with respect to the DB-API. Be sure to use nextset()
to advance through all result sets; otherwise you may get
disconnected.
"""
db = self._get_db()
charset = db.character_set_name()
for index, arg in enumerate(args):
q = "SET @_%s_%d=%s" % (procname, index,
db.literal(arg))
if isinstance(q, unicode):
q = q.encode(charset)
self._query(q)
self.nextset()
q = "CALL %s(%s)" % (procname,
','.join(['@_%s_%d' % (procname, i)
for i in range(len(args))]))
if type(q) is UnicodeType:
q = q.encode(charset)
self._query(q)
self._executed = q
if not self._defer_warnings: self._warning_check()
return args
def _do_query(self, q):
db = self._get_db()
self._last_executed = q
db.query(q)
self._do_get_result()
return self.rowcount
def _query(self, q): return self._do_query(q)
def _fetch_row(self, size=1):
if not self._result:
return ()
return self._result.fetch_row(size, self._fetch_type)
def __iter__(self):
return iter(self.fetchone, None)
Warning = Warning
Error = Error
InterfaceError = InterfaceError
DatabaseError = DatabaseError
DataError = DataError
OperationalError = OperationalError
IntegrityError = IntegrityError
InternalError = InternalError
ProgrammingError = ProgrammingError
NotSupportedError = NotSupportedError
class CursorStoreResultMixIn(object):
"""This is a MixIn class which causes the entire result set to be
stored on the client side, i.e. it uses mysql_store_result(). If the
result set can be very large, consider adding a LIMIT clause to your
query, or using CursorUseResultMixIn instead."""
def _get_result(self): return self._get_db().store_result()
def _query(self, q):
rowcount = self._do_query(q)
self._post_get_result()
return rowcount
def _post_get_result(self):
self._rows = self._fetch_row(0)
self._result = None
def fetchone(self):
"""Fetches a single row from the cursor. None indicates that
no more rows are available."""
self._check_executed()
if self.rownumber >= len(self._rows): return None
result = self._rows[self.rownumber]
self.rownumber = self.rownumber+1
return result
def fetchmany(self, size=None):
"""Fetch up to size rows from the cursor. Result set may be smaller
than size. If size is not defined, cursor.arraysize is used."""
self._check_executed()
end = self.rownumber + (size or self.arraysize)
result = self._rows[self.rownumber:end]
self.rownumber = min(end, len(self._rows))
return result
def fetchall(self):
"""Fetchs all available rows from the cursor."""
self._check_executed()
if self.rownumber:
result = self._rows[self.rownumber:]
else:
result = self._rows
self.rownumber = len(self._rows)
return result
def scroll(self, value, mode='relative'):
"""Scroll the cursor in the result set to a new position according
to mode.
If mode is 'relative' (default), value is taken as offset to
the current position in the result set, if set to 'absolute',
value states an absolute target position."""
self._check_executed()
if mode == 'relative':
r = self.rownumber + value
elif mode == 'absolute':
r = value
else:
self.errorhandler(self, ProgrammingError,
"unknown scroll mode %s" % `mode`)
if r < 0 or r >= len(self._rows):
self.errorhandler(self, IndexError, "out of range")
self.rownumber = r
def __iter__(self):
self._check_executed()
result = self.rownumber and self._rows[self.rownumber:] or self._rows
return iter(result)
class CursorUseResultMixIn(object):
"""This is a MixIn class which causes the result set to be stored
in the server and sent row-by-row to client side, i.e. it uses
mysql_use_result(). You MUST retrieve the entire result set and
close() the cursor before additional queries can be peformed on
the connection."""
_defer_warnings = True
def _get_result(self): return self._get_db().use_result()
def fetchone(self):
"""Fetches a single row from the cursor."""
self._check_executed()
r = self._fetch_row(1)
if not r:
self._warning_check()
return None
self.rownumber = self.rownumber + 1
return r[0]
def fetchmany(self, size=None):
"""Fetch up to size rows from the cursor. Result set may be smaller
than size. If size is not defined, cursor.arraysize is used."""
self._check_executed()
r = self._fetch_row(size or self.arraysize)
self.rownumber = self.rownumber + len(r)
if not r:
self._warning_check()
return r
def fetchall(self):
"""Fetchs all available rows from the cursor."""
self._check_executed()
r = self._fetch_row(0)
self.rownumber = self.rownumber + len(r)
self._warning_check()
return r
def __iter__(self):
return self
def next(self):
row = self.fetchone()
if row is None:
raise StopIteration
return row
class CursorTupleRowsMixIn(object):
"""This is a MixIn class that causes all rows to be returned as tuples,
which is the standard form required by DB API."""
_fetch_type = 0
class CursorDictRowsMixIn(object):
"""This is a MixIn class that causes all rows to be returned as
dictionaries. This is a non-standard feature."""
_fetch_type = 1
def fetchoneDict(self):
"""Fetch a single row as a dictionary. Deprecated:
Use fetchone() instead. Will be removed in 1.3."""
from warnings import warn
warn("fetchoneDict() is non-standard and will be removed in 1.3",
DeprecationWarning, 2)
return self.fetchone()
def fetchmanyDict(self, size=None):
"""Fetch several rows as a list of dictionaries. Deprecated:
Use fetchmany() instead. Will be removed in 1.3."""
from warnings import warn
warn("fetchmanyDict() is non-standard and will be removed in 1.3",
DeprecationWarning, 2)
return self.fetchmany(size)
def fetchallDict(self):
"""Fetch all available rows as a list of dictionaries. Deprecated:
Use fetchall() instead. Will be removed in 1.3."""
from warnings import warn
warn("fetchallDict() is non-standard and will be removed in 1.3",
DeprecationWarning, 2)
return self.fetchall()
class CursorOldDictRowsMixIn(CursorDictRowsMixIn):
"""This is a MixIn class that returns rows as dictionaries with
the same key convention as the old Mysqldb (MySQLmodule). Don't
use this."""
_fetch_type = 2
class Cursor(CursorStoreResultMixIn, CursorTupleRowsMixIn,
BaseCursor):
"""This is the standard Cursor class that returns rows as tuples
and stores the result set in the client."""
class DictCursor(CursorStoreResultMixIn, CursorDictRowsMixIn,
BaseCursor):
"""This is a Cursor class that returns rows as dictionaries and
stores the result set in the client."""
class SSCursor(CursorUseResultMixIn, CursorTupleRowsMixIn,
BaseCursor):
"""This is a Cursor class that returns rows as tuples and stores
the result set in the server."""
class SSDictCursor(CursorUseResultMixIn, CursorDictRowsMixIn,
BaseCursor):
"""This is a Cursor class that returns rows as dictionaries and
stores the result set in the server."""
================================================
FILE: dev_server/sae/_restful_mysql/monkey.py
================================================
# Copyright (C) 2012-2013 SINA, All rights reserved.
def patch():
import sys
if 'MySQLdb' in sys.modules:
import warnings
warnings.warn('MySQLdb has alreay been imported', Warning)
modules_to_replace = (
'MySQLdb',
'MySQLdb.release',
'MySQLdb.connections',
'MySQLdb.cursors',
'MySQLdb.converters',
'MySQLdb.constants',
'MySQLdb.constants.CLIENT',
'MySQLdb.constants.FIELD_TYPE',
'MySQLdb.constants.FLAG',
)
for name in modules_to_replace:
if name in sys.modules:
sys.modules.pop(name)
import sae._restful_mysql
from sae._restful_mysql import _mysql, _mysql_exceptions
sys.modules['MySQLdb'] = sae._restful_mysql
sys.modules['_mysql'] = _mysql
sys.modules['_mysql_exceptions'] = _mysql_exceptions
================================================
FILE: dev_server/sae/_restful_mysql/release.py
================================================
__author__ = "Andy Dustman <adustman@users.sourceforge.net>"
version_info = (1,2,3,'final',0)
__version__ = "1.2.3"
================================================
FILE: dev_server/sae/_restful_mysql/times.py
================================================
"""times module
This module provides some Date and Time classes for dealing with MySQL data.
Use Python datetime module to handle date and time columns."""
import math
from time import localtime
from datetime import date, datetime, time, timedelta
from _mysql import string_literal
Date = date
Time = time
TimeDelta = timedelta
Timestamp = datetime
DateTimeDeltaType = timedelta
DateTimeType = datetime
def DateFromTicks(ticks):
"""Convert UNIX ticks into a date instance."""
return date(*localtime(ticks)[:3])
def TimeFromTicks(ticks):
"""Convert UNIX ticks into a time instance."""
return time(*localtime(ticks)[3:6])
def TimestampFromTicks(ticks):
"""Convert UNIX ticks into a datetime instance."""
return datetime(*localtime(ticks)[:6])
format_TIME = format_DATE = str
def format_TIMEDELTA(v):
seconds = int(v.seconds) % 60
minutes = int(v.seconds / 60) % 60
hours = int(v.seconds / 3600) % 24
return '%d %d:%d:%d' % (v.days, hours, minutes, seconds)
def format_TIMESTAMP(d):
return d.strftime("%Y-%m-%d %H:%M:%S")
def DateTime_or_None(s):
if ' ' in s:
sep = ' '
elif 'T' in s:
sep = 'T'
else:
return Date_or_None(s)
try:
d, t = s.split(sep, 1)
return datetime(*[ int(x) for x in d.split('-')+t.split(':') ])
except:
return Date_or_None(s)
def TimeDelta_or_None(s):
try:
h, m, s = s.split(':')
h, m, s = int(h), int(m), float(s)
td = timedelta(hours=abs(h), minutes=m, seconds=int(s),
microseconds=int(math.modf(s)[0] * 1000000))
if h < 0:
return -td
else:
return td
except ValueError:
# unpacking or int/float conversion failed
return None
def Time_or_None(s):
try:
h, m, s = s.split(':')
h, m, s = int(h), int(m), float(s)
return time(hour=h, minute=m, second=int(s),
microsecond=int(math.modf(s)[0] * 1000000))
except ValueError:
return None
def Date_or_None(s):
try: return date(*[ int(x) for x in s.split('-',2)])
except: return None
def DateTime2literal(d, c):
"""Format a DateTime object as an ISO timestamp."""
return string_literal(format_TIMESTAMP(d),c)
def DateTimeDelta2literal(d, c):
"""Format a DateTimeDelta object as a time."""
return string_literal(format_TIMEDELTA(d),c)
def mysql_timestamp_converter(s):
"""Convert a MySQL TIMESTAMP to a Timestamp object."""
# MySQL>4.1 returns TIMESTAMP in the same format as DATETIME
if s[4] == '-': return DateTime_or_None(s)
s = s + "0"*(14-len(s)) # padding
parts = map(int, filter(None, (s[:4],s[4:6],s[6:8],
s[8:10],s[10:12],s[12:14])))
try: return Timestamp(*parts)
except: return None
================================================
FILE: dev_server/sae/channel.js
================================================
(function(){var COMPILED=!0,goog=goog||{};goog.global=this;goog.exportPath_=function(a,b,c){a=a.split(".");c=c||goog.global;a[0]in c||!c.execScript||c.execScript("var "+a[0]);for(var d;a.length&&(d=a.shift());)a.length||void 0===b?c=c[d]?c[d]:c[d]={}:c[d]=b};goog.define=function(a,b){var c=b;COMPILED||goog.global.CLOSURE_DEFINES&&Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES,a)&&(c=goog.global.CLOSURE_DEFINES[a]);goog.exportPath_(a,c)};goog.DEBUG=!0;goog.LOCALE="en";goog.TRUSTED_SITE=!0;
goog.provide=function(a){if(!COMPILED){if(goog.isProvided_(a))throw Error('Namespace "'+a+'" already declared.');delete goog.implicitNamespaces_[a];for(var b=a;(b=b.substring(0,b.lastIndexOf(".")))&&!goog.getObjectByName(b);)goog.implicitNamespaces_[b]=!0}goog.exportPath_(a)};goog.setTestOnly=function(a){if(COMPILED&&!goog.DEBUG)throw a=a||"",Error("Importing test-only code into non-debug environment"+a?": "+a:".");};
COMPILED||(goog.isProvided_=function(a){return!goog.implicitNamespaces_[a]&&!!goog.getObjectByName(a)},goog.implicitNamespaces_={});goog.getObjectByName=function(a,b){for(var c=a.split("."),d=b||goog.global,e;e=c.shift();)if(goog.isDefAndNotNull(d[e]))d=d[e];else return null;return d};goog.globalize=function(a,b){var c=b||goog.global,d;for(d in a)c[d]=a[d]};
goog.addDependency=function(a,b,c){if(goog.DEPENDENCIES_ENABLED){var d;a=a.replace(/\\/g,"/");for(var e=goog.dependencies_,f=0;d=b[f];f++)e.nameToPath[d]=a,a in e.pathToNames||(e.pathToNames[a]={}),e.pathToNames[a][d]=!0;for(d=0;b=c[d];d++)a in e.requires||(e.requires[a]={}),e.requires[a][b]=!0}};goog.ENABLE_DEBUG_LOADER=!0;
goog.require=function(a){if(!COMPILED&&!goog.isProvided_(a)){if(goog.ENABLE_DEBUG_LOADER){var b=goog.getPathFromDeps_(a);if(b){goog.included_[b]=!0;goog.writeScripts_();return}}a="goog.require could not find: "+a;goog.global.console&&goog.global.console.error(a);throw Error(a);}};goog.basePath="";goog.nullFunction=function(){};goog.identityFunction=function(a,b){return a};goog.abstractMethod=function(){throw Error("unimplemented abstract method");};
goog.addSingletonGetter=function(a){a.getInstance=function(){if(a.instance_)return a.instance_;goog.DEBUG&&(goog.instantiatedSingletons_[goog.instantiatedSingletons_.length]=a);return a.instance_=new a}};goog.instantiatedSingletons_=[];goog.DEPENDENCIES_ENABLED=!COMPILED&&goog.ENABLE_DEBUG_LOADER;
goog.DEPENDENCIES_ENABLED&&(goog.included_={},goog.dependencies_={pathToNames:{},nameToPath:{},requires:{},visited:{},written:{}},goog.inHtmlDocument_=function(){var a=goog.global.document;return"undefined"!=typeof a&&"write"in a},goog.findBasePath_=function(){if(goog.global.CLOSURE_BASE_PATH)goog.basePath=goog.global.CLOSURE_BASE_PATH;else if(goog.inHtmlDocument_())for(var a=goog.global.document.getElementsByTagName("script"),b=a.length-1;0<=b;--b){var c=a[b].src,d=c.lastIndexOf("?"),d=-1==d?c.length:
d;if("base.js"==c.substr(d-7,7)){goog.basePath=c.substr(0,d-7);break}}},goog.importScript_=function(a){var b=goog.global.CLOSURE_IMPORT_SCRIPT||goog.writeScriptTag_;!goog.dependencies_.written[a]&&b(a)&&(goog.dependencies_.written[a]=!0)},goog.writeScriptTag_=function(a){if(goog.inHtmlDocument_()){var b=goog.global.document;if("complete"==b.readyState){if(/\bdeps.js$/.test(a))return!1;throw Error('Cannot write "'+a+'" after document load');}b.write('<script type="text/javascript" src="'+a+'">\x3c/script>');
return!0}return!1},goog.writeScripts_=function(){function a(e){if(!(e in d.written)){if(!(e in d.visited)&&(d.visited[e]=!0,e in d.requires))for(var g in d.requires[e])if(!goog.isProvided_(g))if(g in d.nameToPath)a(d.nameToPath[g]);else throw Error("Undefined nameToPath for "+g);e in c||(c[e]=!0,b.push(e))}}var b=[],c={},d=goog.dependencies_,e;for(e in goog.included_)d.written[e]||a(e);for(e=0;e<b.length;e++)if(b[e])goog.importScript_(goog.basePath+b[e]);else throw Error("Undefined script input");
},goog.getPathFromDeps_=function(a){return a in goog.dependencies_.nameToPath?goog.dependencies_.nameToPath[a]:null},goog.findBasePath_(),goog.global.CLOSURE_NO_DEPS||goog.importScript_(goog.basePath+"deps.js"));
goog.typeOf=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
else if("function"==b&&"undefined"==typeof a.call)return"object";return b};goog.isDef=function(a){return void 0!==a};goog.isNull=function(a){return null===a};goog.isDefAndNotNull=function(a){return null!=a};goog.isArray=function(a){return"array"==goog.typeOf(a)};goog.isArrayLike=function(a){var b=goog.typeOf(a);return"array"==b||"object"==b&&"number"==typeof a.length};goog.isDateLike=function(a){return goog.isObject(a)&&"function"==typeof a.getFullYear};goog.isString=function(a){return"string"==typeof a};
goog.isBoolean=function(a){return"boolean"==typeof a};goog.isNumber=function(a){return"number"==typeof a};goog.isFunction=function(a){return"function"==goog.typeOf(a)};goog.isObject=function(a){var b=typeof a;return"object"==b&&null!=a||"function"==b};goog.getUid=function(a){return a[goog.UID_PROPERTY_]||(a[goog.UID_PROPERTY_]=++goog.uidCounter_)};goog.hasUid=function(a){return!!a[goog.UID_PROPERTY_]};goog.removeUid=function(a){"removeAttribute"in a&&a.removeAttribute(goog.UID_PROPERTY_);try{delete a[goog.UID_PROPERTY_]}catch(b){}};
goog.UID_PROPERTY_="closure_uid_"+(1E9*Math.random()>>>0);goog.uidCounter_=0;goog.getHashCode=goog.getUid;goog.removeHashCode=goog.removeUid;goog.cloneObject=function(a){var b=goog.typeOf(a);if("object"==b||"array"==b){if(a.clone)return a.clone();var b="array"==b?[]:{},c;for(c in a)b[c]=goog.cloneObject(a[c]);return b}return a};goog.bindNative_=function(a,b,c){return a.call.apply(a.bind,arguments)};
goog.bindJs_=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}};goog.bind=function(a,b,c){Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?goog.bind=goog.bindNative_:goog.bind=goog.bindJs_;return goog.bind.apply(null,arguments)};
goog.partial=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=c.slice();b.push.apply(b,arguments);return a.apply(this,b)}};goog.mixin=function(a,b){for(var c in b)a[c]=b[c]};goog.now=goog.TRUSTED_SITE&&Date.now||function(){return+new Date};
goog.globalEval=function(a){if(goog.global.execScript)goog.global.execScript(a,"JavaScript");else if(goog.global.eval)if(null==goog.evalWorksForGlobals_&&(goog.global.eval("var _et_ = 1;"),"undefined"!=typeof goog.global._et_?(delete goog.global._et_,goog.evalWorksForGlobals_=!0):goog.evalWorksForGlobals_=!1),goog.evalWorksForGlobals_)goog.global.eval(a);else{var b=goog.global.document,c=b.createElement("script");c.type="text/javascript";c.defer=!1;c.appendChild(b.createTextNode(a));b.body.appendChild(c);
b.body.removeChild(c)}else throw Error("goog.globalEval not available");};goog.evalWorksForGlobals_=null;goog.getCssName=function(a,b){var c=function(a){return goog.cssNameMapping_[a]||a},d=function(a){a=a.split("-");for(var b=[],d=0;d<a.length;d++)b.push(c(a[d]));return b.join("-")},d=goog.cssNameMapping_?"BY_WHOLE"==goog.cssNameMappingStyle_?c:d:function(a){return a};return b?a+"-"+d(b):d(a)};goog.setCssNameMapping=function(a,b){goog.cssNameMapping_=a;goog.cssNameMappingStyle_=b};
!COMPILED&&goog.global.CLOSURE_CSS_NAME_MAPPING&&(goog.cssNameMapping_=goog.global.CLOSURE_CSS_NAME_MAPPING);goog.getMsg=function(a,b){var c=b||{},d;for(d in c){var e=(""+c[d]).replace(/\$/g,"$$$$");a=a.replace(RegExp("\\{\\$"+d+"\\}","gi"),e)}return a};goog.getMsgWithFallback=function(a,b){return a};goog.exportSymbol=function(a,b,c){goog.exportPath_(a,b,c)};goog.exportProperty=function(a,b,c){a[b]=c};
goog.inherits=function(a,b){function c(){}c.prototype=b.prototype;a.superClass_=b.prototype;a.prototype=new c;a.prototype.constructor=a};
goog.base=function(a,b,c){var d=arguments.callee.caller;if(goog.DEBUG&&!d)throw Error("arguments.caller not defined. goog.base() expects not to be running in strict mode. See http://www.ecma-international.org/ecma-262/5.1/#sec-C");if(d.superClass_)return d.superClass_.constructor.apply(a,Array.prototype.slice.call(arguments,1));for(var e=Array.prototype.slice.call(arguments,2),f=!1,g=a.constructor;g;g=g.superClass_&&g.superClass_.constructor)if(g.prototype[b]===d)f=!0;else if(f)return g.prototype[b].apply(a,
e);if(a[b]===d)return a.constructor.prototype[b].apply(a,e);throw Error("goog.base called from a method of one name to a method of a different name");};goog.scope=function(a){a.call(goog.global)};goog.debug={};goog.debug.Error=function(a){Error.captureStackTrace?Error.captureStackTrace(this,goog.debug.Error):this.stack=Error().stack||"";a&&(this.message=String(a))};goog.inherits(goog.debug.Error,Error);goog.debug.Error.prototype.name="CustomError";goog.dom={};goog.dom.NodeType={ELEMENT:1,ATTRIBUTE:2,TEXT:3,CDATA_SECTION:4,ENTITY_REFERENCE:5,ENTITY:6,PROCESSING_INSTRUCTION:7,COMMENT:8,DOCUMENT:9,DOCUMENT_TYPE:10,DOCUMENT_FRAGMENT:11,NOTATION:12};goog.string={};goog.string.Unicode={NBSP:"\u00a0"};goog.string.startsWith=function(a,b){return 0==a.lastIndexOf(b,0)};goog.string.endsWith=function(a,b){var c=a.length-b.length;return 0<=c&&a.indexOf(b,c)==c};goog.string.caseInsensitiveStartsWith=function(a,b){return 0==goog.string.caseInsensitiveCompare(b,a.substr(0,b.length))};goog.string.caseInsensitiveEndsWith=function(a,b){return 0==goog.string.caseInsensitiveCompare(b,a.substr(a.length-b.length,b.length))};
goog.string.caseInsensitiveEquals=function(a,b){return a.toLowerCase()==b.toLowerCase()};goog.string.subs=function(a,b){for(var c=a.split("%s"),d="",e=Array.prototype.slice.call(arguments,1);e.length&&1<c.length;)d+=c.shift()+e.shift();return d+c.join("%s")};goog.string.collapseWhitespace=function(a){return a.replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")};goog.string.isEmpty=function(a){return/^[\s\xa0]*$/.test(a)};goog.string.isEmptySafe=function(a){return goog.string.isEmpty(goog.string.makeSafe(a))};
goog.string.isBreakingWhitespace=function(a){return!/[^\t\n\r ]/.test(a)};goog.string.isAlpha=function(a){return!/[^a-zA-Z]/.test(a)};goog.string.isNumeric=function(a){return!/[^0-9]/.test(a)};goog.string.isAlphaNumeric=function(a){return!/[^a-zA-Z0-9]/.test(a)};goog.string.isSpace=function(a){return" "==a};goog.string.isUnicodeChar=function(a){return 1==a.length&&" "<=a&&"~">=a||"\u0080"<=a&&"\ufffd">=a};goog.string.stripNewlines=function(a){return a.replace(/(\r\n|\r|\n)+/g," ")};
goog.string.canonicalizeNewlines=function(a){return a.replace(/(\r\n|\r|\n)/g,"\n")};goog.string.normalizeWhitespace=function(a){return a.replace(/\xa0|\s/g," ")};goog.string.normalizeSpaces=function(a){return a.replace(/\xa0|[ \t]+/g," ")};goog.string.collapseBreakingSpaces=function(a){return a.replace(/[\t\r\n ]+/g," ").replace(/^[\t\r\n ]+|[\t\r\n ]+$/g,"")};goog.string.trim=function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")};
goog.string.trimLeft=function(a){return a.replace(/^[\s\xa0]+/,"")};goog.string.trimRight=function(a){return a.replace(/[\s\xa0]+$/,"")};goog.string.caseInsensitiveCompare=function(a,b){var c=String(a).toLowerCase(),d=String(b).toLowerCase();return c<d?-1:c==d?0:1};goog.string.numerateCompareRegExp_=/(\.\d+)|(\d+)|(\D+)/g;
goog.string.numerateCompare=function(a,b){if(a==b)return 0;if(!a)return-1;if(!b)return 1;for(var c=a.toLowerCase().match(goog.string.numerateCompareRegExp_),d=b.toLowerCase().match(goog.string.numerateCompareRegExp_),e=Math.min(c.length,d.length),f=0;f<e;f++){var g=c[f],h=d[f];if(g!=h)return c=parseInt(g,10),!isNaN(c)&&(d=parseInt(h,10),!isNaN(d)&&c-d)?c-d:g<h?-1:1}return c.length!=d.length?c.length-d.length:a<b?-1:1};goog.string.urlEncode=function(a){return encodeURIComponent(String(a))};
goog.string.urlDecode=function(a){return decodeURIComponent(a.replace(/\+/g," "))};goog.string.newLineToBr=function(a,b){return a.replace(/(\r\n|\r|\n)/g,b?"<br />":"<br>")};
goog.string.htmlEscape=function(a,b){if(b)return a.replace(goog.string.amperRe_,"&").replace(goog.string.ltRe_,"<").replace(goog.string.gtRe_,">").replace(goog.string.quotRe_,""");if(!goog.string.allRe_.test(a))return a;-1!=a.indexOf("&")&&(a=a.replace(goog.string.amperRe_,"&"));-1!=a.indexOf("<")&&(a=a.replace(goog.string.ltRe_,"<"));-1!=a.indexOf(">")&&(a=a.replace(goog.string.gtRe_,">"));-1!=a.indexOf('"')&&(a=a.replace(goog.string.quotRe_,"""));return a};
goog.string.amperRe_=/&/g;goog.string.ltRe_=/</g;goog.string.gtRe_=/>/g;goog.string.quotRe_=/\"/g;goog.string.allRe_=/[&<>\"]/;goog.string.unescapeEntities=function(a){return goog.string.contains(a,"&")?"document"in goog.global?goog.string.unescapeEntitiesUsingDom_(a):goog.string.unescapePureXmlEntities_(a):a};
goog.string.unescapeEntitiesUsingDom_=function(a){var b={"&":"&","<":"<",">":">",""":'"'},c=document.createElement("div");return a.replace(goog.string.HTML_ENTITY_PATTERN_,function(a,e){var f=b[a];if(f)return f;if("#"==e.charAt(0)){var g=Number("0"+e.substr(1));isNaN(g)||(f=String.fromCharCode(g))}f||(c.innerHTML=a+" ",f=c.firstChild.nodeValue.slice(0,-1));return b[a]=f})};
goog.string.unescapePureXmlEntities_=function(a){return a.replace(/&([^;]+);/g,function(a,c){switch(c){case "amp":return"&";case "lt":return"<";case "gt":return">";case "quot":return'"';default:if("#"==c.charAt(0)){var d=Number("0"+c.substr(1));if(!isNaN(d))return String.fromCharCode(d)}return a}})};goog.string.HTML_ENTITY_PATTERN_=/&([^;\s<&]+);?/g;goog.string.whitespaceEscape=function(a,b){return goog.string.newLineToBr(a.replace(/ /g,"  "),b)};
goog.string.stripQuotes=function(a,b){for(var c=b.length,d=0;d<c;d++){var e=1==c?b:b.charAt(d);if(a.charAt(0)==e&&a.charAt(a.length-1)==e)return a.substring(1,a.length-1)}return a};goog.string.truncate=function(a,b,c){c&&(a=goog.string.unescapeEntities(a));a.length>b&&(a=a.substring(0,b-3)+"...");c&&(a=goog.string.htmlEscape(a));return a};
goog.string.truncateMiddle=function(a,b,c,d){c&&(a=goog.string.unescapeEntities(a));if(d&&a.length>b){d>b&&(d=b);var e=a.length-d;a=a.substring(0,b-d)+"..."+a.substring(e)}else a.length>b&&(d=Math.floor(b/2),e=a.length-d,a=a.substring(0,d+b%2)+"..."+a.substring(e));c&&(a=goog.string.htmlEscape(a));return a};goog.string.specialEscapeChars_={"\x00":"\\0","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\x0B":"\\x0B",'"':'\\"',"\\":"\\\\"};goog.string.jsEscapeCache_={"'":"\\'"};
goog.string.quote=function(a){a=String(a);if(a.quote)return a.quote();for(var b=['"'],c=0;c<a.length;c++){var d=a.charAt(c),e=d.charCodeAt(0);b[c+1]=goog.string.specialEscapeChars_[d]||(31<e&&127>e?d:goog.string.escapeChar(d))}b.push('"');return b.join("")};goog.string.escapeString=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=goog.string.escapeChar(a.charAt(c));return b.join("")};
goog.string.escapeChar=function(a){if(a in goog.string.jsEscapeCache_)return goog.string.jsEscapeCache_[a];if(a in goog.string.specialEscapeChars_)return goog.string.jsEscapeCache_[a]=goog.string.specialEscapeChars_[a];var b=a,c=a.charCodeAt(0);if(31<c&&127>c)b=a;else{if(256>c){if(b="\\x",16>c||256<c)b+="0"}else b="\\u",4096>c&&(b+="0");b+=c.toString(16).toUpperCase()}return goog.string.jsEscapeCache_[a]=b};goog.string.toMap=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=!0;return b};
goog.string.contains=function(a,b){return-1!=a.indexOf(b)};goog.string.countOf=function(a,b){return a&&b?a.split(b).length-1:0};goog.string.removeAt=function(a,b,c){var d=a;0<=b&&b<a.length&&0<c&&(d=a.substr(0,b)+a.substr(b+c,a.length-b-c));return d};goog.string.remove=function(a,b){var c=RegExp(goog.string.regExpEscape(b),"");return a.replace(c,"")};goog.string.removeAll=function(a,b){var c=RegExp(goog.string.regExpEscape(b),"g");return a.replace(c,"")};
goog.string.regExpEscape=function(a){return String(a).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g,"\\$1").replace(/\x08/g,"\\x08")};goog.string.repeat=function(a,b){return Array(b+1).join(a)};goog.string.padNumber=function(a,b,c){a=goog.isDef(c)?a.toFixed(c):String(a);c=a.indexOf(".");-1==c&&(c=a.length);return goog.string.repeat("0",Math.max(0,b-c))+a};goog.string.makeSafe=function(a){return null==a?"":String(a)};goog.string.buildString=function(a){return Array.prototype.join.call(arguments,"")};
goog.string.getRandomString=function(){return Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^goog.now()).toString(36)};
goog.string.compareVersions=function(a,b){for(var c=0,d=goog.string.trim(String(a)).split("."),e=goog.string.trim(String(b)).split("."),f=Math.max(d.length,e.length),g=0;0==c&&g<f;g++){var h=d[g]||"",k=e[g]||"",l=RegExp("(\\d*)(\\D*)","g"),p=RegExp("(\\d*)(\\D*)","g");do{var m=l.exec(h)||["","",""],n=p.exec(k)||["","",""];if(0==m[0].length&&0==n[0].length)break;var c=0==m[1].length?0:parseInt(m[1],10),q=0==n[1].length?0:parseInt(n[1],10),c=goog.string.compareElements_(c,q)||goog.string.compareElements_(0==
m[2].length,0==n[2].length)||goog.string.compareElements_(m[2],n[2])}while(0==c)}return c};goog.string.compareElements_=function(a,b){return a<b?-1:a>b?1:0};goog.string.HASHCODE_MAX_=4294967296;goog.string.hashCode=function(a){for(var b=0,c=0;c<a.length;++c)b=31*b+a.charCodeAt(c),b%=goog.string.HASHCODE_MAX_;return b};goog.string.uniqueStringCounter_=2147483648*Math.random()|0;goog.string.createUniqueString=function(){return"goog_"+goog.string.uniqueStringCounter_++};
goog.string.toNumber=function(a){var b=Number(a);return 0==b&&goog.string.isEmpty(a)?NaN:b};goog.string.isLowerCamelCase=function(a){return/^[a-z]+([A-Z][a-z]*)*$/.test(a)};goog.string.isUpperCamelCase=function(a){return/^([A-Z][a-z]*)+$/.test(a)};goog.string.toCamelCase=function(a){return String(a).replace(/\-([a-z])/g,function(a,c){return c.toUpperCase()})};goog.string.toSelectorCase=function(a){return String(a).replace(/([A-Z])/g,"-$1").toLowerCase()};
goog.string.toTitleCase=function(a,b){var c=goog.isString(b)?goog.string.regExpEscape(b):"\\s";return a.replace(RegExp("(^"+(c?"|["+c+"]+":"")+")([a-z])","g"),function(a,b,c){return b+c.toUpperCase()})};goog.string.parseInt=function(a){isFinite(a)&&(a=String(a));return goog.isString(a)?/^\s*-?0x/i.test(a)?parseInt(a,16):parseInt(a,10):NaN};goog.string.splitLimit=function(a,b,c){a=a.split(b);for(var d=[];0<c&&a.length;)d.push(a.shift()),c--;a.length&&d.push(a.join(b));return d};goog.asserts={};goog.asserts.ENABLE_ASSERTS=goog.DEBUG;goog.asserts.AssertionError=function(a,b){b.unshift(a);goog.debug.Error.call(this,goog.string.subs.apply(null,b));b.shift();this.messagePattern=a};goog.inherits(goog.asserts.AssertionError,goog.debug.Error);goog.asserts.AssertionError.prototype.name="AssertionError";goog.asserts.doAssertFailure_=function(a,b,c,d){var e="Assertion failed";if(c)var e=e+(": "+c),f=d;else a&&(e+=": "+a,f=b);throw new goog.asserts.AssertionError(""+e,f||[]);};
goog.asserts.assert=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!a&&goog.asserts.doAssertFailure_("",null,b,Array.prototype.slice.call(arguments,2));return a};goog.asserts.fail=function(a,b){if(goog.asserts.ENABLE_ASSERTS)throw new goog.asserts.AssertionError("Failure"+(a?": "+a:""),Array.prototype.slice.call(arguments,1));};
goog.asserts.assertNumber=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isNumber(a)&&goog.asserts.doAssertFailure_("Expected number but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};goog.asserts.assertString=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isString(a)&&goog.asserts.doAssertFailure_("Expected string but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};
goog.asserts.assertFunction=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isFunction(a)&&goog.asserts.doAssertFailure_("Expected function but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};goog.asserts.assertObject=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isObject(a)&&goog.asserts.doAssertFailure_("Expected object but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};
goog.asserts.assertArray=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isArray(a)&&goog.asserts.doAssertFailure_("Expected array but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};goog.asserts.assertBoolean=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isBoolean(a)&&goog.asserts.doAssertFailure_("Expected boolean but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};
goog.asserts.assertElement=function(a,b,c){!goog.asserts.ENABLE_ASSERTS||goog.isObject(a)&&a.nodeType==goog.dom.NodeType.ELEMENT||goog.asserts.doAssertFailure_("Expected Element but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};goog.asserts.assertInstanceof=function(a,b,c,d){!goog.asserts.ENABLE_ASSERTS||a instanceof b||goog.asserts.doAssertFailure_("instanceof check failed.",null,c,Array.prototype.slice.call(arguments,3));return a};
goog.asserts.assertObjectPrototypeIsIntact=function(){for(var a in Object.prototype)goog.asserts.fail(a+" should not be enumerable in Object.prototype.")};goog.array={};goog.NATIVE_ARRAY_PROTOTYPES=goog.TRUSTED_SITE;goog.array.peek=function(a){return a[a.length-1]};goog.array.ARRAY_PROTOTYPE_=Array.prototype;
goog.array.indexOf=goog.NATIVE_ARRAY_PROTOTYPES&&goog.array.ARRAY_PROTOTYPE_.indexOf?function(a,b,c){goog.asserts.assert(null!=a.length);return goog.array.ARRAY_PROTOTYPE_.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(goog.isString(a))return goog.isString(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1};
goog.array.lastIndexOf=goog.NATIVE_ARRAY_PROTOTYPES&&goog.array.ARRAY_PROTOTYPE_.lastIndexOf?function(a,b,c){goog.asserts.assert(null!=a.length);return goog.array.ARRAY_PROTOTYPE_.lastIndexOf.call(a,b,null==c?a.length-1:c)}:function(a,b,c){c=null==c?a.length-1:c;0>c&&(c=Math.max(0,a.length+c));if(goog.isString(a))return goog.isString(b)&&1==b.length?a.lastIndexOf(b,c):-1;for(;0<=c;c--)if(c in a&&a[c]===b)return c;return-1};
goog.array.forEach=goog.NATIVE_ARRAY_PROTOTYPES&&goog.array.ARRAY_PROTOTYPE_.forEach?function(a,b,c){goog.asserts.assert(null!=a.length);goog.array.ARRAY_PROTOTYPE_.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)};goog.array.forEachRight=function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,d=d-1;0<=d;--d)d in e&&b.call(c,e[d],d,a)};
goog.array.filter=goog.NATIVE_ARRAY_PROTOTYPES&&goog.array.ARRAY_PROTOTYPE_.filter?function(a,b,c){goog.asserts.assert(null!=a.length);return goog.array.ARRAY_PROTOTYPE_.filter.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=[],f=0,g=goog.isString(a)?a.split(""):a,h=0;h<d;h++)if(h in g){var k=g[h];b.call(c,k,h,a)&&(e[f++]=k)}return e};
goog.array.map=goog.NATIVE_ARRAY_PROTOTYPES&&goog.array.ARRAY_PROTOTYPE_.map?function(a,b,c){goog.asserts.assert(null!=a.length);return goog.array.ARRAY_PROTOTYPE_.map.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=Array(d),f=goog.isString(a)?a.split(""):a,g=0;g<d;g++)g in f&&(e[g]=b.call(c,f[g],g,a));return e};
goog.array.reduce=goog.NATIVE_ARRAY_PROTOTYPES&&goog.array.ARRAY_PROTOTYPE_.reduce?function(a,b,c,d){goog.asserts.assert(null!=a.length);d&&(b=goog.bind(b,d));return goog.array.ARRAY_PROTOTYPE_.reduce.call(a,b,c)}:function(a,b,c,d){var e=c;goog.array.forEach(a,function(c,g){e=b.call(d,e,c,g,a)});return e};
goog.array.reduceRight=goog.NATIVE_ARRAY_PROTOTYPES&&goog.array.ARRAY_PROTOTYPE_.reduceRight?function(a,b,c,d){goog.asserts.assert(null!=a.length);d&&(b=goog.bind(b,d));return goog.array.ARRAY_PROTOTYPE_.reduceRight.call(a,b,c)}:function(a,b,c,d){var e=c;goog.array.forEachRight(a,function(c,g){e=b.call(d,e,c,g,a)});return e};
goog.array.some=goog.NATIVE_ARRAY_PROTOTYPES&&goog.array.ARRAY_PROTOTYPE_.some?function(a,b,c){goog.asserts.assert(null!=a.length);return goog.array.ARRAY_PROTOTYPE_.some.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return!0;return!1};
goog.array.every=goog.NATIVE_ARRAY_PROTOTYPES&&goog.array.ARRAY_PROTOTYPE_.every?function(a,b,c){goog.asserts.assert(null!=a.length);return goog.array.ARRAY_PROTOTYPE_.every.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&!b.call(c,e[f],f,a))return!1;return!0};goog.array.count=function(a,b,c){var d=0;goog.array.forEach(a,function(a,f,g){b.call(c,a,f,g)&&++d},c);return d};
goog.array.find=function(a,b,c){b=goog.array.findIndex(a,b,c);return 0>b?null:goog.isString(a)?a.charAt(b):a[b]};goog.array.findIndex=function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return f;return-1};goog.array.findRight=function(a,b,c){b=goog.array.findIndexRight(a,b,c);return 0>b?null:goog.isString(a)?a.charAt(b):a[b]};
goog.array.findIndexRight=function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,d=d-1;0<=d;d--)if(d in e&&b.call(c,e[d],d,a))return d;return-1};goog.array.contains=function(a,b){return 0<=goog.array.indexOf(a,b)};goog.array.isEmpty=function(a){return 0==a.length};goog.array.clear=function(a){if(!goog.isArray(a))for(var b=a.length-1;0<=b;b--)delete a[b];a.length=0};goog.array.insert=function(a,b){goog.array.contains(a,b)||a.push(b)};
goog.array.insertAt=function(a,b,c){goog.array.splice(a,c,0,b)};goog.array.insertArrayAt=function(a,b,c){goog.partial(goog.array.splice,a,c,0).apply(null,b)};goog.array.insertBefore=function(a,b,c){var d;2==arguments.length||0>(d=goog.array.indexOf(a,c))?a.push(b):goog.array.insertAt(a,b,d)};goog.array.remove=function(a,b){var c=goog.array.indexOf(a,b),d;(d=0<=c)&&goog.array.removeAt(a,c);return d};
goog.array.removeAt=function(a,b){goog.asserts.assert(null!=a.length);return 1==goog.array.ARRAY_PROTOTYPE_.splice.call(a,b,1).length};goog.array.removeIf=function(a,b,c){b=goog.array.findIndex(a,b,c);return 0<=b?(goog.array.removeAt(a,b),!0):!1};goog.array.concat=function(a){return goog.array.ARRAY_PROTOTYPE_.concat.apply(goog.array.ARRAY_PROTOTYPE_,arguments)};goog.array.toArray=function(a){var b=a.length;if(0<b){for(var c=Array(b),d=0;d<b;d++)c[d]=a[d];return c}return[]};goog.array.clone=goog.array.toArray;
goog.array.extend=function(a,b){for(var c=1;c<arguments.length;c++){var d=arguments[c],e;if(goog.isArray(d)||(e=goog.isArrayLike(d))&&Object.prototype.hasOwnProperty.call(d,"callee"))a.push.apply(a,d);else if(e)for(var f=a.length,g=d.length,h=0;h<g;h++)a[f+h]=d[h];else a.push(d)}};goog.array.splice=function(a,b,c,d){goog.asserts.assert(null!=a.length);return goog.array.ARRAY_PROTOTYPE_.splice.apply(a,goog.array.slice(arguments,1))};
goog.array.slice=function(a,b,c){goog.asserts.assert(null!=a.length);return 2>=arguments.length?goog.array.ARRAY_PROTOTYPE_.slice.call(a,b):goog.array.ARRAY_PROTOTYPE_.slice.call(a,b,c)};goog.array.removeDuplicates=function(a,b,c){b=b||a;var d=function(a){return goog.isObject(g)?"o"+goog.getUid(g):(typeof g).charAt(0)+g};c=c||d;for(var d={},e=0,f=0;f<a.length;){var g=a[f++],h=c(g);Object.prototype.hasOwnProperty.call(d,h)||(d[h]=!0,b[e++]=g)}b.length=e};
goog.array.binarySearch=function(a,b,c){return goog.array.binarySearch_(a,c||goog.array.defaultCompare,!1,b)};goog.array.binarySelect=function(a,b,c){return goog.array.binarySearch_(a,b,!0,void 0,c)};goog.array.binarySearch_=function(a,b,c,d,e){for(var f=0,g=a.length,h;f<g;){var k=f+g>>1,l;l=c?b.call(e,a[k],k,a):b(d,a[k]);0<l?f=k+1:(g=k,h=!l)}return h?f:~f};goog.array.sort=function(a,b){goog.asserts.assert(null!=a.length);goog.array.ARRAY_PROTOTYPE_.sort.call(a,b||goog.array.defaultCompare)};
goog.array.stableSort=function(a,b){for(var c=0;c<a.length;c++)a[c]={index:c,value:a[c]};var d=b||goog.array.defaultCompare;goog.array.sort(a,function(a,b){return d(a.value,b.value)||a.index-b.index});for(c=0;c<a.length;c++)a[c]=a[c].value};goog.array.sortObjectsByKey=function(a,b,c){var d=c||goog.array.defaultCompare;goog.array.sort(a,function(a,c){return d(a[b],c[b])})};
goog.array.isSorted=function(a,b,c){b=b||goog.array.defaultCompare;for(var d=1;d<a.length;d++){var e=b(a[d-1],a[d]);if(0<e||0==e&&c)return!1}return!0};goog.array.equals=function(a,b,c){if(!goog.isArrayLike(a)||!goog.isArrayLike(b)||a.length!=b.length)return!1;var d=a.length;c=c||goog.array.defaultCompareEquality;for(var e=0;e<d;e++)if(!c(a[e],b[e]))return!1;return!0};goog.array.compare=function(a,b,c){return goog.array.equals(a,b,c)};
goog.array.compare3=function(a,b,c){c=c||goog.array.defaultCompare;for(var d=Math.min(a.length,b.length),e=0;e<d;e++){var f=c(a[e],b[e]);if(0!=f)return f}return goog.array.defaultCompare(a.length,b.length)};goog.array.defaultCompare=function(a,b){return a>b?1:a<b?-1:0};goog.array.defaultCompareEquality=function(a,b){return a===b};goog.array.binaryInsert=function(a,b,c){c=goog.array.binarySearch(a,b,c);return 0>c?(goog.array.insertAt(a,b,-(c+1)),!0):!1};
goog.array.binaryRemove=function(a,b,c){b=goog.array.binarySearch(a,b,c);return 0<=b?goog.array.removeAt(a,b):!1};goog.array.bucket=function(a,b,c){for(var d={},e=0;e<a.length;e++){var f=a[e],g=b.call(c,f,e,a);goog.isDef(g)&&(d[g]||(d[g]=[])).push(f)}return d};goog.array.toObject=function(a,b,c){var d={};goog.array.forEach(a,function(e,f){d[b.call(c,e,f,a)]=e});return d};
goog.array.range=function(a,b,c){var d=[],e=0,f=a;c=c||1;void 0!==b&&(e=a,f=b);if(0>c*(f-e))return[];if(0<c)for(a=e;a<f;a+=c)d.push(a);else for(a=e;a>f;a+=c)d.push(a);return d};goog.array.repeat=function(a,b){for(var c=[],d=0;d<b;d++)c[d]=a;return c};goog.array.flatten=function(a){for(var b=[],c=0;c<arguments.length;c++){var d=arguments[c];goog.isArray(d)?b.push.apply(b,goog.array.flatten.apply(null,d)):b.push(d)}return b};
goog.array.rotate=function(a,b){goog.asserts.assert(null!=a.length);a.length&&(b%=a.length,0<b?goog.array.ARRAY_PROTOTYPE_.unshift.apply(a,a.splice(-b,b)):0>b&&goog.array.ARRAY_PROTOTYPE_.push.apply(a,a.splice(0,-b)));return a};goog.array.moveItem=function(a,b,c){goog.asserts.assert(0<=b&&b<a.length);goog.asserts.assert(0<=c&&c<a.length);b=goog.array.ARRAY_PROTOTYPE_.splice.call(a,b,1);goog.array.ARRAY_PROTOTYPE_.splice.call(a,c,0,b[0])};
goog.array.zip=function(a){if(!arguments.length)return[];for(var b=[],c=0;;c++){for(var d=[],e=0;e<arguments.length;e++){var f=arguments[e];if(c>=f.length)return b;d.push(f[c])}b.push(d)}};goog.array.shuffle=function(a,b){for(var c=b||Math.random,d=a.length-1;0<d;d--){var e=Math.floor(c()*(d+1)),f=a[d];a[d]=a[e];a[e]=f}};goog.userAgent={};goog.userAgent.ASSUME_IE=!1;goog.userAgent.ASSUME_GECKO=!1;goog.userAgent.ASSUME_WEBKIT=!1;goog.userAgent.ASSUME_MOBILE_WEBKIT=!1;goog.userAgent.ASSUME_OPERA=!1;goog.userAgent.ASSUME_ANY_VERSION=!1;goog.userAgent.BROWSER_KNOWN_=goog.userAgent.ASSUME_IE||goog.userAgent.ASSUME_GECKO||goog.userAgent.ASSUME_MOBILE_WEBKIT||goog.userAgent.ASSUME_WEBKIT||goog.userAgent.ASSUME_OPERA;
goog.userAgent.getUserAgentString=function(){return goog.global.navigator?goog.global.navigator.userAgent:null};goog.userAgent.getNavigator=function(){return goog.global.navigator};
goog.userAgent.init_=function(){goog.userAgent.detectedOpera_=!1;goog.userAgent.detectedIe_=!1;goog.userAgent.detectedWebkit_=!1;goog.userAgent.detectedMobile_=!1;goog.userAgent.detectedGecko_=!1;var a;if(!goog.userAgent.BROWSER_KNOWN_&&(a=goog.userAgent.getUserAgentString())){var b=goog.userAgent.getNavigator();goog.userAgent.detectedOpera_=goog.string.startsWith(a,"Opera");goog.userAgent.detectedIe_=!goog.userAgent.detectedOpera_&&(goog.string.contains(a,"MSIE")||goog.string.contains(a,"Trident"));
goog.userAgent.detectedWebkit_=!goog.userAgent.detectedOpera_&&goog.string.contains(a,"WebKit");goog.userAgent.detectedMobile_=goog.userAgent.detectedWebkit_&&goog.string.contains(a,"Mobile");goog.userAgent.detectedGecko_=!goog.userAgent.detectedOpera_&&!goog.userAgent.detectedWebkit_&&!goog.userAgent.detectedIe_&&"Gecko"==b.product}};goog.userAgent.BROWSER_KNOWN_||goog.userAgent.init_();goog.userAgent.OPERA=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_OPERA:goog.userAgent.detectedOpera_;
goog.userAgent.IE=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_IE:goog.userAgent.detectedIe_;goog.userAgent.GECKO=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_GECKO:goog.userAgent.detectedGecko_;goog.userAgent.WEBKIT=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_WEBKIT||goog.userAgent.ASSUME_MOBILE_WEBKIT:goog.userAgent.detectedWebkit_;goog.userAgent.MOBILE=goog.userAgent.ASSUME_MOBILE_WEBKIT||goog.userAgent.detectedMobile_;goog.userAgent.SAFARI=goog.userAgent.WEBKIT;
goog.userAgent.determinePlatform_=function(){var a=goog.userAgent.getNavigator();return a&&a.platform||""};goog.userAgent.PLATFORM=goog.userAgent.determinePlatform_();goog.userAgent.ASSUME_MAC=!1;goog.userAgent.ASSUME_WINDOWS=!1;goog.userAgent.ASSUME_LINUX=!1;goog.userAgent.ASSUME_X11=!1;goog.userAgent.ASSUME_ANDROID=!1;goog.userAgent.ASSUME_IPHONE=!1;goog.userAgent.ASSUME_IPAD=!1;
goog.userAgent.PLATFORM_KNOWN_=goog.userAgent.ASSUME_MAC||goog.userAgent.ASSUME_WINDOWS||goog.userAgent.ASSUME_LINUX||goog.userAgent.ASSUME_X11||goog.userAgent.ASSUME_ANDROID||goog.userAgent.ASSUME_IPHONE||goog.userAgent.ASSUME_IPAD;
goog.userAgent.initPlatform_=function(){goog.userAgent.detectedMac_=goog.string.contains(goog.userAgent.PLATFORM,"Mac");goog.userAgent.detectedWindows_=goog.string.contains(goog.userAgent.PLATFORM,"Win");goog.userAgent.detectedLinux_=goog.string.contains(goog.userAgent.PLATFORM,"Linux");goog.userAgent.detectedX11_=!!goog.userAgent.getNavigator()&&goog.string.contains(goog.userAgent.getNavigator().appVersion||"","X11");var a=goog.userAgent.getUserAgentString();goog.userAgent.detectedAndroid_=!!a&&
goog.string.contains(a,"Android");goog.userAgent.detectedIPhone_=!!a&&goog.string.contains(a,"iPhone");goog.userAgent.detectedIPad_=!!a&&goog.string.contains(a,"iPad")};goog.userAgent.PLATFORM_KNOWN_||goog.userAgent.initPlatform_();goog.userAgent.MAC=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_MAC:goog.userAgent.detectedMac_;goog.userAgent.WINDOWS=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_WINDOWS:goog.userAgent.detectedWindows_;
goog.userAgent.LINUX=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_LINUX:goog.userAgent.detectedLinux_;goog.userAgent.X11=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_X11:goog.userAgent.detectedX11_;goog.userAgent.ANDROID=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_ANDROID:goog.userAgent.detectedAndroid_;goog.userAgent.IPHONE=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_IPHONE:goog.userAgent.detectedIPhone_;
goog.userAgent.IPAD=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_IPAD:goog.userAgent.detectedIPad_;
goog.userAgent.determineVersion_=function(){var a="",b;goog.userAgent.OPERA&&goog.global.opera?(a=goog.global.opera.version,a="function"==typeof a?a():a):(goog.userAgent.GECKO?b=/rv\:([^\);]+)(\)|;)/:goog.userAgent.IE?b=/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/:goog.userAgent.WEBKIT&&(b=/WebKit\/(\S+)/),b&&(a=(a=b.exec(goog.userAgent.getUserAgentString()))?a[1]:""));return goog.userAgent.IE&&(b=goog.userAgent.getDocumentMode_(),b>parseFloat(a))?String(b):a};
goog.userAgent.getDocumentMode_=function(){var a=goog.global.document;return a?a.documentMode:void 0};goog.userAgent.VERSION=goog.userAgent.determineVersion_();goog.userAgent.compare=function(a,b){return goog.string.compareVersions(a,b)};goog.userAgent.isVersionOrHigherCache_={};
goog.userAgent.isVersionOrHigher=function(a){return goog.userAgent.ASSUME_ANY_VERSION||goog.userAgent.isVersionOrHigherCache_[a]||(goog.userAgent.isVersionOrHigherCache_[a]=0<=goog.string.compareVersions(goog.userAgent.VERSION,a))};goog.userAgent.isVersion=goog.userAgent.isVersionOrHigher;goog.userAgent.isDocumentModeOrHigher=function(a){return goog.userAgent.IE&&goog.userAgent.DOCUMENT_MODE>=a};goog.userAgent.isDocumentMode=goog.userAgent.isDocumentModeOrHigher;
goog.userAgent.DOCUMENT_MODE=function(){var a=goog.global.document;return a&&goog.userAgent.IE?goog.userAgent.getDocumentMode_()||("CSS1Compat"==a.compatMode?parseInt(goog.userAgent.VERSION,10):5):void 0}();goog.dom.BrowserFeature={CAN_ADD_NAME_OR_TYPE_ATTRIBUTES:!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9),CAN_USE_CHILDREN_ATTRIBUTE:!goog.userAgent.GECKO&&!goog.userAgent.IE||goog.userAgent.IE&&goog.userAgent.isDocumentModeOrHigher(9)||goog.userAgent.GECKO&&goog.userAgent.isVersionOrHigher("1.9.1"),CAN_USE_INNER_TEXT:goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),CAN_USE_PARENT_ELEMENT_PROPERTY:goog.userAgent.IE||goog.userAgent.OPERA||goog.userAgent.WEBKIT,INNER_HTML_NEEDS_SCOPED_ELEMENT:goog.userAgent.IE};goog.dom.TagName={A:"A",ABBR:"ABBR",ACRONYM:"ACRONYM",ADDRESS:"ADDRESS",APPLET:"APPLET",AREA:"AREA",ARTICLE:"ARTICLE",ASIDE:"ASIDE",AUDIO:"AUDIO",B:"B",BASE:"BASE",BASEFONT:"BASEFONT",BDI:"BDI",BDO:"BDO",BIG:"BIG",BLOCKQUOTE:"BLOCKQUOTE",BODY:"BODY",BR:"BR",BUTTON:"BUTTON",CANVAS:"CANVAS",CAPTION:"CAPTION",CENTER:"CENTER",CITE:"CITE",CODE:"CODE",COL:"COL",COLGROUP:"COLGROUP",COMMAND:"COMMAND",DATA:"DATA",DATALIST:"DATALIST",DD:"DD",DEL:"DEL",DETAILS:"DETAILS",DFN:"DFN",DIALOG:"DIALOG",DIR:"DIR",DIV:"DIV",
DL:"DL",DT:"DT",EM:"EM",EMBED:"EMBED",FIELDSET:"FIELDSET",FIGCAPTION:"FIGCAPTION",FIGURE:"FIGURE",FONT:"FONT",FOOTER:"FOOTER",FORM:"FORM",FRAME:"FRAME",FRAMESET:"FRAMESET",H1:"H1",H2:"H2",H3:"H3",H4:"H4",H5:"H5",H6:"H6",HEAD:"HEAD",HEADER:"HEADER",HGROUP:"HGROUP",HR:"HR",HTML:"HTML",I:"I",IFRAME:"IFRAME",IMG:"IMG",INPUT:"INPUT",INS:"INS",ISINDEX:"ISINDEX",KBD:"KBD",KEYGEN:"KEYGEN",LABEL:"LABEL",LEGEND:"LEGEND",LI:"LI",LINK:"LINK",MAP:"MAP",MARK:"MARK",MATH:"MATH",MENU:"MENU",META:"META",METER:"METER",
NAV:"NAV",NOFRAMES:"NOFRAMES",NOSCRIPT:"NOSCRIPT",OBJECT:"OBJECT",OL:"OL",OPTGROUP:"OPTGROUP",OPTION:"OPTION",OUTPUT:"OUTPUT",P:"P",PARAM:"PARAM",PRE:"PRE",PROGRESS:"PROGRESS",Q:"Q",RP:"RP",RT:"RT",RUBY:"RUBY",S:"S",SAMP:"SAMP",SCRIPT:"SCRIPT",SECTION:"SECTION",SELECT:"SELECT",SMALL:"SMALL",SOURCE:"SOURCE",SPAN:"SPAN",STRIKE:"STRIKE",STRONG:"STRONG",STYLE:"STYLE",SUB:"SUB",SUMMARY:"SUMMARY",SUP:"SUP",SVG:"SVG",TABLE:"TABLE",TBODY:"TBODY",TD:"TD",TEXTAREA:"TEXTAREA",TFOOT:"TFOOT",TH:"TH",THEAD:"THEAD",
TIME:"TIME",TITLE:"TITLE",TR:"TR",TRACK:"TRACK",TT:"TT",U:"U",UL:"UL",VAR:"VAR",VIDEO:"VIDEO",WBR:"WBR"};goog.dom.classes={};goog.dom.classes.set=function(a,b){a.className=b};goog.dom.classes.get=function(a){a=a.className;return goog.isString(a)&&a.match(/\S+/g)||[]};goog.dom.classes.add=function(a,b){var c=goog.dom.classes.get(a),d=goog.array.slice(arguments,1),e=c.length+d.length;goog.dom.classes.add_(c,d);goog.dom.classes.set(a,c.join(" "));return c.length==e};
goog.dom.classes.remove=function(a,b){var c=goog.dom.classes.get(a),d=goog.array.slice(arguments,1),e=goog.dom.classes.getDifference_(c,d);goog.dom.classes.set(a,e.join(" "));return e.length==c.length-d.length};goog.dom.classes.add_=function(a,b){for(var c=0;c<b.length;c++)goog.array.contains(a,b[c])||a.push(b[c])};goog.dom.classes.getDifference_=function(a,b){return goog.array.filter(a,function(a){return!goog.array.contains(b,a)})};
goog.dom.classes.swap=function(a,b,c){for(var d=goog.dom.classes.get(a),e=!1,f=0;f<d.length;f++)d[f]==b&&(goog.array.splice(d,f--,1),e=!0);e&&(d.push(c),goog.dom.classes.set(a,d.join(" ")));return e};goog.dom.classes.addRemove=function(a,b,c){var d=goog.dom.classes.get(a);goog.isString(b)?goog.array.remove(d,b):goog.isArray(b)&&(d=goog.dom.classes.getDifference_(d,b));goog.isString(c)&&!goog.array.contains(d,c)?d.push(c):goog.isArray(c)&&goog.dom.classes.add_(d,c);goog.dom.classes.set(a,d.join(" "))};
goog.dom.classes.has=function(a,b){return goog.array.contains(goog.dom.classes.get(a),b)};goog.dom.classes.enable=function(a,b,c){c?goog.dom.classes.add(a,b):goog.dom.classes.remove(a,b)};goog.dom.classes.toggle=function(a,b){var c=!goog.dom.classes.has(a,b);goog.dom.classes.enable(a,b,c);return c};goog.functions={};goog.functions.constant=function(a){return function(){return a}};goog.functions.FALSE=goog.functions.constant(!1);goog.functions.TRUE=goog.functions.constant(!0);goog.functions.NULL=goog.functions.constant(null);goog.functions.identity=function(a,b){return a};goog.functions.error=function(a){return function(){throw Error(a);}};goog.functions.fail=function(a){return function(){throw a;}};
goog.functions.lock=function(a,b){b=b||0;return function(){return a.apply(this,Array.prototype.slice.call(arguments,0,b))}};goog.functions.nth=function(a){return function(){return arguments[a]}};goog.functions.withReturnValue=function(a,b){return goog.functions.sequence(a,goog.functions.constant(b))};goog.functions.compose=function(a,b){var c=arguments,d=c.length;return function(){var a;d&&(a=c[d-1].apply(this,arguments));for(var b=d-2;0<=b;b--)a=c[b].call(this,a);return a}};
goog.functions.sequence=function(a){var b=arguments,c=b.length;return function(){for(var a,e=0;e<c;e++)a=b[e].apply(this,arguments);return a}};goog.functions.and=function(a){var b=arguments,c=b.length;return function(){for(var a=0;a<c;a++)if(!b[a].apply(this,arguments))return!1;return!0}};goog.functions.or=function(a){var b=arguments,c=b.length;return function(){for(var a=0;a<c;a++)if(b[a].apply(this,arguments))return!0;return!1}};
goog.functions.not=function(a){return function(){return!a.apply(this,arguments)}};goog.functions.create=function(a,b){var c=function(){};c.prototype=a.prototype;c=new c;a.apply(c,Array.prototype.slice.call(arguments,1));return c};goog.functions.CACHE_RETURN_VALUE=!0;goog.functions.cacheReturnValue=function(a){var b=!1,c;return function(){if(!goog.functions.CACHE_RETURN_VALUE)return a();b||(c=a(),b=!0);return c}};goog.math={};goog.math.randomInt=function(a){return Math.floor(Math.random()*a)};goog.math.uniformRandom=function(a,b){return a+Math.random()*(b-a)};goog.math.clamp=function(a,b,c){return Math.min(Math.max(a,b),c)};goog.math.modulo=function(a,b){var c=a%b;return 0>c*b?c+b:c};goog.math.lerp=function(a,b,c){return a+c*(b-a)};goog.math.nearlyEquals=function(a,b,c){return Math.abs(a-b)<=(c||1E-6)};goog.math.standardAngle=function(a){return goog.math.modulo(a,360)};
goog.math.toRadians=function(a){return a*Math.PI/180};goog.math.toDegrees=function(a){return 180*a/Math.PI};goog.math.angleDx=function(a,b){return b*Math.cos(goog.math.toRadians(a))};goog.math.angleDy=function(a,b){return b*Math.sin(goog.math.toRadians(a))};goog.math.angle=function(a,b,c,d){return goog.math.standardAngle(goog.math.toDegrees(Math.atan2(d-b,c-a)))};goog.math.angleDifference=function(a,b){var c=goog.math.standardAngle(b)-goog.math.standardAngle(a);180<c?c-=360:-180>=c&&(c=360+c);return c};
goog.math.sign=function(a){return 0==a?0:0>a?-1:1};goog.math.longestCommonSubsequence=function(a,b,c,d){c=c||function(a,b){return a==b};d=d||function(b,c){return a[b]};for(var e=a.length,f=b.length,g=[],h=0;h<e+1;h++)g[h]=[],g[h][0]=0;for(var k=0;k<f+1;k++)g[0][k]=0;for(h=1;h<=e;h++)for(k=1;k<=f;k++)c(a[h-1],b[k-1])?g[h][k]=g[h-1][k-1]+1:g[h][k]=Math.max(g[h-1][k],g[h][k-1]);for(var l=[],h=e,k=f;0<h&&0<k;)c(a[h-1],b[k-1])?(l.unshift(d(h-1,k-1)),h--,k--):g[h-1][k]>g[h][k-1]?h--:k--;return l};
goog.math.sum=function(a){return goog.array.reduce(arguments,function(a,c){return a+c},0)};goog.math.average=function(a){return goog.math.sum.apply(null,arguments)/arguments.length};goog.math.sampleVariance=function(a){var b=arguments.length;if(2>b)return 0;var c=goog.math.average.apply(null,arguments);return goog.math.sum.apply(null,goog.array.map(arguments,function(a){return Math.pow(a-c,2)}))/(b-1)};goog.math.standardDeviation=function(a){return Math.sqrt(goog.math.sampleVariance.apply(null,arguments))};
goog.math.isInt=function(a){return isFinite(a)&&0==a%1};goog.math.isFiniteNumber=function(a){return isFinite(a)&&!isNaN(a)};goog.math.safeFloor=function(a,b){goog.asserts.assert(!goog.isDef(b)||0<b);return Math.floor(a+(b||2E-15))};goog.math.safeCeil=function(a,b){goog.asserts.assert(!goog.isDef(b)||0<b);return Math.ceil(a-(b||2E-15))};goog.math.Coordinate=function(a,b){this.x=goog.isDef(a)?a:0;this.y=goog.isDef(b)?b:0};goog.math.Coordinate.prototype.clone=function(){return new goog.math.Coordinate(this.x,this.y)};goog.DEBUG&&(goog.math.Coordinate.prototype.toString=function(){return"("+this.x+", "+this.y+")"});goog.math.Coordinate.equals=function(a,b){return a==b?!0:a&&b?a.x==b.x&&a.y==b.y:!1};goog.math.Coordinate.distance=function(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)};
goog.math.Coordinate.magnitude=function(a){return Math.sqrt(a.x*a.x+a.y*a.y)};goog.math.Coordinate.azimuth=function(a){return goog.math.angle(0,0,a.x,a.y)};goog.math.Coordinate.squaredDistance=function(a,b){var c=a.x-b.x,d=a.y-b.y;return c*c+d*d};goog.math.Coordinate.difference=function(a,b){return new goog.math.Coordinate(a.x-b.x,a.y-b.y)};goog.math.Coordinate.sum=function(a,b){return new goog.math.Coordinate(a.x+b.x,a.y+b.y)};
goog.math.Coordinate.prototype.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};goog.math.Coordinate.prototype.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};goog.math.Coordinate.prototype.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};goog.math.Coordinate.prototype.translate=function(a,b){a instanceof goog.math.Coordinate?(this.x+=a.x,this.y+=a.y):(this.x+=a,goog.isNumber(b)&&(this.y+=b));return this};
goog.math.Coordinate.prototype.scale=function(a,b){var c=goog.isNumber(b)?b:a;this.x*=a;this.y*=c;return this};goog.math.Size=function(a,b){this.width=a;this.height=b};goog.math.Size.equals=function(a,b){return a==b?!0:a&&b?a.width==b.width&&a.height==b.height:!1};goog.math.Size.prototype.clone=function(){return new goog.math.Size(this.width,this.height)};goog.DEBUG&&(goog.math.Size.prototype.toString=function(){return"("+this.width+" x "+this.height+")"});goog.math.Size.prototype.getLongest=function(){return Math.max(this.width,this.height)};
goog.math.Size.prototype.getShortest=function(){return Math.min(this.width,this.height)};goog.math.Size.prototype.area=function(){return this.width*this.height};goog.math.Size.prototype.perimeter=function(){return 2*(this.width+this.height)};goog.math.Size.prototype.aspectRatio=function(){return this.width/this.height};goog.math.Size.prototype.isEmpty=function(){return!this.area()};goog.math.Size.prototype.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};
goog.math.Size.prototype.fitsInside=function(a){return this.width<=a.width&&this.height<=a.height};goog.math.Size.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};goog.math.Size.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};goog.math.Size.prototype.scale=function(a,b){var c=goog.isNumber(b)?b:a;this.width*=a;this.height*=c;return this};
goog.math.Size.prototype.scaleToFit=function(a){a=this.aspectRatio()>a.aspectRatio()?a.width/this.width:a.height/this.height;return this.scale(a)};goog.object={};goog.object.forEach=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)};goog.object.filter=function(a,b,c){var d={},e;for(e in a)b.call(c,a[e],e,a)&&(d[e]=a[e]);return d};goog.object.map=function(a,b,c){var d={},e;for(e in a)d[e]=b.call(c,a[e],e,a);return d};goog.object.some=function(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return!0;return!1};goog.object.every=function(a,b,c){for(var d in a)if(!b.call(c,a[d],d,a))return!1;return!0};
goog.object.getCount=function(a){var b=0,c;for(c in a)b++;return b};goog.object.getAnyKey=function(a){for(var b in a)return b};goog.object.getAnyValue=function(a){for(var b in a)return a[b]};goog.object.contains=function(a,b){return goog.object.containsValue(a,b)};goog.object.getValues=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b};goog.object.getKeys=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b};
goog.object.getValueByKeys=function(a,b){for(var c=goog.isArrayLike(b),d=c?b:arguments,c=c?0:1;c<d.length&&(a=a[d[c]],goog.isDef(a));c++);return a};goog.object.containsKey=function(a,b){return b in a};goog.object.containsValue=function(a,b){for(var c in a)if(a[c]==b)return!0;return!1};goog.object.findKey=function(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};goog.object.findValue=function(a,b,c){return(b=goog.object.findKey(a,b,c))&&a[b]};
goog.object.isEmpty=function(a){for(var b in a)return!1;return!0};goog.object.clear=function(a){for(var b in a)delete a[b]};goog.object.remove=function(a,b){var c;(c=b in a)&&delete a[b];return c};goog.object.add=function(a,b,c){if(b in a)throw Error('The object already contains the key "'+b+'"');goog.object.set(a,b,c)};goog.object.get=function(a,b,c){return b in a?a[b]:c};goog.object.set=function(a,b,c){a[b]=c};goog.object.setIfUndefined=function(a,b,c){return b in a?a[b]:a[b]=c};
goog.object.clone=function(a){var b={},c;for(c in a)b[c]=a[c];return b};goog.object.unsafeClone=function(a){var b=goog.typeOf(a);if("object"==b||"array"==b){if(a.clone)return a.clone();var b="array"==b?[]:{},c;for(c in a)b[c]=goog.object.unsafeClone(a[c]);return b}return a};goog.object.transpose=function(a){var b={},c;for(c in a)b[a[c]]=c;return b};goog.object.PROTOTYPE_FIELDS_="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");
goog.object.extend=function(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var f=0;f<goog.object.PROTOTYPE_FIELDS_.length;f++)c=goog.object.PROTOTYPE_FIELDS_[f],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};
goog.object.create=function(a){var b=arguments.length;if(1==b&&goog.isArray(arguments[0]))return goog.object.create.apply(null,arguments[0]);if(b%2)throw Error("Uneven number of arguments");for(var c={},d=0;d<b;d+=2)c[arguments[d]]=arguments[d+1];return c};goog.object.createSet=function(a){var b=arguments.length;if(1==b&&goog.isArray(arguments[0]))return goog.object.createSet.apply(null,arguments[0]);for(var c={},d=0;d<b;d++)c[arguments[d]]=!0;return c};
goog.object.createImmutableView=function(a){var b=a;Object.isFrozen&&!Object.isFrozen(a)&&(b=Object.create(a),Object.freeze(b));return b};goog.object.isImmutableView=function(a){return!!Object.isFrozen&&Object.isFrozen(a)};goog.dom.ASSUME_QUIRKS_MODE=!1;goog.dom.ASSUME_STANDARDS_MODE=!1;goog.dom.COMPAT_MODE_KNOWN_=goog.dom.ASSUME_QUIRKS_MODE||goog.dom.ASSUME_STANDARDS_MODE;goog.dom.getDomHelper=function(a){return a?new goog.dom.DomHelper(goog.dom.getOwnerDocument(a)):goog.dom.defaultDomHelper_||(goog.dom.defaultDomHelper_=new goog.dom.DomHelper)};goog.dom.getDocument=function(){return document};goog.dom.getElement=function(a){return goog.dom.getElementHelper_(document,a)};
goog.dom.getElementHelper_=function(a,b){return goog.isString(b)?a.getElementById(b):b};goog.dom.getRequiredElement=function(a){return goog.dom.getRequiredElementHelper_(document,a)};goog.dom.getRequiredElementHelper_=function(a,b){goog.asserts.assertString(b);var c=goog.dom.getElementHelper_(a,b);return c=goog.asserts.assertElement(c,"No element found with id: "+b)};goog.dom.$=goog.dom.getElement;
goog.dom.getElementsByTagNameAndClass=function(a,b,c){return goog.dom.getElementsByTagNameAndClass_(document,a,b,c)};goog.dom.getElementsByClass=function(a,b){var c=b||document;return goog.dom.canUseQuerySelector_(c)?c.querySelectorAll("."+a):c.getElementsByClassName?c.getElementsByClassName(a):goog.dom.getElementsByTagNameAndClass_(document,"*",a,b)};
goog.dom.getElementByClass=function(a,b){var c=b||document,d=null;return(d=goog.dom.canUseQuerySelector_(c)?c.querySelector("."+a):goog.dom.getElementsByClass(a,b)[0])||null};goog.dom.canUseQuerySelector_=function(a){return!(!a.querySelectorAll||!a.querySelector)};
goog.dom.getElementsByTagNameAndClass_=function(a,b,c,d){a=d||a;b=b&&"*"!=b?b.toUpperCase():"";if(goog.dom.canUseQuerySelector_(a)&&(b||c))return a.querySelectorAll(b+(c?"."+c:""));if(c&&a.getElementsByClassName){a=a.getElementsByClassName(c);if(b){d={};for(var e=0,f=0,g;g=a[f];f++)b==g.nodeName&&(d[e++]=g);d.length=e;return d}return a}a=a.getElementsByTagName(b||"*");if(c){d={};for(f=e=0;g=a[f];f++)b=g.className,"function"==typeof b.split&&goog.array.contains(b.split(/\s+/),c)&&(d[e++]=g);d.length=
e;return d}return a};goog.dom.$$=goog.dom.getElementsByTagNameAndClass;goog.dom.setProperties=function(a,b){goog.object.forEach(b,function(b,d){"style"==d?a.style.cssText=b:"class"==d?a.className=b:"for"==d?a.htmlFor=b:d in goog.dom.DIRECT_ATTRIBUTE_MAP_?a.setAttribute(goog.dom.DIRECT_ATTRIBUTE_MAP_[d],b):goog.string.startsWith(d,"aria-")||goog.string.startsWith(d,"data-")?a.setAttribute(d,b):a[d]=b})};
goog.dom.DIRECT_ATTRIBUTE_MAP_={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",width:"width"};goog.dom.getViewportSize=function(a){return goog.dom.getViewportSize_(a||window)};goog.dom.getViewportSize_=function(a){a=a.document;a=goog.dom.isCss1CompatMode_(a)?a.documentElement:a.body;return new goog.math.Size(a.clientWidth,a.clientHeight)};
goog.dom.getDocumentHeight=function(){return goog.dom.getDocumentHeight_(window)};goog.dom.getDocumentHeight_=function(a){var b=a.document,c=0;if(b){a=goog.dom.getViewportSize_(a).height;var c=b.body,d=b.documentElement;if(goog.dom.isCss1CompatMode_(b)&&d.scrollHeight)c=d.scrollHeight!=a?d.scrollHeight:d.offsetHeight;else{var b=d.scrollHeight,e=d.offsetHeight;d.clientHeight!=e&&(b=c.scrollHeight,e=c.offsetHeight);c=b>a?b>e?b:e:b<e?b:e}}return c};
goog.dom.getPageScroll=function(a){return goog.dom.getDomHelper((a||goog.global||window).document).getDocumentScroll()};goog.dom.getDocumentScroll=function(){return goog.dom.getDocumentScroll_(document)};
goog.dom.getDocumentScroll_=function(a){var b=goog.dom.getDocumentScrollElement_(a);a=goog.dom.getWindow_(a);return goog.userAgent.IE&&goog.userAgent.isVersionOrHigher("10")&&a.pageYOffset!=b.scrollTop?new goog.math.Coordinate(b.scrollLeft,b.scrollTop):new goog.math.Coordinate(a.pageXOffset||b.scrollLeft,a.pageYOffset||b.scrollTop)};goog.dom.getDocumentScrollElement=function(){return goog.dom.getDocumentScrollElement_(document)};
goog.dom.getDocumentScrollElement_=function(a){return!goog.userAgent.WEBKIT&&goog.dom.isCss1CompatMode_(a)?a.documentElement:a.body||a.documentElement};goog.dom.getWindow=function(a){return a?goog.dom.getWindow_(a):window};goog.dom.getWindow_=function(a){return a.parentWindow||a.defaultView};goog.dom.createDom=function(a,b,c){return goog.dom.createDom_(document,arguments)};
goog.dom.createDom_=function(a,b){var c=b[0],d=b[1];if(!goog.dom.BrowserFeature.CAN_ADD_NAME_OR_TYPE_ATTRIBUTES&&d&&(d.name||d.type)){c=["<",c];d.name&&c.push(' name="',goog.string.htmlEscape(d.name),'"');if(d.type){c.push(' type="',goog.string.htmlEscape(d.type),'"');var e={};goog.object.extend(e,d);delete e.type;d=e}c.push(">");c=c.join("")}c=a.createElement(c);d&&(goog.isString(d)?c.className=d:goog.isArray(d)?goog.dom.classes.add.apply(null,[c].concat(d)):goog.dom.setProperties(c,d));2<b.length&&
goog.dom.append_(a,c,b,2);return c};goog.dom.append_=function(a,b,c,d){function e(c){c&&b.appendChild(goog.isString(c)?a.createTextNode(c):c)}for(;d<c.length;d++){var f=c[d];goog.isArrayLike(f)&&!goog.dom.isNodeLike(f)?goog.array.forEach(goog.dom.isNodeList(f)?goog.array.toArray(f):f,e):e(f)}};goog.dom.$dom=goog.dom.createDom;goog.dom.createElement=function(a){return document.createElement(a)};goog.dom.createTextNode=function(a){return document.createTextNode(String(a))};
goog.dom.createTable=function(a,b,c){return goog.dom.createTable_(document,a,b,!!c)};goog.dom.createTable_=function(a,b,c,d){for(var e=["<tr>"],f=0;f<c;f++)e.push(d?"<td> </td>":"<td></td>");e.push("</tr>");e=e.join("");c=["<table>"];for(f=0;f<b;f++)c.push(e);c.push("</table>");a=a.createElement(goog.dom.TagName.DIV);a.innerHTML=c.join("");return a.removeChild(a.firstChild)};goog.dom.htmlToDocumentFragment=function(a){return goog.dom.htmlToDocumentFragment_(document,a)};
goog.dom.htmlToDocumentFragment_=function(a,b){var c=a.createElement("div");goog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT?(c.innerHTML="<br>"+b,c.removeChild(c.firstChild)):c.innerHTML=b;if(1==c.childNodes.length)return c.removeChild(c.firstChild);for(var d=a.createDocumentFragment();c.firstChild;)d.appendChild(c.firstChild);return d};goog.dom.isCss1CompatMode=function(){return goog.dom.isCss1CompatMode_(document)};
goog.dom.isCss1CompatMode_=function(a){return goog.dom.COMPAT_MODE_KNOWN_?goog.dom.ASSUME_STANDARDS_MODE:"CSS1Compat"==a.compatMode};goog.dom.canHaveChildren=function(a){if(a.nodeType!=goog.dom.NodeType.ELEMENT)return!1;switch(a.tagName){case goog.dom.TagName.APPLET:case goog.dom.TagName.AREA:case goog.dom.TagName.BASE:case goog.dom.TagName.BR:case goog.dom.TagName.COL:case goog.dom.TagName.COMMAND:case goog.dom.TagName.EMBED:case goog.dom.TagName.FRAME:case goog.dom.TagName.HR:case goog.dom.TagName.IMG:case goog.dom.TagName.INPUT:case goog.dom.TagName.IFRAME:case goog.dom.TagName.ISINDEX:case goog.dom.TagName.KEYGEN:case goog.dom.TagName.LINK:case goog.dom.TagName.NOFRAMES:case goog.dom.TagName.NOSCRIPT:case goog.dom.TagName.META:case goog.dom.TagName.OBJECT:case goog.dom.TagName.PARAM:case goog.dom.TagName.SCRIPT:case goog.dom.TagName.SOURCE:case goog.dom.TagName.STYLE:case goog.dom.TagName.TRACK:case goog.dom.TagName.WBR:return!1}return!0};
goog.dom.appendChild=function(a,b){a.appendChild(b)};goog.dom.append=function(a,b){goog.dom.append_(goog.dom.getOwnerDocument(a),a,arguments,1)};goog.dom.removeChildren=function(a){for(var b;b=a.firstChild;)a.removeChild(b)};goog.dom.insertSiblingBefore=function(a,b){b.parentNode&&b.parentNode.insertBefore(a,b)};goog.dom.insertSiblingAfter=function(a,b){b.parentNode&&b.parentNode.insertBefore(a,b.nextSibling)};goog.dom.insertChildAt=function(a,b,c){a.insertBefore(b,a.childNodes[c]||null)};
goog.dom.removeNode=function(a){return a&&a.parentNode?a.parentNode.removeChild(a):null};goog.dom.replaceNode=function(a,b){var c=b.parentNode;c&&c.replaceChild(a,b)};goog.dom.flattenElement=function(a){var b,c=a.parentNode;if(c&&c.nodeType!=goog.dom.NodeType.DOCUMENT_FRAGMENT){if(a.removeNode)return a.removeNode(!1);for(;b=a.firstChild;)c.insertBefore(b,a);return goog.dom.removeNode(a)}};
goog.dom.getChildren=function(a){return goog.dom.BrowserFeature.CAN_USE_CHILDREN_ATTRIBUTE&&void 0!=a.children?a.children:goog.array.filter(a.childNodes,function(a){return a.nodeType==goog.dom.NodeType.ELEMENT})};goog.dom.getFirstElementChild=function(a){return void 0!=a.firstElementChild?a.firstElementChild:goog.dom.getNextElementNode_(a.firstChild,!0)};goog.dom.getLastElementChild=function(a){return void 0!=a.lastElementChild?a.lastElementChild:goog.dom.getNextElementNode_(a.lastChild,!1)};
goog.dom.getNextElementSibling=function(a){return void 0!=a.nextElementSibling?a.nextElementSibling:goog.dom.getNextElementNode_(a.nextSibling,!0)};goog.dom.getPreviousElementSibling=function(a){return void 0!=a.previousElementSibling?a.previousElementSibling:goog.dom.getNextElementNode_(a.previousSibling,!1)};goog.dom.getNextElementNode_=function(a,b){for(;a&&a.nodeType!=goog.dom.NodeType.ELEMENT;)a=b?a.nextSibling:a.previousSibling;return a};
goog.dom.getNextNode=function(a){if(!a)return null;if(a.firstChild)return a.firstChild;for(;a&&!a.nextSibling;)a=a.parentNode;return a?a.nextSibling:null};goog.dom.getPreviousNode=function(a){if(!a)return null;if(!a.previousSibling)return a.parentNode;for(a=a.previousSibling;a&&a.lastChild;)a=a.lastChild;return a};goog.dom.isNodeLike=function(a){return goog.isObject(a)&&0<a.nodeType};goog.dom.isElement=function(a){return goog.isObject(a)&&a.nodeType==goog.dom.NodeType.ELEMENT};
goog.dom.isWindow=function(a){return goog.isObject(a)&&a.window==a};goog.dom.getParentElement=function(a){if(goog.dom.BrowserFeature.CAN_USE_PARENT_ELEMENT_PROPERTY&&!(goog.userAgent.IE&&goog.userAgent.isVersionOrHigher("9")&&!goog.userAgent.isVersionOrHigher("10")&&goog.global.SVGElement&&a instanceof goog.global.SVGElement))return a.parentElement;a=a.parentNode;return goog.dom.isElement(a)?a:null};
goog.dom.contains=function(a,b){if(a.contains&&b.nodeType==goog.dom.NodeType.ELEMENT)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a};
goog.dom.compareNodeOrder=function(a,b){if(a==b)return 0;if(a.compareDocumentPosition)return a.compareDocumentPosition(b)&2?1:-1;if(goog.userAgent.IE&&!goog.userAgent.isDocumentModeOrHigher(9)){if(a.nodeType==goog.dom.NodeType.DOCUMENT)return-1;if(b.nodeType==goog.dom.NodeType.DOCUMENT)return 1}if("sourceIndex"in a||a.parentNode&&"sourceIndex"in a.parentNode){var c=a.nodeType==goog.dom.NodeType.ELEMENT,d=b.nodeType==goog.dom.NodeType.ELEMENT;if(c&&d)return a.sourceIndex-b.sourceIndex;var e=a.parentNode,
f=b.parentNode;return e==f?goog.dom.compareSiblingOrder_(a,b):!c&&goog.dom.contains(e,b)?-1*goog.dom.compareParentsDescendantNodeIe_(a,b):!d&&goog.dom.contains(f,a)?goog.dom.compareParentsDescendantNodeIe_(b,a):(c?a.sourceIndex:e.sourceIndex)-(d?b.sourceIndex:f.sourceIndex)}d=goog.dom.getOwnerDocument(a);c=d.createRange();c.selectNode(a);c.collapse(!0);d=d.createRange();d.selectNode(b);d.collapse(!0);return c.compareBoundaryPoints(goog.global.Range.START_TO_END,d)};
goog.dom.compareParentsDescendantNodeIe_=function(a,b){var c=a.parentNode;if(c==b)return-1;for(var d=b;d.parentNode!=c;)d=d.parentNode;return goog.dom.compareSiblingOrder_(d,a)};goog.dom.compareSiblingOrder_=function(a,b){for(var c=b;c=c.previousSibling;)if(c==a)return-1;return 1};
goog.dom.findCommonAncestor=function(a){var b,c=arguments.length;if(!c)return null;if(1==c)return arguments[0];var d=[],e=Infinity;for(b=0;b<c;b++){for(var f=[],g=arguments[b];g;)f.unshift(g),g=g.parentNode;d.push(f);e=Math.min(e,f.length)}f=null;for(b=0;b<e;b++){for(var g=d[0][b],h=1;h<c;h++)if(g!=d[h][b])return f;f=g}return f};goog.dom.getOwnerDocument=function(a){return a.nodeType==goog.dom.NodeType.DOCUMENT?a:a.ownerDocument||a.document};
goog.dom.getFrameContentDocument=function(a){return a.contentDocument||a.contentWindow.document};goog.dom.getFrameContentWindow=function(a){return a.contentWindow||goog.dom.getWindow(goog.dom.getFrameContentDocument(a))};
goog.dom.setTextContent=function(a,b){goog.asserts.assert(null!=a,"goog.dom.setTextContent expects a non-null value for node");if("textContent"in a)a.textContent=b;else if(a.nodeType==goog.dom.NodeType.TEXT)a.data=b;else if(a.firstChild&&a.firstChild.nodeType==goog.dom.NodeType.TEXT){for(;a.lastChild!=a.firstChild;)a.removeChild(a.lastChild);a.firstChild.data=b}else{goog.dom.removeChildren(a);var c=goog.dom.getOwnerDocument(a);a.appendChild(c.createTextNode(String(b)))}};
goog.dom.getOuterHtml=function(a){if("outerHTML"in a)return a.outerHTML;var b=goog.dom.getOwnerDocument(a).createElement("div");b.appendChild(a.cloneNode(!0));return b.innerHTML};goog.dom.findNode=function(a,b){var c=[];return goog.dom.findNodes_(a,b,c,!0)?c[0]:void 0};goog.dom.findNodes=function(a,b){var c=[];goog.dom.findNodes_(a,b,c,!1);return c};goog.dom.findNodes_=function(a,b,c,d){if(null!=a)for(a=a.firstChild;a;){if(b(a)&&(c.push(a),d)||goog.dom.findNodes_(a,b,c,d))return!0;a=a.nextSibling}return!1};
goog.dom.TAGS_TO_IGNORE_={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1};goog.dom.PREDEFINED_TAG_VALUES_={IMG:" ",BR:"\n"};goog.dom.isFocusableTabIndex=function(a){return goog.dom.hasSpecifiedTabIndex_(a)&&goog.dom.isTabIndexFocusable_(a)};goog.dom.setFocusableTabIndex=function(a,b){b?a.tabIndex=0:(a.tabIndex=-1,a.removeAttribute("tabIndex"))};
goog.dom.isFocusable=function(a){var b;return(b=goog.dom.nativelySupportsFocus_(a)?!a.disabled&&(!goog.dom.hasSpecifiedTabIndex_(a)||goog.dom.isTabIndexFocusable_(a)):goog.dom.isFocusableTabIndex(a))&&goog.userAgent.IE?goog.dom.hasNonZeroBoundingRect_(a):b};goog.dom.hasSpecifiedTabIndex_=function(a){a=a.getAttributeNode("tabindex");return goog.isDefAndNotNull(a)&&a.specified};goog.dom.isTabIndexFocusable_=function(a){a=a.tabIndex;return goog.isNumber(a)&&0<=a&&32768>a};
goog.dom.nativelySupportsFocus_=function(a){return a.tagName==goog.dom.TagName.A||a.tagName==goog.dom.TagName.INPUT||a.tagName==goog.dom.TagName.TEXTAREA||a.tagName==goog.dom.TagName.SELECT||a.tagName==goog.dom.TagName.BUTTON};goog.dom.hasNonZeroBoundingRect_=function(a){a=goog.isFunction(a.getBoundingClientRect)?a.getBoundingClientRect():{height:a.offsetHeight,width:a.offsetWidth};return goog.isDefAndNotNull(a)&&0<a.height&&0<a.width};
goog.dom.getTextContent=function(a){if(goog.dom.BrowserFeature.CAN_USE_INNER_TEXT&&"innerText"in a)a=goog.string.canonicalizeNewlines(a.innerText);else{var b=[];goog.dom.getTextContent_(a,b,!0);a=b.join("")}a=a.replace(/ \xAD /g," ").replace(/\xAD/g,"");a=a.replace(/\u200B/g,"");goog.dom.BrowserFeature.CAN_USE_INNER_TEXT||(a=a.replace(/ +/g," "));" "!=a&&(a=a.replace(/^\s*/,""));return a};goog.dom.getRawTextContent=function(a){var b=[];goog.dom.getTextContent_(a,b,!1);return b.join("")};
goog.dom.getTextContent_=function(a,b,c){if(!(a.nodeName in goog.dom.TAGS_TO_IGNORE_))if(a.nodeType==goog.dom.NodeType.TEXT)c?b.push(String(a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in goog.dom.PREDEFINED_TAG_VALUES_)b.push(goog.dom.PREDEFINED_TAG_VALUES_[a.nodeName]);else for(a=a.firstChild;a;)goog.dom.getTextContent_(a,b,c),a=a.nextSibling};goog.dom.getNodeTextLength=function(a){return goog.dom.getTextContent(a).length};
goog.dom.getNodeTextOffset=function(a,b){for(var c=b||goog.dom.getOwnerDocument(a).body,d=[];a&&a!=c;){for(var e=a;e=e.previousSibling;)d.unshift(goog.dom.getTextContent(e));a=a.parentNode}return goog.string.trimLeft(d.join("")).replace(/ +/g," ").length};
goog.dom.getNodeAtOffset=function(a,b,c){a=[a];for(var d=0,e=null;0<a.length&&d<b;)if(e=a.pop(),!(e.nodeName in goog.dom.TAGS_TO_IGNORE_))if(e.nodeType==goog.dom.NodeType.TEXT)var f=e.nodeValue.replace(/(\r\n|\r|\n)/g,"").replace(/ +/g," "),d=d+f.length;else if(e.nodeName in goog.dom.PREDEFINED_TAG_VALUES_)d+=goog.dom.PREDEFINED_TAG_VALUES_[e.nodeName].length;else for(f=e.childNodes.length-1;0<=f;f--)a.push(e.childNodes[f]);goog.isObject(c)&&(c.remainder=e?e.nodeValue.length+b-d-1:0,c.node=e);return e};
goog.dom.isNodeList=function(a){if(a&&"number"==typeof a.length){if(goog.isObject(a))return"function"==typeof a.item||"string"==typeof a.item;if(goog.isFunction(a))return"function"==typeof a.item}return!1};goog.dom.getAncestorByTagNameAndClass=function(a,b,c){if(!b&&!c)return null;var d=b?b.toUpperCase():null;return goog.dom.getAncestor(a,function(a){return(!d||a.nodeName==d)&&(!c||goog.dom.classes.has(a,c))},!0)};
goog.dom.getAncestorByClass=function(a,b){return goog.dom.getAncestorByTagNameAndClass(a,null,b)};goog.dom.getAncestor=function(a,b,c,d){c||(a=a.parentNode);c=null==d;for(var e=0;a&&(c||e<=d);){if(b(a))return a;a=a.parentNode;e++}return null};goog.dom.getActiveElement=function(a){try{return a&&a.activeElement}catch(b){}return null};
goog.dom.getPixelRatio=goog.functions.cacheReturnValue(function(){var a=goog.dom.getWindow(),b=goog.userAgent.GECKO&&goog.userAgent.MOBILE;return goog.isDef(a.devicePixelRatio)&&!b?a.devicePixelRatio:a.matchMedia?goog.dom.matchesPixelRatio_(0.75)||goog.dom.matchesPixelRatio_(1.5)||goog.dom.matchesPixelRatio_(2)||goog.dom.matchesPixelRatio_(3)||1:1});
goog.dom.matchesPixelRatio_=function(a){return goog.dom.getWindow().matchMedia("(-webkit-min-device-pixel-ratio: "+a+"),(min--moz-device-pixel-ratio: "+a+"),(min-resolution: "+a+"dppx)").matches?a:0};goog.dom.DomHelper=function(a){this.document_=a||goog.global.document||document};goog.dom.DomHelper.prototype.getDomHelper=goog.dom.getDomHelper;goog.dom.DomHelper.prototype.setDocument=function(a){this.document_=a};goog.dom.DomHelper.prototype.getDocument=function(){return this.document_};
goog.dom.DomHelper.prototype.getElement=function(a){return goog.dom.getElementHelper_(this.document_,a)};goog.dom.DomHelper.prototype.getRequiredElement=function(a){return goog.dom.getRequiredElementHelper_(this.document_,a)};goog.dom.DomHelper.prototype.$=goog.dom.DomHelper.prototype.getElement;goog.dom.DomHelper.prototype.getElementsByTagNameAndClass=function(a,b,c){return goog.dom.getElementsByTagNameAndClass_(this.document_,a,b,c)};
goog.dom.DomHelper.prototype.getElementsByClass=function(a,b){return goog.dom.getElementsByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.getElementByClass=function(a,b){return goog.dom.getElementByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.$$=goog.dom.DomHelper.prototype.getElementsByTagNameAndClass;goog.dom.DomHelper.prototype.setProperties=goog.dom.setProperties;goog.dom.DomHelper.prototype.getViewportSize=function(a){return goog.dom.getViewportSize(a||this.getWindow())};
goog.dom.DomHelper.prototype.getDocumentHeight=function(){return goog.dom.getDocumentHeight_(this.getWindow())};goog.dom.DomHelper.prototype.createDom=function(a,b,c){return goog.dom.createDom_(this.document_,arguments)};goog.dom.DomHelper.prototype.$dom=goog.dom.DomHelper.prototype.createDom;goog.dom.DomHelper.prototype.createElement=function(a){return this.document_.createElement(a)};goog.dom.DomHelper.prototype.createTextNode=function(a){return this.document_.createTextNode(String(a))};
goog.dom.DomHelper.prototype.createTable=function(a,b,c){return goog.dom.createTable_(this.document_,a,b,!!c)};goog.dom.DomHelper.prototype.htmlToDocumentFragment=function(a){return goog.dom.htmlToDocumentFragment_(this.document_,a)};goog.dom.DomHelper.prototype.isCss1CompatMode=function(){return goog.dom.isCss1CompatMode_(this.document_)};goog.dom.DomHelper.prototype.getWindow=function(){return goog.dom.getWindow_(this.document_)};goog.dom.DomHelper.prototype.getDocumentScrollElement=function(){return goog.dom.getDocumentScrollElement_(this.document_)};
goog.dom.DomHelper.prototype.getDocumentScroll=function(){return goog.dom.getDocumentScroll_(this.document_)};goog.dom.DomHelper.prototype.getActiveElement=function(a){return goog.dom.getActiveElement(a||this.document_)};goog.dom.DomHelper.prototype.appendChild=goog.dom.appendChild;goog.dom.DomHelper.prototype.append=goog.dom.append;goog.dom.DomHelper.prototype.canHaveChildren=goog.dom.canHaveChildren;goog.dom.DomHelper.prototype.removeChildren=goog.dom.removeChildren;
goog.dom.DomHelper.prototype.insertSiblingBefore=goog.dom.insertSiblingBefore;goog.dom.DomHelper.prototype.insertSiblingAfter=goog.dom.insertSiblingAfter;goog.dom.DomHelper.prototype.insertChildAt=goog.dom.insertChildAt;goog.dom.DomHelper.prototype.removeNode=goog.dom.removeNode;goog.dom.DomHelper.prototype.replaceNode=goog.dom.replaceNode;goog.dom.DomHelper.prototype.flattenElement=goog.dom.flattenElement;goog.dom.DomHelper.prototype.getChildren=goog.dom.getChildren;
goog.dom.DomHelper.prototype.getFirstElementChild=goog.dom.getFirstElementChild;goog.dom.DomHelper.prototype.getLastElementChild=goog.dom.getLastElementChild;goog.dom.DomHelper.prototype.getNextElementSibling=goog.dom.getNextElementSibling;goog.dom.DomHelper.prototype.getPreviousElementSibling=goog.dom.getPreviousElementSibling;goog.dom.DomHelper.prototype.getNextNode=goog.dom.getNextNode;goog.dom.DomHelper.prototype.getPreviousNode=goog.dom.getPreviousNode;
goog.dom.DomHelper.prototype.isNodeLike=goog.dom.isNodeLike;goog.dom.DomHelper.prototype.isElement=goog.dom.isElement;goog.dom.DomHelper.prototype.isWindow=goog.dom.isWindow;goog.dom.DomHelper.prototype.getParentElement=goog.dom.getParentElement;goog.dom.DomHelper.prototype.contains=goog.dom.contains;goog.dom.DomHelper.prototype.compareNodeOrder=goog.dom.compareNodeOrder;goog.dom.DomHelper.prototype.findCommonAncestor=goog.dom.findCommonAncestor;goog.dom.DomHelper.prototype.getOwnerDocument=goog.dom.getOwnerDocument;
goog.dom.DomHelper.prototype.getFrameContentDocument=goog.dom.getFrameContentDocument;goog.dom.DomHelper.prototype.getFrameContentWindow=goog.dom.getFrameContentWindow;goog.dom.DomHelper.prototype.setTextContent=goog.dom.setTextContent;goog.dom.DomHelper.prototype.getOuterHtml=goog.dom.getOuterHtml;goog.dom.DomHelper.prototype.findNode=goog.dom.findNode;goog.dom.DomHelper.prototype.findNodes=goog.dom.findNodes;goog.dom.DomHelper.prototype.isFocusableTabIndex=goog.dom.isFocusableTabIndex;
goog.dom.DomHelper.prototype.setFocusableTabIndex=goog.dom.setFocusableTabIndex;goog.dom.DomHelper.prototype.isFocusable=goog.dom.isFocusable;goog.dom.DomHelper.prototype.getTextContent=goog.dom.getTextContent;goog.dom.DomHelper.prototype.getNodeTextLength=goog.dom.getNodeTextLength;goog.dom.DomHelper.prototype.getNodeTextOffset=goog.dom.getNodeTextOffset;goog.dom.DomHelper.prototype.getNodeAtOffset=goog.dom.getNodeAtOffset;goog.dom.DomHelper.prototype.isNodeList=goog.dom.isNodeList;
goog.dom.DomHelper.prototype.getAncestorByTagNameAndClass=goog.dom.getAncestorByTagNameAndClass;goog.dom.DomHelper.prototype.getAncestorByClass=goog.dom.getAncestorByClass;goog.dom.DomHelper.prototype.getAncestor=goog.dom.getAncestor;goog.disposable={};goog.disposable.IDisposable=function(){};goog.Disposable=function(){goog.Disposable.MONITORING_MODE!=goog.Disposable.MonitoringMode.OFF&&(goog.Disposable.INCLUDE_STACK_ON_CREATION&&(this.creationStack=Error().stack),goog.Disposable.instances_[goog.getUid(this)]=this)};goog.Disposable.MonitoringMode={OFF:0,PERMANENT:1,INTERACTIVE:2};goog.Disposable.MONITORING_MODE=0;goog.Disposable.INCLUDE_STACK_ON_CREATION=!0;goog.Disposable.instances_={};
goog.Disposable.getUndisposedObjects=function(){var a=[],b;for(b in goog.Disposable.instances_)goog.Disposable.instances_.hasOwnProperty(b)&&a.push(goog.Disposable.instances_[Number(b)]);return a};goog.Disposable.clearUndisposedObjects=function(){goog.Disposable.instances_={}};goog.Disposable.prototype.disposed_=!1;goog.Disposable.prototype.isDisposed=function(){return this.disposed_};goog.Disposable.prototype.getDisposed=goog.Disposable.prototype.isDisposed;
goog.Disposable.prototype.dispose=function(){if(!this.disposed_&&(this.disposed_=!0,this.disposeInternal(),goog.Disposable.MONITORING_MODE!=goog.Disposable.MonitoringMode.OFF)){var a=goog.getUid(this);if(goog.Disposable.MONITORING_MODE==goog.Disposable.MonitoringMode.PERMANENT&&!goog.Disposable.instances_.hasOwnProperty(a))throw Error(this+" did not call the goog.Disposable base constructor or was disposed of after a clearUndisposedObjects call");delete goog.Disposable.instances_[a]}};
goog.Disposable.prototype.registerDisposable=function(a){this.addOnDisposeCallback(goog.partial(goog.dispose,a))};goog.Disposable.prototype.addOnDisposeCallback=function(a,b){this.onDisposeCallbacks_||(this.onDisposeCallbacks_=[]);this.onDisposeCallbacks_.push(goog.bind(a,b))};goog.Disposable.prototype.disposeInternal=function(){if(this.onDisposeCallbacks_)for(;this.onDisposeCallbacks_.length;)this.onDisposeCallbacks_.shift()()};
goog.Disposable.isDisposed=function(a){return a&&"function"==typeof a.isDisposed?a.isDisposed():!1};goog.dispose=function(a){a&&"function"==typeof a.dispose&&a.dispose()};goog.disposeAll=function(a){for(var b=0,c=arguments.length;b<c;++b){var d=arguments[b];goog.isArrayLike(d)?goog.disposeAll.apply(null,d):goog.dispose(d)}};goog.debug.entryPointRegistry={};goog.debug.EntryPointMonitor=function(){};goog.debug.entryPointRegistry.refList_=[];goog.debug.entryPointRegistry.monitors_=[];goog.debug.entryPointRegistry.monitorsMayExist_=!1;goog.debug.entryPointRegistry.register=function(a){goog.debug.entryPointRegistry.refList_[goog.debug.entryPointRegistry.refList_.length]=a;if(goog.debug.entryPointRegistry.monitorsMayExist_)for(var b=goog.debug.entryPointRegistry.monitors_,c=0;c<b.length;c++)a(goog.bind(b[c].wrap,b[c]))};
goog.debug.entryPointRegistry.monitorAll=function(a){goog.debug.entryPointRegistry.monitorsMayExist_=!0;for(var b=goog.bind(a.wrap,a),c=0;c<goog.debug.entryPointRegistry.refList_.length;c++)goog.debug.entryPointRegistry.refList_[c](b);goog.debug.entryPointRegistry.monitors_.push(a)};
goog.debug.entryPointRegistry.unmonitorAllIfPossible=function(a){var b=goog.debug.entryPointRegistry.monitors_;goog.asserts.assert(a==b[b.length-1],"Only the most recent monitor can be unwrapped.");a=goog.bind(a.unwrap,a);for(var c=0;c<goog.debug.entryPointRegistry.refList_.length;c++)goog.debug.entryPointRegistry.refList_[c](a);b.length--};goog.events={};
goog.events.BrowserFeature={HAS_W3C_BUTTON:!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9),HAS_W3C_EVENT_SUPPORT:!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9),SET_KEY_CODE_TO_PREVENT_DEFAULT:goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),HAS_NAVIGATOR_ONLINE_PROPERTY:!goog.userAgent.WEBKIT||goog.userAgent.isVersionOrHigher("528"),HAS_HTML5_NETWORK_EVENT_SUPPORT:goog.userAgent.GECKO&&goog.userAgent.isVersionOrHigher("1.9b")||goog.userAgent.IE&&goog.userAgent.isVersionOrHigher("8")||
goog.userAgent.OPERA&&goog.userAgent.isVersionOrHigher("9.5")||goog.userAgent.WEBKIT&&goog.userAgent.isVersionOrHigher("528"),HTML5_NETWORK_EVENTS_FIRE_ON_BODY:goog.userAgent.GECKO&&!goog.userAgent.isVersionOrHigher("8")||goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),TOUCH_ENABLED:"ontouchstart"in goog.global||!!(goog.global.document&&document.documentElement&&"ontouchstart"in document.documentElement)||!(!goog.global.navigator||!goog.global.navigator.msMaxTouchPoints)};goog.events.Event=function(a,b){this.type=a;this.currentTarget=this.target=b};goog.events.Event.prototype.disposeInternal=function(){};goog.events.Event.prototype.dispose=function(){};goog.events.Event.prototype.propagationStopped_=!1;goog.events.Event.prototype.defaultPrevented=!1;goog.events.Event.prototype.returnValue_=!0;goog.events.Event.prototype.stopPropagation=function(){this.propagationStopped_=!0};
goog.events.Event.prototype.preventDefault=function(){this.defaultPrevented=!0;this.returnValue_=!1};goog.events.Event.stopPropagation=function(a){a.stopPropagation()};goog.events.Event.preventDefault=function(a){a.preventDefault()};goog.events.getVendorPrefixedName_=function(a){return goog.userAgent.WEBKIT?"webkit"+a:goog.userAgent.OPERA?"o"+a.toLowerCase():a.toLowerCase()};
goog.events.EventType={CLICK:"click",DBLCLICK:"dblclick",MOUSEDOWN:"mousedown",MOUSEUP:"mouseup",MOUSEOVER:"mouseover",MOUSEOUT:"mouseout",MOUSEMOVE:"mousemove",MOUSEENTER:"mouseenter",MOUSELEAVE:"mouseleave",SELECTSTART:"selectstart",KEYPRESS:"keypress",KEYDOWN:"keydown",KEYUP:"keyup",BLUR:"blur",FOCUS:"focus",DEACTIVATE:"deactivate",FOCUSIN:goog.userAgent.IE?"focusin":"DOMFocusIn",FOCUSOUT:goog.userAgent.IE?"focusout":"DOMFocusOut",CHANGE:"change",SELECT:"select",SUBMIT:"submit",INPUT:"input",PROPERTYCHANGE:"propertychange",
DRAGSTART:"dragstart",DRAG:"drag",DRAGENTER:"dragenter",DRAGOVER:"dragover",DRAGLEAVE:"dragleave",DROP:"drop",DRAGEND:"dragend",TOUCHSTART:"touchstart",TOUCHMOVE:"touchmove",TOUCHEND:"touchend",TOUCHCANCEL:"touchcancel",BEFOREUNLOAD:"beforeunload",CONSOLEMESSAGE:"consolemessage",CONTEXTMENU:"contextmenu",DOMCONTENTLOADED:"DOMContentLoaded",ERROR:"error",HELP:"help",LOAD:"load",LOSECAPTURE:"losecapture",ORIENTATIONCHANGE:"orientationchange",READYSTATECHANGE:"readystatechange",RESIZE:"resize",SCROLL:"scroll",
UNLOAD:"unload",HASHCHANGE:"hashchange",PAGEHIDE:"pagehide",PAGESHOW:"pageshow",POPSTATE:"popstate",COPY:"copy",PASTE:"paste",CUT:"cut",BEFORECOPY:"beforecopy",BEFORECUT:"beforecut",BEFOREPASTE:"beforepaste",ONLINE:"online",OFFLINE:"offline",MESSAGE:"message",CONNECT:"connect",ANIMATIONSTART:goog.events.getVendorPrefixedName_("AnimationStart"),ANIMATIONEND:goog.events.getVendorPrefixedName_("AnimationEnd"),ANIMATIONITERATION:goog.events.getVendorPrefixedName_("AnimationIteration"),TRANSITIONEND:goog.events.getVendorPrefixedName_("TransitionEnd"),
POINTERDOWN:"pointerdown",POINTERUP:"pointerup",POINTERCANCEL:"pointercancel",POINTERMOVE:"pointermove",POINTEROVER:"pointerover",POINTEROUT:"pointerout",POINTERENTER:"pointerenter",POINTERLEAVE:"pointerleave",GOTPOINTERCAPTURE:"gotpointercapture",LOSTPOINTERCAPTURE:"lostpointercapture",MSGESTURECHANGE:"MSGestureChange",MSGESTUREEND:"MSGestureEnd",MSGESTUREHOLD:"MSGestureHold",MSGESTURESTART:"MSGestureStart",MSGESTURETAP:"MSGestureTap",MSGOTPOINTERCAPTURE:"MSGotPointerCapture",MSINERTIASTART:"MSInertiaStart",
MSLOSTPOINTERCAPTURE:"MSLostPointerCapture",MSPOINTERCANCEL:"MSPointerCancel",MSPOINTERDOWN:"MSPointerDown",MSPOINTERENTER:"MSPointerEnter",MSPOINTERHOVER:"MSPointerHover",MSPOINTERLEAVE:"MSPointerLeave",MSPOINTERMOVE:"MSPointerMove",MSPOINTEROUT:"MSPointerOut",MSPOINTEROVER:"MSPointerOver",MSPOINTERUP:"MSPointerUp",TEXTINPUT:"textinput",COMPOSITIONSTART:"compositionstart",COMPOSITIONUPDATE:"compositionupdate",COMPOSITIONEND:"compositionend",EXIT:"exit",LOADABORT:"loadabort",LOADCOMMIT:"loadcommit",
LOADREDIRECT:"loadredirect",LOADSTART:"loadstart",LOADSTOP:"loadstop",RESPONSIVE:"responsive",SIZECHANGED:"sizechanged",UNRESPONSIVE:"unresponsive",VISIBILITYCHANGE:"visibilitychange"};goog.reflect={};goog.reflect.object=function(a,b){return b};goog.reflect.sinkValue=function(a){goog.reflect.sinkValue[" "](a);return a};goog.reflect.sinkValue[" "]=goog.nullFunction;goog.reflect.canAccessProperty=function(a,b){try{return goog.reflect.sinkValue(a[b]),!0}catch(c){}return!1};goog.events.BrowserEvent=function(a,b){a&&this.init(a,b)};goog.inherits(goog.events.BrowserEvent,goog.events.Event);goog.events.BrowserEvent.MouseButton={LEFT:0,MIDDLE:1,RIGHT:2};goog.events.BrowserEvent.IEButtonMap=[1,4,2];goog.events.BrowserEvent.prototype.target=null;goog.events.BrowserEvent.prototype.relatedTarget=null;goog.events.BrowserEvent.prototype.offsetX=0;goog.events.BrowserEvent.prototype.offsetY=0;goog.events.BrowserEvent.prototype.clientX=0;
goog.events.BrowserEvent.prototype.clientY=0;goog.events.BrowserEvent.prototype.screenX=0;goog.events.BrowserEvent.prototype.screenY=0;goog.events.BrowserEvent.prototype.button=0;goog.events.BrowserEvent.prototype.keyCode=0;goog.events.BrowserEvent.prototype.charCode=0;goog.events.BrowserEvent.prototype.ctrlKey=!1;goog.events.BrowserEvent.prototype.altKey=!1;goog.events.BrowserEvent.prototype.shiftKey=!1;goog.events.BrowserEvent.prototype.metaKey=!1;
goog.events.BrowserEvent.prototype.platformModifierKey=!1;goog.events.BrowserEvent.prototype.event_=null;
goog.events.BrowserEvent.prototype.init=function(a,b){var c=this.type=a.type;goog.events.Event.call(this,c);this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;d?goog.userAgent.GECKO&&(goog.reflect.canAccessProperty(d,"nodeName")||(d=null)):c==goog.events.EventType.MOUSEOVER?d=a.fromElement:c==goog.events.EventType.MOUSEOUT&&(d=a.toElement);this.relatedTarget=d;this.offsetX=goog.userAgent.WEBKIT||void 0!==a.offsetX?a.offsetX:a.layerX;this.offsetY=goog.userAgent.WEBKIT||void 0!==
a.offsetY?a.offsetY:a.layerY;this.clientX=void 0!==a.clientX?a.clientX:a.pageX;this.clientY=void 0!==a.clientY?a.clientY:a.pageY;this.screenX=a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=a.metaKey;this.platformModifierKey=goog.userAgent.MAC?a.metaKey:a.ctrlKey;this.state=a.state;this.event_=a;a.defaultPrevented&&this.preventDefault();
delete this.propagationStopped_};goog.events.BrowserEvent.prototype.isButton=function(a){return goog.events.BrowserFeature.HAS_W3C_BUTTON?this.event_.button==a:"click"==this.type?a==goog.events.BrowserEvent.MouseButton.LEFT:!!(this.event_.button&goog.events.BrowserEvent.IEButtonMap[a])};goog.events.BrowserEvent.prototype.isMouseActionButton=function(){return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT)&&!(goog.userAgent.WEBKIT&&goog.userAgent.MAC&&this.ctrlKey)};
goog.events.BrowserEvent.prototype.stopPropagation=function(){goog.events.BrowserEvent.superClass_.stopPropagation.call(this);this.event_.stopPropagation?this.event_.stopPropagation():this.event_.cancelBubble=!0};
goog.events.BrowserEvent.prototype.preventDefault=function(){goog.events.BrowserEvent.superClass_.preventDefault.call(this);var a=this.event_;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};goog.events.BrowserEvent.prototype.getBrowserEvent=function(){return this.event_};goog.events.BrowserEvent.prototype.disposeInternal=function(){};goog.events.EventId=function(a){this.id=a};goog.events.EventId.prototype.toString=function(){return this.id};goog.events.Listenable=function(){};goog.events.Listenable.IMPLEMENTED_BY_PROP="closure_listenable_"+(1E6*Math.random()|0);goog.events.Listenable.addImplementation=function(a){a.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP]=!0};goog.events.Listenable.isImplementedBy=function(a){try{return!(!a||!a[goog.events.Listenable.IMPLEMENTED_BY_PROP])}catch(b){return!1}};goog.events.ListenableKey=function(){};goog.events.ListenableKey.counter_=0;goog.events.ListenableKey.reserveKey=function(){return++goog.events.ListenableKey.counter_};goog.events.Listener=function(a,b,c,d,e,f){goog.events.Listener.ENABLE_MONITORING&&(this.creationStack=Error().stack);this.listener=a;this.proxy=b;this.src=c;this.type=d;this.capture=!!e;this.handler=f;this.key=goog.events.ListenableKey.reserveKey();this.removed=this.callOnce=!1};goog.events.Listener.ENABLE_MONITORING=!1;goog.events.Listener.prototype.markAsRemoved=function(){this.removed=!0;this.handler=this.src=this.proxy=this.listener=null};goog.events.ListenerMap=function(a){this.src=a;this.listeners={};this.typeCount_=0};goog.events.ListenerMap.prototype.getTypeCount=function(){return this.typeCount_};goog.events.ListenerMap.prototype.getListenerCount=function(){var a=0,b;for(b in this.listeners)a+=this.listeners[b].length;return a};
goog.events.ListenerMap.prototype.add=function(a,b,c,d,e){var f=this.listeners[a];f||(f=this.listeners[a]=[],this.typeCount_++);var g=goog.events.ListenerMap.findListenerIndex_(f,b,d,e);-1<g?(a=f[g],c||(a.callOnce=!1)):(a=new goog.events.Listener(b,null,this.src,a,!!d,e),a.callOnce=c,f.push(a));return a};
goog.events.ListenerMap.prototype.remove=function(a,b,c,d){if(!(a in this.listeners))return!1;var e=this.listeners[a];b=goog.events.ListenerMap.findListenerIndex_(e,b,c,d);return-1<b?(e[b].markAsRemoved(),goog.array.removeAt(e,b),0==e.length&&(delete this.listeners[a],this.typeCount_--),!0):!1};
goog.events.ListenerMap.prototype.removeByKey=function(a){var b=a.type;if(!(b in this.listeners))return!1;var c=goog.array.remove(this.listeners[b],a);c&&(a.markAsRemoved(),0==this.listeners[b].length&&(delete this.listeners[b],this.typeCount_--));return c};goog.events.ListenerMap.prototype.removeAll=function(a){var b=0,c;for(c in this.listeners)if(!a||c==a){for(var d=this.listeners[c],e=0;e<d.length;e++)++b,d[e].markAsRemoved();delete this.listeners[c];this.typeCount_--}return b};
goog.events.ListenerMap.prototype.getListeners=function(a,b){var c=this.listeners[a],d=[];if(c)for(var e=0;e<c.length;++e){var f=c[e];f.capture==b&&d.push(f)}return d};goog.events.ListenerMap.prototype.getListener=function(a,b,c,d){a=this.listeners[a];var e=-1;a&&(e=goog.events.ListenerMap.findListenerIndex_(a,b,c,d));return-1<e?a[e]:null};
goog.events.ListenerMap.prototype.hasListener=function(a,b){var c=goog.isDef(a),d=goog.isDef(b);return goog.object.some(this.listeners,function(e,f){for(var g=0;g<e.length;++g)if(!(c&&e[g].type!=a||d&&e[g].capture!=b))return!0;return!1})};goog.events.ListenerMap.findListenerIndex_=function(a,b,c,d){for(var e=0;e<a.length;++e){var f=a[e];if(!f.removed&&f.listener==b&&f.capture==!!c&&f.handler==d)return e}return-1};goog.events.listeners_={};goog.events.LISTENER_MAP_PROP_="closure_lm_"+(1E6*Math.random()|0);goog.events.onString_="on";goog.events.onStringMap_={};goog.events.CaptureSimulationMode={OFF_AND_FAIL:0,OFF_AND_SILENT:1,ON:2};goog.events.CAPTURE_SIMULATION_MODE=2;goog.events.listenerCountEstimate_=0;
goog.events.listen=function(a,b,c,d,e){if(goog.isArray(b)){for(var f=0;f<b.length;f++)goog.events.listen(a,b[f],c,d,e);return null}c=goog.events.wrapListener_(c);return goog.events.Listenable.isImplementedBy(a)?a.listen(b,c,d,e):goog.events.listen_(a,b,c,!1,d,e)};
goog.events.listen_=function(a,b,c,d,e,f){if(!b)throw Error("Invalid event type");var g=!!e;if(g&&!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT){if(goog.events.CAPTURE_SIMULATION_MODE==goog.events.CaptureSimulationMode.OFF_AND_FAIL)return goog.asserts.fail("Can not register capture listener in IE8-."),null;if(goog.events.CAPTURE_SIMULATION_MODE==goog.events.CaptureSimulationMode.OFF_AND_SILENT)return null}var h=goog.events.getListenerMap_(a);h||(a[goog.events.LISTENER_MAP_PROP_]=h=new goog.events.ListenerMap(a));
c=h.add(b,c,d,e,f);if(c.proxy)return c;d=goog.events.getProxy();c.proxy=d;d.src=a;d.listener=c;a.addEventListener?a.addEventListener(b,d,g):a.attachEvent(goog.events.getOnString_(b),d);goog.events.listenerCountEstimate_++;return c};goog.events.getProxy=function(){var a=goog.events.handleBrowserEvent_,b=goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT?function(c){return a.call(b.src,b.listener,c)}:function(c){c=a.call(b.src,b.listener,c);if(!c)return c};return b};
goog.events.listenOnce=function(a,b,c,d,e){if(goog.isArray(b)){for(var f=0;f<b.length;f++)goog.events.listenOnce(a,b[f],c,d,e);return null}c=goog.events.wrapListener_(c);return goog.events.Listenable.isImplementedBy(a)?a.listenOnce(b,c,d,e):goog.events.listen_(a,b,c,!0,d,e)};goog.events.listenWithWrapper=function(a,b,c,d,e){b.listen(a,c,d,e)};
goog.events.unlisten=function(a,b,c,d,e){if(goog.isArray(b)){for(var f=0;f<b.length;f++)goog.events.unlisten(a,b[f],c,d,e);return null}c=goog.events.wrapListener_(c);if(goog.events.Listenable.isImplementedBy(a))return a.unlisten(b,c,d,e);if(!a)return!1;d=!!d;if(a=goog.events.getListenerMap_(a))if(b=a.getListener(b,c,d,e))return goog.events.unlistenByKey(b);return!1};
goog.events.unlistenByKey=function(a){if(goog.isNumber(a)||!a||a.removed)return!1;var b=a.src;if(goog.events.Listenable.isImplementedBy(b))return b.unlistenByKey(a);var c=a.type,d=a.proxy;b.removeEventListener?b.removeEventListener(c,d,a.capture):b.detachEvent&&b.detachEvent(goog.events.getOnString_(c),d);goog.events.listenerCountEstimate_--;(c=goog.events.getListenerMap_(b))?(c.removeByKey(a),0==c.getTypeCount()&&(c.src=null,b[goog.events.LISTENER_MAP_PROP_]=null)):a.markAsRemoved();return!0};
goog.events.unlistenWithWrapper=function(a,b,c,d,e){b.unlisten(a,c,d,e)};goog.events.removeAll=function(a,b){if(!a)return 0;if(goog.events.Listenable.isImplementedBy(a))return a.removeAllListeners(b);var c=goog.events.getListenerMap_(a);if(!c)return 0;var d=0,e;for(e in c.listeners)if(!b||e==b)for(var f=goog.array.clone(c.listeners[e]),g=0;g<f.length;++g)goog.events.unlistenByKey(f[g])&&++d;return d};goog.events.removeAllNativeListeners=function(){return goog.events.listenerCountEstimate_=0};
goog.events.getListeners=function(a,b,c){return goog.events.Listenable.isImplementedBy(a)?a.getListeners(b,c):a?(a=goog.events.getListenerMap_(a))?a.getListeners(b,c):[]:[]};goog.events.getListener=function(a,b,c,d,e){c=goog.events.wrapListener_(c);d=!!d;return goog.events.Listenable.isImplementedBy(a)?a.getListener(b,c,d,e):a?(a=goog.events.getListenerMap_(a))?a.getListener(b,c,d,e):null:null};
goog.events.hasListener=function(a,b,c){if(goog.events.Listenable.isImplementedBy(a))return a.hasListener(b,c);a=goog.events.getListenerMap_(a);return!!a&&a.hasListener(b,c)};goog.events.expose=function(a){var b=[],c;for(c in a)a[c]&&a[c].id?b.push(c+" = "+a[c]+" ("+a[c].id+")"):b.push(c+" = "+a[c]);return b.join("\n")};goog.events.getOnString_=function(a){return a in goog.events.onStringMap_?goog.events.onStringMap_[a]:goog.events.onStringMap_[a]=goog.events.onString_+a};
goog.events.fireListeners=function(a,b,c,d){return goog.events.Listenable.isImplementedBy(a)?a.fireListeners(b,c,d):goog.events.fireListeners_(a,b,c,d)};goog.events.fireListeners_=function(a,b,c,d){var e=1;if(a=goog.events.getListenerMap_(a))if(b=a.listeners[b])for(b=goog.array.clone(b),a=0;a<b.length;a++){var f=b[a];f&&f.capture==c&&!f.removed&&(e&=!1!==goog.events.fireListener(f,d))}return Boolean(e)};
goog.events.fireListener=function(a,b){var c=a.listener,d=a.handler||a.src;a.callOnce&&goog.events.unlistenByKey(a);return c.call(d,b)};goog.events.getTotalListenerCount=function(){return goog.events.listenerCountEstimate_};goog.events.dispatchEvent=function(a,b){goog.asserts.assert(goog.events.Listenable.isImplementedBy(a),"Can not use goog.events.dispatchEvent with non-goog.events.Listenable instance.");return a.dispatchEvent(b)};
goog.events.protectBrowserEventEntryPoint=function(a){goog.events.handleBrowserEvent_=a.protectEntryPoint(goog.events.handleBrowserEvent_)};
goog.events.handleBrowserEvent_=function(a,b){if(a.removed)return!0;if(!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT){var c=b||goog.getObjectByName("window.event"),d=new goog.events.BrowserEvent(c,this),e=!0;if(goog.events.CAPTURE_SIMULATION_MODE==goog.events.CaptureSimulationMode.ON){if(!goog.events.isMarkedIeEvent_(c)){goog.events.markIeEvent_(c);for(var c=[],f=d.currentTarget;f;f=f.parentNode)c.push(f);for(var f=a.type,g=c.length-1;!d.propagationStopped_&&0<=g;g--)d.currentTarget=c[g],e&=goog.events.fireListeners_(c[g],
f,!0,d);for(g=0;!d.propagationStopped_&&g<c.length;g++)d.currentTarget=c[g],e&=goog.events.fireListeners_(c[g],f,!1,d)}}else e=goog.events.fireListener(a,d);return e}return goog.events.fireListener(a,new goog.events.BrowserEvent(b,this))};goog.events.markIeEvent_=function(a){var b=!1;if(0==a.keyCode)try{a.keyCode=-1;return}catch(c){b=!0}if(b||void 0==a.returnValue)a.returnValue=!0};goog.events.isMarkedIeEvent_=function(a){return 0>a.keyCode||void 0!=a.returnValue};goog.events.uniqueIdCounter_=0;
goog.events.getUniqueId=function(a){return a+"_"+goog.events.uniqueIdCounter_++};goog.events.getListenerMap_=function(a){a=a[goog.events.LISTENER_MAP_PROP_];return a instanceof goog.events.ListenerMap?a:null};goog.events.LISTENER_WRAPPER_PROP_="__closure_events_fn_"+(1E9*Math.random()>>>0);
goog.events.wrapListener_=function(a){goog.asserts.assert(a,"Listener can not be null.");if(goog.isFunction(a))return a;goog.asserts.assert(a.handleEvent,"An object listener must have handleEvent method.");return a[goog.events.LISTENER_WRAPPER_PROP_]||(a[goog.events.LISTENER_WRAPPER_PROP_]=function(b){return a.handleEvent(b)})};goog.debug.entryPointRegistry.register(function(a){goog.events.handleBrowserEvent_=a(goog.events.handleBrowserEvent_)});goog.events.EventTarget=function(){goog.Disposable.call(this);this.eventTargetListeners_=new goog.events.ListenerMap(this);this.actualEventTarget_=this};goog.inherits(goog.events.EventTarget,goog.Disposable);goog.events.Listenable.addImplementation(goog.events.EventTarget);goog.events.EventTarget.MAX_ANCESTORS_=1E3;goog.events.EventTarget.prototype.parentEventTarget_=null;goog.events.EventTarget.prototype.getParentEventTarget=function(){return this.parentEventTarget_};
goog.events.EventTarget.prototype.setParentEventTarget=function(a){this.parentEventTarget_=a};goog.events.EventTarget.prototype.addEventListener=function(a,b,c,d){goog.events.listen(this,a,b,c,d)};goog.events.EventTarget.prototype.removeEventListener=function(a,b,c,d){goog.events.unlisten(this,a,b,c,d)};
goog.events.EventTarget.prototype.dispatchEvent=function(a){this.assertInitialized_();var b,c=this.getParentEventTarget();if(c){b=[];for(var d=1;c;c=c.getParentEventTarget())b.push(c),goog.asserts.assert(++d<goog.events.EventTarget.MAX_ANCESTORS_,"infinite loop")}return goog.events.EventTarget.dispatchEventInternal_(this.actualEventTarget_,a,b)};
goog.events.EventTarget.prototype.disposeInternal=function(){goog.events.EventTarget.superClass_.disposeInternal.call(this);this.removeAllListeners();this.parentEventTarget_=null};goog.events.EventTarget.prototype.listen=function(a,b,c,d){this.assertInitialized_();return this.eventTargetListeners_.add(String(a),b,!1,c,d)};goog.events.EventTarget.prototype.listenOnce=function(a,b,c,d){return this.eventTargetListeners_.add(String(a),b,!0,c,d)};
goog.events.EventTarget.prototype.unlisten=function(a,b,c,d){return this.eventTargetListeners_.remove(String(a),b,c,d)};goog.events.EventTarget.prototype.unlistenByKey=function(a){return this.eventTargetListeners_.removeByKey(a)};goog.events.EventTarget.prototype.removeAllListeners=function(a){return this.eventTargetListeners_?this.eventTargetListeners_.removeAll(a):0};
goog.events.EventTarget.prototype.fireListeners=function(a,b,c){a=this.eventTargetListeners_.listeners[String(a)];if(!a)return!0;a=goog.array.clone(a);for(var d=!0,e=0;e<a.length;++e){var f=a[e];if(f&&!f.removed&&f.capture==b){var g=f.listener,h=f.handler||f.src;f.callOnce&&this.unlistenByKey(f);d=!1!==g.call(h,c)&&d}}return d&&!1!=c.returnValue_};goog.events.EventTarget.prototype.getListeners=function(a,b){return this.eventTargetListeners_.getListeners(String(a),b)};
goog.events.EventTarget.prototype.getListener=function(a,b,c,d){return this.eventTargetListeners_.getListener(String(a),b,c,d)};goog.events.EventTarget.prototype.hasListener=function(a,b){var c=goog.isDef(a)?String(a):void 0;return this.eventTargetListeners_.hasListener(c,b)};goog.events.EventTarget.prototype.setTargetForTesting=function(a){this.actualEventTarget_=a};goog.events.EventTarget.prototype.assertInitialized_=function(){goog.asserts.assert(this.eventTargetListeners_,"Event target is not initialized. Did you call the superclass (goog.events.EventTarget) constructor?")};
goog.events.EventTarget.dispatchEventInternal_=function(a,b,c){var d=b.type||b;if(goog.isString(b))b=new goog.events.Event(b,a);else if(b instanceof goog.events.Event)b.target=b.target||a;else{var e=b;b=new goog.events.Event(d,a);goog.object.extend(b,e)}var e=!0,f;if(c)for(var g=c.length-1;!b.propagationStopped_&&0<=g;g--)f=b.currentTarget=c[g],e=f.fireListeners(d,!0,b)&&e;b.propagationStopped_||(f=b.currentTarget=a,e=f.fireListeners(d,!0,b)&&e,b.propagationStopped_||(e=f.fireListeners(d,!1,b)&&e));
if(c)for(g=0;!b.propagationStopped_&&g<c.length;g++)f=b.currentTarget=c[g],e=f.fireListeners(d,!1,b)&&e;return e};goog.Timer=function(a,b){goog.events.EventTarget.call(this);this.interval_=a||1;this.timerObject_=b||goog.Timer.defaultTimerObject;this.boundTick_=goog.bind(this.tick_,this);this.last_=goog.now()};goog.inherits(goog.Timer,goog.events.EventTarget);goog.Timer.MAX_TIMEOUT_=2147483647;goog.Timer.prototype.enabled=!1;goog.Timer.defaultTimerObject=goog.global;goog.Timer.intervalScale=0.8;goog.Timer.prototype.timer_=null;goog.Timer.prototype.getInterval=function(){return this.interval_};
goog.Timer.prototype.setInterval=function(a){this.interval_=a;this.timer_&&this.enabled?(this.stop(),this.start()):this.timer_&&this.stop()};
goog.Timer.prototype.tick_=function(){if(this.enabled){var a=goog.now()-this.last_;0<a&&a<this.interval_*goog.Timer.intervalScale?this.timer_=this.timerObject_.setTimeout(this.boundTick_,this.interval_-a):(this.timer_&&(this.timerObject_.clearTimeout(this.timer_),this.timer_=null),this.dispatchTick(),this.enabled&&(this.timer_=this.timerObject_.setTimeout(this.boundTick_,this.interval_),this.last_=goog.now()))}};goog.Timer.prototype.dispatchTick=function(){this.dispatchEvent(goog.Timer.TICK)};
goog.Timer.prototype.start=function(){this.enabled=!0;this.timer_||(this.timer_=this.timerObject_.setTimeout(this.boundTick_,this.interval_),this.last_=goog.now())};goog.Timer.prototype.stop=function(){this.enabled=!1;this.timer_&&(this.timerObject_.clearTimeout(this.timer_),this.timer_=null)};goog.Timer.prototype.disposeInternal=function(){goog.Timer.superClass_.disposeInternal.call(this);this.stop();delete this.timerObject_};goog.Timer.TICK="tick";
goog.Timer.callOnce=function(a,b,c){if(goog.isFunction(a))c&&(a=goog.bind(a,c));else if(a&&"function"==typeof a.handleEvent)a=goog.bind(a.handleEvent,a);else throw Error("Invalid listener argument");return b>goog.Timer.MAX_TIMEOUT_?-1:goog.Timer.defaultTimerObject.setTimeout(a,b||0)};goog.Timer.clear=function(a){goog.Timer.defaultTimerObject.clearTimeout(a)};goog.json={};goog.json.isValid_=function(a){return/^\s*$/.test(a)?!1:/^[\],:{}\s\u2028\u2029]*$/.test(a.replace(/\\["\\\/bfnrtu]/g,"@").replace(/"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g,""))};goog.json.parse=function(a){a=String(a);if(goog.json.isValid_(a))try{return eval("("+a+")")}catch(b){}throw Error("Invalid JSON string: "+a);};goog.json.unsafeParse=function(a){return eval("("+a+")")};
goog.json.serialize=function(a,b){return(new goog.json.Serializer(b)).serialize(a)};goog.json.Serializer=function(a){this.replacer_=a};goog.json.Serializer.prototype.serialize=function(a){var b=[];this.serialize_(a,b);return b.join("")};
goog.json.Serializer.prototype.serialize_=function(a,b){switch(typeof a){case "string":this.serializeString_(a,b);break;case "number":this.serializeNumber_(a,b);break;case "boolean":b.push(a);break;case "undefined":b.push("null");break;case "object":if(null==a){b.push("null");break}if(goog.isArray(a)){this.serializeArray(a,b);break}this.serializeObject_(a,b);break;case "function":break;default:throw Error("Unknown type: "+typeof a);}};
goog.json.Serializer.charToJsonCharCache_={'"':'\\"',"\\":"\\\\","/":"\\/","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\x0B":"\\u000b"};goog.json.Serializer.charsToReplace_=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
goog.json.Serializer.prototype.serializeString_=function(a,b){b.push('"',a.replace(goog.json.Serializer.charsToReplace_,function(a){if(a in goog.json.Serializer.charToJsonCharCache_)return goog.json.Serializer.charToJsonCharCache_[a];var b=a.charCodeAt(0),e="\\u";16>b?e+="000":256>b?e+="00":4096>b&&(e+="0");return goog.json.Serializer.charToJsonCharCache_[a]=e+b.toString(16)}),'"')};goog.json.Serializer.prototype.serializeNumber_=function(a,b){b.push(isFinite(a)&&!isNaN(a)?a:"null")};
goog.json.Serializer.prototype.serializeArray=function(a,b){var c=a.length;b.push("[");for(var d="",e=0;e<c;e++)b.push(d),d=a[e],this.serialize_(this.replacer_?this.replacer_.call(a,String(e),d):d,b),d=",";b.push("]")};
goog.json.Serializer.prototype.serializeObject_=function(a,b){b.push("{");var c="",d;for(d in a)if(Object.prototype.hasOwnProperty.call(a,d)){var e=a[d];"function"!=typeof e&&(b.push(c),this.serializeString_(d,b),b.push(":"),this.serialize_(this.replacer_?this.replacer_.call(a,d,e):e,b),c=",")}b.push("}")};goog.structs={};goog.structs.getCount=function(a){return"function"==typeof a.getCount?a.getCount():goog.isArrayLike(a)||goog.isString(a)?a.length:goog.object.getCount(a)};goog.structs.getValues=function(a){if("function"==typeof a.getValues)return a.getValues();if(goog.isString(a))return a.split("");if(goog.isArrayLike(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return goog.object.getValues(a)};
goog.structs.getKeys=function(a){if("function"==typeof a.getKeys)return a.getKeys();if("function"!=typeof a.getValues){if(goog.isArrayLike(a)||goog.isString(a)){var b=[];a=a.length;for(var c=0;c<a;c++)b.push(c);return b}return goog.object.getKeys(a)}};goog.structs.contains=function(a,b){return"function"==typeof a.contains?a.contains(b):"function"==typeof a.containsValue?a.containsValue(b):goog.isArrayLike(a)||goog.isString(a)?goog.array.contains(a,b):goog.object.containsValue(a,b)};
goog.structs.isEmpty=function(a){return"function"==typeof a.isEmpty?a.isEmpty():goog.isArrayLike(a)||goog.isString(a)?goog.array.isEmpty(a):goog.object.isEmpty(a)};goog.structs.clear=function(a){"function"==typeof a.clear?a.clear():goog.isArrayLike(a)?goog.array.clear(a):goog.object.clear(a)};
goog.structs.forEach=function(a,b,c){if("function"==typeof a.forEach)a.forEach(b,c);else if(goog.isArrayLike(a)||goog.isString(a))goog.array.forEach(a,b,c);else for(var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length,g=0;g<f;g++)b.call(c,e[g],d&&d[g],a)};
goog.structs.filter=function(a,b,c){if("function"==typeof a.filter)return a.filter(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.filter(a,b,c);var d,e=goog.structs.getKeys(a),f=goog.structs.getValues(a),g=f.length;if(e){d={};for(var h=0;h<g;h++)b.call(c,f[h],e[h],a)&&(d[e[h]]=f[h])}else for(d=[],h=0;h<g;h++)b.call(c,f[h],void 0,a)&&d.push(f[h]);return d};
goog.structs.map=function(a,b,c){if("function"==typeof a.map)return a.map(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.map(a,b,c);var d,e=goog.structs.getKeys(a),f=goog.structs.getValues(a),g=f.length;if(e){d={};for(var h=0;h<g;h++)d[e[h]]=b.call(c,f[h],e[h],a)}else for(d=[],h=0;h<g;h++)d[h]=b.call(c,f[h],void 0,a);return d};
goog.structs.some=function(a,b,c){if("function"==typeof a.some)return a.some(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.some(a,b,c);for(var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length,g=0;g<f;g++)if(b.call(c,e[g],d&&d[g],a))return!0;return!1};
goog.structs.every=function(a,b,c){if("function"==typeof a.every)return a.every(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.every(a,b,c);for(var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length,g=0;g<f;g++)if(!b.call(c,e[g],d&&d[g],a))return!1;return!0};goog.structs.Collection=function(){};goog.iter={};goog.iter.StopIteration="StopIteration"in goog.global?goog.global.StopIteration:Error("StopIteration");goog.iter.Iterator=function(){};goog.iter.Iterator.prototype.next=function(){throw goog.iter.StopIteration;};goog.iter.Iterator.prototype.__iterator__=function(a){return this};
goog.iter.toIterator=function(a){if(a instanceof goog.iter.Iterator)return a;if("function"==typeof a.__iterator__)return a.__iterator__(!1);if(goog.isArrayLike(a)){var b=0,c=new goog.iter.Iterator;c.next=function(){for(;;){if(b>=a.length)throw goog.iter.StopIteration;if(b in a)return a[b++];b++}};return c}throw Error("Not implemented");};
goog.iter.forEach=function(a,b,c){if(goog.isArrayLike(a))try{goog.array.forEach(a,b,c)}catch(d){if(d!==goog.iter.StopIteration)throw d;}else{a=goog.iter.toIterator(a);try{for(;;)b.call(c,a.next(),void 0,a)}catch(e){if(e!==goog.iter.StopIteration)throw e;}}};goog.iter.filter=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;a.next=function(){for(;;){var a=d.next();if(b.call(c,a,void 0,d))return a}};return a};
goog.iter.range=function(a,b,c){var d=0,e=a,f=c||1;1<arguments.length&&(d=a,e=b);if(0==f)throw Error("Range step argument must not be zero");var g=new goog.iter.Iterator;g.next=function(){if(0<f&&d>=e||0>f&&d<=e)throw goog.iter.StopIteration;var a=d;d+=f;return a};return g};goog.iter.join=function(a,b){return goog.iter.toArray(a).join(b)};goog.iter.map=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;a.next=function(){for(;;){var a=d.next();return b.call(c,a,void 0,d)}};return a};
goog.iter.reduce=function(a,b,c,d){var e=c;goog.iter.forEach(a,function(a){e=b.call(d,e,a)});return e};goog.iter.some=function(a,b,c){a=goog.iter.toIterator(a);try{for(;;)if(b.call(c,a.next(),void 0,a))return!0}catch(d){if(d!==goog.iter.StopIteration)throw d;}return!1};goog.iter.every=function(a,b,c){a=goog.iter.toIterator(a);try{for(;;)if(!b.call(c,a.next(),void 0,a))return!1}catch(d){if(d!==goog.iter.StopIteration)throw d;}return!0};
goog.iter.chain=function(a){var b=goog.iter.toIterator(arguments),c=new goog.iter.Iterator,d=null;c.next=function(){for(;;){if(null==d){var a=b.next();d=goog.iter.toIterator(a)}try{return d.next()}catch(c){if(c!==goog.iter.StopIteration)throw c;d=null}}};return c};goog.iter.chainFromIterable=function(a){return goog.iter.chain.apply(void 0,a)};
goog.iter.dropWhile=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;var e=!0;a.next=function(){for(;;){var a=d.next();if(!e||!b.call(c,a,void 0,d))return e=!1,a}};return a};goog.iter.takeWhile=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;var e=!0;a.next=function(){for(;;)if(e){var a=d.next();if(b.call(c,a,void 0,d))return a;e=!1}else throw goog.iter.StopIteration;};return a};
goog.iter.toArray=function(a){if(goog.isArrayLike(a))return goog.array.toArray(a);a=goog.iter.toIterator(a);var b=[];goog.iter.forEach(a,function(a){b.push(a)});return b};goog.iter.equals=function(a,b){var c=goog.iter.zipLongest({},a,b);return goog.iter.every(c,function(a){return a[0]==a[1]})};goog.iter.nextOrValue=function(a,b){try{return goog.iter.toIterator(a).next()}catch(c){if(c!=goog.iter.StopIteration)throw c;return b}};
goog.iter.product=function(a){if(goog.array.some(arguments,function(a){return!a.length})||!arguments.length)return new goog.iter.Iterator;var b=new goog.iter.Iterator,c=arguments,d=goog.array.repeat(0,c.length);b.next=function(){if(d){for(var a=goog.array.map(d,function(a,b){return c[b][a]}),b=d.length-1;0<=b;b--){goog.asserts.assert(d);if(d[b]<c[b].length-1){d[b]++;break}if(0==b){d=null;break}d[b]=0}return a}throw goog.iter.StopIteration;};return b};
goog.iter.cycle=function(a){var b=goog.iter.toIterator(a),c=[],d=0;a=new goog.iter.Iterator;var e=!1;a.next=function(){var a=null;if(!e)try{return a=b.next(),c.push(a),a}catch(g){if(g!=goog.iter.StopIteration||goog.array.isEmpty(c))throw g;e=!0}a=c[d];d=(d+1)%c.length;return a};return a};goog.iter.count=function(a,b){var c=a||0,d=goog.isDef(b)?b:1,e=new goog.iter.Iterator;e.next=function(){var a=c;c+=d;return a};return e};
goog.iter.repeat=function(a){var b=new goog.iter.Iterator;b.next=goog.functions.constant(a);return b};goog.iter.accumulate=function(a){var b=goog.iter.toIterator(a),c=0;a=new goog.iter.Iterator;a.next=function(){return c+=b.next()};return a};goog.iter.zip=function(a){var b=arguments,c=new goog.iter.Iterator;if(0<b.length){var d=goog.array.map(b,goog.iter.toIterator);c.next=function(){return goog.array.map(d,function(a){return a.next()})}}return c};
goog.iter.zipLongest=function(a,b){var c=goog.array.slice(arguments,1),d=new goog.iter.Iterator;if(0<c.length){var e=goog.array.map(c,goog.iter.toIterator);d.next=function(){var b=!1,c=goog.array.map(e,function(c){var d;try{d=c.next(),b=!0}catch(e){if(e!==goog.iter.StopIteration)throw e;d=a}return d});if(!b)throw goog.iter.StopIteration;return c}}return d};goog.iter.compress=function(a,b){var c=goog.iter.toIterator(b);return goog.iter.filter(a,function(){return!!c.next()})};
goog.iter.GroupByIterator_=function(a,b){this.iterator=goog.iter.toIterator(a);this.keyFunc=b||goog.functions.identity};goog.inherits(goog.iter.GroupByIterator_,goog.iter.Iterator);goog.iter.GroupByIterator_.prototype.next=function(){for(;this.currentKey==this.targetKey;)this.currentValue=this.iterator.next(),this.currentKey=this.keyFunc(this.currentValue);this.targetKey=this.currentKey;return[this.currentKey,this.groupItems_(this.targetKey)]};
goog.iter.GroupByIterator_.prototype.groupItems_=function(a){for(var b=[];this.currentKey==a;){b.push(this.currentValue);try{this.currentValue=this.iterator.next()}catch(c){if(c!==goog.iter.StopIteration)throw c;break}this.currentKey=this.keyFunc(this.currentValue)}return b};goog.iter.groupBy=function(a,b){return new goog.iter.GroupByIterator_(a,b)};
goog.iter.tee=function(a,b){var c=goog.iter.toIterator(a),d=goog.isNumber(b)?b:2,e=goog.array.map(goog.array.range(d),function(){return[]}),f=function(){var a=c.next();goog.array.forEach(e,function(b){b.push(a)})};return goog.array.map(e,function(a){var b=new goog.iter.Iterator;b.next=function(){goog.array.isEmpty(a)&&f();goog.asserts.assert(!goog.array.isEmpty(a));return a.shift()};return b})};goog.iter.enumerate=function(a,b){return goog.iter.zip(goog.iter.count(b),a)};
goog.iter.limit=function(a,b){goog.asserts.assert(goog.math.isInt(b)&&0<=b);var c=goog.iter.toIterator(a),d=new goog.iter.Iterator,e=b;d.next=function(){if(0<e--)return c.next();throw goog.iter.StopIteration;};return d};goog.iter.consume=function(a,b){goog.asserts.assert(goog.math.isInt(b)&&0<=b);for(var c=goog.iter.toIterator(a);0<b--;)goog.iter.nextOrValue(c,null);return c};
goog.iter.slice=function(a,b,c){goog.asserts.assert(goog.math.isInt(b)&&0<=b);a=goog.iter.consume(a,b);goog.isNumber(c)&&(goog.asserts.assert(goog.math.isInt(c)&&c>=b),a=goog.iter.limit(a,c-b));return a};goog.iter.hasDuplicates_=function(a){var b=[];goog.array.removeDuplicates(a,b);return a.length!=b.length};goog.iter.permutations=function(a,b){var c=goog.iter.toArray(a),d=goog.isNumber(b)?b:c.length,c=goog.array.repeat(c,d),c=goog.iter.product.apply(void 0,c);return goog.iter.filter(c,function(a){return!goog.iter.hasDuplicates_(a)})};
goog.iter.combinations=function(a,b){function c(a){return d[a]}var d=goog.iter.toArray(a),e=goog.iter.range(d.length),e=goog.iter.permutations(e,b),f=goog.iter.filter(e,function(a){return goog.array.isSorted(a)}),e=new goog.iter.Iterator;e.next=function(){return goog.array.map(f.next(),c)};return e};
goog.iter.combinationsWithReplacement=function(a,b){function c(a){return d[a]}var d=goog.iter.toArray(a),e=goog.array.range(d.length),e=goog.array.repeat(e,b),e=goog.iter.product.apply(void 0,e),f=goog.iter.filter(e,function(a){return goog.array.isSorted(a)}),e=new goog.iter.Iterator;e.next=function(){return goog.array.map(f.next(),c)};return e};goog.stru
gitextract_f045oq39/
├── .gitignore
├── README
├── dev_server/
│ ├── README
│ ├── bundle_local.py
│ ├── cloudsql.py
│ ├── dev_server.py
│ ├── sae/
│ │ ├── __init__.py
│ │ ├── _restful_mysql/
│ │ │ ├── __init__.py
│ │ │ ├── _mysql.py
│ │ │ ├── _mysql_exceptions.py
│ │ │ ├── connections.py
│ │ │ ├── constants/
│ │ │ │ ├── CLIENT.py
│ │ │ │ ├── CR.py
│ │ │ │ ├── ER.py
│ │ │ │ ├── FIELD_TYPE.py
│ │ │ │ ├── FLAG.py
│ │ │ │ ├── REFRESH.py
│ │ │ │ └── __init__.py
│ │ │ ├── converters.py
│ │ │ ├── cursors.py
│ │ │ ├── monkey.py
│ │ │ ├── release.py
│ │ │ └── times.py
│ │ ├── channel.js
│ │ ├── channel.py
│ │ ├── channel.src.js
│ │ ├── conf.py
│ │ ├── const.py
│ │ ├── core.py
│ │ ├── ext/
│ │ │ ├── __init__.py
│ │ │ ├── django/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── mail/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── backend.py
│ │ │ │ └── storage/
│ │ │ │ ├── __init__.py
│ │ │ │ └── backend.py
│ │ │ ├── shell.py
│ │ │ └── storage/
│ │ │ ├── __init__.py
│ │ │ └── monkey.py
│ │ ├── kvdb.py
│ │ ├── mail.py
│ │ ├── memcache.py
│ │ ├── sae_signature.py
│ │ ├── storage.py
│ │ ├── taskqueue.py
│ │ └── util.py
│ ├── saecloud
│ └── setup.py
├── docs/
│ ├── Makefile
│ ├── conf.py
│ ├── exts/
│ │ └── chinese_search.py
│ ├── faq.rst
│ ├── index.rst
│ ├── quickstart.rst
│ ├── runtime.rst
│ ├── service.rst
│ ├── static/
│ │ └── memcache.html
│ ├── theme/
│ │ └── nature/
│ │ ├── layout.html
│ │ ├── static/
│ │ │ ├── nature.css_t
│ │ │ └── sae.js
│ │ └── theme.conf
│ └── tools.rst
└── examples/
├── apibus/
│ └── apibus_handler.py
├── bottle/
│ ├── README
│ └── index.wsgi
├── django/
│ ├── 1.2.7/
│ │ ├── README
│ │ ├── config.yaml
│ │ ├── index.wsgi
│ │ ├── mysite/
│ │ │ ├── __init__.py
│ │ │ ├── demo/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── models.py
│ │ │ │ ├── tests.py
│ │ │ │ └── views.py
│ │ │ ├── manage.py
│ │ │ ├── settings.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ └── static/
│ │ ├── css/
│ │ │ ├── base.css
│ │ │ ├── changelists.css
│ │ │ ├── dashboard.css
│ │ │ ├── forms.css
│ │ │ ├── ie.css
│ │ │ ├── login.css
│ │ │ ├── rtl.css
│ │ │ └── widgets.css
│ │ └── js/
│ │ ├── SelectBox.js
│ │ ├── SelectFilter2.js
│ │ ├── actions.js
│ │ ├── admin/
│ │ │ ├── DateTimeShortcuts.js
│ │ │ ├── RelatedObjectLookups.js
│ │ │ └── ordering.js
│ │ ├── calendar.js
│ │ ├── collapse.js
│ │ ├── compress.py
│ │ ├── core.js
│ │ ├── dateparse.js
│ │ ├── getElementsBySelector.js
│ │ ├── inlines.js
│ │ ├── jquery.init.js
│ │ ├── jquery.js
│ │ ├── prepopulate.js
│ │ ├── timeparse.js
│ │ └── urlify.js
│ └── 1.4/
│ ├── README
│ ├── config.yaml
│ ├── db.sql
│ ├── index.wsgi
│ ├── manage.py
│ ├── mysite/
│ │ ├── __init__.py
│ │ ├── settings.py
│ │ ├── templates/
│ │ │ ├── 404.html
│ │ │ └── 500.html
│ │ ├── urls.py
│ │ └── wsgi.py
│ └── polls/
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── templates/
│ │ ├── detail.html
│ │ ├── index.html
│ │ └── results.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── flask/
│ ├── README
│ ├── app.py
│ ├── index.wsgi
│ └── myapp.py
├── helloworld/
│ └── 1/
│ └── index.wsgi
├── matplotshell/
│ ├── README
│ ├── config.yaml
│ └── index.wsgi
├── renren/
│ ├── config.yaml
│ ├── db.sql
│ ├── error.html
│ ├── index.wsgi
│ ├── oauth.html
│ └── renrenoauth.py
├── segment/
│ ├── config.yaml
│ └── index.wsgi
├── static-site/
│ ├── README
│ ├── config.yaml
│ └── www/
│ └── index.html
├── tornado/
│ ├── async/
│ │ ├── config.yaml
│ │ └── index.wsgi
│ └── wsgi/
│ ├── README
│ └── index.wsgi
├── trac/
│ ├── README.md
│ ├── config.yaml
│ ├── index.wsgi
│ ├── project/
│ │ ├── README
│ │ ├── VERSION
│ │ ├── conf/
│ │ │ ├── trac.ini
│ │ │ └── trac.ini.sample
│ │ └── templates/
│ │ └── site.html.sample
│ └── setup.sql
├── webpy/
│ ├── index.wsgi
│ └── templates/
│ └── hello.html
└── weibo/
├── appstack.py
└── index.wsgi
SYMBOL INDEX (551 symbols across 53 files)
FILE: dev_server/bundle_local.py
function main (line 24) | def main():
function copy_modules (line 65) | def copy_modules(mod_paths, dest):
FILE: dev_server/cloudsql.py
class CloudSqlDriver (line 37) | class CloudSqlDriver(mysql.MySQLDriver):
method get_import (line 42) | def get_import(self):
method get_display_name (line 45) | def get_display_name(self):
method do_connect (line 48) | def do_connect(self, host, port, user, password, database):
class CloudSqlCmd (line 54) | class CloudSqlCmd(sqlcmd.SQLCmd):
method do_redo (line 79) | def do_redo(self, args):
method _SQLCmd__set_setting (line 83) | def _SQLCmd__set_setting(self, varname, value):
method do_desc (line 87) | def do_desc(self, args):
method do_load (line 91) | def do_load(self, args):
method preloop (line 94) | def preloop(self, *args, **kwargs):
method __init__ (line 99) | def __init__(self, *args, **kwargs):
method set_output_encoding (line 104) | def set_output_encoding(self, encoding):
method _build_table (line 107) | def _build_table(self, cursor):
method _SQLCmd__handle_select (line 122) | def _SQLCmd__handle_select(self, args, cursor, command='select'):
function _create_config_dir (line 133) | def _create_config_dir():
function main (line 141) | def main(argv):
FILE: dev_server/dev_server.py
function setup_sae_environ (line 20) | def setup_sae_environ(conf):
class Worker (line 71) | class Worker:
method __init__ (line 72) | def __init__(self, conf, app):
method collect_statifiles (line 77) | def collect_statifiles(self):
method run (line 99) | def run(self):
class WsgiWorker (line 102) | class WsgiWorker(Worker):
method run (line 103) | def run(self):
class TornadoWorker (line 133) | class TornadoWorker(Worker):
method run (line 134) | def run(self):
function main (line 156) | def main(options):
FILE: dev_server/sae/__init__.py
function create_wsgi_app (line 8) | def create_wsgi_app(app):
function dev_server (line 11) | def dev_server(conf):
function add_vendor_dir (line 17) | def add_vendor_dir(path, index=1):
FILE: dev_server/sae/_restful_mysql/__init__.py
class DBAPISet (line 39) | class DBAPISet(frozenset):
method __eq__ (line 44) | def __eq__(self, other):
function test_DBAPISet_set_equality (line 63) | def test_DBAPISet_set_equality():
function test_DBAPISet_set_inequality (line 66) | def test_DBAPISet_set_inequality():
function test_DBAPISet_set_equality_membership (line 69) | def test_DBAPISet_set_equality_membership():
function test_DBAPISet_set_inequality_membership (line 72) | def test_DBAPISet_set_inequality_membership():
function Binary (line 75) | def Binary(x):
function Connect (line 78) | def Connect(*args, **kwargs):
FILE: dev_server/sae/_restful_mysql/_mysql.py
class connection (line 26) | class connection(object):
method __init__ (line 27) | def __init__(self, *args, **kwargs):
method open (line 41) | def open(self):
method close (line 44) | def close(self):
method shutdown (line 47) | def shutdown(self):
method select_db (line 50) | def select_db(self, *args):
method change_user (line 53) | def change_user(self):
method character_set_name (line 56) | def character_set_name(self):
method set_character_set (line 61) | def set_character_set(self, charset):
method set_server_option (line 66) | def set_server_option(self, *args, **kws):
method query (line 69) | def query(self, query):
method commit (line 79) | def commit(self):
method rollback (line 82) | def rollback(self):
method autocommit (line 85) | def autocommit(self, value):
method use_result (line 88) | def use_result(self):
method store_result (line 91) | def store_result(self):
method next_result (line 98) | def next_result(self, *args, **kws):
method affected_rows (line 102) | def affected_rows(self):
method insert_id (line 105) | def insert_id(self):
method info (line 108) | def info(self):
method get_host_info (line 111) | def get_host_info(self):
method get_proto_info (line 114) | def get_proto_info(self):
method get_server_info (line 117) | def get_server_info(self):
method ping (line 120) | def ping(self):
method escape (line 123) | def escape(self, item, dct=None):
method escape_string (line 126) | def escape_string(self, str):
method string_literal (line 129) | def string_literal(self, obj):
method _open_connection (line 132) | def _open_connection(self):
method _request (line 140) | def _request(self, op, *args, **kwargs):
function _mysql_rows_to_python (line 154) | def _mysql_rows_to_python(rows, conv, field_info, how):
class StoreResult (line 174) | class StoreResult:
method __init__ (line 175) | def __init__(self, conn, rows, conv, description, description_flags):
method _init_conv (line 183) | def _init_conv(self, conv):
method fetch_row (line 202) | def fetch_row(self, maxrows=1, how=0):
method describe (line 211) | def describe(self):
method field_flags (line 214) | def field_flags(self):
function get_client_info (line 219) | def get_client_info():
function escape (line 223) | def escape(item, dct):
function _escape_item (line 226) | def _escape_item(val, dct):
function escape_string (line 234) | def escape_string(value):
function string_literal (line 250) | def string_literal(obj):
function escape_dict (line 253) | def escape_dict(val, dct):
function escape_sequence (line 260) | def escape_sequence(val, dct):
FILE: dev_server/sae/_restful_mysql/_mysql_exceptions.py
class MySQLError (line 10) | class MySQLError(StandardError):
class Warning (line 15) | class Warning(Warning, MySQLError):
class Error (line 20) | class Error(MySQLError):
class InterfaceError (line 26) | class InterfaceError(Error):
class DatabaseError (line 32) | class DatabaseError(Error):
class DataError (line 38) | class DataError(DatabaseError):
class OperationalError (line 45) | class OperationalError(DatabaseError):
class IntegrityError (line 54) | class IntegrityError(DatabaseError):
class InternalError (line 61) | class InternalError(DatabaseError):
class ProgrammingError (line 68) | class ProgrammingError(DatabaseError):
class NotSupportedError (line 75) | class NotSupportedError(DatabaseError):
FILE: dev_server/sae/_restful_mysql/connections.py
function defaulterrorhandler (line 17) | def defaulterrorhandler(connection, cursor, errorclass, errorvalue):
function numeric_part (line 40) | def numeric_part(s):
class Connection (line 56) | class Connection(_mysql.connection):
method __init__ (line 62) | def __init__(self, *args, **kwargs):
method cursor (line 234) | def cursor(self, cursorclass=None):
method __enter__ (line 245) | def __enter__(self): return self.cursor()
method __exit__ (line 247) | def __exit__(self, exc, value, tb):
method literal (line 253) | def literal(self, o):
method begin (line 266) | def begin(self):
method warning_count (line 277) | def warning_count(self):
method set_character_set (line 287) | def set_character_set(self, charset):
method set_sql_mode (line 303) | def set_sql_mode(self, sql_mode):
method show_warnings (line 311) | def show_warnings(self):
FILE: dev_server/sae/_restful_mysql/converters.py
function Bool2Str (line 46) | def Bool2Str(s, d): return str(int(s))
function Str2Set (line 48) | def Str2Set(s):
function Set2Str (line 51) | def Set2Str(s, d):
function Thing2Str (line 54) | def Thing2Str(s, d):
function Unicode2Str (line 58) | def Unicode2Str(s, d):
function Float2Str (line 66) | def Float2Str(o, d):
function None2NULL (line 69) | def None2NULL(o, d):
function Thing2Literal (line 73) | def Thing2Literal(o, d):
function Instance2Str (line 83) | def Instance2Str(o, d):
function char_array (line 111) | def char_array(s):
function array2Str (line 114) | def array2Str(o, d):
FILE: dev_server/sae/_restful_mysql/cursors.py
class BaseCursor (line 25) | class BaseCursor(object):
method __init__ (line 50) | def __init__(self, connection):
method __del__ (line 67) | def __del__(self):
method close (line 72) | def close(self):
method _check_executed (line 78) | def _check_executed(self):
method _warning_check (line 82) | def _warning_check(self):
method nextset (line 97) | def nextset(self):
method _post_get_result (line 115) | def _post_get_result(self): pass
method _do_get_result (line 117) | def _do_get_result(self):
method setinputsizes (line 128) | def setinputsizes(self, *args):
method setoutputsizes (line 131) | def setoutputsizes(self, *args):
method _get_db (line 134) | def _get_db(self):
method execute (line 139) | def execute(self, query, args=None):
method executemany (line 179) | def executemany(self, query, args):
method callproc (line 227) | def callproc(self, procname, args=()):
method _do_query (line 277) | def _do_query(self, q):
method _query (line 284) | def _query(self, q): return self._do_query(q)
method _fetch_row (line 286) | def _fetch_row(self, size=1):
method __iter__ (line 291) | def __iter__(self):
class CursorStoreResultMixIn (line 306) | class CursorStoreResultMixIn(object):
method _get_result (line 313) | def _get_result(self): return self._get_db().store_result()
method _query (line 315) | def _query(self, q):
method _post_get_result (line 320) | def _post_get_result(self):
method fetchone (line 324) | def fetchone(self):
method fetchmany (line 333) | def fetchmany(self, size=None):
method fetchall (line 342) | def fetchall(self):
method scroll (line 352) | def scroll(self, value, mode='relative'):
method __iter__ (line 371) | def __iter__(self):
class CursorUseResultMixIn (line 377) | class CursorUseResultMixIn(object):
method _get_result (line 387) | def _get_result(self): return self._get_db().use_result()
method fetchone (line 389) | def fetchone(self):
method fetchmany (line 399) | def fetchmany(self, size=None):
method fetchall (line 409) | def fetchall(self):
method __iter__ (line 417) | def __iter__(self):
method next (line 420) | def next(self):
class CursorTupleRowsMixIn (line 427) | class CursorTupleRowsMixIn(object):
class CursorDictRowsMixIn (line 435) | class CursorDictRowsMixIn(object):
method fetchoneDict (line 442) | def fetchoneDict(self):
method fetchmanyDict (line 450) | def fetchmanyDict(self, size=None):
method fetchallDict (line 458) | def fetchallDict(self):
class CursorOldDictRowsMixIn (line 467) | class CursorOldDictRowsMixIn(CursorDictRowsMixIn):
class Cursor (line 476) | class Cursor(CursorStoreResultMixIn, CursorTupleRowsMixIn,
class DictCursor (line 483) | class DictCursor(CursorStoreResultMixIn, CursorDictRowsMixIn,
class SSCursor (line 490) | class SSCursor(CursorUseResultMixIn, CursorTupleRowsMixIn,
class SSDictCursor (line 497) | class SSDictCursor(CursorUseResultMixIn, CursorDictRowsMixIn,
FILE: dev_server/sae/_restful_mysql/monkey.py
function patch (line 4) | def patch():
FILE: dev_server/sae/_restful_mysql/times.py
function DateFromTicks (line 20) | def DateFromTicks(ticks):
function TimeFromTicks (line 24) | def TimeFromTicks(ticks):
function TimestampFromTicks (line 28) | def TimestampFromTicks(ticks):
function format_TIMEDELTA (line 34) | def format_TIMEDELTA(v):
function format_TIMESTAMP (line 40) | def format_TIMESTAMP(d):
function DateTime_or_None (line 44) | def DateTime_or_None(s):
function TimeDelta_or_None (line 58) | def TimeDelta_or_None(s):
function Time_or_None (line 72) | def Time_or_None(s):
function Date_or_None (line 81) | def Date_or_None(s):
function DateTime2literal (line 85) | def DateTime2literal(d, c):
function DateTimeDelta2literal (line 89) | def DateTimeDelta2literal(d, c):
function mysql_timestamp_converter (line 93) | def mysql_timestamp_converter(s):
FILE: dev_server/sae/channel.js
function a (line 9) | function a(e){if(!(e in d.written)){if(!(e in d.visited)&&(d.visited[e]=...
function c (line 20) | function c(){}
function e (line 124) | function e(c){c&&b.appendChild(goog.isString(c)?a.createTextNode(c):c)}
function c (line 248) | function c(a){return d[a]}
function c (line 249) | function c(a){return d[a]}
FILE: dev_server/sae/channel.py
class Error (line 17) | class Error(Exception):
class InvalidChannelClientIdError (line 20) | class InvalidChannelClientIdError(Error):
class InvalidChannelTokenDurationError (line 23) | class InvalidChannelTokenDurationError(Error):
class InvalidMessageError (line 26) | class InvalidMessageError(Error):
class InternalError (line 29) | class InternalError(Error):
function _validate_client_id (line 32) | def _validate_client_id(client_id):
function create_channel (line 46) | def create_channel(name, duration=None):
function send_message (line 64) | def send_message(name, message, async=False):
function _channel_wrapper (line 87) | def _channel_wrapper(app):
FILE: dev_server/sae/core.py
function get_access_key (line 7) | def get_access_key():
function get_secret_key (line 11) | def get_secret_key():
function get_trusted_hosts (line 15) | def get_trusted_hosts():
FILE: dev_server/sae/ext/django/mail/backend.py
class EmailBackend (line 12) | class EmailBackend(BaseEmailBackend):
method __init__ (line 13) | def __init__(self, host=None, port=None, username=None, password=None,
method send_messages (line 34) | def send_messages(self, email_messages):
method _send (line 45) | def _send(self, email_message):
FILE: dev_server/sae/ext/django/storage/backend.py
class Storage (line 19) | class Storage(Storage):
method __init__ (line 20) | def __init__(self, bucket_name=STORAGE_BUCKET_NAME,
method _open (line 26) | def _open(self, name, mode='rb'):
method _save (line 30) | def _save(self, name, content):
method delete (line 38) | def delete(self, name):
method exists (line 45) | def exists(self, name):
method size (line 63) | def size(self, name):
method url (line 71) | def url(self, name):
method _open_read (line 75) | def _open_read(self, name):
method _normalize_name (line 96) | def _normalize_name(self, name):
class StorageFile (line 99) | class StorageFile(File):
method __init__ (line 100) | def __init__(self, name, mode, storage):
method size (line 108) | def size(self):
method read (line 113) | def read(self, num_bytes=None):
method write (line 118) | def write(self, content):
method close (line 124) | def close(self):
FILE: dev_server/sae/ext/storage/monkey.py
function _parse_name (line 15) | def _parse_name(filename):
function _get_storage_path (line 25) | def _get_storage_path(path):
class _File (line 31) | class _File(file):
method isatty (line 33) | def isatty(self):
method flush (line 38) | def flush(self):
method fileno (line 41) | def fileno(self):
method next (line 44) | def next(self):
method readinto (line 47) | def readinto(self):
method readline (line 50) | def readline(self):
method readlines (line 53) | def readlines(self):
method truncate (line 56) | def truncate(self):
method writelines (line 59) | def writelines(self):
method xreadlines (line 62) | def xreadlines(self):
function open (line 68) | def open(filename, mode='r', buffering=-1):
function os_listdir (line 76) | def os_listdir(path):
function os_mkdir (line 82) | def os_mkdir(path, mode=0777):
function os_open (line 88) | def os_open(filename, flag, mode=0777):
function os_fdopen (line 94) | def os_fdopen(fd, mode='r', bufsize=-1):
function os_close (line 98) | def os_close(fd):
function os_chmod (line 102) | def os_chmod(path, mode):
function os_stat (line 109) | def os_stat(path):
function os_unlink (line 115) | def os_unlink(path):
function os_path_exists (line 123) | def os_path_exists(path):
function os_path_isdir (line 129) | def os_path_isdir(path):
function os_rmdir (line 135) | def os_rmdir(path):
function patch_all (line 140) | def patch_all():
FILE: dev_server/sae/kvdb.py
class _Error (line 30) | class _Error(Exception):
class _ConnectionDeadError (line 33) | class _ConnectionDeadError(Exception):
class _CacheEntry (line 36) | class _CacheEntry(object):
method __init__ (line 38) | def __init__(self, value, flags, expiration):
method _set_expiration (line 46) | def _set_expiration(self, expiration):
method is_expired (line 52) | def is_expired(self):
class local (line 55) | class local(object):
class Client (line 63) | class Client(local):
class MemcachedKeyError (line 92) | class MemcachedKeyError(Exception):
class MemcachedKeyLengthError (line 94) | class MemcachedKeyLengthError(MemcachedKeyError):
class MemcachedKeyCharacterError (line 96) | class MemcachedKeyCharacterError(MemcachedKeyError):
class MemcachedKeyNoneError (line 98) | class MemcachedKeyNoneError(MemcachedKeyError):
class MemcachedKeyTypeError (line 100) | class MemcachedKeyTypeError(MemcachedKeyError):
class MemcachedStringEncodingError (line 102) | class MemcachedStringEncodingError(Exception):
method __init__ (line 105) | def __init__(self, servers=[], debug=0, pickleProtocol=0,
method reset_stats (line 151) | def reset_stats(self):
method reset_cas (line 157) | def reset_cas(self):
method set_servers (line 166) | def set_servers(self, servers):
method get_info (line 178) | def get_info(self, stat_args = None):
method debuglog (line 202) | def debuglog(self, str):
method forget_dead_hosts (line 206) | def forget_dead_hosts(self):
method disconnect_all (line 212) | def disconnect_all(self):
method delete (line 215) | def delete(self, key):
method add (line 225) | def add(self, key, val, time = 0, min_compress_len = 0):
method replace (line 236) | def replace(self, key, val, time=0, min_compress_len=0):
method set (line 247) | def set(self, key, val, time=0, min_compress_len=0):
method _set (line 273) | def _set(self, cmd, key, val, time, min_compress_len = 0):
method _get (line 296) | def _get(self, cmd, key):
method get (line 309) | def get(self, key):
method get_multi (line 316) | def get_multi(self, keys, key_prefix=''):
method get_by_prefix (line 350) | def get_by_prefix(self, prefix, limit=None, max_count=None,
method getkeys_by_prefix (line 382) | def getkeys_by_prefix(self, prefix, limit=None, max_count=None,
method check_key (line 389) | def check_key(self, key, key_extra_len=0):
function _doctest (line 420) | def _doctest():
function to_s (line 440) | def to_s(val):
function test_setget (line 444) | def test_setget(key, val):
class FooStruct (line 457) | class FooStruct(object):
method __init__ (line 458) | def __init__(self):
method __str__ (line 460) | def __str__(self):
method __eq__ (line 462) | def __eq__(self, other):
function _save_cache (line 550) | def _save_cache():
function _restore_cache (line 557) | def _restore_cache():
FILE: dev_server/sae/mail.py
class Error (line 47) | class Error(Exception):
class InternalError (line 50) | class InternalError(Error):
class InvalidRequestError (line 54) | class InvalidRequestError(Error):
class MissingRecipientError (line 57) | class MissingRecipientError(Error):
class MissingSubjectError (line 60) | class MissingSubjectError(Error):
class MissingBodyError (line 63) | class MissingBodyError(Error):
class MissingSMTPError (line 66) | class MissingSMTPError(Error):
class InvalidAttachmentTypeError (line 69) | class InvalidAttachmentTypeError(Error):
class MailTooLargeError (line 72) | class MailTooLargeError(Error):
class ServiceUnavailableError (line 75) | class ServiceUnavailableError(Error):
class EmailMessage (line 85) | class EmailMessage(object):
method __init__ (line 103) | def __init__(self, **kwargs):
method initialize (line 107) | def initialize(self, **kwargs):
method send (line 125) | def send(self):
method check_initialized (line 134) | def check_initialized(self):
method _check_email_valid (line 147) | def _check_email_valid(self, address):
method _check_smtp_valid (line 153) | def _check_smtp_valid(self, smtp):
method _check_attachments (line 157) | def _check_attachments(self, attachments):
method __setattr__ (line 162) | def __setattr__(self, attr, value):
method _to_proto (line 185) | def _to_proto(self):
method _remote_call (line 228) | def _remote_call(self, message):
method _get_headers (line 236) | def _get_headers(self):
function send_mail (line 248) | def send_mail(to, subject, body, smtp, **kwargs):
FILE: dev_server/sae/memcache.py
class _Error (line 53) | class _Error(Exception):
class _ConnectionDeadError (line 56) | class _ConnectionDeadError(Exception):
class _CacheEntry (line 59) | class _CacheEntry(object):
method __init__ (line 61) | def __init__(self, value, flags, expiration):
method _set_expiration (line 69) | def _set_expiration(self, expiration):
method is_expired (line 75) | def is_expired(self):
class local (line 78) | class local(object):
class Client (line 86) | class Client(local):
class MemcachedKeyError (line 115) | class MemcachedKeyError(Exception):
class MemcachedKeyLengthError (line 117) | class MemcachedKeyLengthError(MemcachedKeyError):
class MemcachedKeyCharacterError (line 119) | class MemcachedKeyCharacterError(MemcachedKeyError):
class MemcachedKeyNoneError (line 121) | class MemcachedKeyNoneError(MemcachedKeyError):
class MemcachedKeyTypeError (line 123) | class MemcachedKeyTypeError(MemcachedKeyError):
class MemcachedStringEncodingError (line 125) | class MemcachedStringEncodingError(Exception):
method __init__ (line 128) | def __init__(self, servers=[], debug=0, pickleProtocol=0,
method reset_stats (line 174) | def reset_stats(self):
method reset_cas (line 180) | def reset_cas(self):
method set_servers (line 189) | def set_servers(self, servers):
method get_stats (line 201) | def get_stats(self, stat_args = None):
method flush_all (line 247) | def flush_all(self):
method debuglog (line 251) | def debuglog(self, str):
method forget_dead_hosts (line 255) | def forget_dead_hosts(self):
method disconnect_all (line 261) | def disconnect_all(self):
method delete_multi (line 264) | def delete_multi(self, keys, time=0, key_prefix=''):
method delete (line 299) | def delete(self, key):
method incr (line 309) | def incr(self, key, delta=1):
method decr (line 335) | def decr(self, key, delta=1):
method _incrdecr (line 347) | def _incrdecr(self, cmd, key, delta):
method add (line 362) | def add(self, key, val, time = 0, min_compress_len = 0):
method append (line 373) | def append(self, key, val, time=0, min_compress_len=0):
method prepend (line 384) | def prepend(self, key, val, time=0, min_compress_len=0):
method replace (line 395) | def replace(self, key, val, time=0, min_compress_len=0):
method set (line 406) | def set(self, key, val, time=0, min_compress_len=0):
method cas (line 433) | def cas(self, key, val, time=0, min_compress_len=0):
method set_multi (line 462) | def set_multi(self, mapping, time=0, key_prefix='', min_compress_len=0):
method _set (line 516) | def _set(self, cmd, key, val, time, min_compress_len = 0):
method _get (line 539) | def _get(self, cmd, key):
method get (line 552) | def get(self, key):
method gets (line 559) | def gets(self, key):
method get_multi (line 566) | def get_multi(self, keys, key_prefix=''):
method check_key (line 624) | def check_key(self, key, key_extra_len=0):
function _doctest (line 653) | def _doctest():
function to_s (line 673) | def to_s(val):
function test_setget (line 677) | def test_setget(key, val):
class FooStruct (line 690) | class FooStruct(object):
method __init__ (line 691) | def __init__(self):
method __str__ (line 693) | def __str__(self):
method __eq__ (line 695) | def __eq__(self, other):
FILE: dev_server/sae/sae_signature.py
function get_signature (line 7) | def get_signature(key, msg):
function get_signatured_headers (line 11) | def get_signatured_headers(headers):
FILE: dev_server/sae/storage.py
class Error (line 18) | class Error(Exception): pass
class AttrDict (line 20) | class AttrDict(dict):
method __getattr__ (line 21) | def __getattr__(self, name):
function q (line 27) | def q(value, safe='/'):
function encode_utf8 (line 34) | def encode_utf8(value):
class Bucket (line 39) | class Bucket:
method __init__ (line 40) | def __init__(self, bucket, conn=None):
class Connection (line 62) | class Connection(object):
method __init__ (line 63) | def __init__(self, accesskey=ACCESS_KEY, secretkey=SECRET_KEY,
method list_bucket (line 74) | def list_bucket(self, bucket, prefix=None, delimiter=None,
method stat_bucket (line 112) | def stat_bucket(self, bucket):
method get_bucket (line 120) | def get_bucket(self, bucket):
method put_bucket (line 123) | def put_bucket(self, bucket, acl=None, metadata=None):
method post_bucket (line 131) | def post_bucket(self, bucket, acl=None, metadata=None):
method delete_bucket (line 134) | def delete_bucket(self, bucket):
method get_object (line 146) | def get_object(self, bucket, obj, chunk_size=None):
method get_object_contents (line 150) | def get_object_contents(self, bucket, obj, chunk_size=None):
method stat_object (line 169) | def stat_object(self, bucket, obj):
method put_object (line 190) | def put_object(self, bucket, obj, contents,
method post_object (line 206) | def post_object(self, bucket, obj,
method generate_url (line 211) | def generate_url(self, bucket, obj):
method delete_object (line 215) | def delete_object(self, bucket, obj):
method _get_storage_path (line 235) | def _get_storage_path(self, *args):
FILE: dev_server/sae/taskqueue.py
class Error (line 47) | class Error(Exception):
class InvalidTaskError (line 50) | class InvalidTaskError(Error):
class InternalError (line 53) | class InternalError(Error):
class PermissionDeniedError (line 57) | class PermissionDeniedError(Error):
class TaskQueueNotExistsError (line 60) | class TaskQueueNotExistsError(Error):
class TooManyTasksError (line 63) | class TooManyTasksError(Error):
class Task (line 74) | class Task:
method __init__ (line 78) | def __init__(self, url, payload = None, **kwargs):
method extract_params (line 108) | def extract_params(self):
class TaskQueue (line 111) | class TaskQueue:
method __init__ (line 113) | def __init__(self, name, auth_token=None):
method add (line 129) | def add(self, task):
method size (line 152) | def size(self):
method _remote_call (line 159) | def _remote_call(self, args):
method _get_headers (line 186) | def _get_headers(self):
function add_task (line 195) | def add_task(queue_name, url, payload=None, **kws):
FILE: dev_server/sae/util.py
function half_secret (line 4) | def half_secret(d, k):
function protect_secret (line 12) | def protect_secret(d):
function search_file_bottom_up (line 19) | def search_file_bottom_up(name):
FILE: docs/exts/chinese_search.py
class SearchChinese (line 4) | class SearchChinese(SearchLanguage):
method init (line 7) | def init(self, options):
method split (line 10) | def split(self, input):
method word_filter (line 13) | def word_filter(self, stemmed_word):
function setup (line 16) | def setup(app):
FILE: docs/theme/nature/static/sae.js
function strip_tags (line 3) | function strip_tags(st) {
FILE: examples/apibus/apibus_handler.py
class SaeApibusAuthHandler (line 28) | class SaeApibusAuthHandler(BaseHandler):
method __init__ (line 32) | def __init__(self, accesskey, secretkey):
method http_request (line 36) | def http_request(self, req):
class SaeApibusAuth (line 59) | class SaeApibusAuth(AuthBase):
method __init__ (line 61) | def __init__(self, accesskey, secretkey):
method __call__ (line 65) | def __call__(self, r):
function _signature (line 78) | def _signature(secret, method, resource, headers):
FILE: examples/django/1.2.7/mysite/demo/models.py
class Demo (line 4) | class Demo(models.Model):
FILE: examples/django/1.2.7/mysite/demo/tests.py
class SimpleTest (line 10) | class SimpleTest(TestCase):
method test_basic_addition (line 11) | def test_basic_addition(self):
FILE: examples/django/1.2.7/mysite/demo/views.py
function showdemo (line 8) | def showdemo(request):
FILE: examples/django/1.2.7/mysite/views.py
function hello (line 3) | def hello(request):
FILE: examples/django/1.2.7/static/js/SelectFilter2.js
function findForm (line 9) | function findForm(node) {
FILE: examples/django/1.2.7/static/js/admin/RelatedObjectLookups.js
function html_unescape (line 4) | function html_unescape(text) {
function id_to_windowname (line 18) | function id_to_windowname(text) {
function windowname_to_id (line 24) | function windowname_to_id(text) {
function showRelatedObjectLookupPopup (line 30) | function showRelatedObjectLookupPopup(triggeringLink) {
function dismissRelatedLookupPopup (line 44) | function dismissRelatedLookupPopup(win, chosenId) {
function showAddAnotherPopup (line 55) | function showAddAnotherPopup(triggeringLink) {
function dismissAddAnotherPopup (line 69) | function dismissAddAnotherPopup(win, newId, newRepr) {
FILE: examples/django/1.2.7/static/js/admin/ordering.js
function reorder_init (line 8) | function reorder_init() {
function submitOrderForm (line 27) | function submitOrderForm() {
function startDrag (line 33) | function startDrag() {
function endDrag (line 38) | function endDrag(x, y) {
function moveItem (line 50) | function moveItem(oldIndex, newIndex) {
function reIndex (line 87) | function reIndex(lis) {
function draw (line 93) | function draw() {
function getOrder (line 103) | function getOrder() {
function setOrder (line 111) | function setOrder(id_list) {
function addEvent (line 123) | function addEvent(elm, evType, fn, useCapture)
FILE: examples/django/1.2.7/static/js/calendar.js
function removeChildren (line 5) | function removeChildren(a) { // "a" is reference to an object
function quickElement (line 10) | function quickElement() {
function Calendar (line 107) | function Calendar(div_id, callback) {
FILE: examples/django/1.2.7/static/js/compress.py
function main (line 9) | def main():
FILE: examples/django/1.2.7/static/js/core.js
function addEvent (line 8) | function addEvent(obj, evType, fn) {
function removeEvent (line 20) | function removeEvent(obj, evType, fn) {
function quickElement (line 33) | function quickElement() {
function findPosX (line 74) | function findPosX(obj) {
function findPosY (line 91) | function findPosY(obj) {
function getStyle (line 209) | function getStyle(oElm, strCssRule){
FILE: examples/django/1.2.7/static/js/dateparse.js
function parseMonth (line 38) | function parseMonth(month) {
function parseWeekday (line 51) | function parseWeekday(weekday) {
function parseDateString (line 179) | function parseDateString(s) {
function fmt00 (line 191) | function fmt00(x) {
function parseDateStringISO (line 201) | function parseDateStringISO(s) {
function magicDate (line 208) | function magicDate(input) {
FILE: examples/django/1.2.7/static/js/getElementsBySelector.js
function getAllChildren (line 20) | function getAllChildren(e) {
FILE: examples/django/1.2.7/static/js/jquery.js
function doScrollCheck (line 759) | function doScrollCheck() {
function evalScript (line 777) | function evalScript( i, elem ) {
function access (line 795) | function access( elems, key, value, exec, fn, pass ) {
function now (line 822) | function now() {
function returnFalse (line 2099) | function returnFalse() {
function returnTrue (line 2102) | function returnTrue() {
function trigger (line 2336) | function trigger( type, elem, args ) {
function handler (line 2353) | function handler( e ) {
function liveHandler (line 2528) | function liveHandler( event ) {
function liveConvert (line 2590) | function liveConvert( type, selector ) {
function getText (line 3419) | function getText( elems ) {
function dirNodeCheck (line 3573) | function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
function dirCheck (line 3604) | function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
function isDisconnected (line 3849) | function isDisconnected( node ) {
function root (line 4320) | function root( elem, cur ) {
function cloneCopyEvent (line 4329) | function cloneCopyEvent(orig, ret) {
function buildFragment (line 4352) | function buildFragment( args, nodes, scripts ) {
function getWH (line 4628) | function getWH() {
function success (line 5264) | function success() {
function complete (line 5276) | function complete() {
function trigger (line 5293) | function trigger(type, args) {
function buildParams (line 5404) | function buildParams( prefix, obj ) {
function add (line 5435) | function add( key, value ) {
function t (line 5762) | function t( gotoEnd ) {
function genFx (line 5915) | function genFx( type, num ) {
function getWindow (line 6173) | function getWindow( elem ) {
FILE: examples/django/1.2.7/static/js/timeparse.js
function parseTimeString (line 84) | function parseTimeString(s) {
FILE: examples/django/1.2.7/static/js/urlify.js
function URLify (line 123) | function URLify(s, num_chars) {
FILE: examples/django/1.4/db.sql
type `auth_group` (line 28) | CREATE TABLE IF NOT EXISTS `auth_group` (
type `auth_group_permissions` (line 46) | CREATE TABLE IF NOT EXISTS `auth_group_permissions` (
type `auth_permission` (line 67) | CREATE TABLE IF NOT EXISTS `auth_permission` (
type `auth_user` (line 116) | CREATE TABLE IF NOT EXISTS `auth_user` (
type `auth_user_groups` (line 145) | CREATE TABLE IF NOT EXISTS `auth_user_groups` (
type `auth_user_user_permissions` (line 166) | CREATE TABLE IF NOT EXISTS `auth_user_user_permissions` (
type `django_admin_log` (line 187) | CREATE TABLE IF NOT EXISTS `django_admin_log` (
type `django_content_type` (line 219) | CREATE TABLE IF NOT EXISTS `django_content_type` (
type `django_session` (line 249) | CREATE TABLE IF NOT EXISTS `django_session` (
type `django_site` (line 298) | CREATE TABLE IF NOT EXISTS `django_site` (
type `polls_choice` (line 318) | CREATE TABLE IF NOT EXISTS `polls_choice` (
type `polls_poll` (line 347) | CREATE TABLE IF NOT EXISTS `polls_poll` (
FILE: examples/django/1.4/polls/admin.py
class ChoiceInline (line 4) | class ChoiceInline(admin.StackedInline):
class PollAdmin (line 8) | class PollAdmin(admin.ModelAdmin):
FILE: examples/django/1.4/polls/models.py
class Poll (line 4) | class Poll(models.Model):
method was_published_recently (line 8) | def was_published_recently(self):
class Choice (line 15) | class Choice(models.Model):
FILE: examples/django/1.4/polls/tests.py
class SimpleTest (line 11) | class SimpleTest(TestCase):
method test_basic_addition (line 12) | def test_basic_addition(self):
FILE: examples/django/1.4/polls/views.py
function index (line 7) | def index(request):
function detail (line 11) | def detail(request, poll_id):
function vote (line 16) | def vote(request, poll_id):
function results (line 34) | def results(request, poll_id):
FILE: examples/flask/myapp.py
function before_request (line 13) | def before_request():
function teardown_request (line 18) | def teardown_request(exception):
function hello (line 22) | def hello():
function greeting (line 26) | def greeting():
FILE: examples/renren/db.sql
type `users` (line 22) | CREATE TABLE IF NOT EXISTS `users` (
FILE: examples/renren/renrenoauth.py
class User (line 81) | class User:
method __init__ (line 82) | def __init__(self, uid=None, name=None, avatar=None, access_token=None):
method get (line 89) | def get(cls, uid):
method put (line 100) | def put(self):
class BaseHandler (line 108) | class BaseHandler(tornado.web.RequestHandler):
method current_user (line 110) | def current_user(self):
class HomeHandler (line 120) | class HomeHandler(BaseHandler):
method get (line 121) | def get(self):
class LoginHandler (line 126) | class LoginHandler(BaseHandler):
method get (line 127) | def get(self):
class LogoutHandler (line 190) | class LogoutHandler(BaseHandler):
method get (line 191) | def get(self):
class RenRenAPIClient (line 195) | class RenRenAPIClient(object):
method __init__ (line 196) | def __init__(self, session_key = None, api_key = None, secret_key = No...
method request (line 200) | def request(self, params = None):
method hash_params (line 229) | def hash_params(self, params = None):
method unicode_encode (line 233) | def unicode_encode(self, str):
class RenRenAPIError (line 239) | class RenRenAPIError(Exception):
method __init__ (line 240) | def __init__(self, code, message):
function set_cookie (line 244) | def set_cookie(response, name, value, domain=None, path="/", expires=None):
function parse_cookie (line 250) | def parse_cookie(value):
FILE: examples/trac/setup.sql
type `attachment` (line 28) | CREATE TABLE IF NOT EXISTS `attachment` (
type `auth_cookie` (line 51) | CREATE TABLE IF NOT EXISTS `auth_cookie` (
type `cache` (line 70) | CREATE TABLE IF NOT EXISTS `cache` (
type `component` (line 90) | CREATE TABLE IF NOT EXISTS `component` (
type `enum` (line 111) | CREATE TABLE IF NOT EXISTS `enum` (
type `milestone` (line 143) | CREATE TABLE IF NOT EXISTS `milestone` (
type `node_change` (line 167) | CREATE TABLE IF NOT EXISTS `node_change` (
type `permission` (line 190) | CREATE TABLE IF NOT EXISTS `permission` (
type `report` (line 224) | CREATE TABLE IF NOT EXISTS `report` (
type `repository` (line 253) | CREATE TABLE IF NOT EXISTS `repository` (
type `revision` (line 271) | CREATE TABLE IF NOT EXISTS `revision` (
type `session` (line 292) | CREATE TABLE IF NOT EXISTS `session` (
type `session_attribute` (line 312) | CREATE TABLE IF NOT EXISTS `session_attribute` (
type `system` (line 331) | CREATE TABLE IF NOT EXISTS `system` (
type `ticket` (line 351) | CREATE TABLE IF NOT EXISTS `ticket` (
type `ticket_change` (line 385) | CREATE TABLE IF NOT EXISTS `ticket_change` (
type `ticket_custom` (line 408) | CREATE TABLE IF NOT EXISTS `ticket_custom` (
type `version` (line 426) | CREATE TABLE IF NOT EXISTS `version` (
type `wiki` (line 447) | CREATE TABLE IF NOT EXISTS `wiki` (
FILE: examples/weibo/appstack.py
function get_referer (line 12) | def get_referer():
function get_weibo_user (line 15) | def get_weibo_user():
function login_ok (line 24) | def login_ok(f):
function hello (line 33) | def hello():
function login (line 38) | def login():
function login_callback (line 50) | def login_callback():
function logout (line 64) | def logout():
Condensed preview — 158 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,392K chars).
[
{
"path": ".gitignore",
"chars": 253,
"preview": "build/*\ndocs/_build/*\ndev_server/build/*\ndev_server/sae_python_dev.egg-info/*\n*~\n*.DS_Store\n*.default\n*.types\n*.pyc\n*.eg"
},
{
"path": "README",
"chars": 64,
"preview": "Copyright © 2011 新浪网研发中心. All rights reserved.\n\nSAE Python Team\n"
},
{
"path": "dev_server/README",
"chars": 1960,
"preview": "SAE Python development server - experimental\n\nAll Rights Reserved 2011\nSAE Python Team\n\n目前支持的服务包括:mysql, taskqueue, memc"
},
{
"path": "dev_server/bundle_local.py",
"chars": 2329,
"preview": "#!/usr/bin/env python\n\n\"\"\"Create a local bundle for your virtualenv environment\n\nExport all the packages listed in requi"
},
{
"path": "dev_server/cloudsql.py",
"chars": 6474,
"preview": "#!/usr/bin/env python\n\n# Copyright (C) 2012-2013 SINA, All rights reserved.\n\n\"\"\"Command line client for SAE MySQL Servic"
},
{
"path": "dev_server/dev_server.py",
"chars": 7014,
"preview": "#!/usr/bin/env python\n\n\"\"\"Simple development server\n\nMake sure you're use python 2.7 for developing\n\n\"\"\"\nimport sys\nimpo"
},
{
"path": "dev_server/sae/__init__.py",
"chars": 1017,
"preview": "\"\"\"SAE Python\n\nJaime Chen<chenzheng2@staff.sina.com.cn> 2011\n\"\"\"\n\nimport core\n\ndef create_wsgi_app(app):\n return app\n"
},
{
"path": "dev_server/sae/_restful_mysql/__init__.py",
"chars": 3105,
"preview": "\"\"\"MySQLdb - A DB API v2.0 compatible interface to MySQL.\n\nThis package is a wrapper around _mysql, which mostly impleme"
},
{
"path": "dev_server/sae/_restful_mysql/_mysql.py",
"chars": 7358,
"preview": "\n# Copyright (C) 2012-2013 SINA, All rights reserved.\n\nfrom _mysql_exceptions import *\n\n\"\"\"An proxy for the MySQL C API\n"
},
{
"path": "dev_server/sae/_restful_mysql/_mysql_exceptions.py",
"chars": 2306,
"preview": "\"\"\"_mysql_exceptions: Exception classes for _mysql and MySQLdb.\n\nThese classes are dictated by the DB API v2.0:\n\n htt"
},
{
"path": "dev_server/sae/_restful_mysql/connections.py",
"chars": 10930,
"preview": "\"\"\"\n\nThis module implements connections for MySQLdb. Presently there is\nonly one class: Connection. Others are unlikely."
},
{
"path": "dev_server/sae/_restful_mysql/constants/CLIENT.py",
"chars": 667,
"preview": "\"\"\"MySQL CLIENT constants\n\nThese constants are used when creating the connection. Use bitwise-OR\n(|) to combine options "
},
{
"path": "dev_server/sae/_restful_mysql/constants/CR.py",
"chars": 674,
"preview": "\"\"\"MySQL Connection Errors\n\nNearly all of these raise OperationalError. COMMANDS_OUT_OF_SYNC\nraises ProgrammingError.\n\n\""
},
{
"path": "dev_server/sae/_restful_mysql/constants/ER.py",
"chars": 12028,
"preview": "\"\"\"MySQL ER Constants\n\nThese constants are error codes for the bulk of the error conditions\nthat may occur.\n\n\"\"\"\n\nHASHCH"
},
{
"path": "dev_server/sae/_restful_mysql/constants/FIELD_TYPE.py",
"chars": 485,
"preview": "\"\"\"MySQL FIELD_TYPE Constants\n\nThese constants represent the various column (field) types that are\nsupported by MySQL.\n\n"
},
{
"path": "dev_server/sae/_restful_mysql/constants/FLAG.py",
"chars": 363,
"preview": "\"\"\"MySQL FLAG Constants\n\nThese flags are used along with the FIELD_TYPE to indicate various\nproperties of columns in a r"
},
{
"path": "dev_server/sae/_restful_mysql/constants/REFRESH.py",
"chars": 252,
"preview": "\"\"\"MySQL REFRESH Constants\n\nThese constants seem to mostly deal with things internal to the\nMySQL server. Forget you saw"
},
{
"path": "dev_server/sae/_restful_mysql/constants/__init__.py",
"chars": 62,
"preview": "__all__ = ['CR', 'FIELD_TYPE','CLIENT','REFRESH','ER','FLAG']\n"
},
{
"path": "dev_server/sae/_restful_mysql/converters.py",
"chars": 4624,
"preview": "\"\"\"MySQLdb type conversion module\n\nThis module handles all the type conversions for MySQL. If the default\ntype conversio"
},
{
"path": "dev_server/sae/_restful_mysql/cursors.py",
"chars": 16644,
"preview": "\"\"\"MySQLdb Cursors\n\nThis module implements Cursors of various types for MySQLdb. By\ndefault, MySQLdb uses the Cursor cla"
},
{
"path": "dev_server/sae/_restful_mysql/monkey.py",
"chars": 851,
"preview": "\n# Copyright (C) 2012-2013 SINA, All rights reserved.\n\ndef patch():\n import sys\n\n if 'MySQLdb' in sys.modules:\n "
},
{
"path": "dev_server/sae/_restful_mysql/release.py",
"chars": 117,
"preview": "\n__author__ = \"Andy Dustman <adustman@users.sourceforge.net>\"\nversion_info = (1,2,3,'final',0)\n__version__ = \"1.2.3\"\n"
},
{
"path": "dev_server/sae/_restful_mysql/times.py",
"chars": 2845,
"preview": "\"\"\"times module\n\nThis module provides some Date and Time classes for dealing with MySQL data.\n\nUse Python datetime modul"
},
{
"path": "dev_server/sae/channel.js",
"chars": 175573,
"preview": "(function(){var COMPILED=!0,goog=goog||{};goog.global=this;goog.exportPath_=function(a,b,c){a=a.split(\".\");c=c||goog.glo"
},
{
"path": "dev_server/sae/channel.py",
"chars": 3645,
"preview": "#!/usr/bin/env python\n# -*-coding: utf8 -*-\n\n\"\"\"Channel API\n\"\"\"\n\nimport time\nimport json\nimport os\n\nMAXIMUM_CLIENT_ID_LE"
},
{
"path": "dev_server/sae/channel.src.js",
"chars": 4729,
"preview": "// ==ClosureCompiler==\n// @output_file_name default.js\n// @compilation_level SIMPLE_OPTIMIZATIONS\n// @use_closure_librar"
},
{
"path": "dev_server/sae/conf.py",
"chars": 344,
"preview": "\"\"\" SAE Settings\"\"\"\n\nimport os\n\nSAE_STOREHOST = 'http://stor.sae.sina.com.cn/storageApi.php'\nSAE_S3HOST = 'http://s3.sae"
},
{
"path": "dev_server/sae/const.py",
"chars": 439,
"preview": "\"\"\"Constants about app\n\n\"\"\"\nimport os\nimport conf\n\n# Private\nAPP_NAME = os.environ.get('APP_NAME', '')\nAPP_HASH = os.env"
},
{
"path": "dev_server/sae/core.py",
"chars": 452,
"preview": "\"\"\"Core functions of SAE\n\nenviron A copy of the environ passed to your wsgi app, should not be used directly\n\n\"\"\"\n\nde"
},
{
"path": "dev_server/sae/ext/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dev_server/sae/ext/django/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dev_server/sae/ext/django/mail/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dev_server/sae/ext/django/mail/backend.py",
"chars": 2407,
"preview": "\"\"\"send mail via sae's mail service\"\"\"\n\nimport threading\n\nfrom django.conf import settings\nfrom django.core.mail.backend"
},
{
"path": "dev_server/sae/ext/django/storage/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dev_server/sae/ext/django/storage/backend.py",
"chars": 4139,
"preview": "import sys\nfrom StringIO import StringIO\n\nfrom django.conf import settings\nfrom django.core.files.base import File\nfrom "
},
{
"path": "dev_server/sae/ext/shell.py",
"chars": 85,
"preview": "\n# Copyright (C) 2012-2013 SINA, All rights reserved.\n\nShellMiddleware = lambda x: x\n"
},
{
"path": "dev_server/sae/ext/storage/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dev_server/sae/ext/storage/monkey.py",
"chars": 3619,
"preview": "\n# Copyright (C) 2012-2013 SINA, All rights reserved.\n\nimport os.path\nimport sys\nimport re\nimport time\nimport errno\n\nfro"
},
{
"path": "dev_server/sae/kvdb.py",
"chars": 19616,
"preview": "#!/usr/bin/env python\n\n\"\"\"\nFake client for sae kvdb service.\n\nThis should give you a feel for how this module operates::"
},
{
"path": "dev_server/sae/mail.py",
"chars": 8062,
"preview": "#!/usr/bin/env python\n# -*-coding: utf8 -*-\n\n\"\"\"SAE Mail API\n\nProvides functions for application developers to deliver m"
},
{
"path": "dev_server/sae/memcache.py",
"chars": 28367,
"preview": "#!/usr/bin/env python\n\n\"\"\"\nFake client for sae memcached service.\n\nThis client keeps all the data in local memory, and t"
},
{
"path": "dev_server/sae/sae_signature.py",
"chars": 518,
"preview": "\nimport os\nimport base64\nimport hmac\nimport hashlib\n\ndef get_signature(key, msg):\n h = hmac.new(key, msg, hashlib.sha"
},
{
"path": "dev_server/sae/storage.py",
"chars": 7995,
"preview": "#!/usr/bin/env python\n# -*-coding: utf8 -*-\n\n\"\"\" Dummy SAE Storage API\n\"\"\"\n\nimport os\nimport errno\nimport mimetypes\nfrom"
},
{
"path": "dev_server/sae/taskqueue.py",
"chars": 5945,
"preview": "#!/usr/bin/env python\n# -*-coding: utf8 -*-\n\n\"\"\"Task Queue API\nTaskQueue is a distributed task queue service provided by"
},
{
"path": "dev_server/sae/util.py",
"chars": 649,
"preview": "\nfrom sae_signature import get_signature, get_signatured_headers\n\ndef half_secret(d, k):\n \"\"\"Hidden part of the secre"
},
{
"path": "dev_server/saecloud",
"chars": 10394,
"preview": "#!/usr/bin/env python\n\nimport os\nimport sys\nimport yaml \nimport json\nimport shutil\nimport filecmp\nimport subprocess\nimpo"
},
{
"path": "dev_server/setup.py",
"chars": 962,
"preview": "\nimport os.path\nfrom setuptools import setup, find_packages\n\nVERSION = '1.3.6'\n\nscripts = ['dev_server.py', 'saecloud', "
},
{
"path": "docs/Makefile",
"chars": 4642,
"preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS =\nSPHINXBUILD "
},
{
"path": "docs/conf.py",
"chars": 8462,
"preview": "# -*- coding: utf-8 -*-\n#\n# SAE Python References documentation build configuration file, created by\n# sphinx-quickstart"
},
{
"path": "docs/exts/chinese_search.py",
"chars": 400,
"preview": "from sphinx.search import SearchLanguage\nimport jieba\n\nclass SearchChinese(SearchLanguage):\n lang = 'zh'\n\n def ini"
},
{
"path": "docs/faq.rst",
"chars": 5544,
"preview": "FAQ\n===============\n\nBUG反馈以及问题求助\n-------------------------\n\n关于SAE Python相关服务的问题可以在以下地方反馈和提问。\n\n* `SAE Python邮件列表`_ (推荐)\n\n"
},
{
"path": "docs/index.rst",
"chars": 600,
"preview": ".. SAE Python References documentation master file, created by\n sphinx-quickstart on Fri Sep 23 11:25:19 2011.\n You "
},
{
"path": "docs/quickstart.rst",
"chars": 6332,
"preview": "Quick Start 快速指引\n==============================\n\nHello, world!\n-----------------\n\n首先我们以一个简单的hello world应用介绍一下一个Python应用在"
},
{
"path": "docs/runtime.rst",
"chars": 4836,
"preview": "SAE Python环境\n=======================\n\nSAE应用运行于沙箱环境之中,SAE会根据负载在后端的多个节点中选择一个来处理HTTP请求。\nSAE Python支持标准WSGI应用。\n\n请求处理\n-------"
},
{
"path": "docs/service.rst",
"chars": 28320,
"preview": "可用服务列表\n=========================\n\n注意:MySQL, TaskQueue, Memcache, KVDB 服务需开启才能使用,请在前端管理界面 `服务管理` 中开启并初始化。\n\n访问互联网\n--------"
},
{
"path": "docs/static/memcache.html",
"chars": 37712,
"preview": "\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n<html><head><title>Python: module memcache</title>\n</hea"
},
{
"path": "docs/theme/nature/layout.html",
"chars": 94,
"preview": "{% extends \"basic/layout.html\" %}\n{% set script_files = script_files + [\"_static/sae.js\"] %}\n\n"
},
{
"path": "docs/theme/nature/static/nature.css_t",
"chars": 4577,
"preview": "/*\n * nature.css_t\n * ~~~~~~~~~~~~\n *\n * Sphinx stylesheet -- nature theme.\n *\n * :copyright: Copyright 2007-2011 by the"
},
{
"path": "docs/theme/nature/static/sae.js",
"chars": 1268,
"preview": "DESELEMENT = \"h2,h3,h4\"; //\"h1,h2,h3,h4,ul,div.section p,div.highlight-python\";\n\nfunction strip_tags(st) {\n return st"
},
{
"path": "docs/theme/nature/theme.conf",
"chars": 71,
"preview": "[theme]\ninherit = basic\nstylesheet = nature.css\npygments_style = tango\n"
},
{
"path": "docs/tools.rst",
"chars": 5701,
"preview": "相关工具\n==============\n\n代码部署\n------------\n\nSAE Python使用SVN作为部署工具。使用SVN部署代码到SAE需要遵循以下规则:\n\n SVN根目录下只允许存在以正整数命名的目录,不允许有文件存在"
},
{
"path": "examples/apibus/apibus_handler.py",
"chars": 2806,
"preview": "#-*-coding: utf8 -*-\n\n\"\"\"\nSAE API auth handler for urllib2 and requests\n\nurllib2:\n\n>>> import urllib2\n>>> apibus_handler"
},
{
"path": "examples/bottle/README",
"chars": 15,
"preview": "Hello, Bottle!\n"
},
{
"path": "examples/bottle/index.wsgi",
"chars": 166,
"preview": "from bottle import Bottle, run\n\nimport sae\n\napp = Bottle()\n\n@app.route('/')\ndef hello():\n return \"Hello, world! - Bot"
},
{
"path": "examples/django/1.2.7/README",
"chars": 15,
"preview": "Hello, Django!\n"
},
{
"path": "examples/django/1.2.7/config.yaml",
"chars": 24,
"preview": "name: pylabs\nversion: 9\n"
},
{
"path": "examples/django/1.2.7/index.wsgi",
"chars": 700,
"preview": "import sys\nimport os.path\n\n# manage.py is automatically created in each Django project. manage.py is a thin\n# wrapper ar"
},
{
"path": "examples/django/1.2.7/mysite/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "examples/django/1.2.7/mysite/demo/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "examples/django/1.2.7/mysite/demo/models.py",
"chars": 128,
"preview": "from django.db import models\n\n# Create your models here.\nclass Demo(models.Model):\n text = models.CharField(max_lengt"
},
{
"path": "examples/django/1.2.7/mysite/demo/tests.py",
"chars": 514,
"preview": "\"\"\"\nThis file demonstrates two different styles of tests (one doctest and one\nunittest). These will both pass when you r"
},
{
"path": "examples/django/1.2.7/mysite/demo/views.py",
"chars": 744,
"preview": "# Create your views here.\n\nfrom django.http import HttpResponse\nfrom django.template import Template, Context\nfrom djang"
},
{
"path": "examples/django/1.2.7/mysite/manage.py",
"chars": 546,
"preview": "#!/usr/bin/env python\nfrom django.core.management import execute_manager\ntry:\n import settings # Assumed to be in the"
},
{
"path": "examples/django/1.2.7/mysite/settings.py",
"chars": 3188,
"preview": "# Django settings for mysite project.\n\nDEBUG = True\nTEMPLATE_DEBUG = DEBUG\n\nADMINS = (\n # ('Your Name', 'your_email@d"
},
{
"path": "examples/django/1.2.7/mysite/urls.py",
"chars": 559,
"preview": "from django.conf.urls.defaults import *\n\n# Uncomment the next two lines to enable the admin:\nfrom django.contrib import "
},
{
"path": "examples/django/1.2.7/mysite/views.py",
"chars": 109,
"preview": "from django.http import HttpResponse\n\ndef hello(request):\n return HttpResponse(\"Hello, world! - Django\")\n\n"
},
{
"path": "examples/django/1.2.7/static/css/base.css",
"chars": 12504,
"preview": "/*\n DJANGO Admin styles\n*/\n\nbody {\n margin: 0;\n padding: 0;\n font-size: 12px;\n font-family: \"Lucida Grand"
},
{
"path": "examples/django/1.2.7/static/css/changelists.css",
"chars": 5220,
"preview": "/* CHANGELISTS */\n\n#changelist {\n position: relative;\n width: 100%;\n}\n\n#changelist table {\n width: 100%;\n}\n\n.ch"
},
{
"path": "examples/django/1.2.7/static/css/dashboard.css",
"chars": 329,
"preview": "/* DASHBOARD */\n\n.dashboard .module table th {\n width: 100%;\n}\n\n.dashboard .module table td {\n white-space: nowrap"
},
{
"path": "examples/django/1.2.7/static/css/forms.css",
"chars": 5721,
"preview": "@import url('widgets.css');\n\n/* FORM ROWS */\n\n.form-row {\n overflow: hidden;\n padding: 8px 12px;\n font-size: 11"
},
{
"path": "examples/django/1.2.7/static/css/ie.css",
"chars": 963,
"preview": "/* IE 6 & 7 */\n\n/* Proper fixed width for dashboard in IE6 */\n\n.dashboard #content {\n *width: 768px;\n}\n\n.dashboard #c"
},
{
"path": "examples/django/1.2.7/static/css/login.css",
"chars": 780,
"preview": "/* LOGIN FORM */\n\nbody.login {\n background: #eee;\n}\n\n.login #container {\n background: white;\n border: 1px solid"
},
{
"path": "examples/django/1.2.7/static/css/rtl.css",
"chars": 3357,
"preview": "body {\n direction: rtl;\n}\n\n/* LOGIN */\n\n.login .form-row {\n float: right;\n}\n\n.login .form-row label {\n float: r"
},
{
"path": "examples/django/1.2.7/static/css/widgets.css",
"chars": 9031,
"preview": "/* SELECTOR (FILTER INTERFACE) */\n\n.selector {\n width: 580px;\n float: left;\n}\n\n.selector select {\n width: 270px"
},
{
"path": "examples/django/1.2.7/static/js/SelectBox.js",
"chars": 4051,
"preview": "var SelectBox = {\n cache: new Object(),\n init: function(id) {\n var box = document.getElementById(id);\n "
},
{
"path": "examples/django/1.2.7/static/js/SelectFilter2.js",
"chars": 6451,
"preview": "/*\nSelectFilter2 - Turns a multiple-select box into a filter interface.\n\nDifferent than SelectFilter because this is cou"
},
{
"path": "examples/django/1.2.7/static/js/actions.js",
"chars": 4740,
"preview": "(function($) {\n\t$.fn.actions = function(opts) {\n\t\tvar options = $.extend({}, $.fn.actions.defaults, opts);\n\t\tvar actionC"
},
{
"path": "examples/django/1.2.7/static/js/admin/DateTimeShortcuts.js",
"chars": 14252,
"preview": "// Inserts shortcut buttons after all of the following:\n// <input type=\"text\" class=\"vDateField\">\n// <input type"
},
{
"path": "examples/django/1.2.7/static/js/admin/RelatedObjectLookups.js",
"chars": 3223,
"preview": "// Handles related-objects functionality: lookup link for raw_id_fields\n// and Add Another links.\n\nfunction html_unescap"
},
{
"path": "examples/django/1.2.7/static/js/admin/ordering.js",
"chars": 3826,
"preview": "addEvent(window, 'load', reorder_init);\n\nvar lis;\nvar top = 0;\nvar left = 0;\nvar height = 30;\n\nfunction reorder_init() {"
},
{
"path": "examples/django/1.2.7/static/js/calendar.js",
"chars": 5448,
"preview": "/*\ncalendar.js - Calendar functions by Adrian Holovaty\n*/\n\nfunction removeChildren(a) { // \"a\" is reference to an object"
},
{
"path": "examples/django/1.2.7/static/js/collapse.js",
"chars": 827,
"preview": "(function($) {\n\t$(document).ready(function() {\n\t\t// Add anchor tag for Show/Hide link\n\t\t$(\"fieldset.collapse\").each(func"
},
{
"path": "examples/django/1.2.7/static/js/compress.py",
"chars": 1896,
"preview": "#!/usr/bin/env python\nimport os\nimport optparse\nimport subprocess\nimport sys\n\nhere = os.path.dirname(__file__)\n\ndef main"
},
{
"path": "examples/django/1.2.7/static/js/core.js",
"chars": 7026,
"preview": "// Core javascript helper functions\n\n// basic browser identification & version\nvar isOpera = (navigator.userAgent.indexO"
},
{
"path": "examples/django/1.2.7/static/js/dateparse.js",
"chars": 7172,
"preview": "/* 'Magic' date parsing, by Simon Willison (6th October 2003)\n http://simon.incutio.com/archive/2003/10/06/betterDateI"
},
{
"path": "examples/django/1.2.7/static/js/getElementsBySelector.js",
"chars": 6427,
"preview": "/* document.getElementsBySelector(selector)\n - returns an array of element objects from the current document\n matc"
},
{
"path": "examples/django/1.2.7/static/js/inlines.js",
"chars": 5922,
"preview": "/**\n * Django admin inlines\n *\n * Based on jQuery Formset 1.1\n * @author Stanislaus Madueke (stan DOT madueke AT gmail D"
},
{
"path": "examples/django/1.2.7/static/js/jquery.init.js",
"chars": 107,
"preview": "// Puts the included jQuery into our own namespace\nvar django = {\n \"jQuery\": jQuery.noConflict(true)\n};\n"
},
{
"path": "examples/django/1.2.7/static/js/jquery.js",
"chars": 163855,
"preview": "/*!\n * jQuery JavaScript Library v1.4.2\n * http://jquery.com/\n *\n * Copyright 2010, John Resig\n * Dual licensed under th"
},
{
"path": "examples/django/1.2.7/static/js/prepopulate.js",
"chars": 1191,
"preview": "(function($) {\n $.fn.prepopulate = function(dependencies, maxLength) {\n /*\n Depends on urlify.js\n "
},
{
"path": "examples/django/1.2.7/static/js/timeparse.js",
"chars": 2450,
"preview": "var timeParsePatterns = [\n // 9\n { re: /^\\d{1,2}$/i,\n handler: function(bits) {\n if (bits[0].l"
},
{
"path": "examples/django/1.2.7/static/js/urlify.js",
"chars": 5305,
"preview": "var LATIN_MAP = {\n 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç':\n 'C', 'È': 'E', 'É'"
},
{
"path": "examples/django/1.4/README",
"chars": 30,
"preview": "django admin的用户名:root,密码:root\n"
},
{
"path": "examples/django/1.4/config.yaml",
"chars": 111,
"preview": "name: pylabs\nversion: 9\n\nlibraries:\n- name: \"django\"\n version: \"1.4\"\n\nhandlers:\n- url: /foo\n static_dir: foo\n"
},
{
"path": "examples/django/1.4/db.sql",
"chars": 14621,
"preview": "-- phpMyAdmin SQL Dump\n-- version 3.3.8.1\n-- http://www.phpmyadmin.net\n--\n-- 主机: w.rdc.sae.sina.com.cn:3307\n-- 生成日期: 201"
},
{
"path": "examples/django/1.4/index.wsgi",
"chars": 88,
"preview": "import sae\nfrom mysite import wsgi\n\napplication = sae.create_wsgi_app(wsgi.application)\n"
},
{
"path": "examples/django/1.4/manage.py",
"chars": 249,
"preview": "#!/usr/bin/env python\nimport os\nimport sys\n\nif __name__ == \"__main__\":\n os.environ.setdefault(\"DJANGO_SETTINGS_MODULE"
},
{
"path": "examples/django/1.4/mysite/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "examples/django/1.4/mysite/settings.py",
"chars": 5443,
"preview": "# Django settings for mysite project.\n\nDEBUG = True\nTEMPLATE_DEBUG = DEBUG\n\nADMINS = (\n # ('Your Name', 'your_email@e"
},
{
"path": "examples/django/1.4/mysite/templates/404.html",
"chars": 19,
"preview": "<h1>NOT FOUND</h1>\n"
},
{
"path": "examples/django/1.4/mysite/templates/500.html",
"chars": 24,
"preview": "<h1>INTERNAL ERROR</h1>\n"
},
{
"path": "examples/django/1.4/mysite/urls.py",
"chars": 816,
"preview": "from django.conf.urls import patterns, include, url\n\n# Uncomment the next two lines to enable the admin:\nfrom django.con"
},
{
"path": "examples/django/1.4/mysite/wsgi.py",
"chars": 1134,
"preview": "\"\"\"\nWSGI config for mysite project.\n\nThis module contains the WSGI application used by Django's development server\nand a"
},
{
"path": "examples/django/1.4/polls/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "examples/django/1.4/polls/admin.py",
"chars": 576,
"preview": "from django.contrib import admin\nfrom polls.models import Poll, Choice\n\nclass ChoiceInline(admin.StackedInline):\n mod"
},
{
"path": "examples/django/1.4/polls/models.py",
"chars": 595,
"preview": "import time\nfrom django.db import models\n\nclass Poll(models.Model):\n question = models.CharField(max_length=200)\n "
},
{
"path": "examples/django/1.4/polls/templates/detail.html",
"chars": 457,
"preview": "<h1>{{ poll.question }}</h1>\n\n{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}\n\n<form action"
},
{
"path": "examples/django/1.4/polls/templates/index.html",
"chars": 232,
"preview": "{% if latest_poll_list %}\n <ul>\n {% for poll in latest_poll_list %}\n <li><a href=\"/polls/{{ poll.id }}/\">{{"
},
{
"path": "examples/django/1.4/polls/templates/results.html",
"chars": 231,
"preview": "<h1>{{ poll.question }}</h1>\n\n<ul>\n{% for choice in poll.choice_set.all %}\n <li>{{ choice.choice }} -- {{ choice.vote"
},
{
"path": "examples/django/1.4/polls/tests.py",
"chars": 383,
"preview": "\"\"\"\nThis file demonstrates writing tests using the unittest module. These will pass\nwhen you run \"manage.py test\".\n\nRepl"
},
{
"path": "examples/django/1.4/polls/urls.py",
"chars": 259,
"preview": "from django.conf.urls import patterns, include, url\n\nurlpatterns = patterns('polls.views',\n url(r'^$', 'index'),\n "
},
{
"path": "examples/django/1.4/polls/views.py",
"chars": 1535,
"preview": "from django.shortcuts import render_to_response, get_object_or_404\nfrom django.template import RequestContext\nfrom djang"
},
{
"path": "examples/flask/README",
"chars": 14,
"preview": "Hello, Flask!\n"
},
{
"path": "examples/flask/app.py",
"chars": 0,
"preview": ""
},
{
"path": "examples/flask/index.wsgi",
"chars": 75,
"preview": "\nimport sae\n\nfrom myapp import app\n\napplication = sae.create_wsgi_app(app)\n"
},
{
"path": "examples/flask/myapp.py",
"chars": 1098,
"preview": "\nimport MySQLdb\nfrom flask import Flask, g, request\n\napp = Flask(__name__)\napp.debug = True\n\nfrom sae.const import (MYSQ"
},
{
"path": "examples/helloworld/1/index.wsgi",
"chars": 238,
"preview": "import sae\n\ndef app(environ, start_response):\n status = '200 OK'\n response_headers = [('Content-type', 'text/plain"
},
{
"path": "examples/matplotshell/README",
"chars": 71,
"preview": "Run matplotlib source code on SAE.\n\nhttp://matplotlib.org/gallery.html\n"
},
{
"path": "examples/matplotshell/config.yaml",
"chars": 118,
"preview": "name: matplotshell\nversion: 1\n\nlibraries:\n- name: numpy\n version: \"1.6.1\"\n \n- name: matplotlib\n version: \"1.1.1\"\n"
},
{
"path": "examples/matplotshell/index.wsgi",
"chars": 1065,
"preview": "import sae\nimport cStringIO\nfrom bottle import Bottle, request, response\n\napp = Bottle()\n\n@app.route('/')\ndef index():\n "
},
{
"path": "examples/renren/config.yaml",
"chars": 24,
"preview": "name: pylabs\nversion: 2\n"
},
{
"path": "examples/renren/db.sql",
"chars": 561,
"preview": "-- phpMyAdmin SQL Dump\n-- version 3.3.8.1\n-- http://www.phpmyadmin.net\n--\n-- 主机: w.rdc.sae.sina.com.cn:3307\n-- 生成日期: 201"
},
{
"path": "examples/renren/error.html",
"chars": 562,
"preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmln"
},
{
"path": "examples/renren/index.wsgi",
"chars": 79,
"preview": "import sae\nfrom renrenoauth import app\n\napplication = sae.create_wsgi_app(app)\n"
},
{
"path": "examples/renren/oauth.html",
"chars": 965,
"preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmln"
},
{
"path": "examples/renren/renrenoauth.py",
"chars": 10123,
"preview": "#!/usr/bin/env python\n#coding=utf-8\n# \n# Copyright 2010 RenRen\n#\n# Licensed under the Apache License, Version 2.0 (the \""
},
{
"path": "examples/segment/config.yaml",
"chars": 24,
"preview": "name: pylabs\nversion: 3\n"
},
{
"path": "examples/segment/index.wsgi",
"chars": 5003,
"preview": "#-*-coding: utf8 -*-\n\n\"\"\"\n分词服务请求\n------------\n\nSAE分词服务请求采用以下形式的HTTP网址: ::\n\n http://segment.sae.sina.com.cn/urlclient."
},
{
"path": "examples/static-site/README",
"chars": 48,
"preview": "A demo for pure static site with 0 python code.\n"
},
{
"path": "examples/static-site/config.yaml",
"chars": 67,
"preview": "name: staticsite\nversion: 1\n\nhandlers:\n- url: /\n static_path: www\n"
},
{
"path": "examples/static-site/www/index.html",
"chars": 170,
"preview": "<html>\n <head>\n <title>Hello App Engine!</title>\n </head>\n <body>\n <img src=\"/appengine_button_noborder.gif\" valign=\"m"
},
{
"path": "examples/tornado/async/config.yaml",
"chars": 41,
"preview": "name: pylabs\nversion: 1\n\nworker: tornado\n"
},
{
"path": "examples/tornado/async/index.wsgi",
"chars": 680,
"preview": "import tornado.web\nfrom tornado.httpclient import AsyncHTTPClient\n\nclass MainHandler(tornado.web.RequestHandler):\n @t"
},
{
"path": "examples/tornado/wsgi/README",
"chars": 16,
"preview": "Hello, Tornado!\n"
},
{
"path": "examples/tornado/wsgi/index.wsgi",
"chars": 251,
"preview": "import tornado.wsgi\n\nimport sae\n\nclass MainHandler(tornado.web.RequestHandler):\n def get(self):\n self.write(\"H"
},
{
"path": "examples/trac/README.md",
"chars": 632,
"preview": "如何在SAE上安装和运行Trac\n---------------------------\n\n1. 下载本示例代码,进入本代码所在目录,使用以下命令打包安装所有的依赖包\n\n saecloud install -r requir"
},
{
"path": "examples/trac/config.yaml",
"chars": 26,
"preview": "name: tractest\nversion: 1\n"
},
{
"path": "examples/trac/index.wsgi",
"chars": 328,
"preview": "#-*-coding: utf8 -*-\n\nimport os.path\nroot = os.path.dirname(__file__)\n\nimport sys\nsys.path.insert(0, os.path.join(root, "
},
{
"path": "examples/trac/project/README",
"chars": 98,
"preview": "This directory contains a Trac environment.\nVisit http://trac.edgewall.org/ for more information.\n"
},
{
"path": "examples/trac/project/VERSION",
"chars": 27,
"preview": "Trac Environment Version 1\n"
},
{
"path": "examples/trac/project/conf/trac.ini",
"chars": 5133,
"preview": "# -*- coding: utf-8 -*-\n\n[attachment]\nmax_size = 262144\nmax_zip_size = 2097152\nrender_unsafe_content = false\n\n[browser]\n"
},
{
"path": "examples/trac/project/conf/trac.ini.sample",
"chars": 5208,
"preview": "# -*- coding: utf-8 -*-\n\n[attachment]\nmax_size = 262144\nmax_zip_size = 2097152\nrender_unsafe_content = false\n\n[authz_pol"
},
{
"path": "examples/trac/project/templates/site.html.sample",
"chars": 603,
"preview": "<html xmlns=\"http://www.w3.org/1999/xhtml\"\n xmlns:xi=\"http://www.w3.org/2001/XInclude\"\n xmlns:py=\"http://gensh"
},
{
"path": "examples/trac/setup.sql",
"chars": 466734,
"preview": "-- phpMyAdmin SQL Dump\n-- version 3.3.2deb1\n-- http://www.phpmyadmin.net\n--\n-- 主机: localhost\n-- 生成日期: 2013 年 03 月 11 日 1"
},
{
"path": "examples/webpy/index.wsgi",
"chars": 368,
"preview": "import os\n\nimport sae\nimport web\n \nurls = (\n '/', 'Hello'\n)\n\napp_root = os.path.dirname(__file__)\ntemplates_ro"
},
{
"path": "examples/webpy/templates/hello.html",
"chars": 28,
"preview": "Hello, web.py and templates\n"
},
{
"path": "examples/weibo/appstack.py",
"chars": 2061,
"preview": "\nfrom flask import Flask, request, redirect, session\nfrom weibopy import OAuthHandler, oauth, API\n\napp = Flask(__name__)"
},
{
"path": "examples/weibo/index.wsgi",
"chars": 79,
"preview": "\nimport sae\n\nfrom appstack import app\n\napplication = sae.create_wsgi_app(app)\n\n"
}
]
About this extraction
This page contains the full source code of the sinacloud/sae-python-dev-guide GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 158 files (1.2 MB), approximately 365.8k tokens, and a symbol index with 551 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.