Full Code of hidu/pproxy for AI

master cc3978cfd1b7 cached
59 files
466.2 KB
188.1k tokens
300 symbols
1 requests
Download .txt
Showing preview only (490K chars total). Download the full file or copy to clipboard to get everything.
Repository: hidu/pproxy
Branch: master
Commit: cc3978cfd1b7
Files: 59
Total size: 466.2 KB

Directory structure:
gitextract_gqzuybd4/

├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README-en.md
├── README.md
├── assest.json
├── build.sh
├── fmt.sh
├── go.mod
├── go.sum
├── main.go
├── res/
│   ├── conf/
│   │   └── demo.conf
│   ├── css/
│   │   ├── flat.css
│   │   └── style.css
│   ├── js/
│   │   ├── base64.js
│   │   ├── default.js
│   │   ├── jquery.js
│   │   ├── session.js
│   │   └── socket.io.js
│   ├── private/
│   │   ├── client_cert.pem
│   │   └── server_key.pem
│   ├── sjs/
│   │   └── req_rewrite.js
│   ├── tpl/
│   │   ├── about.html
│   │   ├── config/
│   │   │   ├── req_demo.html
│   │   │   └── req_form.html
│   │   ├── config.html
│   │   ├── error.html
│   │   ├── file.html
│   │   ├── file_edit.html
│   │   ├── file_new.html
│   │   ├── layout.html
│   │   ├── login.html
│   │   ├── network.html
│   │   ├── replay.html
│   │   ├── replay_direct.html
│   │   └── useage.html
│   └── version
├── script/
│   ├── create_dest_zip.sh
│   ├── pproxy_control.sh
│   └── windows_run.bat
└── serve/
    ├── assest.go
    ├── auth.go
    ├── broadcast.go
    ├── certs.go
    ├── config.go
    ├── init.go
    ├── kvStore.go
    ├── proxy.go
    ├── reqCtx.go
    ├── req_modifer.go
    ├── req_replay.go
    ├── req_rewrite.go
    ├── serve.go
    ├── sessions.go
    ├── util.go
    ├── web.go
    ├── web_file.go
    ├── wsClient.go
    └── wsServer.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so

# Folders
_obj
_test

# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out

*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*

_testmain.go
test/

*.exe
*.test
data/
dest/
hosts_*
conf/*
file/
.*.html
.DS_Store


================================================
FILE: CHANGELOG.md
================================================
2016-07-27
   1. 升级依赖   

2016-07-27
    1. version 0.5.2
    2. 修复文件上传页面错误
    3. 更新lib otto ,boltdb 为最新版本
    
2016-03-25
    1.版本号升级为0.5.1
    2.改进request动态修改引擎并发异常问题
    
2014-12-27
	1.版本号升级为0.4.7
	2.添加adminPort配置项,以独立的端口提供给管理界面

2014-12-17
	1.静态资源使用goassest方式而不使用之前的读取zip的方式
	
2014-11-08
	1.重构代理处理逻辑,改进Upgrade代理协议
	2.会话详情页面展现请求时间
	3.upgrade结束的时候也记录一条response 以方便查看何时断开连接
	
2014-09-27
    1.http session list support local filter
    
    
2014-09-14
    1.downgrade the socket.io lib
    
2014-08-14
   1.emit data with base64encode
   2.fix some url has no schema
   
2014-08-10
   1.websocket proxy support
   
2014-08-06
   1.update socket.io
   
2014-07-19
   1.修复监听端口为80时不能查看会话列表的问题
   2.完善帮助说明

2014-07-15
   1.get和post参数支持重写
   2.重写请求出现错误自己返回502错误

2014-07-12 
   1.认证机制升级,新认证机制:一个ip第一次访问的时候会要求登录,若没有输入登录信息也跳过。  
   2.管理员用户(登录后)在session filter 输入user:any 可以查看到所有的会话信息  


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2014 du

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

================================================
FILE: README-en.md
================================================
pproxy 0.5.2
======
HTTP protocol analysis tool.  



features:
<pre>
1.url redirect
   redirect *http://www.baidu.com/s?wd=pproxy* to  *http://m.baidu.com/s?wd=pproxy*
   redirect  *ws://www.test.com/a* to  *ws://www.example.com/b*
   
2.form dynamic modification  
   get、post and header all can modify  
   
3.hosts
  www.baidu.com to 127.0.0.1  
  or www.baidu.com:81 to 192.168.1.2:8080 ,and only  takes effect on port 81  
  
4.view request and response detail
   form params,header and all response and easy to share
   
5.auth sup
   http Basic or only try basic auth at first request
   
6.replay
   can modify the get、post、header params and replay the request

7.parent proxy
  
</pre>

use javascript code as config to modify the request params:
```
if(req.host=="www.baidu.com"){
   req.host="www.163.com"
   req.host_addr="127.0.0.0:81" // send req to 127.0.0.1:81
}
```
or:
```
if(req.host.indexOf("baidu.com")>-1){
  req.host_addr="127.0.0.0:81"
}
```

request params dump:
```
#url : http://www.example.com/album/list?cid=126
#request has these attrs:
schema : http
host : www.example.com
port : 80
path : /album/list
get: {cid:[123]}
post: {}
username : 
password : 
method: GET
form_get  : {add:function(k,v){},set:function(k,v){},get:function(k){},len:function(){}} 
form_post : {add:function(k,v){},set:function(k,v){},get:function(k){},len:function(){}}

host_addr: #modify hosts eg:127.0.0.1:3218

#note get and post value is array
#form_get: helper function for get params
#form_post: helper function for post params
```


hosts config demo:
```
www.baidu.com 127.0.0.1
www.baidu.com:81 10.0.2.2:8080
```

disable req_rewrite.js  
first line ```//ignore```


req_rewrite.js支持不同用户设置不同的规则。默认使用当前验证使用用户名的规则,若无则使用默认的。  

configs:
```
conf/
├── pproxy.conf          #server config
├── hosts_8080           #hosts for 8080
├── req_rewrite_8080.js  #8080端口server的url重写规则
├── hosts_8081
├── req_rewrite_8081.js
└── users                #全局帐号配置文件
```

users配置:
```
#帐号 admin,密码 是 psw,是管理员帐号
name:admin psw:psw is_admin:admin

#密码也可以存储为md5值,使用  psw_md5:32位md密码
name:admin_sec psw_md5:7bb483729b5a8e26f73e1831cde5b842 is_admin:admin
```
可以在线修改配置时必须使用管理员帐号登录

配置文件示例:
```

port : 8080

title : demo
notice :notice notice

#数据存放目录,相对于当前配置的路径
dataDir : ../data/

#数据存放天数,0为永久存储(目前只在重启的时候会进行数据清理)
dataStoreDay : 15

#代理服务认证方式
#options:{none : 无认证,basic:http basic ,basic_try:尝试httpBasic认证 ,basic_any:任意帐号}
authType : none

#那些request和response数据进行存储
#options:{ all : 所有   only_broadcast : 发送到session list的才存储}
responseSave : only_broadcast

#session列表查看数据
# options :{ all:所有人可见 ip_or_user : 输入正确的ip或者user后可见}
sessionView : all

#父级代理
#eg http://10.10.2.2:3128 or http://name:psw@10.10.2.2:3128
# http://pass:pass@10.10.2.2:3128 the user and psw will pass through to the parent proxy
parentProxy:
```


================================================
FILE: README.md
================================================
pproxy 0.5.2
======
## intro
HTTP 协议抓包代理程序, HTTP 协议调试工具。  
采用 Go 编写,采用 BS 模式(s-代理程序,b-会话查看、配置管理等功能)  

0.4.2版本已经支持websocket代理,以及重定向(和普通http请求一样使用)  

0.5 版本是对底层存储进行了替换,并且尝试支持https抓包

## install

已经安装go的用户直接安装:  
>go install  github.com/hidu/pproxy@master

## 功能特性
<pre>
1.url重定向
   如把 http://www.baidu.com/s?wd=pproxy 修改为 http://m.baidu.com/s?wd=pproxy
   或者把 ws://www.test.com/a 重定向到 ws://www.example.com/b
   
2.form表单动态修改  
   get、post可以动态修改(增删改)  
   
3.hosts文件支持
  相当于 修改host或者dns 如  
  将www.baidu.com 请求全部发往127.0.0.1  
  将www.baidu.com:81 请求全部发往192.168.1.2:8080  
  
4.可查看request 和response详情
   form表单参数,header等都可以很方便的看到
   
5.登录认证支持
   支持httpBasic认证
   
6.replay功能
   可以修改request的参数(get、post、header)

7.父级代理
  
</pre>

## 配置

### rewrite req
使用javascript来配置重定向功能,如
```
if(req.host=="www.baidu.com"){
   req.host="www.163.com"
   req.host_addr="127.0.0.0:81" // send req to 127.0.0.1:81
}
```
当然也可以这样:
```
if(req.host.indexOf("baidu.com")>-1){
  req.host_addr="127.0.0.0:81"
}
```

### req变量示例
```
#url : http://www.example.com/album/list?cid=126
#req对象有如下一下属性:
schema : http
host : www.example.com
port : 80
path : /album/list
get: {cid:[123]}
post: {}
username : 
password : 
method: GET
form_get  : {add:function(k,v){},set:function(k,v){},get:function(k){},len:function(){}} 
form_post : {add:function(k,v){},set:function(k,v){},get:function(k){},len:function(){}}

host_addr: #修改该请求的host是使用,如 127.0.0.1:3218

#注意 get 和post的值是数组,如上cid参数
#form_get 用于更方便的操作  get参数对象
#form_post 用于更方便的操作 post参数对象
```

### hosts
增强的hosts文件使用:
```
www.baidu.com 127.0.0.1
www.baidu.com:81 10.0.2.2:8080
```

### other
忽略禁用req_rewrite.js  
在js文件的第一行内容写入 ```//ignore```

req_rewrite.js支持不同用户设置不同的规则。默认使用当前验证使用用户名的规则,若无则使用默认的。  

### 配置文件结构:
```
conf/
├── pproxy.conf          #server的配置
├── hosts_8080           #8080端口server的hosts规则
├── req_rewrite_8080.js  #8080端口server的url重写规则
├── hosts_8081
├── req_rewrite_8081.js
└── users                #全局帐号配置文件
```

### users配置:
```
#帐号 admin,密码 是 psw,是管理员帐号
name:admin psw:psw is_admin:admin

#密码也可以存储为md5值,使用  psw_md5:32位md密码
name:admin_sec psw_md5:7bb483729b5a8e26f73e1831cde5b842 is_admin:admin
```
可以在线修改配置时必须使用管理员帐号登录

### 配置文件示例(pproxy.conf):
```
#提供代理服务的端口
port : 8080

#管理界面的端口,为0表示和代理服务使用相同的端口,eg:8081
adminPort : 0

title : demo
notice :notice notice

#数据存放目录,相对于当前配置的路径
dataDir : ../data/

#数据存放天数,0为永久存储(目前只在重启的时候会进行数据清理)
dataStoreDay : 15

#代理服务认证方式
#options:{none : 无认证,basic:http basic ,basic_try:尝试httpBasic认证 ,basic_any:任意帐号}
authType : none

#那些request和response数据进行存储
#options:{ all : 所有   only_broadcast : 发送到session list的才存储}
responseSave : only_broadcast

#session列表查看数据
# options :{ all:所有人可见 ip_or_user : 输入正确的ip或者user后可见}
sessionView : all

#父级代理
#eg http://10.10.2.2:3128 or http://name:psw@10.10.2.2:3128
# http://pass:pass@10.10.2.2:3128 the user and psw will pass through to the parent proxy
parentProxy:


#是否使用中间人方式对https进行抓包,若启用的话 需要客户端按照证书-/res/private/client_cert.pem
#pproxy内置默认证书存放在/res/private目录中
#options:{on:启用  off:禁用}
ssl : on

#ssl 服务端秘钥文件地址,为空则使用默认内置的 /res/private/server_key.pem
ssl_server_key: 
#ssl 公钥地址 ,为空则使用默认内置的 /res/private/client_cert.pem
ssl_client_cert :
```

## (管理)web查看界面
方式1: 直接访问 http://serverHost:port  
方式2: 直接访问 http://serverHost:adminPort  
方式3: 浏览器设置http代理 serverHost:port,访问 http://pproxy.man 或者 http://pproxy.com  

# 其他
## 如何自己修改源码中的静态资源?
该项目的静态资源(res目录中的所有内容)都编译到go文件中去了,可以处理即可:  
1. 安装goassest工具:
```
go get -u github.com/hidu/goassest
```
2.到pproxy代码根目录下运行命令:
```
goassest
```

调试过程中可以添加参数  `-assest_direct` 可以让静态资源实时生效而不需要重新编译静态资源:
```
go run proxy_main.go -assest_direct
```


================================================
FILE: assest.json
================================================
{
  "src":"res",
  "dest":"serve/assest.go",
  "package":"serve"
}


================================================
FILE: build.sh
================================================
#!/bin/bash
# build for window: build.sh windows
# default linux
#./gox -build-toolchain

set -e
cd $(dirname $0)

#export GOPATH=`readlink -f Godeps/_workspace`:$GOPATH

export GO15VENDOREXPERIMENT=1

go install

================================================
FILE: fmt.sh
================================================
#/bin/bash
cd $(dirname $0)
cd serve
#gofmt -tabs=false -w=true -tabwidth=4 .
gofmt -w=true -s=true .



================================================
FILE: go.mod
================================================
module github.com/hidu/pproxy

go 1.23

require (
	github.com/Unknwon/goconfig v1.0.0
	github.com/boltdb/bolt v1.3.1
	github.com/elazarl/goproxy v0.0.0-20241219141958-0cbc93263399
	github.com/googollee/go-socket.io v0.9.1
	github.com/hidu/goutils v0.0.2
	github.com/robertkrimen/otto v0.5.1
)

require (
	github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
	github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac // indirect
	github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect
	golang.org/x/net v0.33.0 // indirect
	golang.org/x/sys v0.28.0 // indirect
	golang.org/x/text v0.21.0 // indirect
	gopkg.in/sourcemap.v1 v1.0.5 // indirect
)


================================================
FILE: go.sum
================================================
github.com/Unknwon/goconfig v1.0.0 h1:9IAu/BYbSLQi8puFjUQApZTxIHqSwrj5d8vpP8vTq4A=
github.com/Unknwon/goconfig v1.0.0/go.mod h1:wngxua9XCNjvHjDiTiV26DaKDT+0c63QR6H5hjVUUxw=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/elazarl/goproxy v0.0.0-20241219141958-0cbc93263399 h1:WBf0ImRm78m/cgOOob9PUyQdYYod2luQA6fs+OqAjbw=
github.com/elazarl/goproxy v0.0.0-20241219141958-0cbc93263399/go.mod h1:3tPvP6c6GrQS4u4TJEbOoqGC2wDNMLra3t6AXWwtL0M=
github.com/elazarl/goproxy/ext v0.0.0-20241217120900-7711dfa3811c h1:R+i10jtNSzKJKqEZAYJnR9M8y14k0zrNHqD1xkv/A2M=
github.com/elazarl/goproxy/ext v0.0.0-20241217120900-7711dfa3811c/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/googollee/go-socket.io v0.9.1 h1:KYsu63c3H5SaeQ3MDlHSTE/LJnwok2SH1M5wy4ZaYD0=
github.com/googollee/go-socket.io v0.9.1/go.mod h1:Q0CvnKmaZNgDXIi85at4eLadAOS1hWDLaDATQpuH3i4=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hidu/goutils v0.0.2 h1:ZjwXZhuWXZjzQ4dHoFo2iN6oDXH1TCudQZ0V2vdAUfQ=
github.com/hidu/goutils v0.0.2/go.mod h1:m13DejGt6FVHM+taWpMHpavxBRZnnQBZeDJyB/YsyRI=
github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robertkrimen/otto v0.5.1 h1:avDI4ToRk8k1hppLdYFTuuzND41n37vPGJU7547dGf0=
github.com/robertkrimen/otto v0.5.1/go.mod h1:bS433I4Q9p+E5pZLu7r17vP6FkE6/wLxBdmKjoqJXF8=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac h1:wbW+Bybf9pXxnCFAOWZTqkRjAc7rAIwo2e1ArUhiHxg=
github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=


================================================
FILE: main.go
================================================
package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"github.com/hidu/pproxy/serve"
)

var configPath = flag.String("conf", "./conf/pproxy.conf", "pproxy's config file")
var port = flag.Int("port", 0, "proxy port")
var vv = flag.Bool("vv", false, "debug,log request with more detail")
var showConf = flag.Bool("demo_conf", false, "show default conf")

var version = flag.Bool("v", false, "show version")

func init() {
	df := flag.Usage

	flag.Usage = func() {
		df()
		fmt.Fprintln(os.Stderr, "\n HTTP protocol analysis tool\n https://github.com/hidu/pproxy/\n")
	}
}

func main() {
	flag.Parse()

	if *showConf {
		demoConf := serve.GetDemoConf()
		fmt.Println(demoConf)
		os.Exit(0)
	}

	if *version {
		fmt.Println("pproxy version:", serve.GetVersion())
		os.Exit(0)
	}

	log.SetFlags(log.Lshortfile | log.LstdFlags | log.Ldate)
	ser, err := serve.NewProxyServe(*configPath, *port)
	if err != nil {
		fmt.Println("start pproxy failed", err)
		os.Exit(2)
	}
	ser.Debug = *vv
	ser.Start()
}


================================================
FILE: res/conf/demo.conf
================================================
##########################################################
#                  pproxy demo conf                      #
##########################################################

#提供代理服务的端口
port : 8080

#管理界面的端口,为0表示和代理服务使用相同的端口
adminPort : 0

title : hello pproxy
notice : notice notice

#数据存放目录,相对于当前配置的路径
dataDir : ../data/

#静态文件存放目录
fileDir:  ../file/


#数据存放天数,0为永久存储(目前只在重启的时候会进行数据清理)
dataStoreDay : 15

#代理服务认证方式
#options:{none : 无认证,basic:http basic ,basic_try:尝试httpBasic认证 ,basic_any:任意帐号}
authType : none

#那些request和response数据进行存储
#options:{ all : 所有   only_broadcast : 发送到session list的才存储}
responseSave : only_broadcast

#session列表查看数据
# options :{ all:所有人可见 ip_or_user : 输入正确的ip或者user后可见}
sessionView : all

#eg http://10.10.2.2:3128 or http://name:psw@10.10.2.2:3128
# http://name:psw@10.10.2.2:3128 the user and psw will pass through to the parent proxy
parentProxy:

================================================
FILE: res/css/flat.css
================================================
.dropdown-arrow-inverse {
  border-bottom-color: #34495e !important;
  border-top-color: #34495e !important;
}
a {
  color: #428bca;
  text-decoration: none;
  -webkit-transition: 0.25s;
  transition: 0.25s;
}
a:hover,
a:focus {
  color: #428bca;
  text-decoration: none;
}
a:focus {
  outline: none;
}
.img-rounded {
  border-radius: 6px;
}
.img-thumbnail {
  padding: 4px;
  line-height: 1.72222;
  background-color: #ffffff;
  border: 2px solid #bdc3c7;
  border-radius: 6px;
  -webkit-transition: all 0.25s ease-in-out;
  transition: all 0.25s ease-in-out;
  display: inline-block;
  max-width: 100%;
  height: auto;
}
.img-comment {
  font-size: 15px;
  line-height: 1.2;
  font-style: italic;
  margin: 24px 0;
}
h1,
h2,
h3,
h4,
h5,
h6,
.h1,
.h2,
.h3,
.h4,
.h5,
.h6 {
  font-family: inherit;
  font-weight: 700;
  line-height: 1.1;
  color: inherit;
}
h1 small,
h2 small,
h3 small,
h4 small,
h5 small,
h6 small,
.h1 small,
.h2 small,
.h3 small,
.h4 small,
.h5 small,
.h6 small {
  color: #e7e9ec;
}
h1,
h2,
h3 {
  margin-top: 30px;
  margin-bottom: 15px;
}
h4,
h5,
h6 {
  margin-top: 15px;
  margin-bottom: 15px;
}
h6 {
  font-weight: normal;
}
h1,
.h1 {
  font-size: 61px;
}
h2,
.h2 {
  font-size: 53px;
}
h3,
.h3 {
  font-size: 40px;
}
h4,
.h4 {
  font-size: 29px;
}
h5,
.h5 {
  font-size: 28px;
}
h6,
.h6 {
  font-size: 24px;
}
p {
  font-size: 18px;
  line-height: 1.72222;
  margin: 0 0 15px;
}
.lead {
  margin-bottom: 30px;
  font-size: 28px;
  line-height: 1.46428571;
  font-weight: 300;
}
@media (min-width: 768px) {
  .lead {
    font-size: 30.006px;
  }
}
small,
.small {
  font-size: 83%;
  line-height: 2.067;
}
.text-muted {
  color: #bdc3c7;
}
.text-inverse {
  color: #ffffff;
}
.text-primary {
  color: #428bca;
}
a.text-primary:hover {
  color: #15967d;
}
.text-warning {
  color: #f1c40f;
}
a.text-warning:hover {
  color: #c19d0c;
}
.text-danger {
  color: #e74c3c;
}
a.text-danger:hover {
  color: #b93d30;
}
.text-success {
  color: #2ecc71;
}
a.text-success:hover {
  color: #25a35a;
}
.text-info {
  color: #3498db;
}
a.text-info:hover {
  color: #2a7aaf;
}
.bg-primary {
  color: #ffffff;
  background-color: #34495e;
}
a.bg-primary:hover {
  background-color: #222f3d;
}
.bg-success {
  background-color: #dff0d8;
}
a.bg-success:hover {
  background-color: #c1e2b3;
}
.bg-info {
  background-color: #d9edf7;
}
a.bg-info:hover {
  background-color: #afd9ee;
}
.bg-warning {
  background-color: #fcf8e3;
}
a.bg-warning:hover {
  background-color: #f7ecb5;
}
.bg-danger {
  background-color: #f2dede;
}
a.bg-danger:hover {
  background-color: #e4b9b9;
}
.page-header {
  padding-bottom: 14px;
  margin: 60px 0 30px;
  border-bottom: 1px solid #e7e9ec;
}
ul,
ol {
  margin-bottom: 15px;
}
dl {
  margin-bottom: 30px;
}
dt,
dd {
  line-height: 1.72222;
}
@media (min-width: 768px) {
  .dl-horizontal dt {
    width: 160px;
  }
  .dl-horizontal dd {
    margin-left: 180px;
  }
}
abbr[title],
abbr[data-original-title] {
  border-bottom: 1px dotted #bdc3c7;
}
blockquote {
  border-left: 3px solid #e7e9ec;
  padding: 0 0 0 16px;
  margin: 0 0 30px;
}
blockquote p {
  font-size: 20px;
  line-height: 1.55;
  font-weight: normal;
  margin-bottom: .4em;
}
blockquote small,
blockquote .small {
  font-size: 18px;
  line-height: 1.72222;
  font-style: italic;
  color: inherit;
}
blockquote small:before,
blockquote .small:before {
  content: "";
}
blockquote.pull-right {
  padding-right: 16px;
  padding-left: 0;
  border-right: 3px solid #e7e9ec;
  border-left: 0;
}
blockquote.pull-right small:after {
  content: "";
}
address {
  margin-bottom: 30px;
  line-height: 1.72222;
}
code,
kbd,
pre,
samp {
  font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
}
code {
  padding: 2px 6px;
  font-size: 85%;
  color: #c7254e;
  background-color: #f9f2f4;
  border-radius: 4px;
}
kbd {
  padding: 2px 6px;
  font-size: 85%;
  color: #ffffff;
  background-color: #34495e;
  border-radius: 4px;
  box-shadow: none;
}
pre {
  padding: 8px;
  margin: 0 0 15px;
  font-size: 13px;
  line-height: 1.72222;
  color: inherit;
  background-color: #ffffff;
  border: 2px solid #e7e9ec;
  border-radius: 6px;
  white-space: pre;
}
.pre-scrollable {
  max-height: 340px;
}
.btn {
  border: none;
  font-size: 14px;
  font-weight: normal;
  cursor: pointer;
  line-height: 1.4;
  border-radius: 4px;
  padding: 6px 12px;
  -webkit-font-smoothing: subpixel-antialiased;
  -webkit-transition: border .25s linear, color .25s linear, background-color .25s linear;
  transition: border .25s linear, color .25s linear, background-color .25s linear;
}
.btn:hover,
.btn:focus {
  outline: none;
  color: #ffffff;
}
.btn:active,
.btn.active {
  outline: none;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.btn.disabled,
.btn[disabled],
fieldset[disabled] .btn {
  background-color: #bdc3c7;
  color: rgba(255, 255, 255, 0.75);
  opacity: 0.7;
  filter: alpha(opacity=70);
}
.btn > [class^="fui-"] {
  margin: 0 1px;
  position: relative;
  line-height: 1;
  top: 1px;
}
.btn-xs.btn > [class^="fui-"] {
  font-size: 11px;
  top: 0;
}
.btn-hg.btn > [class^="fui-"] {
  top: 2px;
}
.btn-default {
  color: #ffffff;
  background-color: #bdc3c7;
}
.btn-default:hover,
.btn-default:focus,
.btn-default:active,
.btn-default.active,
.open .dropdown-toggle.btn-default {
  color: #ffffff;
  background-color: #cacfd2;
  border-color: #cacfd2;
}
.btn-default:active,
.btn-default.active,
.open .dropdown-toggle.btn-default {
  background: #a1a6a9;
  border-color: #a1a6a9;
}
.btn-default.disabled,
.btn-default[disabled],
fieldset[disabled] .btn-default,
.btn-default.disabled:hover,
.btn-default[disabled]:hover,
fieldset[disabled] .btn-default:hover,
.btn-default.disabled:focus,
.btn-default[disabled]:focus,
fieldset[disabled] .btn-default:focus,
.btn-default.disabled:active,
.btn-default[disabled]:active,
fieldset[disabled] .btn-default:active,
.btn-default.disabled.active,
.btn-default[disabled].active,
fieldset[disabled] .btn-default.active {
  background-color: #bdc3c7;
  border-color: #bdc3c7;
}
.btn-primary {
  color: #ffffff;
  background-color: #428bca;
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active,
.btn-primary.active,
.open .dropdown-toggle.btn-primary {
  color: #ffffff;
  background-color: #3276b1;
  border-color: #3276b1;
}
.btn-primary:active,
.btn-primary.active,
.open .dropdown-toggle.btn-primary {
  background: #428bca;
  border-color: #428bca;
}
.btn-primary.disabled,
.btn-primary[disabled],
fieldset[disabled] .btn-primary,
.btn-primary.disabled:hover,
.btn-primary[disabled]:hover,
fieldset[disabled] .btn-primary:hover,
.btn-primary.disabled:focus,
.btn-primary[disabled]:focus,
fieldset[disabled] .btn-primary:focus,
.btn-primary.disabled:active,
.btn-primary[disabled]:active,
fieldset[disabled] .btn-primary:active,
.btn-primary.disabled.active,
.btn-primary[disabled].active,
fieldset[disabled] .btn-primary.active {
  background-color: #428bca;
  border-color: #428bca;
}
.btn-info {
  color: #ffffff;
  background-color: #3498db;
}
.btn-info:hover,
.btn-info:focus,
.btn-info:active,
.btn-info.active,
.open .dropdown-toggle.btn-info {
  color: #ffffff;
  background-color: #5dade2;
  border-color: #5dade2;
}
.btn-info:active,
.btn-info.active,
.open .dropdown-toggle.btn-info {
  background: #2c81ba;
  border-color: #2c81ba;
}
.btn-info.disabled,
.btn-info[disabled],
fieldset[disabled] .btn-info,
.btn-info.disabled:hover,
.btn-info[disabled]:hover,
fieldset[disabled] .btn-info:hover,
.btn-info.disabled:focus,
.btn-info[disabled]:focus,
fieldset[disabled] .btn-info:focus,
.btn-info.disabled:active,
.btn-info[disabled]:active,
fieldset[disabled] .btn-info:active,
.btn-info.disabled.active,
.btn-info[disabled].active,
fieldset[disabled] .btn-info.active {
  background-color: #3498db;
  border-color: #3498db;
}
.btn-danger {
  color: #ffffff;
  background-color: #e74c3c;
}
.btn-danger:hover,
.btn-danger:focus,
.btn-danger:active,
.btn-danger.active,
.open .dropdown-toggle.btn-danger {
  color: #ffffff;
  background-color: #ec7063;
  border-color: #ec7063;
}
.btn-danger:active,
.btn-danger.active,
.open .dropdown-toggle.btn-danger {
  background: #c44133;
  border-color: #c44133;
}
.btn-danger.disabled,
.btn-danger[disabled],
fieldset[disabled] .btn-danger,
.btn-danger.disabled:hover,
.btn-danger[disabled]:hover,
fieldset[disabled] .btn-danger:hover,
.btn-danger.disabled:focus,
.btn-danger[disabled]:focus,
fieldset[disabled] .btn-danger:focus,
.btn-danger.disabled:active,
.btn-danger[disabled]:active,
fieldset[disabled] .btn-danger:active,
.btn-danger.disabled.active,
.btn-danger[disabled].active,
fieldset[disabled] .btn-danger.active {
  background-color: #e74c3c;
  border-color: #e74c3c;
}
.btn-success {
  color: #ffffff;
  background-color: #2ecc71;
}
.btn-success:hover,
.btn-success:focus,
.btn-success:active,
.btn-success.active,
.open .dropdown-toggle.btn-success {
  color: #ffffff;
  background-color: #58d68d;
  border-color: #58d68d;
}
.btn-success:active,
.btn-success.active,
.open .dropdown-toggle.btn-success {
  background: #27ad60;
  border-color: #27ad60;
}
.btn-success.disabled,
.btn-success[disabled],
fieldset[disabled] .btn-success,
.btn-success.disabled:hover,
.btn-success[disabled]:hover,
fieldset[disabled] .btn-success:hover,
.btn-success.disabled:focus,
.btn-success[disabled]:focus,
fieldset[disabled] .btn-success:focus,
.btn-success.disabled:active,
.btn-success[disabled]:active,
fieldset[disabled] .btn-success:active,
.btn-success.disabled.active,
.btn-success[disabled].active,
fieldset[disabled] .btn-success.active {
  background-color: #2ecc71;
  border-color: #2ecc71;
}
.btn-warning {
  color: #ffffff;
  background-color: #f1c40f;
}
.btn-warning:hover,
.btn-warning:focus,
.btn-warning:active,
.btn-warning.active,
.open .dropdown-toggle.btn-warning {
  color: #ffffff;
  background-color: #f4d313;
  border-color: #f4d313;
}
.btn-warning:active,
.btn-warning.active,
.open .dropdown-toggle.btn-warning {
  background: #cda70d;
  border-color: #cda70d;
}
.btn-warning.disabled,
.btn-warning[disabled],
fieldset[disabled] .btn-warning,
.btn-warning.disabled:hover,
.btn-warning[disabled]:hover,
fieldset[disabled] .btn-warning:hover,
.btn-warning.disabled:focus,
.btn-warning[disabled]:focus,
fieldset[disabled] .btn-warning:focus,
.btn-warning.disabled:active,
.btn-warning[disabled]:active,
fieldset[disabled] .btn-warning:active,
.btn-warning.disabled.active,
.btn-warning[disabled].active,
fieldset[disabled] .btn-warning.active {
  background-color: #f1c40f;
  border-color: #f1c40f;
}
.btn-inverse {
  color: #ffffff;
  background-color: #34495e;
}
.btn-inverse:hover,
.btn-inverse:focus,
.btn-inverse:active,
.btn-inverse.active,
.open .dropdown-toggle.btn-inverse {
  color: #ffffff;
  background-color: #415b76;
  border-color: #415b76;
}
.btn-inverse:active,
.btn-inverse.active,
.open .dropdown-toggle.btn-inverse {
  background: #2c3e50;
  border-color: #2c3e50;
}
.btn-inverse.disabled,
.btn-inverse[disabled],
fieldset[disabled] .btn-inverse,
.btn-inverse.disabled:hover,
.btn-inverse[disabled]:hover,
fieldset[disabled] .btn-inverse:hover,
.btn-inverse.disabled:focus,
.btn-inverse[disabled]:focus,
fieldset[disabled] .btn-inverse:focus,
.btn-inverse.disabled:active,
.btn-inverse[disabled]:active,
fieldset[disabled] .btn-inverse:active,
.btn-inverse.disabled.active,
.btn-inverse[disabled].active,
fieldset[disabled] .btn-inverse.active {
  background-color: #34495e;
  border-color: #34495e;
}
.btn-embossed {
  -webkit-box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.15);
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.15);
}
.btn-embossed.active,
.btn-embossed:active {
  -webkit-box-shadow: inset 0 2px 0 rgba(0, 0, 0, 0.15);
  box-shadow: inset 0 2px 0 rgba(0, 0, 0, 0.15);
}
.btn-wide {
  min-width: 140px;
  padding-left: 30px;
  padding-right: 30px;
}
.btn-link {
  color: #428bca;
}
.btn-link:hover,
.btn-link:focus {
  color: #428bca;
  text-decoration: underline;
  background-color: transparent;
}
.btn-link[disabled]:hover,
fieldset[disabled] .btn-link:hover,
.btn-link[disabled]:focus,
fieldset[disabled] .btn-link:focus {
  color: #bdc3c7;
  text-decoration: none;
}
.btn-hg {
  padding: 13px 20px;
  font-size: 22px;
  line-height: 1.227;
  border-radius: 6px;
}
.btn-lg {
  padding: 10px 19px;
  font-size: 17px;
  line-height: 1.471;
  border-radius: 6px;
}
.btn-sm {
  padding: 9px 13px;
  font-size: 13px;
  line-height: 1.385;
  border-radius: 4px;
}
.btn-xs {
  padding: 6px 9px;
  font-size: 12px;
  line-height: 1.083;
  border-radius: 3px;
}
.btn-tip {
  font-weight: 300;
  padding-left: 10px;
  font-size: 92%;
}
.btn-block {
  white-space: normal;
}
.caret {
  border-width: 8px 6px;
  border-bottom-color: #34495e;
  border-top-color: #34495e;
  border-style: solid;
  border-bottom-style: none;
  -webkit-transition: 0.25s;
  transition: 0.25s;
  -webkit-transform: scale(1.001, );
  -ms-transform: scale(1.001, );
  transform: scale(1.001, );
}
.dropup .caret,
.dropup .btn-lg .caret,
.navbar-fixed-bottom .dropdown .caret {
  border-bottom-width: 8px;
}
.btn-lg .caret {
  border-top-width: 8px;
  border-right-width: 6px;
  border-left-width: 6px;
}
.select {
  display: inline-block;
  margin-bottom: 10px;
}
[class*="span"] > .select[class*="span"] {
  margin-left: 0;
}
.select[class*="span"] .btn {
  width: 100%;
}
.select.select-block {
  display: block;
  float: none;
  margin-left: 0;
  width: auto;
}
.select.select-block:before,
.select.select-block:after {
  content: " ";
  /* 1 */
  display: table;
  /* 2 */
}
.select.select-block:after {
  clear: both;
}
.select.select-block .btn {
  width: 100%;
}
.select.select-block .dropdown-menu {
  width: 100%;
}
.select .btn {
  width: 220px;
}
.select .btn.btn-hg .filter-option {
  left: 20px;
  right: 40px;
  top: 13px;
}
.select .btn.btn-hg .caret {
  right: 20px;
}
.select .btn.btn-lg .filter-option {
  left: 18px;
  right: 38px;
}
.select .btn.btn-sm .filter-option {
  left: 13px;
  right: 33px;
}
.select .btn.btn-sm .caret {
  right: 13px;
}
.select .btn.btn-xs .filter-option {
  left: 13px;
  right: 33px;
  top: 5px;
}
.select .btn.btn-xs .caret {
  right: 13px;
}
.select .btn .filter-option {
  height: 26px;
  left: 13px;
  overflow: hidden;
  position: absolute;
  right: 33px;
  text-align: left;
  top: 10px;
}
.select .btn .caret {
  position: absolute;
  right: 16px;
  top: 50%;
  margin-top: -3px;
}
.select .btn .dropdown-toggle {
  border-radius: 6px;
}
.select .btn .dropdown-menu {
  min-width: 100%;
}
.select .btn .dropdown-menu dt {
  cursor: default;
  display: block;
  padding: 3px 20px;
}
.select .btn .dropdown-menu li:not(.disabled) > a:hover small {
  color: rgba(255, 255, 255, 0.004);
}
.select .btn .dropdown-menu li > a {
  min-height: 20px;
}
.select .btn .dropdown-menu li > a.opt {
  padding-left: 35px;
}
.select .btn .dropdown-menu li small {
  padding-left: .5em;
}
.select .btn .dropdown-menu li > dt small {
  font-weight: normal;
}
.select .btn > .disabled,
.select .btn .dropdown-menu li.disabled > a {
  cursor: default;
}
.select .caret {
  border-bottom-color: #ffffff;
  border-top-color: #ffffff;
}

textarea {
  font-size: 20px;
  line-height: 24px;
  padding: 5px 11px;
}
input[type="search"] {
  -webkit-appearance: none !important;
}
label {
  font-weight: normal;
  font-size: 15px;
  line-height: 2.4;
}
.form-control:-moz-placeholder {
  color: #b2bcc5;
}
.form-control::-moz-placeholder {
  color: #b2bcc5;
  opacity: 1;
}
.form-control:-ms-input-placeholder {
  color: #b2bcc5;
}
.form-control::-webkit-input-placeholder {
  color: #b2bcc5;
}
.form-control.placeholder {
  color: #b2bcc5;
}
.form-control {
  border: 2px solid #bdc3c7;
  color: #34495e;
  font-family: "Lato", Helvetica, Arial, sans-serif;
  font-size: 15px;
  line-height: 1.467;
  padding: 8px 12px;
  height: 42px;
  -webkit-appearance: none;
  border-radius: 6px;
  -webkit-box-shadow: none;
  box-shadow: none;
  -webkit-transition: border .25s linear, color .25s linear, background-color .25s linear;
  transition: border .25s linear, color .25s linear, background-color .25s linear;
}
.form-group.focus .form-control,
.form-control:focus {
  border-color: #428bca;
  outline: 0;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.form-control[disabled],
.form-control[readonly],
fieldset[disabled] .form-control {
  background-color: #f4f6f6;
  border-color: #d5dbdb;
  color: #d5dbdb;
  cursor: default;
  opacity: 0.7;
  filter: alpha(opacity=70);
}
.form-control.flat {
  border-color: transparent;
}
.form-control.flat:hover {
  border-color: #bdc3c7;
}
.form-control.flat:focus {
  border-color: #428bca;
}
.input-sm {
  height: 35px;
  padding: 6px 10px;
  font-size: 13px;
  line-height: 1.462;
  border-radius: 6px;
}
select.input-sm {
  height: 35px;
  line-height: 35px;
}
textarea.input-sm,
select[multiple].input-sm {
  height: auto;
}
.input-lg {
  height: 45px;
  padding: 10px 15px;
  font-size: 17px;
  line-height: 1.235;
  border-radius: 6px;
}
select.input-lg {
  height: 45px;
  line-height: 45px;
}
textarea.input-lg,
select[multiple].input-lg {
  height: auto;
}
.input-hg {
  height: 53px;
  padding: 10px 16px;
  font-size: 22px;
  line-height: 1.318;
  border-radius: 6px;
}
select.input-hg {
  height: 53px;
  line-height: 53px;
}
textarea.input-hg,
select[multiple].input-hg {
  height: auto;
}
.has-warning .help-block,
.has-warning .control-label,
.has-warning .radio,
.has-warning .checkbox,
.has-warning .radio-inline,
.has-warning .checkbox-inline {
  color: #f1c40f;
}
.has-warning .form-control {
  color: #f1c40f;
  border-color: #f1c40f;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.has-warning .form-control:-moz-placeholder {
  color: #f1c40f;
}
.has-warning .form-control::-moz-placeholder {
  color: #f1c40f;
  opacity: 1;
}
.has-warning .form-control:-ms-input-placeholder {
  color: #f1c40f;
}
.has-warning .form-control::-webkit-input-placeholder {
  color: #f1c40f;
}
.has-warning .form-control.placeholder {
  color: #f1c40f;
}
.has-warning .form-control:focus {
  border-color: #f1c40f;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.has-warning .input-group-addon {
  color: #f1c40f;
  border-color: #f1c40f;
  background-color: #ffffff;
}
.has-error .help-block,
.has-error .control-label,
.has-error .radio,
.has-error .checkbox,
.has-error .radio-inline,
.has-error .checkbox-inline {
  color: #e74c3c;
}
.has-error .form-control {
  color: #e74c3c;
  border-color: #e74c3c;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.has-error .form-control:-moz-placeholder {
  color: #e74c3c;
}
.has-error .form-control::-moz-placeholder {
  color: #e74c3c;
  opacity: 1;
}
.has-error .form-control:-ms-input-placeholder {
  color: #e74c3c;
}
.has-error .form-control::-webkit-input-placeholder {
  color: #e74c3c;
}
.has-error .form-control.placeholder {
  color: #e74c3c;
}
.has-error .form-control:focus {
  border-color: #e74c3c;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.has-error .input-group-addon {
  color: #e74c3c;
  border-color: #e74c3c;
  background-color: #ffffff;
}
.has-success .help-block,
.has-success .control-label,
.has-success .radio,
.has-success .checkbox,
.has-success .radio-inline,
.has-success .checkbox-inline {
  color: #2ecc71;
}
.has-success .form-control {
  color: #2ecc71;
  border-color: #2ecc71;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.has-success .form-control:-moz-placeholder {
  color: #2ecc71;
}
.has-success .form-control::-moz-placeholder {
  color: #2ecc71;
  opacity: 1;
}
.has-success .form-control:-ms-input-placeholder {
  color: #2ecc71;
}
.has-success .form-control::-webkit-input-placeholder {
  color: #2ecc71;
}
.has-success .form-control.placeholder {
  color: #2ecc71;
}
.has-success .form-control:focus {
  border-color: #2ecc71;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.has-success .input-group-addon {
  color: #2ecc71;
  border-color: #2ecc71;
  background-color: #ffffff;
}
.help-block {
  font-size: 15px;
  margin-bottom: 5px;
  color: inherit;
}
.form-group {
  position: relative;
  margin-bottom: 20px;
}
.form-horizontal .control-label,
.form-horizontal .radio,
.form-horizontal .checkbox,
.form-horizontal .radio-inline,
.form-horizontal .checkbox-inline {
  margin-top: 0;
  margin-bottom: 0;
  padding-top: 6px;
}
.form-horizontal .form-group {
  margin-left: -15px;
  margin-right: -15px;
}
.form-horizontal .form-group:before,
.form-horizontal .form-group:after {
  content: " ";
  /* 1 */
  display: table;
  /* 2 */
}
.form-horizontal .form-group:after {
  clear: both;
}
.form-horizontal .form-control-static {
  padding-top: 6px;
}
.form-group {
  position: relative;
}
.form-control + .input-icon {
  position: absolute;
  top: 2px;
  right: 2px;
  line-height: 37px;
  vertical-align: middle;
  font-size: 20px;
  color: #b2bcc5;
  background-color: #ffffff;
  padding: 0 12px 0 0;
  border-radius: 6px;
}
.input-hg + .input-icon {
  line-height: 49px;
  padding: 0 16px 0 0;
}
.input-lg + .input-icon {
  line-height: 41px;
  padding: 0 15px 0 0;
}
.input-sm + .input-icon {
  font-size: 18px;
  line-height: 30px;
  padding: 0 10px 0 0;
}
.has-success .input-icon {
  color: #2ecc71;
}
.has-warning .input-icon {
  color: #f1c40f;
}
.has-error .input-icon {
  color: #e74c3c;
}
.form-control[disabled] + .input-icon,
.form-control[readonly] + .input-icon,
fieldset[disabled] .form-control + .input-icon,
.form-control.disabled + .input-icon {
  color: #d5dbdb;
  background-color: transparent;
  opacity: 0.7;
  filter: alpha(opacity=70);
}
.input-group-hg > .form-control,
.input-group-hg > .input-group-addon,
.input-group-hg > .input-group-btn > .btn {
  height: 53px;
  padding: 10px 16px;
  font-size: 22px;
  line-height: 1.318;
  border-radius: 6px;
}
select.input-group-hg > .form-control,
select.input-group-hg > .input-group-addon,
select.input-group-hg > .input-group-btn > .btn {
  height: 53px;
  line-height: 53px;
}
textarea.input-group-hg > .form-control,
textarea.input-group-hg > .input-group-addon,
textarea.input-group-hg > .input-group-btn > .btn,
select[multiple].input-group-hg > .form-control,
select[multiple].input-group-hg > .input-group-addon,
select[multiple].input-group-hg > .input-group-btn > .btn {
  height: auto;
}
.input-group-lg > .form-control,
.input-group-lg > .input-group-addon,
.input-group-lg > .input-group-btn > .btn {
  height: 45px;
  padding: 10px 15px;
  font-size: 17px;
  line-height: 1.235;
  border-radius: 6px;
}
select.input-group-lg > .form-control,
select.input-group-lg > .input-group-addon,
select.input-group-lg > .input-group-btn > .btn {
  height: 45px;
  line-height: 45px;
}
textarea.input-group-lg > .form-control,
textarea.input-group-lg > .input-group-addon,
textarea.input-group-lg > .input-group-btn > .btn,
select[multiple].input-group-lg > .form-control,
select[multiple].input-group-lg > .input-group-addon,
select[multiple].input-group-lg > .input-group-btn > .btn {
  height: auto;
}
.input-group-sm > .form-control,
.input-group-sm > .input-group-addon,
.input-group-sm > .input-group-btn > .btn {
  height: 35px;
  padding: 6px 10px;
  font-size: 13px;
  line-height: 1.462;
  border-radius: 6px;
}
select.input-group-sm > .form-control,
select.input-group-sm > .input-group-addon,
select.input-group-sm > .input-group-btn > .btn {
  height: 35px;
  line-height: 35px;
}
textarea.input-group-sm > .form-control,
textarea.input-group-sm > .input-group-addon,
textarea.input-group-sm > .input-group-btn > .btn,
select[multiple].input-group-sm > .form-control,
select[multiple].input-group-sm > .input-group-addon,
select[multiple].input-group-sm > .input-group-btn > .btn {
  height: auto;
}
.input-group-addon {
  padding: 10px 12px;
  font-size: 15px;
  color: #ffffff;
  text-align: center;
  background-color: #bdc3c7;
  border: 1px solid #bdc3c7;
  border-radius: 6px;
  -webkit-transition: border .25s linear, color .25s linear, background-color .25s linear;
  transition: border .25s linear, color .25s linear, background-color .25s linear;
}
.input-group-hg .input-group-addon,
.input-group-lg .input-group-addon,
.input-group-sm .input-group-addon {
  line-height: 1;
}
.input-group .form-control:first-child,
.input-group-addon:first-child,
.input-group-btn:first-child > .btn,
.input-group-btn:first-child > .dropdown-toggle,
.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) {
  border-bottom-right-radius: 0;
  border-top-right-radius: 0;
}
.input-group .form-control:last-child,
.input-group-addon:last-child,
.input-group-btn:last-child > .btn,
.input-group-btn:last-child > .dropdown-toggle,
.input-group-btn:first-child > .btn:not(:first-child) {
  border-bottom-left-radius: 0;
  border-top-left-radius: 0;
}
.form-group.focus .input-group-addon,
.input-group.focus .input-group-addon {
  background-color: #428bca;
  border-color: #428bca;
}
.form-group.focus .input-group-btn > .btn-default + .btn-default,
.input-group.focus .input-group-btn > .btn-default + .btn-default {
  border-left-color: #428bca;
}
.form-group.focus .input-group-btn .btn,
.input-group.focus .input-group-btn .btn {
  border-color: #428bca;
  background-color: #ffffff;
  color: #428bca;
}
.form-group.focus .input-group-btn .btn-default,
.input-group.focus .input-group-btn .btn-default {
  color: #ffffff;
  background-color: #428bca;
}
.form-group.focus .input-group-btn .btn-default:hover,
.input-group.focus .input-group-btn .btn-default:hover,
.form-group.focus .input-group-btn .btn-default:focus,
.input-group.focus .input-group-btn .btn-default:focus,
.form-group.focus .input-group-btn .btn-default:active,
.input-group.focus .input-group-btn .btn-default:active,
.form-group.focus .input-group-btn .btn-default.active,
.input-group.focus .input-group-btn .btn-default.active,
.open .dropdown-toggle.form-group.focus .input-group-btn .btn-default,
.open .dropdown-toggle.input-group.focus .input-group-btn .btn-default {
  color: #ffffff;
  background-color: #3276b1;
  border-color: #3276b1;
}
.form-group.focus .input-group-btn .btn-default:active,
.input-group.focus .input-group-btn .btn-default:active,
.form-group.focus .input-group-btn .btn-default.active,
.input-group.focus .input-group-btn .btn-default.active,
.open .dropdown-toggle.form-group.focus .input-group-btn .btn-default,
.open .dropdown-toggle.input-group.focus .input-group-btn .btn-default {
  background: #428bca;
  border-color: #428bca;
}
.form-group.focus .input-group-btn .btn-default.disabled,
.input-group.focus .input-group-btn .btn-default.disabled,
.form-group.focus .input-group-btn .btn-default[disabled],
.input-group.focus .input-group-btn .btn-default[disabled],
fieldset[disabled] .form-group.focus .input-group-btn .btn-default,
fieldset[disabled] .input-group.focus .input-group-btn .btn-default,
.form-group.focus .input-group-btn .btn-default.disabled:hover,
.input-group.focus .input-group-btn .btn-default.disabled:hover,
.form-group.focus .input-group-btn .btn-default[disabled]:hover,
.input-group.focus .input-group-btn .btn-default[disabled]:hover,
fieldset[disabled] .form-group.focus .input-group-btn .btn-default:hover,
fieldset[disabled] .input-group.focus .input-group-btn .btn-default:hover,
.form-group.focus .input-group-btn .btn-default.disabled:focus,
.input-group.focus .input-group-btn .btn-default.disabled:focus,
.form-group.focus .input-group-btn .btn-default[disabled]:focus,
.input-group.focus .input-group-btn .btn-default[disabled]:focus,
fieldset[disabled] .form-group.focus .input-group-btn .btn-default:focus,
fieldset[disabled] .input-group.focus .input-group-btn .btn-default:focus,
.form-group.focus .input-group-btn .btn-default.disabled:active,
.input-group.focus .input-group-btn .btn-default.disabled:active,
.form-group.focus .input-group-btn .btn-default[disabled]:active,
.input-group.focus .input-group-btn .btn-default[disabled]:active,
fieldset[disabled] .form-group.focus .input-group-btn .btn-default:active,
fieldset[disabled] .input-group.focus .input-group-btn .btn-default:active,
.form-group.focus .input-group-btn .btn-default.disabled.active,
.input-group.focus .input-group-btn .btn-default.disabled.active,
.form-group.focus .input-group-btn .btn-default[disabled].active,
.input-group.focus .input-group-btn .btn-default[disabled].active,
fieldset[disabled] .form-group.focus .input-group-btn .btn-default.active,
fieldset[disabled] .input-group.focus .input-group-btn .btn-default.active {
  background-color: #428bca;
  border-color: #428bca;
}
.input-group-btn .btn {
  background-color: #ffffff;
  border: 2px solid #bdc3c7;
  color: #bdc3c7;
  line-height: 18px;
}
.input-group-btn .btn-default {
  color: #ffffff;
  background-color: #bdc3c7;
}
.input-group-btn .btn-default:hover,
.input-group-btn .btn-default:focus,
.input-group-btn .btn-default:active,
.input-group-btn .btn-default.active,
.open .dropdown-toggle.input-group-btn .btn-default {
  color: #ffffff;
  background-color: #cacfd2;
  border-color: #cacfd2;
}
.input-group-btn .btn-default:active,
.input-group-btn .btn-default.active,
.open .dropdown-toggle.input-group-btn .btn-default {
  background: #a1a6a9;
  border-color: #a1a6a9;
}
.input-group-btn .btn-default.disabled,
.input-group-btn .btn-default[disabled],
fieldset[disabled] .input-group-btn .btn-default,
.input-group-btn .btn-default.disabled:hover,
.input-group-btn .btn-default[disabled]:hover,
fieldset[disabled] .input-group-btn .btn-default:hover,
.input-group-btn .btn-default.disabled:focus,
.input-group-btn .btn-default[disabled]:focus,
fieldset[disabled] .input-group-btn .btn-default:focus,
.input-group-btn .btn-default.disabled:active,
.input-group-btn .btn-default[disabled]:active,
fieldset[disabled] .input-group-btn .btn-default:active,
.input-group-btn .btn-default.disabled.active,
.input-group-btn .btn-default[disabled].active,
fieldset[disabled] .input-group-btn .btn-default.active {
  background-color: #bdc3c7;
  border-color: #bdc3c7;
}
.input-group-hg .input-group-btn .btn {
  line-height: 31px;
}
.input-group-lg .input-group-btn .btn {
  line-height: 21px;
}
.input-group-sm .input-group-btn .btn {
  line-height: 19px;
}
.input-group-btn:first-child > .btn {
  border-right-width: 0;
  margin-right: -2px;
}
.input-group-btn:last-child > .btn {
  border-left-width: 0;
  margin-left: -2px;
}
.input-group-btn > .btn-default + .btn-default {
  border-left: 2px solid #bdc3c7;
}
.input-group-btn > .btn:first-child + .btn .caret {
  margin-left: 0;
}
.input-group-rounded .input-group-btn + .form-control,
.input-group-rounded .input-group-btn:last-child .btn {
  border-bottom-right-radius: 20px;
  border-top-right-radius: 20px;
}
.input-group-hg.input-group-rounded .input-group-btn + .form-control,
.input-group-hg.input-group-rounded .input-group-btn:last-child .btn {
  border-bottom-right-radius: 27px;
  border-top-right-radius: 27px;
}
.input-group-lg.input-group-rounded .input-group-btn + .form-control,
.input-group-lg.input-group-rounded .input-group-btn:last-child .btn {
  border-bottom-right-radius: 25px;
  border-top-right-radius: 25px;
}
.input-group-rounded .form-control:first-child,
.input-group-rounded .input-group-btn:first-child .btn {
  border-bottom-left-radius: 20px;
  border-top-left-radius: 20px;
}
.input-group-hg.input-group-rounded .form-control:first-child,
.input-group-hg.input-group-rounded .input-group-btn:first-child .btn {
  border-bottom-left-radius: 27px;
  border-top-left-radius: 27px;
}
.input-group-lg.input-group-rounded .form-control:first-child,
.input-group-lg.input-group-rounded .input-group-btn:first-child .btn {
  border-bottom-left-radius: 25px;
  border-top-left-radius: 25px;
}
.input-group-rounded .input-group-btn + .form-control {
  padding-left: 0;
}
.checkbox,
.radio {
  margin-bottom: 12px;
  padding-left: 32px;
  position: relative;
  -webkit-transition: color 0.25s linear;
  transition: color 0.25s linear;
  font-size: 14px;
  line-height: 1.5;
}
.checkbox input,
.radio input {
  outline: none !important;
  display: none;
}
.checkbox .icons,
.radio .icons {
  color: #bdc3c7;
  display: block;
  height: 20px;
  left: 0;
  position: absolute;
  top: 0;
  width: 20px;
  text-align: center;
  line-height: 21px;
  font-size: 20px;
  cursor: pointer;
  -webkit-transition: color 0.25s linear;
  transition: color 0.25s linear;
}
.checkbox .icons .first-icon,
.radio .icons .first-icon,
.checkbox .icons .second-icon,
.radio .icons .second-icon {
  display: inline-table;
  position: absolute;
  left: 0;
  top: 0;
  background-color: transparent;
  margin: 0;
  opacity: 1;
  filter: alpha(opacity=100);
}
.checkbox .icons .second-icon,
.radio .icons .second-icon {
  opacity: 0;
  filter: alpha(opacity=0);
}
.checkbox:hover,
.radio:hover {
  -webkit-transition: color 0.25s linear;
  transition: color 0.25s linear;
}
.checkbox:hover .first-icon,
.radio:hover .first-icon {
  opacity: 0;
  filter: alpha(opacity=0);
}
.checkbox:hover .second-icon,
.radio:hover .second-icon {
  opacity: 1;
  filter: alpha(opacity=100);
}
.checkbox.checked,
.radio.checked {
  color: #428bca;
}
.checkbox.checked .first-icon,
.radio.checked .first-icon {
  opacity: 0;
  filter: alpha(opacity=0);
}
.checkbox.checked .second-icon,
.radio.checked .second-icon {
  opacity: 1;
  filter: alpha(opacity=100);
  color: #428bca;
  -webkit-transition: color 0.25s linear;
  transition: color 0.25s linear;
}
.checkbox.disabled,
.radio.disabled {
  cursor: default;
  color: #e6e8ea;
}
.checkbox.disabled .icons,
.radio.disabled .icons {
  color: #e6e8ea;
}
.checkbox.disabled .first-icon,
.radio.disabled .first-icon {
  opacity: 1;
  filter: alpha(opacity=100);
}
.checkbox.disabled .second-icon,
.radio.disabled .second-icon {
  opacity: 0;
  filter: alpha(opacity=0);
}
.checkbox.disabled.checked .icons,
.radio.disabled.checked .icons {
  color: #e6e8ea;
}
.checkbox.disabled.checked .first-icon,
.radio.disabled.checked .first-icon {
  opacity: 0;
  filter: alpha(opacity=0);
}
.checkbox.disabled.checked .second-icon,
.radio.disabled.checked .second-icon {
  opacity: 1;
  filter: alpha(opacity=100);
  color: #e6e8ea;
}
.checkbox.primary .icons,
.radio.primary .icons {
  color: #34495e;
}
.checkbox.primary.checked,
.radio.primary.checked {
  color: #428bca;
}
.checkbox.primary.checked .icons,
.radio.primary.checked .icons {
  color: #428bca;
}
.checkbox.primary.disabled,
.radio.primary.disabled {
  cursor: default;
  color: #bdc3c7;
}
.checkbox.primary.disabled .icons,
.radio.primary.disabled .icons {
  color: #bdc3c7;
}
.checkbox.primary.disabled.checked .icons,
.radio.primary.disabled.checked .icons {
  color: #bdc3c7;
}
.radio + .radio,
.checkbox + .checkbox {
  margin-top: 10px;
}
.tooltip {
  font-size: 14px;
  line-height: 1.286;
}
.tooltip.in {
  opacity: 1;
}
.tooltip.top {
  padding-bottom: 9px;
}
.tooltip.top .tooltip-arrow {
  border-top-color: #34495e;
  border-width: 9px 9px 0;
  bottom: 0;
  margin-left: -9px;
}
.tooltip.right .tooltip-arrow {
  border-right-color: #34495e;
  border-width: 9px 9px 9px 0;
  margin-top: -9px;
  left: -3px;
}
.tooltip.bottom {
  padding-top: 8px;
}
.tooltip.bottom .tooltip-arrow {
  border-bottom-color: #34495e;
  border-width: 0 9px 9px;
  margin-left: -9px;
  top: -1px;
}
.tooltip.left .tooltip-arrow {
  border-left-color: #34495e;
  border-width: 9px 0 9px 9px;
  margin-top: -9px;
  right: -3px;
}
.tooltip-inner {
  background-color: #34495e;
  line-height: 1.286;
  padding: 12px 12px;
  text-align: center;
  width: 183px;
  border-radius: 6px;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (-moz-min-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 2) {
  .login {
    background-image: url(../images/login/imac-2x.png);
  }
}


================================================
FILE: res/css/style.css
================================================
@CHARSET "UTF-8";
.clear {
  clear: both;
}
html,body{margin: 0;padding: 0}
#nav {
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=90);
  opacity: 0.9;
  background: #FFF;
  padding: 0;
  margin:0;
  background: #446CB3;
  color:white;
}
#menu{  width: 80%;
  margin: 0 auto
 }
#nav ul {
  margin: 0px auto;
  padding: 0px;
  list-style-type: none;
}
#nav ul li {
  float: left;
  padding: 10px 10px;
  font-size: 14px;
  border-right: 1px solid rgba(0, 0, 0, 0.1);
  box-shadow: 1px 0 0 rgba(255, 255, 255, 0.11);
  font-weight: bold;
  text-align: center;
}
.border_first{
  border-left: 1px solid rgba(0, 0, 0, 0.1);
  box-shadow: 1px 0 0 rgba(255, 255, 255, 0.11);
}

#nav ul#left_submenu li:HOVER{
	background: white;
}
#nav ul#left_submenu li:HOVER a{
	color:#446CB3
}
#nav ul li a{display: inline-block;width:50px; color:white;}

#network-tb td{
    vertical-align: top
}

#aside {
    width:33%;
    min-width: 450px;
}
.w120{width: 120px}
.w140{width: 140px}
.w150{width: 150px}

#connect_status{padding:6px;color: white}

table {border-collapse: collapse;border-spacing: 0;}
.tb_1{border:1px solid #cccccc;table-layout:fixed;word-break:break-all;width: 100%;background:#ffffff;margin-bottom:5px}
.tb_1 caption{text-align: center;background: #F0F4F6;font-weight: bold;padding-top: 5px;height: 25px;border:1px solid #cccccc;border-bottom:none}
.tb_1 a{margin:0 3px 0 3px}
.tb_1 tr th,.tb_1 tr td{padding: 3px;border:1px solid #cccccc;line-height:20px}
.tb_1 thead tr th{font-weight:bold;text-align: center;background:#e3eaee}
.tb_1 tbody tr th{text-align: right;background:#f0f4f6;padding-right:5px}
.tb_1 tfoot{color:#cccccc}
.td_c td{text-align: center}
.td_r td{text-align: right}
.t_c{text-align: center !important;}
.t_r{text-align: right !important;}
.t_l{text-align: left !important;}

.panel_1{background: #e5e2eb;padding:4px}
#network_filter_form fieldset{padding-right:3px}

 #tb_network{font-size: 11px;margin-top: -8px;}
 #tb_network td{overflow: auto;cursor: pointer;}
#right_content{margin-top:5px}
 #right_content table th,#right_content table td{font-size:11px;vertical-align: top}
 #right_content pre{border:none}
 
 #div_tb_network_list {overflow:auto;max-height: 1000px;min-height:450px}
 tr.selected{background: #ccffee;}
 .right{float: right}
 .left{float:left}
 .c{clear: both}
 .hide{display:none}
#network_list_div tbody th{text-align: right;}
.td_ul{list-style: none inside;padding: 0;margin: 0}
.td_ul li{list-style: none inside;}

td.td_has_sub{padding: 0 !important;}
td.td_has_sub .tb_1{margin: 0;border: 0;}

#bd0{margin:0 auto;width:80%}
.form-control{height: 26px;padding:0}
fieldset {
	border-radius:10px;
	border: 1px solid gray
}
tr.replay{
	color:blue;
}

.res_td_body{
	max-height: 120px;
	overflow: scroll;
}

.div_b_i{
	display: inline-block;
}

.login-screen {
  min-height: 400px;
  width:300px;
  margin: 0 auto;
  text-align: center;
}

#bd{
	margin: 0 auto;
	width:80%;
	padding-top: 30px;
}

.form_0 table{width: 100%}
.form_0 th{text-align: right;width: 180px;vertical-align:top;}
.form_0 input[type=text]{width: 100%;margin-bottom:2px}
.form_0 td.last{width: 90px;padding-left: 10px}
.oneline{height: 20px;overflow: hidden;}

img {margin-bottom: -3px}

================================================
FILE: res/js/base64.js
================================================
/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/
var Base64 = {

// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

// public method for encoding
encode : function (input) {
    var output = "";
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    var i = 0;

    input = Base64._utf8_encode(input);

    while (i < input.length) {

        chr1 = input.charCodeAt(i++);
        chr2 = input.charCodeAt(i++);
        chr3 = input.charCodeAt(i++);

        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;

        if (isNaN(chr2)) {
            enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
            enc4 = 64;
        }

        output = output +
        this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
        this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

    }

    return output;
},

// public method for decoding
decode : function (input) {
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;

    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

    while (i < input.length) {

        enc1 = this._keyStr.indexOf(input.charAt(i++));
        enc2 = this._keyStr.indexOf(input.charAt(i++));
        enc3 = this._keyStr.indexOf(input.charAt(i++));
        enc4 = this._keyStr.indexOf(input.charAt(i++));

        chr1 = (enc1 << 2) | (enc2 >> 4);
        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
        chr3 = ((enc3 & 3) << 6) | enc4;

        output = output + String.fromCharCode(chr1);

        if (enc3 != 64) {
            output = output + String.fromCharCode(chr2);
        }
        if (enc4 != 64) {
            output = output + String.fromCharCode(chr3);
        }

    }

    output = Base64._utf8_decode(output);

    return output;

},

// private method for UTF-8 encoding
_utf8_encode : function (string) {
    string = string.replace(/\r\n/g,"\n");
    var utftext = "";

    for (var n = 0; n < string.length; n++) {

        var c = string.charCodeAt(n);

        if (c < 128) {
            utftext += String.fromCharCode(c);
        }
        else if((c > 127) && (c < 2048)) {
            utftext += String.fromCharCode((c >> 6) | 192);
            utftext += String.fromCharCode((c & 63) | 128);
        }
        else {
            utftext += String.fromCharCode((c >> 12) | 224);
            utftext += String.fromCharCode(((c >> 6) & 63) | 128);
            utftext += String.fromCharCode((c & 63) | 128);
        }

    }

    return utftext;
},

// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
    var string = "";
    var i = 0;
    var c = c1 = c2 = 0;

    while ( i < utftext.length ) {

        c = utftext.charCodeAt(i);

        if (c < 128) {
            string += String.fromCharCode(c);
            i++;
        }
        else if((c > 191) && (c < 224)) {
            c2 = utftext.charCodeAt(i+1);
            string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
            i += 2;
        }
        else {
            c2 = utftext.charCodeAt(i+1);
            c3 = utftext.charCodeAt(i+2);
            string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }

    }

    return string;
}

}

================================================
FILE: res/js/default.js
================================================
function pproxy_tab_sup(target){
	$(target).find("textarea").bind('keydown', function(e) {
	    if (e.keyCode == 9 ) {
	        e.preventDefault();
	        this.setRangeText('\t');
	        this.selectionEnd = ++this.selectionStart;
	    }
	});
}

================================================
FILE: res/js/jquery.js
================================================
/*! jQuery v1.6.4 http://jquery.com/ | http://jquery.org/license */
(function(a,b){function cu(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cr(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cp(){cn=b}function co(){setTimeout(cp,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function bZ(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bY(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bA.test(a)?d(a,e):bY(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)bY(a+"["+e+"]",b[e],c,d);else d(a,b)}function bX(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bW(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bP,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bW(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bW(a,c,d,e,"*",g));return l}function bV(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bL),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function by(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bt:bu;if(d>0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bv(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bd,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)f.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function bf(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function V(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(Q.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function U(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function M(a,b){return(a&&a!=="*"?a+".":"")+b.replace(y,"`").replace(z,"&")}function L(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;i<s.length;i++)g=s[i],g.origType.replace(w,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function J(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function D(){return!0}function C(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(K,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.4",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;B.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:H?function(a){return a==null?"":H.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?F.call(c,a):e.merge(c,a)}return c},inArray:function(a,b){if(!b)return-1;if(I)return I.call(b,a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=G.call(arguments,2),g=function(){return a.apply(c,f.concat(G.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){J["[object "+b+"]"]=b.toLowerCase()}),A=e.uaMatch(z),A.browser&&(e.browser[A.browser]=!0,e.browser.version=A.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?C=function(){c.removeEventListener("DOMContentLoaded",C,!1),e.ready()}:c.attachEvent&&(C=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",C),e.ready())});return e}(),g="done fail isResolved isRejected promise then always pipe".split(" "),h=[].slice;f.extend({_Deferred:function(){var a=[],b,c,d,e={done:function(){if(!d){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=f.type(i),j==="array"?e.done.apply(e,i):j==="function"&&a.push(i);k&&e.resolveWith(k[0],k[1])}return this},resolveWith:function(e,f){if(!d&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(e,f)}finally{b=[e,f],c=0}}return this},resolve:function(){e.resolveWith(this,arguments);return this},isResolved:function(){return!!c||!!b},cancel:function(){d=1,a=[];return this}};return e},Deferred:function(a){var b=f._Deferred(),c=f._Deferred(),d;f.extend(b,{then:function(a,c){b.done(a).fail(c);return this},always:function(){return b.done.apply(b,arguments).fail.apply(this,arguments)},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,pipe:function(a,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[c,"reject"]},function(a,c){var e=c[0],g=c[1],h;f.isFunction(e)?b[a](function(){h=e.apply(this,arguments),h&&f.isFunction(h.promise)?h.promise().then(d.resolve,d.reject):d[g+"With"](this===b?d:this,[h])}):b[a](d[g])})}).promise()},promise:function(a){if(a==null){if(d)return d;d=a={}}var c=g.length;while(c--)a[g[c]]=b[g[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c<d;c++)b[c]&&f.isFunction(b[c].promise)?b[c].promise().then(i(c),g.reject):--e;e||g.resolveWith(g,b)}else g!==a&&g.resolveWith(g,d?[a]:[]);return g.promise()}}),f.support=function(){var a=c.createElement("div"),b=c.documentElement,d,e,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;a.setAttribute("className","t"),a.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-1000px",top:"-1000px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i=f.expando,j=typeof c=="string",k=a.nodeType,l=k?f.cache:a,m=k?a[f.expando]:a[f.expando]&&f.expando;if((!m||e&&m&&l[m]&&!l[m][i])&&j&&d===b)return;m||(k?a[f.expando]=m=++f.uuid:m=f.expando),l[m]||(l[m]={},k||(l[m].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?l[m][i]=f.extend(l[m][i],c):l[m]=f.extend(l[m],c);g=l[m],e&&(g[i]||(g[i]={}),g=g[i]),d!==b&&(g[f.camelCase(c)]=d);if(c==="events"&&!g[c])return g[i]&&g[i].events;j?(h=g[c],h==null&&(h=g[f.camelCase(c)])):h=g;return h}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e=f.expando,g=a.nodeType,h=g?f.cache:a,i=g?a[f.expando]:f.expando;if(!h[i])return;if(b){d=c?h[i][e]:h[i];if(d){d[b]||(b=f.camelCase(b)),delete d[b];if(!l(d))return}}if(c){delete h[i][e];if(!l(h[i]))return}var j=h[i][e];f.support.deleteExpando||!h.setInterval?delete h[i]:h[i]=null,j?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=j):g&&(f.support.deleteExpando?delete a[f.expando]:a.removeAttribute?a.removeAttribute(f.expando):a[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h<i;h++)g=e[h].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),k(this[0],g,d[g]))}}return d}if(typeof a=="object")return this.each(function(){f.data(this,a)});var j=a.split(".");j[1]=j[1]?"."+j[1]:"";if(c===b){d=this.triggerHandler("getData"+j[1]+"!",[j[0]]),d===b&&this.length&&(d=f.data(this[0],a),d=k(this[0],a,d));return d===b&&j[1]?this.data(j[0]):d}return this.each(function(){var b=f(this),d=[j[0],c];b.triggerHandler("setData"+j[1]+"!",d),f.data(this,a,c),b.triggerHandler("changeData"+j[1]+"!",d)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,c){a&&(c=(c||"fx")+"mark",f.data(a,c,(f.data(a,c,b,!0)||0)+1,!0))},_unmark:function(a,c,d){a!==!0&&(d=c,c=a,a=!1);if(c){d=d||"fx";var e=d+"mark",g=a?0:(f.data(c,e,b,!0)||1)-1;g?f.data(c,e,g,!0):(f.removeData(c,e,!0),m(c,d,"mark"))}},queue:function(a,c,d){if(a){c=(c||"fx")+"queue";var e=f.data(a,c,b,!0);d&&(!e||f.isArray(d)?e=f.data(a,c,f.makeArray(d),!0):e.push(d));return e||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e;d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),d.call(a,function(){f.dequeue(a,b)})),c.length||(f.removeData(a,b+"queue",!0),m(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){f.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f._Deferred(),!0))h++,l.done(m);m();return d.promise()}});var n=/[\n\t\r]/g,o=/\s+/,p=/\r/g,q=/^(?:button|input)$/i,r=/^(?:button|input|object|select|textarea)$/i,s=/^a(?:rea)?$/i,t=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,u,v;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(o);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(o);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(n," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(o);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(n," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h<i;h++){var j=e[h];if(j.selected&&(f.support.optDisabled?!j.disabled:j.getAttribute("disabled")===null)&&(!j.parentNode.disabled||!f.nodeName(j.parentNode,"optgroup"))){b=f(j).val();if(g)return b;d.push(b)}}if(g&&!d.length&&e.length)return f(e[c]).val();return d},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=v:u&&(i=u)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.attr(a,b,""),a.removeAttribute(b),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(u&&f.nodeName(a,"button"))return u.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(u&&f.nodeName(a,"button"))return u.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==null?g:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabIndex=f.propHooks.tabIndex,v={get:function(a,c){var d;return f.prop(a,c)===!0||(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(u=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var w=/\.(.*)$/,x=/^(?:textarea|input|select)$/i,y=/\./g,z=/ /g,A=/[^\w\s.|`]/g,B=function(a){return a.replace(A,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=C;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=C);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),B).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))f.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=f.event.special[h]||{};for(j=e||0;j<p.length;j++){q=p[j];if(d.guid===q.guid){if(l||n.test(q.namespace))e==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(e!=null)break}}if(p.length===0||e!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&f.removeEvent(a,h,s.handle),g=null,delete 
t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,M(a.origType,a.selector),f.extend({},a,{handler:L,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,M(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?D:C):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=D;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=D;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=D,this.stopPropagation()},isDefaultPrevented:C,isPropagationStopped:C,isImmediatePropagationStopped:C};var E=function(a){var b=a.relatedTarget,c=!1,d=a.type;a.type=a.data,b!==this&&(b&&(c=f.contains(this,b)),c||(f.event.handle.apply(this,arguments),a.type=d))},F=function(a){a.type=a.data,f.event.handle.apply(this,arguments)};f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={setup:function(c){f.event.add(this,b,c&&c.selector?F:E,a)},teardown:function(a){f.event.remove(this,b,a&&a.selector?F:E)}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(a,b){if(!f.nodeName(this,"form"))f.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=f.nodeName(b,"input")||f.nodeName(b,"button")?b.type:"";(c==="submit"||c==="image")&&f(b).closest("form").length&&J("submit",this,arguments)}),f.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=f.nodeName(b,"input")||f.nodeName(b,"button")?b.type:"";(c==="text"||c==="password")&&f(b).closest("form").length&&a.keyCode===13&&J("submit",this,arguments)});else return!1},teardown:function(a){f.event.remove(this,".specialSubmit")}});if(!f.support.changeBubbles){var G,H=function(a){var b=f.nodeName(a,"input")?a.type:"",c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},I=function(c){var d=c.target,e,g;if(!!x.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=H(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:I,beforedeactivate:I,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&I.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&I.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",H(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in G)f.event.add(this,c+".specialChange",G[c]);return x.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return x.test(this.nodeName)}},G=f.event.special.change.filters,G.focus=G.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i<j;i++)f.event.add(this[i],a,g,d);return this}}),f.fn.extend({unbind:function(a,b){if(typeof a=="object"&&!a.preventDefault)for(var c in a)this.unbind(c,a[c]);else for(var d=0,e=this.length;d<e;d++)f.event.remove(this[d],a,b);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f.data(this,"lastToggle"+a.guid)||0)%d;f.data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var K={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};f.each(["live","die"],function(a,c){f.fn[c]=function(a,d,e,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:f(this.context);if(typeof a=="object"&&!a.preventDefault){for(var o in a)n[c](o,d,a[o],m);return this}if(c==="die"&&!a&&g&&g.charAt(0)==="."){n.unbind(g);return this}if(d===!1||f.isFunction(d))e=d||C,d=b;a=(a||"").split(" ");while((h=a[i++])!=null){j=w.exec(h),k="",j&&(k=j[0],h=h.replace(w,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,K[h]?(a.push(K[h]+k),h=h+k):h=(K[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)f.event.add(n[p],"live."+M(h,m),{data:d,selector:m,handler:e,origType:h,origHandler:e,preType:l});else n.unbind("live."+M(h,m),e)}return this}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(!f)g=o=!0;else if(f===!0)continue}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("parentNode",b,f,a,e,c)},"~":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("previousSibling",b,f,a,e,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c<f;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){if(a===b){g=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};f.find=k,f.expr=k.selectors,f.expr[":"]=f.expr.filters,f.unique=k.uniqueSort,f.text=k.getText,f.isXMLDoc=k.isXML,f.contains=k.contains}();var N=/Until$/,O=/^(?:parents|prevUntil|prevAll)/,P=/,/,Q=/^.[^:#\[\.,]*$/,R=Array.prototype.slice,S=f.expr.match.POS,T={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(V(this,a,!1),"not",a)},filter:function(a){return this.pushStack(V(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d<e;d++)i=a[d],j[i]||(j[i]=S.test(i)?f(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=S.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(l?l.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(U(c[0])||U(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=R.call(arguments);N.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!T[a]?f.unique(e):e,(this.length>1||P.test(d))&&O.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|object|embed|option|style)/i,bb=/checked\s*(?:[^=]|=\s*.checked.)/i,bc=/\/(java|ecma)script/i,bd=/^\s*<!(?:\[CDATA\[|\-\-)/,be={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};be.optgroup=be.option,be.tbody=be.tfoot=be.colgroup=be.caption=be.thead,be.th=be.td,f.support.htmlSerialize||(be._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!be[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bb.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bf(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bl)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i;b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof a[0]=="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!ba.test(a[0])&&(f.support.checkClone||!bb.test(a[0]))&&(g=!0,h=f.fragments[a[0]],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean
(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)g[h]&&bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=be[l]||be._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bk(k[i]);else bk(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||bc.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bm=/alpha\([^)]*\)/i,bn=/opacity=([^)]*)/,bo=/([A-Z]|^ms)/g,bp=/^-?\d+(?:px)?$/i,bq=/^-?\d/,br=/^([\-+])=([\-+.\de]+)/,bs={position:"absolute",visibility:"hidden",display:"block"},bt=["Left","Right"],bu=["Top","Bottom"],bv,bw,bx;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bv(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=br.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bv)return bv(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return by(a,b,d);f.swap(a,bs,function(){e=by(a,b,d)});return e}},set:function(a,b){if(!bp.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bm,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bm.test(g)?g.replace(bm,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bv(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bw=function(a,c){var d,e,g;c=c.replace(bo,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bx=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bp.test(d)&&bq.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bv=bw||bx,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bz=/%20/g,bA=/\[\]$/,bB=/\r?\n/g,bC=/#.*$/,bD=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bE=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bF=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bG=/^(?:GET|HEAD)$/,bH=/^\/\//,bI=/\?/,bJ=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bK=/^(?:select|textarea)/i,bL=/\s+/,bM=/([?&])_=[^&]*/,bN=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bO=f.fn.load,bP={},bQ={},bR,bS,bT=["*/"]+["*"];try{bR=e.href}catch(bU){bR=c.createElement("a"),bR.href="",bR=bR.href}bS=bN.exec(bR.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bO)return bO.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bJ,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bK.test(this.nodeName)||bE.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bB,"\r\n")}}):{name:b.name,value:c.replace(bB,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?bX(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),bX(a,b);return a},ajaxSettings:{url:bR,isLocal:bF.test(bS[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bT},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bV(bP),ajaxTransport:bV(bQ),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?bZ(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=b$(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bD.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bC,"").replace(bH,bS[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bL),d.crossDomain==null&&(r=bN.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bS[1]&&r[2]==bS[2]&&(r[3]||(r[1]==="http:"?80:443))==(bS[3]||(bS[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bW(bP,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bG.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bI.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bM,"$1_="+x);d.url=y+(y===d.url?(bI.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bT+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bW(bQ,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bz,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cq("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cr(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cq("hide",3),a,b,c);for(var d=0,e=this.length;d<e;d++)if(this[d].style){var g=f.css(this[d],"display");g!=="none"&&!f._data(this[d],"olddisplay")&&f._data(this[d],"olddisplay",g)}for(d=0;d<e;d++)this[d].style&&(this[d].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cq("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return this[e.queue===!1?"each":"queue"](function(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(f.support.inlineBlockNeedsLayout?(j=cr(this.nodeName),j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)):this.style.display="inline-block"))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)k=new f.fx(this,b,i),h=a[i],cj.test(h)?k[h==="toggle"?d?"show":"hide":h]():(l=ck.exec(h),m=k.cur(),l?(n=parseFloat(l[2]),o=l[3]||(f.cssNumber[i]?"":"px"),o!=="px"&&(f.style(this,i,(n||1)+o),m=(n||1)/k.cur()*m,f.style(this,i,m+o)),l[1]&&(n=(l[1]==="-="?-1:1)*n+m),k.custom(m,n,o)):k.custom(m,h,""));return!0})},stop:function(a,b){a&&this.queue([]),this.each(function(){var a=f.timers,c=a.length;b||f._unmark(!0,this);while(c--)a[c].elem===this&&(b&&a[c](!0),a.splice(c,1))}),b||this.dequeue();return this}}),f.each({slideDown:cq("show",1),slideUp:cq("hide",1),slideToggle:cq("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default,d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue!==!1?f.dequeue(this):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function g(a){return d.step(a)}var d=this,e=f.fx;this.startTime=cn||co(),this.start=a,this.end=b,this.unit=c||this.unit||(f.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,g.elem=this.elem,g()&&f.timers.push(g)&&!cl&&(cl=setInterval(e.tick,e.interval))},show:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=cn||co(),c=!0,d=this.elem,e=this.options,g,h;if(a||b>=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b<a.length;++b)a[b]()||a.splice(b--,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cl),cl=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cs=/^t(?:able|d|h)$/i,ct=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cu(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);f.offset.initialize();var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.offset.doesNotAddBorder&&(!f.offset.doesAddBorderForTableAndCells||!cs.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={initialize:function(){var a=c.body,b=c.createElement("div"),d,e,g,h,i=parseFloat(f.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=ct.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!ct.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cu(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cu(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNaN(j)?i:j}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window);

================================================
FILE: res/js/session.js
================================================
var socket = io.connect();
var connectNum=0;
var pproxy_colors=["#FFFFFF","#CCFFFF","#FFCCCC","#99CCCC","996699","#CC9999","#0099CC","#FFFF66","#336633","#99CC00"]

var ip_colors={} 
var pproxy_session_max_len=0;
var pproxy_table_max_row=2000;


var pproxy_req_list=[];

if(window.localStorage){
	pproxy_req_list=$.parseJSON(window.localStorage["reqs"]||"[]")
	pproxy_session_max_len=1000;
}

function pproxy_show_reqs_from_local(){
	for(var i=0;i<pproxy_req_list.length;i++){
		pproxy_show_req(pproxy_req_list[i]);
	}
}

window.onbeforeunload=function(){
	if(pproxy_session_max_len>0){
		window.localStorage["reqs"]=JSON.stringify(pproxy_req_list);
	}
}

function pproxy_save_req_local(dataStr64){
	if(pproxy_session_max_len<1){
		return;
	}
	var n=pproxy_req_list.push(dataStr64)
	if(n>pproxy_session_max_len){
		pproxy_req_list.shift();
	}
}

function pporxy_session_clean(){
	pproxy_req_list=[];
	$('#tb_network tbody').empty();
}

function pproxy_log(msg){
	$("#log_div").append("<div>"+(new Date().toString())+":"+msg+"</div>");
}


function pproxy_net_local_filter(host,path){
	if(!_pproxy_filter(host,$("#net_local_host").val())){
		return false;
	}
	if(!_pproxy_filter(path,$("#net_local_path").val())){
		return false;
	}
	return true;
}

function _pproxy_filter(kw,kwstr){
	if(kwstr==""){
		return true;
	}
	var kws=(kwstr+"").split("|");
	kw+="";
	var tmp=[]	
	for(var i in kws){
		var _kw=$.trim(kws[i]+"");
		if(_kw!=""){
			tmp.push(_kw);
		}
	}
	if(tmp.length==0){
		return true;
	}
	for (var i in tmp){
		if(kw.indexOf(tmp[i])!=-1){
			return true;
		}
	}
	return false;
}

socket.on('connect', function() {
	connectNum++
	if(connectNum>1){
		pproxy_log("ws error.connectNum="+connectNum);
		socket.emit("disconnect");
		return;
	}
    $("#connect_status").html("online")
    $("#network_filter_form").change();
});

socket.on("disconnect", function() {
	connectNum--;
    $("#connect_status").html("<font color=pink>offline</font>");
});

socket.on("hello",function(data){
	console && console.log(new Date().toString(),data);
});

function pproxy_getColor(addr){
	var info=addr.split(":");
	if(info.length!=2){
		return "#FFFFFF";
	}
	var ip=info[0];
	var color=ip_colors[ip];
	if(!color){
		var l=0;
		for(var _t in ip_colors){
			l++;
		}
		color=pproxy_colors[l% pproxy_colors.length];
		ip_colors[ip]=color;
	}
	return color
}


function pproxy_show_req(data) {
	console && console.log("pproxy_show_req:",data)
//    var dataStr=Base64.decode(dataStr64+"");
//	var data={};
//	try{
//		data=$.parseJSON(dataStr)
//	}catch(e){
//		console && console.log("parseJSON_error-pproxy_show_req",e,"datastr:",dataStr)
//		return
//	}
	
//    console && console.log("req", data)
    var html="<tr onclick=\"get_response(this,'" + data['docid'] + "')\" ";
	var cls=[]
    if(data["replay"]){
    	cls.push("replay");
    }
	if(!pproxy_net_local_filter(data["host"],data["path"])){
		cls.push("hide");
	}
	
	if(cls.length>0){
    	html+="class='"+cls.join(" ")+"' ";
	}
    html+=" data-ip='"+data["client_ip"]+"' data-host='"+h(data["host"])+"' data-path='"+h(data["path"])+"'>" 
    + "<td bgcolor='"+pproxy_getColor(data["client_ip"])+"'>" + data["sid"] + "</td>"
    + "<td><div class='oneline' title='"+h(data["host"])+"'>" + data["host"] + "</div></td>" +
    "<td><div class='oneline' title='"+h(data["url"])+"'>" +data["method"]+"&nbsp;"+ h(data["path"])+ "</div></td>" + 
    "</tr>";
    var tb=$("#tb_network tbody");
    tb.prepend(html);
    
    if(Math.random()*100>95 && tb.find("tr").size()>pproxy_table_max_row*1.5){
    	tb.find("tr:gt("+pproxy_table_max_row+")").each(function(){
    		$(this).remove();
    	});
    }
}


socket.on("req",function(data){
	console && console.log("on.req","data:",data);
	pproxy_save_req_local(data);
	pproxy_show_req(data);
});


socket.on("user_num", function(data) {
	$("#user_num_online").html(data);
});

socket.on("res",
        function(data) {
			console && console.log("on.res","data:",data)
//	        var dataStr=Base64.decode(dataStr64+"");
//			try{
//				var data=$.parseJSON(dataStr)
//			}catch(e){
//				console && console.log("parseJSON_error on.res:",e)
//				return
//			}
//			console && console.log(data)
            var req = data["req"];
            var res = data["res"];
            var html="";
            if(req){
	            var re_do_str=req["schema"]=="http"?("&nbsp;<a target='_blank' href='/replay?id="+req["id"]+"'>replay</a>"):"";
	            
	            html += "<div><table class='tb_1'><caption>Request"+re_do_str+pproxy_timeformat(req["now"])+"</caption>";
	            html += "<tr><th width='80px'>url</th><td>" + h(req["url"]) + "&nbsp;&nbsp;<a href='"+h(req["url"])+"' target='_blank'>view</a></td></tr>"
	            if (req["url_origin"]!=req["url"]) {
	                html += "<tr><th>origin</th><td><span style='color:blue'>" + h(req["url_origin"]) + "</span></td></tr>";
	            }
	            if (req["msg"]) {
	            	html += "<tr><th>msg</th><td><span style='color:red'>" + h(req["msg"])+"</span></td></tr>";
	            }
	            html += "<tr><th>proxy_urer</th>" +
	            		"<td><b>remote_addr : </b>&nbsp;" +req["client_ip"] + "&nbsp;&nbsp;<b> docid : </b>&nbsp;"+ req["id"] + 
	            		"</td></tr>";
	            html += pproxy_tr_sub_table(req["form_get"], "get_params");
	            html += pproxy_tr_sub_table(req["form_post"], "post_params");
	            if (req["dump"]) {
	                html += "<tr><th>req_dump</th><td>" + h(Base64.decode(req["dump"])).replace(/\n/g, "<br/>")
	                        + "</td></tr>";
	            }
	            html += "</table></div>";
            }else{
            	html="<br/><br/><br/><br/><center>request not exists!</center>";
            }
            var res_link = "";
            
            var hideBigBody=false;
            
            if (res) {
                res_link = "<a href='/response?id=" + res["id"] + "' target='_blank'>view</a>";
                html += "<div><table class='tb_1'><caption>Response&nbsp;" + res_link +pproxy_timeformat(res["now"])+ "</caption>"
                if (res["msg"]) {
	            	html += "<tr><th  width='80px'>msg</th><td><span style='color:red'>" + h(res["msg"])+"</span></td></tr>";
	            }
                
                if (res["dump"]) {
                    html += "<tr><th width='80px'>res_dump</th><td>" + h(Base64.decode(res["dump"])).replace(/\n/g, "<br/>")
                    + "</td></tr>";
                }
                var body_str = Base64.decode(res["body"])
                var isImg = res["header"]["Content-Type"] != undefined
                        && res["header"]["Content-Type"][0].indexOf("image") > -1;

                var isStatusOk = res["status"] == 200;

                var bd_json = pproxy_parseAsjson(body_str);

                if (bd_json) {
                	hideBigBody=true;
                    html += "<tr><th width='80px'>body_json</th><td>" + bd_json + "</td></tr>";
                }
                if (isImg) {
                	hideBigBody=true;
                    html += "<tr><th>body_img</th><td><img src='data:" + res["header"]["Content-Type"][0] + ";base64,"
                            + res["body"] + "'/></td></tr>";
                }
                if (!isImg || res["body"].length < 1000 || !isStatusOk) {
                	html += "<tr><th width='80px'>body";
                	if(res["body"].length>400){
                		html+="<div><a href='#' onclick='return pproxy_res_td_body_toggle()'>toggle</a></div>";
                	}else{
                		hideBigBody=false;
                	}
                	html+= "</th>" +
                			"<td>" +
                			"<div id='res_td_body' "+(hideBigBody?"class='res_td_body' ":"")+">" + h(body_str).replace(/\n/g, "<br/>") + 
                			"</div></td></tr>";
                }
            }

            html += "</table></div>";
            $("#right_content").empty().html(html).hide().slideDown("fast");
        })

function pproxy_res_td_body_toggle(){
	$("#res_td_body").toggleClass("res_td_body");
	return false;
}

function pproxy_timeformat(sec){
	if(!sec ||sec<1000){
		return "";
	}
	var numFill=function(num,len){
		num=num+"";
		var l=len-num.length;
		for(;l>0;l--){
			num="0"+num;
		}
		return num;
	}
	var d=new Date()
	d.setTime(sec*1000)
	return "&nbsp;<font size=-1>"+d.getFullYear()+"-"+numFill(d.getMonth()+1,2)+"-"+numFill(d.getDate(),2)+" "
		   +numFill(d.getHours(),2)+":"+numFill(d.getMinutes(),2)+":"+numFill(d.getSeconds(),2)+"</font>";
}

        
function pproxy_parseAsjson(str) {
    try {
    	str=str+"";
    	if(str[0]!="{" && str[0]!="["){
    		return false;
    	}
        var jsonObj = JSON.parse(str);
        if (jsonObj) {
            var json_str = JSON.stringify(jsonObj, null, 4);
            return "<pre>" + json_str + "</pre>";
        }
    } catch (e) {
    	console.log("pproxy_parseAsjson_error",e);
    }
    return false;
}

function pproxy_tr_sub_table(obj, name) {
    if (!obj) {
        return "";
    }
    var html = "<tr><th>" + name + "</th><td class='td_has_sub'><table class='tb_1'>";
    var i = 0;
    var max_key_len=0;
    for ( var k in obj) {
    	max_key_len=Math.max(max_key_len,(k+"").length);
    }
    for ( var k in obj) {
        html += "<tr><th  "+(max_key_len<40?"width='120px' nowrap":"width='140px'")+">" + k + "</th><td><ul class='td_ul'>";
        for ( var i in obj[k]) {
            html += "<li>";
            var json_str = pproxy_parseAsjson(obj[k][i]);
            if (json_str) {
                html += json_str;
            } else {
                html += h(obj[k][i]);
            }
            html += "</li>";
        }
        html += "</ul></td></tr>";
        i++;
    }
    if (i < 1) {
        return "";
    }
    html += "</table></td></tr>"
    return html;
}

function pproxy_show_response(docid){
	console && console.log("get_response start,docid=", docid);
    var loading_msg="loading...docid=" + docid;
    var isValidId=(docid+"").length>2;
    if(!isValidId){
    	loading_msg="https request:no data";
    }else{
    	loading_msg+="&nbsp;<a href='javascript:;' onclick=\"pproxy_show_response('"+docid+"')\">reload</a>";
    }
    $("#right_content").empty().html("<center style='margin:200px 0 auto'>"+loading_msg+"</center>");
    if(!isValidId){
    	return;
    }
	socket.emit("get_response", docid);
	console.log && console.log("emit get_response,docid=",docid);
}

function get_response(tr, docid) {
    pproxy_show_response(docid);
    $(tr).parent("tbody").find("tr").removeClass("selected");
    $(tr).addClass("selected");
    location.hash="req_"+docid;
}

function bytesToString(bytes) {
    var result = "";
    for (var i = 0; i < bytes.length; i++) {
        result += String.fromCharCode(parseInt(bytes[i], 2));
    }
    return result;
}

function h(html) {
	if(html==""){
		return "&nbsp;";
	}
	html = (html+"").replace(/&/g, '&amp;')
				.replace(/</g, '&lt;')
				.replace(/>/g, '&gt;')
			    .replace(/'/g, '&acute;')
			    .replace(/"/g, '&quot;')
	            .replace(/\|/g, '&brvbar;');
    return html;
}

$().ready(function() {
	$("#network_filter_form input:text").each(function(){
		pproxy_local_save(this,$(this).attr("name"));
	});
	var filter_form=$("#network_filter_form");
	filter_form.change(function() {
        var form_data = $(this).serialize();
        socket.emit("client_filter", form_data);
    });
    
    setTimeout(function(){filter_form.change();},600);
    setTimeout(function(){filter_form.change();},3000);
    
	filter_form.find("input:text").keyup(function(){
		filter_form.change();
    });
    
    if(location.hash.match(/req_\d+/)){
        var docid=location.hash.substr(5);
        setTimeout((function(id){
        	return function(){
        		pproxy_show_response(id);
        	}
        })(docid),500);
    }
    
    setTimeout(pproxy_show_reqs_from_local,0);
    
    
    $("#net_local_host,#net_local_path").bind("keyup change",function(){
    	$('#tb_network tbody tr').each(function(){
    		if(pproxy_net_local_filter($(this).data("host"),$(this).data("path"))){
    			$(this).removeClass("hide");
    		}else{
    			$(this).addClass("hide");
    		}
    	});
    });
});

function pproxy_local_save(target,id){
	if(!window.localStorage){
		return;
	}
	$(target).val(window.localStorage[id]||"").change(function(){
		window.localStorage[id]=$(this).val();
	});
}

================================================
FILE: res/js/socket.io.js
================================================
/*! Socket.IO.js build:0.9.10, development. Copyright(c) 2011 LearnBoost <dev@learnboost.com> MIT Licensed */

var io = ('undefined' === typeof module ? {} : module.exports);
(function() {

/**
 * socket.io
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

(function (exports, global) {

  /**
   * IO namespace.
   *
   * @namespace
   */

  var io = exports;

  /**
   * Socket.IO version
   *
   * @api public
   */

  io.version = '0.9.10';

  /**
   * Protocol implemented.
   *
   * @api public
   */

  io.protocol = 1;

  /**
   * Available transports, these will be populated with the available transports
   *
   * @api public
   */

  io.transports = [];

  /**
   * Keep track of jsonp callbacks.
   *
   * @api private
   */

  io.j = [];

  /**
   * Keep track of our io.Sockets
   *
   * @api private
   */
  io.sockets = {};


  /**
   * Manages connections to hosts.
   *
   * @param {String} uri
   * @Param {Boolean} force creation of new socket (defaults to false)
   * @api public
   */

  io.connect = function (host, details) {
    var uri = io.util.parseUri(host)
      , uuri
      , socket;

    if (global && global.location) {
      uri.protocol = uri.protocol || global.location.protocol.slice(0, -1);
      uri.host = uri.host || (global.document
        ? global.document.domain : global.location.hostname);
      uri.port = uri.port || global.location.port;
    }

    uuri = io.util.uniqueUri(uri);

    var options = {
        host: uri.host
      , secure: 'https' == uri.protocol
      , port: uri.port || ('https' == uri.protocol ? 443 : 80)
      , query: uri.query || ''
    };

    io.util.merge(options, details);

    if (options['force new connection'] || !io.sockets[uuri]) {
      socket = new io.Socket(options);
    }

    if (!options['force new connection'] && socket) {
      io.sockets[uuri] = socket;
    }

    socket = socket || io.sockets[uuri];

    // if path is different from '' or /
    return socket.of(uri.path.length > 1 ? uri.path : '');
  };

})('object' === typeof module ? module.exports : (this.io = {}), this);
/**
 * socket.io
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

(function (exports, global) {

  /**
   * Utilities namespace.
   *
   * @namespace
   */

  var util = exports.util = {};

  /**
   * Parses an URI
   *
   * @author Steven Levithan <stevenlevithan.com> (MIT license)
   * @api public
   */

  var re = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;

  var parts = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password',
               'host', 'port', 'relative', 'path', 'directory', 'file', 'query',
               'anchor'];

  util.parseUri = function (str) {
    var m = re.exec(str || '')
      , uri = {}
      , i = 14;

    while (i--) {
      uri[parts[i]] = m[i] || '';
    }

    return uri;
  };

  /**
   * Produces a unique url that identifies a Socket.IO connection.
   *
   * @param {Object} uri
   * @api public
   */

  util.uniqueUri = function (uri) {
    var protocol = uri.protocol
      , host = uri.host
      , port = uri.port;

    if ('document' in global) {
      host = host || document.domain;
      port = port || (protocol == 'https'
        && document.location.protocol !== 'https:' ? 443 : document.location.port);
    } else {
      host = host || 'localhost';

      if (!port && protocol == 'https') {
        port = 443;
      }
    }

    return (protocol || 'http') + '://' + host + ':' + (port || 80);
  };

  /**
   * Mergest 2 query strings in to once unique query string
   *
   * @param {String} base
   * @param {String} addition
   * @api public
   */

  util.query = function (base, addition) {
    var query = util.chunkQuery(base || '')
      , components = [];

    util.merge(query, util.chunkQuery(addition || ''));
    for (var part in query) {
      if (query.hasOwnProperty(part)) {
        components.push(part + '=' + query[part]);
      }
    }

    return components.length ? '?' + components.join('&') : '';
  };

  /**
   * Transforms a querystring in to an object
   *
   * @param {String} qs
   * @api public
   */

  util.chunkQuery = function (qs) {
    var query = {}
      , params = qs.split('&')
      , i = 0
      , l = params.length
      , kv;

    for (; i < l; ++i) {
      kv = params[i].split('=');
      if (kv[0]) {
        query[kv[0]] = kv[1];
      }
    }

    return query;
  };

  /**
   * Executes the given function when the page is loaded.
   *
   *     io.util.load(function () { console.log('page loaded'); });
   *
   * @param {Function} fn
   * @api public
   */

  var pageLoaded = false;

  util.load = function (fn) {
    if ('document' in global && document.readyState === 'complete' || pageLoaded) {
      return fn();
    }

    util.on(global, 'load', fn, false);
  };

  /**
   * Adds an event.
   *
   * @api private
   */

  util.on = function (element, event, fn, capture) {
    if (element.attachEvent) {
      element.attachEvent('on' + event, fn);
    } else if (element.addEventListener) {
      element.addEventListener(event, fn, capture);
    }
  };

  /**
   * Generates the correct `XMLHttpRequest` for regular and cross domain requests.
   *
   * @param {Boolean} [xdomain] Create a request that can be used cross domain.
   * @returns {XMLHttpRequest|false} If we can create a XMLHttpRequest.
   * @api private
   */

  util.request = function (xdomain) {

    if (xdomain && 'undefined' != typeof XDomainRequest) {
      return new XDomainRequest();
    }

    if ('undefined' != typeof XMLHttpRequest && (!xdomain || util.ua.hasCORS)) {
      return new XMLHttpRequest();
    }

    if (!xdomain) {
      try {
        return new window[(['Active'].concat('Object').join('X'))]('Microsoft.XMLHTTP');
      } catch(e) { }
    }

    return null;
  };

  /**
   * XHR based transport constructor.
   *
   * @constructor
   * @api public
   */

  /**
   * Change the internal pageLoaded value.
   */

  if ('undefined' != typeof window) {
    util.load(function () {
      pageLoaded = true;
    });
  }

  /**
   * Defers a function to ensure a spinner is not displayed by the browser
   *
   * @param {Function} fn
   * @api public
   */

  util.defer = function (fn) {
    if (!util.ua.webkit || 'undefined' != typeof importScripts) {
      return fn();
    }

    util.load(function () {
      setTimeout(fn, 100);
    });
  };

  /**
   * Merges two objects.
   *
   * @api public
   */

  util.merge = function merge (target, additional, deep, lastseen) {
    var seen = lastseen || []
      , depth = typeof deep == 'undefined' ? 2 : deep
      , prop;

    for (prop in additional) {
      if (additional.hasOwnProperty(prop) && util.indexOf(seen, prop) < 0) {
        if (typeof target[prop] !== 'object' || !depth) {
          target[prop] = additional[prop];
          seen.push(additional[prop]);
        } else {
          util.merge(target[prop], additional[prop], depth - 1, seen);
        }
      }
    }

    return target;
  };

  /**
   * Merges prototypes from objects
   *
   * @api public
   */

  util.mixin = function (ctor, ctor2) {
    util.merge(ctor.prototype, ctor2.prototype);
  };

  /**
   * Shortcut for prototypical and static inheritance.
   *
   * @api private
   */

  util.inherit = function (ctor, ctor2) {
    function f() {};
    f.prototype = ctor2.prototype;
    ctor.prototype = new f;
  };

  /**
   * Checks if the given object is an Array.
   *
   *     io.util.isArray([]); // true
   *     io.util.isArray({}); // false
   *
   * @param Object obj
   * @api public
   */

  util.isArray = Array.isArray || function (obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  };

  /**
   * Intersects values of two arrays into a third
   *
   * @api public
   */

  util.intersect = function (arr, arr2) {
    var ret = []
      , longest = arr.length > arr2.length ? arr : arr2
      , shortest = arr.length > arr2.length ? arr2 : arr;

    for (var i = 0, l = shortest.length; i < l; i++) {
      if (~util.indexOf(longest, shortest[i]))
        ret.push(shortest[i]);
    }

    return ret;
  }

  /**
   * Array indexOf compatibility.
   *
   * @see bit.ly/a5Dxa2
   * @api public
   */

  util.indexOf = function (arr, o, i) {

    for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0;
         i < j && arr[i] !== o; i++) {}

    return j <= i ? -1 : i;
  };

  /**
   * Converts enumerables to array.
   *
   * @api public
   */

  util.toArray = function (enu) {
    var arr = [];

    for (var i = 0, l = enu.length; i < l; i++)
      arr.push(enu[i]);

    return arr;
  };

  /**
   * UA / engines detection namespace.
   *
   * @namespace
   */

  util.ua = {};

  /**
   * Whether the UA supports CORS for XHR.
   *
   * @api public
   */

  util.ua.hasCORS = 'undefined' != typeof XMLHttpRequest && (function () {
    try {
      var a = new XMLHttpRequest();
    } catch (e) {
      return false;
    }

    return a.withCredentials != undefined;
  })();

  /**
   * Detect webkit.
   *
   * @api public
   */

  util.ua.webkit = 'undefined' != typeof navigator
    && /webkit/i.test(navigator.userAgent);

   /**
   * Detect iPad/iPhone/iPod.
   *
   * @api public
   */

  util.ua.iDevice = 'undefined' != typeof navigator
      && /iPad|iPhone|iPod/i.test(navigator.userAgent);

})('undefined' != typeof io ? io : module.exports, this);
/**
 * socket.io
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

(function (exports, io) {

  /**
   * Expose constructor.
   */

  exports.EventEmitter = EventEmitter;

  /**
   * Event emitter constructor.
   *
   * @api public.
   */

  function EventEmitter () {};

  /**
   * Adds a listener
   *
   * @api public
   */

  EventEmitter.prototype.on = function (name, fn) {
    if (!this.$events) {
      this.$events = {};
    }

    if (!this.$events[name]) {
      this.$events[name] = fn;
    } else if (io.util.isArray(this.$events[name])) {
      this.$events[name].push(fn);
    } else {
      this.$events[name] = [this.$events[name], fn];
    }

    return this;
  };

  EventEmitter.prototype.addListener = EventEmitter.prototype.on;

  /**
   * Adds a volatile listener.
   *
   * @api public
   */

  EventEmitter.prototype.once = function (name, fn) {
    var self = this;

    function on () {
      self.removeListener(name, on);
      fn.apply(this, arguments);
    };

    on.listener = fn;
    this.on(name, on);

    return this;
  };

  /**
   * Removes a listener.
   *
   * @api public
   */

  EventEmitter.prototype.removeListener = function (name, fn) {
    if (this.$events && this.$events[name]) {
      var list = this.$events[name];

      if (io.util.isArray(list)) {
        var pos = -1;

        for (var i = 0, l = list.length; i < l; i++) {
          if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
            pos = i;
            break;
          }
        }

        if (pos < 0) {
          return this;
        }

        list.splice(pos, 1);

        if (!list.length) {
          delete this.$events[name];
        }
      } else if (list === fn || (list.listener && list.listener === fn)) {
        delete this.$events[name];
      }
    }

    return this;
  };

  /**
   * Removes all listeners for an event.
   *
   * @api public
   */

  EventEmitter.prototype.removeAllListeners = function (name) {
    if (name === undefined) {
      this.$events = {};
      return this;
    }

    if (this.$events && this.$events[name]) {
      this.$events[name] = null;
    }

    return this;
  };

  /**
   * Gets all listeners for a certain event.
   *
   * @api publci
   */

  EventEmitter.prototype.listeners = function (name) {
    if (!this.$events) {
      this.$events = {};
    }

    if (!this.$events[name]) {
      this.$events[name] = [];
    }

    if (!io.util.isArray(this.$events[name])) {
      this.$events[name] = [this.$events[name]];
    }

    return this.$events[name];
  };

  /**
   * Emits an event.
   *
   * @api public
   */

  EventEmitter.prototype.emit = function (name) {
    if (!this.$events) {
      return false;
    }

    var handler = this.$events[name];

    if (!handler) {
      return false;
    }

    var args = Array.prototype.slice.call(arguments, 1);

    if ('function' == typeof handler) {
      handler.apply(this, args);
    } else if (io.util.isArray(handler)) {
      var listeners = handler.slice();

      for (var i = 0, l = listeners.length; i < l; i++) {
        listeners[i].apply(this, args);
      }
    } else {
      return false;
    }

    return true;
  };

})(
    'undefined' != typeof io ? io : module.exports
  , 'undefined' != typeof io ? io : module.parent.exports
);

/**
 * socket.io
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Based on JSON2 (http://www.JSON.org/js.html).
 */

(function (exports, nativeJSON) {
  "use strict";

  // use native JSON if it's available
  if (nativeJSON && nativeJSON.parse){
    return exports.JSON = {
      parse: nativeJSON.parse
    , stringify: nativeJSON.stringify
    }
  }

  var JSON = exports.JSON = {};

  function f(n) {
      // Format integers to have at least two digits.
      return n < 10 ? '0' + n : n;
  }

  function date(d, key) {
    return isFinite(d.valueOf()) ?
        d.getUTCFullYear()     + '-' +
        f(d.getUTCMonth() + 1) + '-' +
        f(d.getUTCDate())      + 'T' +
        f(d.getUTCHours())     + ':' +
        f(d.getUTCMinutes())   + ':' +
        f(d.getUTCSeconds())   + 'Z' : null;
  };

  var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
      escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
      gap,
      indent,
      meta = {    // table of character substitutions
          '\b': '\\b',
          '\t': '\\t',
          '\n': '\\n',
          '\f': '\\f',
          '\r': '\\r',
          '"' : '\\"',
          '\\': '\\\\'
      },
      rep;


  function quote(string) {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.

      escapable.lastIndex = 0;
      return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
          var c = meta[a];
          return typeof c === 'string' ? c :
              '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
      }) + '"' : '"' + string + '"';
  }


  function str(key, holder) {

// Produce a string from holder[key].

      var i,          // The loop counter.
          k,          // The member key.
          v,          // The member value.
          length,
          mind = gap,
          partial,
          value = holder[key];

// If the value has a toJSON method, call it to obtain a replacement value.

      if (value instanceof Date) {
          value = date(key);
      }

// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.

      if (typeof rep === 'function') {
          value = rep.call(holder, key, value);
      }

// What happens next depends on the value's type.

      switch (typeof value) {
      case 'string':
          return quote(value);

      case 'number':

// JSON numbers must be finite. Encode non-finite numbers as null.

          return isFinite(value) ? String(value) : 'null';

      case 'boolean':
      case 'null':

// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.

          return String(value);

// If the type is 'object', we might be dealing with an object or an array or
// null.

      case 'object':

// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.

          if (!value) {
              return 'null';
          }

// Make an array to hold the partial results of stringifying this object value.

          gap += indent;
          partial = [];

// Is the value an array?

          if (Object.prototype.toString.apply(value) === '[object Array]') {

// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.

              length = value.length;
              for (i = 0; i < length; i += 1) {
                  partial[i] = str(i, value) || 'null';
              }

// Join all of the elements together, separated with commas, and wrap them in
// brackets.

              v = partial.length === 0 ? '[]' : gap ?
                  '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
                  '[' + partial.join(',') + ']';
              gap = mind;
              return v;
          }

// If the replacer is an array, use it to select the members to be stringified.

          if (rep && typeof rep === 'object') {
              length = rep.length;
              for (i = 0; i < length; i += 1) {
                  if (typeof rep[i] === 'string') {
                      k = rep[i];
                      v = str(k, value);
                      if (v) {
                          partial.push(quote(k) + (gap ? ': ' : ':') + v);
                      }
                  }
              }
          } else {

// Otherwise, iterate through all of the keys in the object.

              for (k in value) {
                  if (Object.prototype.hasOwnProperty.call(value, k)) {
                      v = str(k, value);
                      if (v) {
                          partial.push(quote(k) + (gap ? ': ' : ':') + v);
                      }
                  }
              }
          }

// Join all of the member texts together, separated with commas,
// and wrap them in braces.

          v = partial.length === 0 ? '{}' : gap ?
              '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
              '{' + partial.join(',') + '}';
          gap = mind;
          return v;
      }
  }

// If the JSON object does not yet have a stringify method, give it one.

  JSON.stringify = function (value, replacer, space) {

// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.

      var i;
      gap = '';
      indent = '';

// If the space parameter is a number, make an indent string containing that
// many spaces.

      if (typeof space === 'number') {
          for (i = 0; i < space; i += 1) {
              indent += ' ';
          }

// If the space parameter is a string, it will be used as the indent string.

      } else if (typeof space === 'string') {
          indent = space;
      }

// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.

      rep = replacer;
      if (replacer && typeof replacer !== 'function' &&
              (typeof replacer !== 'object' ||
              typeof replacer.length !== 'number')) {
          throw new Error('JSON.stringify');
      }

// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.

      return str('', {'': value});
  };

// If the JSON object does not yet have a parse method, give it one.

  JSON.parse = function (text, reviver) {
  // The parse method takes a text and an optional reviver function, and returns
  // a JavaScript value if the text is a valid JSON text.

      var j;

      function walk(holder, key) {

  // The walk method is used to recursively walk the resulting structure so
  // that modifications can be made.

          var k, v, value = holder[key];
          if (value && typeof value === 'object') {
              for (k in value) {
                  if (Object.prototype.hasOwnProperty.call(value, k)) {
                      v = walk(value, k);
                      if (v !== undefined) {
                          value[k] = v;
                      } else {
                          delete value[k];
                      }
                  }
              }
          }
          return reviver.call(holder, key, value);
      }


  // Parsing happens in four stages. In the first stage, we replace certain
  // Unicode characters with escape sequences. JavaScript handles many characters
  // incorrectly, either silently deleting them, or treating them as line endings.

      text = String(text);
      cx.lastIndex = 0;
      if (cx.test(text)) {
          text = text.replace(cx, function (a) {
              return '\\u' +
                  ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
          });
      }

  // In the second stage, we run the text against regular expressions that look
  // for non-JSON patterns. We are especially concerned with '()' and 'new'
  // because they can cause invocation, and '=' because it can cause mutation.
  // But just to be safe, we want to reject all unexpected forms.

  // We split the second stage into 4 regexp operations in order to work around
  // crippling inefficiencies in IE's and Safari's regexp engines. First we
  // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
  // replace all simple value tokens with ']' characters. Third, we delete all
  // open brackets that follow a colon or comma or that begin the text. Finally,
  // we look to see that the remaining characters are only whitespace or ']' or
  // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

      if (/^[\],:{}\s]*$/
              .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
                  .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
                  .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

  // In the third stage we use the eval function to compile the text into a
  // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
  // in JavaScript: it can begin a block or an object literal. We wrap the text
  // in parens to eliminate the ambiguity.

          j = eval('(' + text + ')');

  // In the optional fourth stage, we recursively walk the new structure, passing
  // each name/value pair to a reviver function for possible transformation.

          return typeof reviver === 'function' ?
              walk({'': j}, '') : j;
      }

  // If the text is not JSON parseable, then a SyntaxError is thrown.

      throw new SyntaxError('JSON.parse');
  };

})(
    'undefined' != typeof io ? io : module.exports
  , typeof JSON !== 'undefined' ? JSON : undefined
);

/**
 * socket.io
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

(function (exports, io) {

  /**
   * Parser namespace.
   *
   * @namespace
   */

  var parser = exports.parser = {};

  /**
   * Packet types.
   */

  var packets = parser.packets = [
      'disconnect'
    , 'connect'
    , 'heartbeat'
    , 'message'
    , 'json'
    , 'event'
    , 'ack'
    , 'error'
    , 'noop'
  ];

  /**
   * Errors reasons.
   */

  var reasons = parser.reasons = [
      'transport not supported'
    , 'client not handshaken'
    , 'unauthorized'
  ];

  /**
   * Errors advice.
   */

  var advice = parser.advice = [
      'reconnect'
  ];

  /**
   * Shortcuts.
   */

  var JSON = io.JSON
    , indexOf = io.util.indexOf;

  /**
   * Encodes a packet.
   *
   * @api private
   */

  parser.encodePacket = function (packet) {
    var type = indexOf(packets, packet.type)
      , id = packet.id || ''
      , endpoint = packet.endpoint || ''
      , ack = packet.ack
      , data = null;

    switch (packet.type) {
      case 'error':
        var reason = packet.reason ? indexOf(reasons, packet.reason) : ''
          , adv = packet.advice ? indexOf(advice, packet.advice) : '';

        if (reason !== '' || adv !== '')
          data = reason + (adv !== '' ? ('+' + adv) : '');

        break;

      case 'message':
        if (packet.data !== '')
          data = packet.data;
        break;

      case 'event':
        var ev = { name: packet.name };

        if (packet.args && packet.args.length) {
          ev.args = packet.args;
        }

        data = JSON.stringify(ev);
        break;

      case 'json':
        data = JSON.stringify(packet.data);
        break;

      case 'connect':
        if (packet.qs)
          data = packet.qs;
        break;

      case 'ack':
        data = packet.ackId
          + (packet.args && packet.args.length
              ? '+' + JSON.stringify(packet.args) : '');
        break;
    }

    // construct packet with required fragments
    var encoded = [
        type
      , id + (ack == 'data' ? '+' : '')
      , endpoint
    ];

    // data fragment is optional
    if (data !== null && data !== undefined)
      encoded.push(data);

    return encoded.join(':');
  };

  /**
   * Encodes multiple messages (payload).
   *
   * @param {Array} messages
   * @api private
   */

  parser.encodePayload = function (packets) {
    var decoded = '';

    if (packets.length == 1)
      return packets[0];

    for (var i = 0, l = packets.length; i < l; i++) {
      var packet = packets[i];
      decoded += '\ufffd' + packet.length + '\ufffd' + packets[i];
    }

    return decoded;
  };

  /**
   * Decodes a packet
   *
   * @api private
   */

  var regexp = /([^:]+):([0-9]+)?(\+)?:([^:]+)?:?([\s\S]*)?/;

  parser.decodePacket = function (data) {
    var pieces = data.match(regexp);

    if (!pieces) return {};

    var id = pieces[2] || ''
      , data = pieces[5] || ''
      , packet = {
            type: packets[pieces[1]]
          , endpoint: pieces[4] || ''
        };

    // whether we need to acknowledge the packet
    if (id) {
      packet.id = id;
      if (pieces[3])
        packet.ack = 'data';
      else
        packet.ack = true;
    }

    // handle different packet types
    switch (packet.type) {
      case 'error':
        var pieces = data.split('+');
        packet.reason = reasons[pieces[0]] || '';
        packet.advice = advice[pieces[1]] || '';
        break;

      case 'message':
        packet.data = data || '';
        break;

      case 'event':
        try {
          var opts = JSON.parse(data);
          packet.name = opts.name;
          packet.args = opts.args;
        } catch (e) { }

        packet.args = packet.args || [];
        break;

      case 'json':
        try {
          packet.data = JSON.parse(data);
        } catch (e) { }
        break;

      case 'connect':
        packet.qs = data || '';
        break;

      case 'ack':
        var pieces = data.match(/^([0-9]+)(\+)?(.*)/);
        if (pieces) {
          packet.ackId = pieces[1];
          packet.args = [];

          if (pieces[3]) {
            try {
              packet.args = pieces[3] ? JSON.parse(pieces[3]) : [];
            } catch (e) { }
          }
        }
        break;

      case 'disconnect':
      case 'heartbeat':
        break;
    };

    return packet;
  };

  /**
   * Decodes data payload. Detects multiple messages
   *
   * @return {Array} messages
   * @api public
   */

  parser.decodePayload = function (data) {
    // IE doesn't like data[i] for unicode chars, charAt works fine
    if (data.charAt(0) == '\ufffd') {
      var ret = [];

      for (var i = 1, length = ''; i < data.length; i++) {
        if (data.charAt(i) == '\ufffd') {
          ret.push(parser.decodePacket(data.substr(i + 1).substr(0, length)));
          i += Number(length) + 1;
          length = '';
        } else {
          length += data.charAt(i);
        }
      }

      return ret;
    } else {
      return [parser.decodePacket(data)];
    }
  };

})(
    'undefined' != typeof io ? io : module.exports
  , 'undefined' != typeof io ? io : module.parent.exports
);
/**
 * socket.io
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

(function (exports, io) {

  /**
   * Expose constructor.
   */

  exports.Transport = Transport;

  /**
   * This is the transport template for all supported transport methods.
   *
   * @constructor
   * @api public
   */

  function Transport (socket, sessid) {
    this.socket = socket;
    this.sessid = sessid;
  };

  /**
   * Apply EventEmitter mixin.
   */

  io.util.mixin(Transport, io.EventEmitter);


  /**
   * Indicates whether heartbeats is enabled for this transport
   *
   * @api private
   */

  Transport.prototype.heartbeats = function () {
    return true;
  }

  /**
   * Handles the response from the server. When a new response is received
   * it will automatically update the timeout, decode the message and
   * forwards the response to the onMessage function for further processing.
   *
   * @param {String} data Response from the server.
   * @api private
   */

  Transport.prototype.onData = function (data) {
    this.clearCloseTimeout();

    // If the connection in currently open (or in a reopening state) reset the close
    // timeout since we have just received data. This check is necessary so
    // that we don't reset the timeout on an explicitly disconnected connection.
    if (this.socket.connected || this.socket.connecting || this.socket.reconnecting) {
      this.setCloseTimeout();
    }

    if (data !== '') {
      // todo: we should only do decodePayload for xhr transports
      var msgs = io.parser.decodePayload(data);

      if (msgs && msgs.length) {
        for (var i = 0, l = msgs.length; i < l; i++) {
          this.onPacket(msgs[i]);
        }
      }
    }

    return this;
  };

  /**
   * Handles packets.
   *
   * @api private
   */

  Transport.prototype.onPacket = function (packet) {
    this.socket.setHeartbeatTimeout();

    if (packet.type == 'heartbeat') {
      return this.onHeartbeat();
    }

    if (packet.type == 'connect' && packet.endpoint == '') {
      this.onConnect();
    }

    if (packet.type == 'error' && packet.advice == 'reconnect') {
      this.isOpen = false;
    }

    this.socket.onPacket(packet);

    return this;
  };

  /**
   * Sets close timeout
   *
   * @api private
   */

  Transport.prototype.setCloseTimeout = function () {
    if (!this.closeTimeout) {
      var self = this;

      this.closeTimeout = setTimeout(function () {
        self.onDisconnect();
      }, this.socket.closeTimeout);
    }
  };

  /**
   * Called when transport disconnects.
   *
   * @api private
   */

  Transport.prototype.onDisconnect = function () {
    if (this.isOpen) this.close();
    this.clearTimeouts();
    this.socket.onDisconnect();
    return this;
  };

  /**
   * Called when transport connects
   *
   * @api private
   */

  Transport.prototype.onConnect = function () {
    this.socket.onConnect();
    return this;
  }

  /**
   * Clears close timeout
   *
   * @api private
   */

  Transport.prototype.clearCloseTimeout = function () {
    if (this.closeTimeout) {
      clearTimeout(this.closeTimeout);
      this.closeTimeout = null;
    }
  };

  /**
   * Clear timeouts
   *
   * @api private
   */

  Transport.prototype.clearTimeouts = function () {
    this.clearCloseTimeout();

    if (this.reopenTimeout) {
      clearTimeout(this.reopenTimeout);
    }
  };

  /**
   * Sends a packet
   *
   * @param {Object} packet object.
   * @api private
   */

  Transport.prototype.packet = function (packet) {
    this.send(io.parser.encodePacket(packet));
  };

  /**
   * Send the received heartbeat message back to server. So the server
   * knows we are still connected.
   *
   * @param {String} heartbeat Heartbeat response from the server.
   * @api private
   */

  Transport.prototype.onHeartbeat = function (heartbeat) {
    this.packet({ type: 'heartbeat' });
  };

  /**
   * Called when the transport opens.
   *
   * @api private
   */

  Transport.prototype.onOpen = function () {
    this.isOpen = true;
    this.clearCloseTimeout();
    this.socket.onOpen();
  };

  /**
   * Notifies the base when the connection with the Socket.IO server
   * has been disconnected.
   *
   * @api private
   */

  Transport.prototype.onClose = function () {
    var self = this;

    /* FIXME: reopen delay causing a infinit loop
    this.reopenTimeout = setTimeout(function () {
      self.open();
    }, this.socket.options['reopen delay']);*/

    this.isOpen = false;
    this.socket.onClose();
    this.onDisconnect();
  };

  /**
   * Generates a connection url based on the Socket.IO URL Protocol.
   * See <https://github.com/learnboost/socket.io-node/> for more details.
   *
   * @returns {String} Connection url
   * @api private
   */

  Transport.prototype.prepareUrl = function () {
    var options = this.socket.options;

    return this.scheme() + '://'
      + options.host + ':' + options.port + '/'
      + options.resource + '/' + io.protocol
      + '/' + this.name + '/' + this.sessid;
  };

  /**
   * Checks if the transport is ready to start a connection.
   *
   * @param {Socket} socket The socket instance that needs a transport
   * @param {Function} fn The callback
   * @api private
   */

  Trans
Download .txt
gitextract_gqzuybd4/

├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README-en.md
├── README.md
├── assest.json
├── build.sh
├── fmt.sh
├── go.mod
├── go.sum
├── main.go
├── res/
│   ├── conf/
│   │   └── demo.conf
│   ├── css/
│   │   ├── flat.css
│   │   └── style.css
│   ├── js/
│   │   ├── base64.js
│   │   ├── default.js
│   │   ├── jquery.js
│   │   ├── session.js
│   │   └── socket.io.js
│   ├── private/
│   │   ├── client_cert.pem
│   │   └── server_key.pem
│   ├── sjs/
│   │   └── req_rewrite.js
│   ├── tpl/
│   │   ├── about.html
│   │   ├── config/
│   │   │   ├── req_demo.html
│   │   │   └── req_form.html
│   │   ├── config.html
│   │   ├── error.html
│   │   ├── file.html
│   │   ├── file_edit.html
│   │   ├── file_new.html
│   │   ├── layout.html
│   │   ├── login.html
│   │   ├── network.html
│   │   ├── replay.html
│   │   ├── replay_direct.html
│   │   └── useage.html
│   └── version
├── script/
│   ├── create_dest_zip.sh
│   ├── pproxy_control.sh
│   └── windows_run.bat
└── serve/
    ├── assest.go
    ├── auth.go
    ├── broadcast.go
    ├── certs.go
    ├── config.go
    ├── init.go
    ├── kvStore.go
    ├── proxy.go
    ├── reqCtx.go
    ├── req_modifer.go
    ├── req_replay.go
    ├── req_rewrite.go
    ├── serve.go
    ├── sessions.go
    ├── util.go
    ├── web.go
    ├── web_file.go
    ├── wsClient.go
    └── wsServer.go
Download .txt
SYMBOL INDEX (300 symbols across 25 files)

FILE: main.go
  function init (line 19) | func init() {
  function main (line 28) | func main() {

FILE: res/js/default.js
  function pproxy_tab_sup (line 1) | function pproxy_tab_sup(target){

FILE: res/js/jquery.js
  function cu (line 2) | function cu(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.pa...
  function cr (line 2) | function cr(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.cs...
  function cq (line 2) | function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),funct...
  function cp (line 2) | function cp(){cn=b}
  function co (line 2) | function co(){setTimeout(cp,0);return cn=f.now()}
  function cf (line 2) | function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(...
  function ce (line 2) | function ce(){try{return new a.XMLHttpRequest}catch(b){}}
  function b$ (line 2) | function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.da...
  function bZ (line 2) | function bZ(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i...
  function bY (line 2) | function bY(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bA.test(a...
  function bX (line 2) | function bX(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d...
  function bW (line 2) | function bW(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],...
  function bV (line 2) | function bV(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f...
  function by (line 2) | function by(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b===...
  function bl (line 2) | function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f....
  function bk (line 2) | function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f...
  function bj (line 2) | function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked...
  function bi (line 2) | function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("...
  function bh (line 2) | function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttr...
  function bg (line 2) | function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f....
  function bf (line 2) | function bf(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tb...
  function V (line 2) | function V(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d...
  function U (line 2) | function U(a){return!a||!a.parentNode||a.parentNode.nodeType===11}
  function M (line 2) | function M(a,b){return(a&&a!=="*"?a+".":"")+b.replace(y,"`").replace(z,"...
  function L (line 2) | function L(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"ev...
  function J (line 2) | function J(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e....
  function D (line 2) | function D(){return!0}
  function C (line 2) | function C(){return!1}
  function m (line 2) | function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,...
  function l (line 2) | function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}
  function k (line 2) | function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"-...
  function K (line 2) | function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch...
  function a (line 2) | function a(b,c){return new a.fn.init(b,c)}
  function i (line 2) | function i(a){return function(c){b[a]=arguments.length>1?h.call(argument...
  function m (line 2) | function m(){--h||d.resolveWith(e,[e])}
  function e (line 3) | function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.t...
  function u (line 3) | function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i)...
  function t (line 3) | function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i)...
  function w (line 4) | function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.ready...
  function g (line 4) | function g(a){return d.step(a)}

FILE: res/js/session.js
  function pproxy_show_reqs_from_local (line 17) | function pproxy_show_reqs_from_local(){
  function pproxy_save_req_local (line 29) | function pproxy_save_req_local(dataStr64){
  function pporxy_session_clean (line 39) | function pporxy_session_clean(){
  function pproxy_log (line 44) | function pproxy_log(msg){
  function pproxy_net_local_filter (line 49) | function pproxy_net_local_filter(host,path){
  function _pproxy_filter (line 59) | function _pproxy_filter(kw,kwstr){
  function pproxy_getColor (line 103) | function pproxy_getColor(addr){
  function pproxy_show_req (line 122) | function pproxy_show_req(data) {
  function pproxy_res_td_body_toggle (line 261) | function pproxy_res_td_body_toggle(){
  function pproxy_timeformat (line 266) | function pproxy_timeformat(sec){
  function pproxy_parseAsjson (line 285) | function pproxy_parseAsjson(str) {
  function pproxy_tr_sub_table (line 302) | function pproxy_tr_sub_table(obj, name) {
  function pproxy_show_response (line 334) | function pproxy_show_response(docid){
  function get_response (line 351) | function get_response(tr, docid) {
  function bytesToString (line 358) | function bytesToString(bytes) {
  function h (line 366) | function h(html) {
  function pproxy_local_save (line 419) | function pproxy_local_save(target,id){

FILE: res/js/socket.io.js
  function f (line 358) | function f() {}
  function EventEmitter (line 489) | function EventEmitter () {}
  function on (line 524) | function on () {
  function f (line 675) | function f(n) {
  function date (line 680) | function date(d, key) {
  function quote (line 706) | function quote(string) {
  function str (line 722) | function str(key, holder) {
  function walk (line 897) | function walk(holder, key) {
  function Transport (line 1256) | function Transport (socket, sessid) {
  function Socket (line 1512) | function Socket (options) {
  function empty (line 1604) | function empty () { }
  function complete (line 1610) | function complete (data) {
  function connect (line 1711) | function connect (transports){
  function reset (line 1995) | function reset () {
  function maybeReconnect (line 2020) | function maybeReconnect () {
  function SocketNamespace (line 2088) | function SocketNamespace (socket, name) {
  function ack (line 2208) | function ack () {
  function Flag (line 2278) | function Flag (nsp, name) {
  function WS (line 2335) | function WS (socket) {
  function Flashsocket (line 2527) | function Flashsocket () {
  function init (line 2605) | function init () {
  function f (line 2695) | function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].ap...
  function K (line 2695) | function K(X){if(J){X()}else{U[U.length]=X}}
  function s (line 2695) | function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load"...
  function h (line 2695) | function h(){if(T){V()}else{H()}}
  function V (line 2695) | function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setA...
  function H (line 2695) | function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[a...
  function z (line 2695) | function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typ...
  function A (line 2695) | function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}
  function P (line 2695) | function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X...
  function p (line 2695) | function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNo...
  function g (line 2695) | function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML...
  function u (line 2695) | function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(...
  function e (line 2695) | function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttr...
  function y (line 2695) | function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.s...
  function b (line 2695) | function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function...
  function c (line 2695) | function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}
  function C (line 2695) | function C(X){return j.createElement(X)}
  function i (line 2695) | function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}
  function F (line 2695) | function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=pars...
  function v (line 2695) | function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagN...
  function w (line 2695) | function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z...
  function L (line 2695) | function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof...
  function XHR (line 3070) | function XHR (socket) {
  function empty (line 3139) | function empty () { }
  function stateChange (line 3145) | function stateChange () {
  function onload (line 3158) | function onload () {
  function HTMLFile (line 3288) | function HTMLFile (socket) {
  function XHRPolling (line 3457) | function XHRPolling () {
  function empty (line 3512) | function empty () {}
  function stateChange (line 3519) | function stateChange () {
  function onload (line 3532) | function onload () {
  function onerror (line 3539) | function onerror () {
  function JSONPPolling (line 3641) | function JSONPPolling (socket) {
  function complete (line 3708) | function complete () {
  function initIframe (line 3713) | function initIframe () {

FILE: res/sjs/req_rewrite.js
  function pproxy_rewrite (line 2) | function pproxy_rewrite(req){
  function pproxy_params_copy (line 23) | function pproxy_params_copy(obj){
  function pproxy_obj_helper (line 35) | function pproxy_obj_helper(values){

FILE: serve/assest.go
  type AssestFile (line 24) | type AssestFile struct
  type AssestStruct (line 31) | type AssestStruct struct
    method GetAssestFile (line 48) | func (statics *AssestStruct) GetAssestFile(name string) (*AssestFile, ...
    method GetContent (line 83) | func (statics AssestStruct) GetContent(name string) string {
    method GetFileNames (line 92) | func (statics AssestStruct) GetFileNames(dir string) []string {
    method FileHandlerFunc (line 115) | func (statics *AssestStruct) FileHandlerFunc(name string) http.Handler...
    method HTTPHandler (line 154) | func (statics *AssestStruct) HTTPHandler(baseDir string) http.Handler {
  function init (line 37) | func init() {
  type _assestFileServer (line 158) | type _assestFileServer struct
    method ServeHTTP (line 164) | func (f *_assestFileServer) ServeHTTP(w http.ResponseWriter, r *http.R...
  function _assestGzipBase64decode (line 169) | func _assestGzipBase64decode(data string) string {
  function _assestBase64Decode (line 176) | func _assestBase64Decode(data string) string {

FILE: serve/auth.go
  function getAuthorInfo (line 13) | func getAuthorInfo(req *http.Request) *User {
  method checkUserLogin (line 30) | func (ser *ProxyServe) checkUserLogin(userInfo *User) bool {
  method checkHTTPAuth (line 46) | func (ser *ProxyServe) checkHTTPAuth(reqCtx *requestCtx) bool {

FILE: serve/broadcast.go
  method broadcastReq (line 8) | func (ser *ProxyServe) broadcastReq(reqCtx *requestCtx) bool {

FILE: serve/certs.go
  function newCaCert (line 10) | func newCaCert(caCert []byte, caKey []byte) (tls.Certificate, error) {
  function getSslCert (line 25) | func getSslCert(caCertPath string, caKeyPath string) (ca tls.Certificate...

FILE: serve/config.go
  type Config (line 18) | type Config struct
    method getTransport (line 245) | func (config *Config) getTransport() *http.Transport {
  constant authTypeNO (line 39) | authTypeNO           = 0
  constant authTypeBasic (line 40) | authTypeBasic        = 1
  constant authTypeBasicWithAny (line 41) | authTypeBasicWithAny = 2
  constant authTypeBasicTry (line 42) | authTypeBasicTry     = 3
  constant responseSaveAll (line 44) | responseSaveAll      = 0
  constant responseSaveHasBroad (line 45) | responseSaveHasBroad = 1
  constant sessionViewALL (line 47) | sessionViewALL      = 0
  constant sessionViewIPOrUser (line 48) | sessionViewIPOrUser = 1
  type User (line 52) | type User struct
    method String (line 61) | func (u *User) String() string {
    method ConfigString (line 66) | func (u *User) ConfigString() string {
    method isPswEq (line 86) | func (u *User) isPswEq(psw string) bool {
  constant contentEncoding (line 71) | contentEncoding = "Content-Encoding"
  function GetVersion (line 77) | func GetVersion() string {
  function GetDemoConf (line 82) | func GetDemoConf() string {
  function LoadConfig (line 91) | func LoadConfig(confPath string) (*Config, error) {
  type configHosts (line 180) | type configHosts
  function loadHosts (line 183) | func loadHosts(confPath string) (hosts configHosts, err error) {
  function loadUsers (line 204) | func loadUsers(confPath string) (users map[string]*User, err error) {

FILE: serve/init.go
  function init (line 6) | func init() {

FILE: serve/kvStore.go
  type KV_TBALE_NAME_TYPE (line 10) | type KV_TBALE_NAME_TYPE
  constant KV_TABLE_REQ (line 13) | KV_TABLE_REQ KV_TBALE_NAME_TYPE = "req"
  constant KV_TABLE_RES (line 14) | KV_TABLE_RES KV_TBALE_NAME_TYPE = "res"
  type kvStore (line 17) | type kvStore struct
    method initTable (line 53) | func (kv *kvStore) initTable(name KV_TBALE_NAME_TYPE) {
    method GetkvStoreTable (line 57) | func (kv *kvStore) GetkvStoreTable(name KV_TBALE_NAME_TYPE) (tb *kvSto...
    method Gc (line 64) | func (kv *kvStore) Gc(max_life int64) {
    method StartGcTimer (line 70) | func (kv *kvStore) StartGcTimer(sec int64, max_life int64) {
  type kvStoreTable (line 23) | type kvStoreTable struct
    method Save (line 91) | func (tb *kvStoreTable) Save(key []byte, val *StoreType) error {
    method Get (line 99) | func (tb *kvStoreTable) Get(key []byte) (val *StoreType, err error) {
    method Del (line 111) | func (tb *kvStoreTable) Del(key []byte) (err error) {
    method Gc (line 119) | func (tb *kvStoreTable) Gc(gc_life int64) {
  type StoreType (line 28) | type StoreType struct
  function newStoreType (line 33) | func newStoreType(data map[string]any) *StoreType {
  function newKvStore (line 37) | func newKvStore(dbPath string) (kv *kvStore, err error) {
  function newkvStoreTable (line 79) | func newkvStoreTable(name KV_TBALE_NAME_TYPE, kv *kvStore) *kvStoreTable {

FILE: serve/proxy.go
  type HttpProxy (line 16) | type HttpProxy struct
    method ServeHTTP (line 52) | func (proxy *HttpProxy) ServeHTTP(rw http.ResponseWriter, req *http.Re...
    method httpsHandle (line 57) | func (proxy *HttpProxy) httpsHandle(host string, ctx *goproxy.ProxyCtx...
    method RoundTrip (line 62) | func (proxy *HttpProxy) RoundTrip(ctx *requestCtx) {
    method getReqCtx (line 86) | func (proxy *HttpProxy) getReqCtx(req *http.Request) *requestCtx {
    method onResponse (line 99) | func (proxy *HttpProxy) onResponse(resp *http.Response, ctx *goproxy.P...
    method roundTripUpgrade (line 111) | func (proxy *HttpProxy) roundTripUpgrade(ctx *requestCtx) (err error) {
  function NewHttpProxy (line 24) | func NewHttpProxy(ser *ProxyServe) *HttpProxy {
  function my_requestHanderFunc (line 45) | func my_requestHanderFunc(r *http.Request, ctx *goproxy.ProxyCtx) (*http...
  constant PROXY_CTX_NAME (line 50) | PROXY_CTX_NAME = "X-PPROXY-CTX-ID"

FILE: serve/reqCtx.go
  type requestCtx (line 17) | type requestCtx struct
    method init (line 61) | func (ctx *requestCtx) init() {
    method IsLocalRequest (line 104) | func (ctx *requestCtx) IsLocalRequest() bool {
    method GetIp (line 112) | func (ctx *requestCtx) GetIp() string {
    method PrintLog (line 117) | func (ctx *requestCtx) PrintLog() {
    method RoundTrip (line 136) | func (ctx *requestCtx) RoundTrip() {
    method badGateway (line 171) | func (ctx *requestCtx) badGateway(err error) {
    method DestAddr (line 177) | func (ctx *requestCtx) DestAddr() string {
    method saveRequestData (line 181) | func (ctx *requestCtx) saveRequestData() {
    method saveResponse (line 226) | func (ctx *requestCtx) saveResponse(res *http.Response) {
    method SetLog (line 268) | func (ctx *requestCtx) SetLog(k, v any) {
    method SetTimePoint (line 272) | func (ctx *requestCtx) SetTimePoint(key string) {
    method getNewDocid (line 276) | func (ctx *requestCtx) getNewDocid() int {
  function NewRequestCtx (line 45) | func NewRequestCtx(ser *ProxyServe, rw http.ResponseWriter, req *http.Re...
  function fixRequest (line 88) | func fixRequest(req *http.Request) {

FILE: serve/req_modifer.go
  type requestModifier (line 21) | type requestModifier struct
    method getJsPath (line 38) | func (reqMod *requestModifier) getJsPath(name string) string {
    method tryLoadJs (line 46) | func (reqMod *requestModifier) tryLoadJs(name string) (err error) {
    method loadAllJs (line 59) | func (reqMod *requestModifier) loadAllJs() error {
    method getJsContent (line 77) | func (reqMod *requestModifier) getJsContent(name string) (content stri...
    method CanMod (line 89) | func (reqMod *requestModifier) CanMod() bool {
    method parseJs (line 93) | func (reqMod *requestModifier) parseJs(jsStr string, name string, save...
    method getJsFnByName (line 128) | func (reqMod *requestModifier) getJsFnByName(name string) (*otto.Value...
    method rewrite (line 138) | func (reqMod *requestModifier) rewrite(data map[string]any, name strin...
  function NewRequestModifier (line 29) | func NewRequestModifier(ser *ProxyServe) *requestModifier {

FILE: serve/req_replay.go
  constant REPLAY_FLAG (line 11) | REPLAY_FLAG       = "Proxy-pproxy_replay"
  constant REPLAY_REMOTEADDR (line 12) | REPLAY_REMOTEADDR = "Proxy-pproxy_remoteaddr"
  constant REPLAY_USER_NAME (line 13) | REPLAY_USER_NAME  = "Proxy-pproxy_user"
  method handleReplay (line 16) | func (ctx *webRequestCtx) handleReplay() {
  method reqReplayPost (line 56) | func (ctx *webRequestCtx) reqReplayPost() {

FILE: serve/req_rewrite.go
  method reqRewriteByjs (line 14) | func (ser *ProxyServe) reqRewriteByjs(reqCtx *requestCtx) int {
  method reqRewrite (line 210) | func (ser *ProxyServe) reqRewrite(reqCtx *requestCtx) int {
  method reqRewriteByHosts (line 238) | func (ser *ProxyServe) reqRewriteByHosts(req *http.Request) int {
  function _reqMapToURLValue (line 271) | func _reqMapToURLValue(values any) url.Values {

FILE: serve/serve.go
  type ProxyServe (line 19) | type ProxyServe struct
    method ServeHTTP (line 46) | func (ser *ProxyServe) ServeHTTP(w http.ResponseWriter, req *http.Requ...
    method ServeHTTPProxy (line 77) | func (ser *ProxyServe) ServeHTTPProxy(w http.ResponseWriter, req *http...
    method Start (line 83) | func (ser *ProxyServe) Start() {
    method startAdmin (line 108) | func (ser *ProxyServe) startAdmin() {
    method getResponseByDocid (line 121) | func (ser *ProxyServe) getResponseByDocid(docid int) (resData *StoreTy...
    method getRequestByDocid (line 126) | func (ser *ProxyServe) getRequestByDocid(docid int) (reqData *StoreTyp...
    method getHostsFilePath (line 131) | func (ser *ProxyServe) getHostsFilePath() string {
    method loadHosts (line 135) | func (ser *ProxyServe) loadHosts() {
  type KvType (line 44) | type KvType
  function NewProxyServe (line 143) | func NewProxyServe(confPath string, port int) (*ProxyServe, error) {
  function setupLog (line 201) | func setupLog(dataDir string, port int) {

FILE: serve/sessions.go
  type clientSession (line 8) | type clientSession struct
  method regirestReq (line 17) | func (ser *ProxyServe) regirestReq(reqCtx *requestCtx) {
  method cleanExpiredSession (line 54) | func (ser *ProxyServe) cleanExpiredSession() {

FILE: serve/util.go
  function Int64ToBytes (line 23) | func Int64ToBytes(i int64) []byte {
  function IntToBytes (line 30) | func IntToBytes(i int) []byte {
  function IsLocalIP (line 37) | func IsLocalIP(host string) bool {
  function forgetRead (line 59) | func forgetRead(reader *io.ReadCloser) *bytes.Buffer {
  function dataEncode (line 66) | func dataEncode(data any) []byte {
  function dataDecode (line 75) | func dataDecode(dataInput []byte, out any) error {
  function getMapValStr (line 87) | func getMapValStr(m map[string]any, k string) string {
  function gzipDocode (line 94) | func gzipDocode(buf *bytes.Buffer) string {
  function gzipEncode (line 108) | func gzipEncode(data []byte) *bytes.Buffer {
  function parseURLInputAsSlice (line 116) | func parseURLInputAsSlice(input string) []string {
  function getFormValuesWithPrefix (line 128) | func getFormValuesWithPrefix(values url.Values, prefix string) map[strin...
  function getTextAreaHeightByString (line 139) | func getTextAreaHeightByString(mystr string, minHeight int) int {
  function getHostPortFromReq (line 147) | func getHostPortFromReq(req *http.Request) (host string, port int, err e...
  function parseHostPort (line 164) | func parseHostPort(hostPortstr string) (host string, port int, err error) {
  function checkURLValuesChange (line 180) | func checkURLValuesChange(first url.Values, second url.Values) (change b...
  function parseDocID (line 202) | func parseDocID(strid string) (docid int, err error) {
  function removeHeader (line 210) | func removeHeader(req *http.Request) {
  function getPostData (line 218) | func getPostData(req *http.Request) (post *url.Values) {
  function headerEncode (line 237) | func headerEncode(data []byte) []byte {

FILE: serve/web.go
  type webRequestCtx (line 23) | type webRequestCtx struct
    method checkLogin (line 117) | func (ctx *webRequestCtx) checkLogin() {
    method handle_index (line 129) | func (ctx *webRequestCtx) handle_index() {
    method handle_useage (line 133) | func (ctx *webRequestCtx) handle_useage() {
    method getRewriteJsInfo (line 137) | func (ctx *webRequestCtx) getRewriteJsInfo(name string, title string) ...
    method handleConfig (line 186) | func (ctx *webRequestCtx) handleConfig() {
    method handle_response (line 235) | func (ctx *webRequestCtx) handle_response() {
    method jsAlert (line 282) | func (ctx *webRequestCtx) jsAlert(msg string) {
    method jsAlertJump (line 286) | func (ctx *webRequestCtx) jsAlertJump(msg string, urlStr string) {
    method handle_about (line 290) | func (ctx *webRequestCtx) handle_about() {
    method handle_logout (line 294) | func (ctx *webRequestCtx) handle_logout() {
    method handle_login (line 300) | func (ctx *webRequestCtx) handle_login() {
    method render (line 332) | func (ctx *webRequestCtx) render(name string, layout bool) {
    method showError (line 337) | func (ctx *webRequestCtx) showError(msg string) {
    method showErrorOrAlert (line 343) | func (ctx *webRequestCtx) showErrorOrAlert(msg string) {
  method handleLocalReq (line 35) | func (ser *ProxyServe) handleLocalReq(w http.ResponseWriter, req *http.R...
  method web_checkLogin (line 97) | func (ser *ProxyServe) web_checkLogin(req *http.Request) (user *User, is...
  function reader_html_include (line 351) | func reader_html_include(fileName string) string {
  function render_html (line 366) | func render_html(fileName string, values map[string]any, layout bool) st...
  method handleUserInfo (line 388) | func (ser *ProxyServe) handleUserInfo(w http.ResponseWriter, req *http.R...

FILE: serve/web_file.go
  type webFileInfo (line 16) | type webFileInfo struct
    method String (line 53) | func (f *webFileInfo) String() string {
    method link (line 57) | func (f *webFileInfo) link() string {
    method getContent (line 66) | func (f *webFileInfo) getContent() string {
    method Close (line 78) | func (f *webFileInfo) Close() {
    method subFiles (line 87) | func (f *webFileInfo) subFiles() ([]*webFileInfo, error) {
  function newWebFileInfo (line 27) | func newWebFileInfo(rootDir, name string) (*webFileInfo, error) {
  method getWebFilePath (line 106) | func (ser *ProxyServe) getWebFilePath(name string) (fullPath string, nam...
  method handle_file (line 120) | func (ctx *webRequestCtx) handle_file() {
  method handle_file_edit (line 172) | func (ctx *webRequestCtx) handle_file_edit() {
  method handle_file_del (line 195) | func (ctx *webRequestCtx) handle_file_del() {}
  method handle_file_new (line 197) | func (ctx *webRequestCtx) handle_file_new() {
  method handle_file_save (line 266) | func (ctx *webRequestCtx) handle_file_save() {

FILE: serve/wsClient.go
  type wsClient (line 11) | type wsClient struct
    method checkFilter (line 28) | func (client *wsClient) checkFilter(req *http.Request, reqCtx *request...

FILE: serve/wsServer.go
  type wsServer (line 14) | type wsServer struct
    method init (line 39) | func (wsSer *wsServer) init() {
    method remove (line 61) | func (wsSer *wsServer) remove(id string) {
    method broadProxyClientNum (line 69) | func (wsSer *wsServer) broadProxyClientNum() {
    method getResponse (line 76) | func (wsSer *wsServer) getResponse(ns *socketio.NameSpace, docidStr st...
    method saveFilter (line 102) | func (wsSer *wsServer) saveFilter(ns *socketio.NameSpace, formData str...
    method send (line 127) | func (wsSer *wsServer) send(ns *socketio.NameSpace, msgName string, da...
    method broadcastReq (line 149) | func (wsSer *wsServer) broadcastReq(req *http.Request, reqCtx *request...
    method broadcast (line 171) | func (wsSer *wsServer) broadcast(name string, data any, encode bool) {
  method wsInit (line 21) | func (ser *ProxyServe) wsInit() {
  function newWsServer (line 25) | func newWsServer(ser *ProxyServe) *wsServer {
Condensed preview — 59 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (505K chars).
[
  {
    "path": ".gitignore",
    "chars": 316,
    "preview": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture spe"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 882,
    "preview": "2016-07-27\n   1. 升级依赖   \n\n2016-07-27\n    1. version 0.5.2\n    2. 修复文件上传页面错误\n    3. 更新lib otto ,boltdb 为最新版本\n    \n2016-03"
  },
  {
    "path": "LICENSE",
    "chars": 1068,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 du\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "README-en.md",
    "chars": 2808,
    "preview": "pproxy 0.5.2\n======\nHTTP protocol analysis tool.  \n\n\n\nfeatures:\n<pre>\n1.url redirect\n   redirect *http://www.baidu.com/s"
  },
  {
    "path": "README.md",
    "chars": 3578,
    "preview": "pproxy 0.5.2\n======\n## intro\nHTTP 协议抓包代理程序, HTTP 协议调试工具。  \n采用 Go 编写,采用 BS 模式(s-代理程序,b-会话查看、配置管理等功能)  \n\n0.4.2版本已经支持websoc"
  },
  {
    "path": "assest.json",
    "chars": 67,
    "preview": "{\n  \"src\":\"res\",\n  \"dest\":\"serve/assest.go\",\n  \"package\":\"serve\"\n}\n"
  },
  {
    "path": "build.sh",
    "chars": 212,
    "preview": "#!/bin/bash\n# build for window: build.sh windows\n# default linux\n#./gox -build-toolchain\n\nset -e\ncd $(dirname $0)\n\n#expo"
  },
  {
    "path": "fmt.sh",
    "chars": 103,
    "preview": "#/bin/bash\ncd $(dirname $0)\ncd serve\n#gofmt -tabs=false -w=true -tabwidth=4 .\ngofmt -w=true -s=true .\n\n"
  },
  {
    "path": "go.mod",
    "chars": 706,
    "preview": "module github.com/hidu/pproxy\n\ngo 1.23\n\nrequire (\n\tgithub.com/Unknwon/goconfig v1.0.0\n\tgithub.com/boltdb/bolt v1.3.1\n\tgi"
  },
  {
    "path": "go.sum",
    "chars": 5708,
    "preview": "github.com/Unknwon/goconfig v1.0.0 h1:9IAu/BYbSLQi8puFjUQApZTxIHqSwrj5d8vpP8vTq4A=\ngithub.com/Unknwon/goconfig v1.0.0/go"
  },
  {
    "path": "main.go",
    "chars": 993,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/hidu/pproxy/serve\"\n)\n\nvar configPath = flag.String(\"con"
  },
  {
    "path": "res/conf/demo.conf",
    "chars": 882,
    "preview": "##########################################################\n#                  pproxy demo conf                      #\n##"
  },
  {
    "path": "res/css/flat.css",
    "chars": 35919,
    "preview": ".dropdown-arrow-inverse {\n  border-bottom-color: #34495e !important;\n  border-top-color: #34495e !important;\n}\na {\n  col"
  },
  {
    "path": "res/css/style.css",
    "chars": 3216,
    "preview": "@CHARSET \"UTF-8\";\n.clear {\n  clear: both;\n}\nhtml,body{margin: 0;padding: 0}\n#nav {\n  filter: progid:DXImageTransform.Mic"
  },
  {
    "path": "res/js/base64.js",
    "chars": 3353,
    "preview": "/**\n*\n*  Base64 encode / decode\n*  http://www.webtoolkit.info/\n*\n**/\nvar Base64 = {\n\n// private property\n_keyStr : \"ABCD"
  },
  {
    "path": "res/js/default.js",
    "chars": 247,
    "preview": "function pproxy_tab_sup(target){\n\t$(target).find(\"textarea\").bind('keydown', function(e) {\n\t    if (e.keyCode == 9 ) {\n\t"
  },
  {
    "path": "res/js/jquery.js",
    "chars": 91668,
    "preview": "/*! jQuery v1.6.4 http://jquery.com/ | http://jquery.org/license */\n(function(a,b){function cu(a){return f.isWindow(a)?a"
  },
  {
    "path": "res/js/session.js",
    "chars": 12438,
    "preview": "var socket = io.connect();\nvar connectNum=0;\nvar pproxy_colors=[\"#FFFFFF\",\"#CCFFFF\",\"#FFCCCC\",\"#99CCCC\",\"996699\",\"#CC999"
  },
  {
    "path": "res/js/socket.io.js",
    "chars": 100851,
    "preview": "/*! Socket.IO.js build:0.9.10, development. Copyright(c) 2011 LearnBoost <dev@learnboost.com> MIT Licensed */\n\nvar io = "
  },
  {
    "path": "res/private/client_cert.pem",
    "chars": 1318,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIDnzCCAoegAwIBAgIJAKBuAUr+T7ouMA0GCSqGSIb3DQEBBQUAMGYxCzAJBgNV\nBAYTAlhYMRUwEwYDVQQHDAxEZWZ"
  },
  {
    "path": "res/private/server_key.pem",
    "chars": 1679,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA0JsXsBi/sfgCRqfeSeff1almRidf0wZnjt/2htKmjzluJ/f0\n+irK20AOI4aCtLg+zKopJ8a"
  },
  {
    "path": "res/sjs/req_rewrite.js",
    "chars": 1385,
    "preview": "\nfunction pproxy_rewrite(req){\n\treq.get=pproxy_params_copy(req.origin.get||{});\n\treq.post=pproxy_params_copy(req.origin."
  },
  {
    "path": "res/tpl/about.html",
    "chars": 475,
    "preview": "<div id=\"bd0\">\n <br/>\n<p class=\"h3\">about</p>\n <p>HTTP protocol analysis tool.</p>\n <p>Based on BS architecture,written "
  },
  {
    "path": "res/tpl/config/req_demo.html",
    "chars": 1056,
    "preview": "<div style=\"color:gray\">\nnote:\n<ol>\n<li>put <font color=blue>//ignore</font> at the first line to ignore the js</li>\n<li"
  },
  {
    "path": "res/tpl/config/req_form.html",
    "chars": 761,
    "preview": "<span class=\"h6\">req rewrite</span>\n{{range $i,$js:=.jss}}\n<form  method=\"post\" action=\"/config\" autocomplete=\"off\" targ"
  },
  {
    "path": "res/tpl/config.html",
    "chars": 524,
    "preview": "<script src=\"/res/js/default.js\"></script>\n<style>\n#configTable form{padding:10px;margin-right: 20px}\n</style>\n<br/>\n<di"
  },
  {
    "path": "res/tpl/error.html",
    "chars": 113,
    "preview": "<div id=\"bd\" style=\"text-align:center;font-size:20px\">\nError:\n<span class=\"text-warning\">{{.error}}</span>\n</div>"
  },
  {
    "path": "res/tpl/file.html",
    "chars": 967,
    "preview": "<div id=\"bd\">\n<table class=\"tb_1\">\n<caption>\n<div class=\"left\">\n&nbsp;\n/f/{{.currentDir}} &nbsp;\n<a href=\"/file?op=new&d"
  },
  {
    "path": "res/tpl/file_edit.html",
    "chars": 1089,
    "preview": "<div id=\"bd\">\n<div class=\"h6\">edit file</div>\n<form method=\"post\" action=\"/file\" target=\"ifr_form\">\n<input type=\"hidden\""
  },
  {
    "path": "res/tpl/file_new.html",
    "chars": 796,
    "preview": "<div id=\"bd\">\n\n<div class=\"h6\">new file</div>\n<form method=\"post\" action=\"/file\" target=\"ifr_form\">\n<input type=\"hidden\""
  },
  {
    "path": "res/tpl/layout.html",
    "chars": 1574,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<link href=\"/res/img/favicon.ico\"  rel=\"shortcut icon\" />\n<meta nam"
  },
  {
    "path": "res/tpl/login.html",
    "chars": 702,
    "preview": "<div id=\"bd0\">\n<br/><br/><br/><br/><br/>\n<div class=\"login-screen\">\n<form method=\"post\" action=\"/login\" target=\"ifr_form"
  },
  {
    "path": "res/tpl/network.html",
    "chars": 2144,
    "preview": "<script src=\"/res/js/base64.js\"></script>\n<script src=\"/res/js/socket.io.js\"></script>\n<script src=\"/res/js/session.js\">"
  },
  {
    "path": "res/tpl/replay.html",
    "chars": 3887,
    "preview": "<div id=\"bd\">\n<br/>\n<form action=\"/replay\" method=\"post\" id=\"replay_form\" target=\"_blank\" class=\"form_0\" autocomplete=\"o"
  },
  {
    "path": "res/tpl/replay_direct.html",
    "chars": 625,
    "preview": "<div id=\"bd\">\n<br/>\n<br/>\n<form action=\"{{.form.basic.action_url}}\" method=\"{{.form.basic.method}}\" class=\"form_0\" id=\"f"
  },
  {
    "path": "res/tpl/useage.html",
    "chars": 1754,
    "preview": "<div id=\"bd0\">\n<br/>\n<p class=\"h4\">Useage</p>\n<p class=\"h6\">1.Client(eg:phone)</p>\n<pre>\nset wifi http proxy:\nproxy host"
  },
  {
    "path": "res/version",
    "chars": 5,
    "preview": "0.5.2"
  },
  {
    "path": "script/create_dest_zip.sh",
    "chars": 1234,
    "preview": "#!/bin/bash\n\necho \"bye bye\"\nexit\n\ncd $(dirname $0)\ncd ../\n\nif [ -z \"$1\" ];then\n    gox -arch amd64 -os linux\n    bash bu"
  },
  {
    "path": "script/pproxy_control.sh",
    "chars": 1329,
    "preview": "#!/bin/bash\n\nCUR_DIR=$(dirname $0)\n\nBIN_NAME=\"./pproxy\"\nDEFAULT_CONF=\"./conf/pproxy.conf\"\nINTRO=\"get more info from gith"
  },
  {
    "path": "script/windows_run.bat",
    "chars": 76,
    "preview": "echo \"start pproxy,don't close it\"\n@echo off\npproxy -conf=./conf/pproxy.conf"
  },
  {
    "path": "serve/assest.go",
    "chars": 116483,
    "preview": "// generated by goassest(0.5.3 20161126)\n// https://github.com/hidu/goassest/\n\npackage serve\n\nimport (\n\t\"bytes\"\n\t\"compre"
  },
  {
    "path": "serve/auth.go",
    "chars": 1459,
    "preview": "package serve\n\nimport (\n\t\"encoding/base64\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/hidu/goutils/str_util\"\n)\n\nvar proxyAutho"
  },
  {
    "path": "serve/broadcast.go",
    "chars": 725,
    "preview": "package serve\n\nimport (\n\t\"strconv\"\n)\n\n// broadcastReq broadcast request to user's browser\nfunc (ser *ProxyServe) broadca"
  },
  {
    "path": "serve/certs.go",
    "chars": 963,
    "preview": "package serve\n\nimport (\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"log\"\n\t\"os\"\n)\n\nfunc newCaCert(caCert []byte, caKey []byte) (tls.Ce"
  },
  {
    "path": "serve/config.go",
    "chars": 6653,
    "preview": "package serve\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/Unknwon/go"
  },
  {
    "path": "serve/init.go",
    "chars": 95,
    "preview": "package serve\n\n// 系统版本\nvar PproxyVersion string\n\nfunc init() {\n\tPproxyVersion = GetVersion()\n}\n"
  },
  {
    "path": "serve/kvStore.go",
    "chars": 2666,
    "preview": "package serve\n\nimport (\n\t\"time\"\n\n\t\"github.com/boltdb/bolt\"\n\t\"github.com/hidu/goutils/time_util\"\n)\n\ntype KV_TBALE_NAME_TY"
  },
  {
    "path": "serve/proxy.go",
    "chars": 3546,
    "preview": "package serve\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/el"
  },
  {
    "path": "serve/reqCtx.go",
    "chars": 7281,
    "preview": "package serve\n\nimport (\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"net/url\"\n\t\"strconv"
  },
  {
    "path": "serve/req_modifer.go",
    "chars": 4060,
    "preview": "package serve\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/hidu/goutils/fs\"\n\t\"github.com/rob"
  },
  {
    "path": "serve/req_replay.go",
    "chars": 3154,
    "preview": "package serve\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\nconst (\n\tREPLAY_FLAG       = \"Proxy-pproxy_replay\"\n\t"
  },
  {
    "path": "serve/req_rewrite.go",
    "chars": 6961,
    "preview": "package serve\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc (ser *ProxySer"
  },
  {
    "path": "serve/serve.go",
    "chars": 4999,
    "preview": "package serve\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sync\"\n\t\"syn"
  },
  {
    "path": "serve/sessions.go",
    "chars": 1405,
    "preview": "package serve\n\nimport (\n\t\"log\"\n\t\"time\"\n)\n\ntype clientSession struct {\n\tIp               string\n\tPort             string\n"
  },
  {
    "path": "serve/util.go",
    "chars": 4876,
    "preview": "package serve\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t// \"encoding/base64\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\""
  },
  {
    "path": "serve/web.go",
    "chars": 10073,
    "preview": "package serve\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"html\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strc"
  },
  {
    "path": "serve/web_file.go",
    "chars": 7104,
    "preview": "package serve\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/hidu/go"
  },
  {
    "path": "serve/wsClient.go",
    "chars": 1944,
    "preview": "package serve\n\nimport (\n\t\"net/http\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/googollee/go-socket.io\"\n)\n\ntype wsClient s"
  },
  {
    "path": "serve/wsServer.go",
    "chars": 4483,
    "preview": "package serve\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\n\t\"github.com/googollee/go-socket.io\"\n\t\"github.com/"
  }
]

About this extraction

This page contains the full source code of the hidu/pproxy GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 59 files (466.2 KB), approximately 188.1k tokens, and a symbol index with 300 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.

Copied to clipboard!